252 {
254
255 auto fe_ptr = static_cast<FlatPrismElementForcesAndSourcesCore *>(fe_raw_ptr);
256 const int rule =
funRule(std::max(order_data, std::max(order_row, order_col)));
257
260 "-tie_ref_level has to be >= 0");
261 }
262
265 "Triangle quadrature rule %d is not available for TIE prism face "
266 "integration",
267 rule);
268 }
269
272 "Expected 2D quadrature for TIE prism face integration");
273 }
274
277 "Wrong quadrature order %d < %d for TIE prism face integration",
279 }
280
282
284 const auto cache_key = std::make_pair(rule,
tieRefLevel);
291 }
292 fe_ptr->gaussPts = it->second;
293 }
294
296 const auto nb_gauss_pts = slave_gauss_pts.size2();
297
298 auto &moab = fe_ptr->mField.get_moab();
299 auto get_prism_face_coords = [&](const int side, std::array<double, 9> &coords) {
301 const EntityHandle prism = fe_ptr->getFEEntityHandle();
302 const EntityHandle *prism_conn = nullptr;
303 int num_prism_nodes = 0;
304 CHKERR moab.get_connectivity(prism, prism_conn, num_prism_nodes,
true);
305 if (num_prism_nodes != 6) {
307 "TIE prism is expected to have 6 nodes");
308 }
309
310 std::array<EntityHandle, 3> face_conn;
311 switch (side) {
313 face_conn = {prism_conn[0], prism_conn[1], prism_conn[2]};
314 break;
316 face_conn = {prism_conn[3], prism_conn[4], prism_conn[5]};
317 break;
318 default:
320 "Unsupported TIE prism triangle side %d", side);
321 }
322
323 CHKERR moab.get_coords(face_conn.data(), 3, coords.data());
325 };
326
327 std::array<double, 9> slave_coords;
328 std::array<double, 9> master_coords;
331
332 MatrixDouble slave_global_coords(nb_gauss_pts, 3,
false);
333 MatrixDouble master_global_coords(nb_gauss_pts, 3,
false);
336 &slave_gauss_pts(1, 0), nb_gauss_pts);
337 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
338 for (
int dd = 0;
dd != 3; ++
dd) {
339 slave_global_coords(gg, dd) =
340 slave_shape(gg, 0) * slave_coords[0 +
dd] +
341 slave_shape(gg, 1) * slave_coords[3 +
dd] +
342 slave_shape(gg, 2) * slave_coords[6 +
dd];
343 }
344 }
345
347 slave_global_coords,
348 master_global_coords);
349
350 MatrixDouble master_local_coords(nb_gauss_pts, 2,
false);
351 CHKERR Tools::getLocalCoordinatesOnReferenceThreeNodeTri(
352 master_coords.data(), &master_global_coords(0, 0),
353 master_global_coords.size1(), &master_local_coords(0, 0));
354
355 MatrixDouble combined_gauss_pts(3, 2 * nb_gauss_pts,
false);
356 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
357 const bool valid_master_point =
359 master_local_coords(gg, 1));
360 const double paired_weight = valid_master_point ? slave_gauss_pts(2, gg) : 0.;
361
362 combined_gauss_pts(0, gg) = slave_gauss_pts(0, gg);
363 combined_gauss_pts(1, gg) = slave_gauss_pts(1, gg);
364 combined_gauss_pts(2, gg) = paired_weight;
365
366 combined_gauss_pts(0, gg + nb_gauss_pts) = master_local_coords(gg, 0);
367 combined_gauss_pts(1, gg + nb_gauss_pts) = master_local_coords(gg, 1);
368 combined_gauss_pts(2, gg + nb_gauss_pts) = paired_weight;
369 }
370 fe_ptr->gaussPts.swap(combined_gauss_pts);
371
373 }
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
bool isInsideReferenceTriangle(const double xi, const double eta, const double tol=1e-8)
constexpr int MASTER_FACE_SIDE
constexpr int SLAVE_FACE_SIDE
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
UBlasMatrix< double > MatrixDouble
#define QUAD_2D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
static MoFEMErrorCode setBaseQuadrature(FlatPrismElementForcesAndSourcesCore &fe, const int rule)
static MoFEMErrorCode projectSlavePointsToMasterPlane(const double *master_coords, const MatrixDouble &slave_global_coords, MatrixDouble &master_global_coords)
static std::map< std::pair< int, int >, MatrixDouble > mapRefCoords
static MoFEMErrorCode refineQuadrature(FlatPrismElementForcesAndSourcesCore &fe, const int refinement_levels, MatrixDouble &ref_gauss_pts)