v0.16.3
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Public Attributes | Static Private Member Functions | Static Private Attributes | List of all members
ElasticTie::SetIntegrationOnTiePrismFaces Struct Reference

#include "tutorials/vec-11_elastic_tie_mesh/src/ElasticTie.hpp"

Collaboration diagram for ElasticTie::SetIntegrationOnTiePrismFaces:
[legend]

Public Types

using FunRule = boost::function< int(int)>
 

Public Member Functions

 SetIntegrationOnTiePrismFaces ()=delete
 
 SetIntegrationOnTiePrismFaces (int tie_ref_level=1)
 
 SetIntegrationOnTiePrismFaces (FunRule fun_rule, int tie_ref_level=1)
 
MoFEMErrorCode operator() (ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
 

Public Attributes

FunRule funRule = [](int p) { return 2 * p + 1; }
 
int tieRefLevel = 1
 

Static Private Member Functions

static MoFEMErrorCode setBaseQuadrature (FlatPrismElementForcesAndSourcesCore &fe, const int rule)
 
static MoFEMErrorCode projectPointToMasterPlane (const double *master_coords, const double *point, double *projected_point)
 
static MoFEMErrorCode projectSlavePointsToMasterPlane (const double *master_coords, const MatrixDouble &slave_global_coords, MatrixDouble &master_global_coords)
 
static MoFEMErrorCode refineQuadrature (FlatPrismElementForcesAndSourcesCore &fe, const int refinement_levels, MatrixDouble &ref_gauss_pts)
 

Static Private Attributes

static std::map< std::pair< int, int >, MatrixDouble > mapRefCoords
 

Detailed Description

Definition at line 237 of file ElasticTie.hpp.

Member Typedef Documentation

◆ FunRule

using ElasticTie::SetIntegrationOnTiePrismFaces::FunRule = boost::function<int(int)>

Definition at line 239 of file ElasticTie.hpp.

Constructor & Destructor Documentation

◆ SetIntegrationOnTiePrismFaces() [1/3]

ElasticTie::SetIntegrationOnTiePrismFaces::SetIntegrationOnTiePrismFaces ( )
delete

◆ SetIntegrationOnTiePrismFaces() [2/3]

ElasticTie::SetIntegrationOnTiePrismFaces::SetIntegrationOnTiePrismFaces ( int  tie_ref_level = 1)
inline

Definition at line 245 of file ElasticTie.hpp.

◆ SetIntegrationOnTiePrismFaces() [3/3]

ElasticTie::SetIntegrationOnTiePrismFaces::SetIntegrationOnTiePrismFaces ( FunRule  fun_rule,
int  tie_ref_level = 1 
)
inline

Definition at line 248 of file ElasticTie.hpp.

249 : funRule(fun_rule), tieRefLevel(tie_ref_level) {}

Member Function Documentation

◆ operator()()

MoFEMErrorCode ElasticTie::SetIntegrationOnTiePrismFaces::operator() ( ForcesAndSourcesCore *  fe_raw_ptr,
int  order_row,
int  order_col,
int  order_data 
)
inline

Definition at line 251 of file ElasticTie.hpp.

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
258 if (tieRefLevel < 0) {
259 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
260 "-tie_ref_level has to be >= 0");
261 }
262
263 if (rule < 0 || rule >= QUAD_2D_TABLE_SIZE) {
264 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
265 "Triangle quadrature rule %d is not available for TIE prism face "
266 "integration",
267 rule);
268 }
269
270 if (QUAD_2D_TABLE[rule]->dim != 2) {
271 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
272 "Expected 2D quadrature for TIE prism face integration");
273 }
274
275 if (QUAD_2D_TABLE[rule]->order < rule) {
276 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
277 "Wrong quadrature order %d < %d for TIE prism face integration",
278 QUAD_2D_TABLE[rule]->order, rule);
279 }
280
281 CHKERR setBaseQuadrature(*fe_ptr, rule);
282
283 if (tieRefLevel > 0) {
284 const auto cache_key = std::make_pair(rule, tieRefLevel);
285 auto it = mapRefCoords.find(cache_key);
286 if (it == mapRefCoords.end()) {
287 MatrixDouble ref_gauss_pts;
288 CHKERR refineQuadrature(*fe_ptr, tieRefLevel, ref_gauss_pts);
289 mapRefCoords[cache_key].swap(ref_gauss_pts);
290 it = mapRefCoords.find(cache_key);
291 }
292 fe_ptr->gaussPts = it->second;
293 }
294
295 const MatrixDouble slave_gauss_pts = fe_ptr->gaussPts;
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) {
306 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
307 "TIE prism is expected to have 6 nodes");
308 }
309
310 std::array<EntityHandle, 3> face_conn;
311 switch (side) {
312 case SLAVE_FACE_SIDE:
313 face_conn = {prism_conn[0], prism_conn[1], prism_conn[2]};
314 break;
315 case MASTER_FACE_SIDE:
316 face_conn = {prism_conn[3], prism_conn[4], prism_conn[5]};
317 break;
318 default:
319 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
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; // nodal coords
328 std::array<double, 9> master_coords; // nodal coords
329 CHKERR get_prism_face_coords(SLAVE_FACE_SIDE, slave_coords);
330 CHKERR get_prism_face_coords(MASTER_FACE_SIDE, master_coords);
331
332 MatrixDouble slave_global_coords(nb_gauss_pts, 3, false); // gp coords
333 MatrixDouble master_global_coords(nb_gauss_pts, 3, false); //gp coords
334 MatrixDouble slave_shape(nb_gauss_pts, 3, false);
335 CHKERR ShapeMBTRI(&slave_shape(0, 0), &slave_gauss_pts(0, 0),
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
346 CHKERR projectSlavePointsToMasterPlane(master_coords.data(),
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 =
358 isInsideReferenceTriangle(master_local_coords(gg, 0),
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
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int order
PetscErrorCode ShapeMBTRI(double *N, const double *X, const double *Y, const int G_DIM)
calculate shape functions on triangle
Definition fem_tools.c:182
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)
Definition ddTensor0.hpp:33
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
#define QUAD_2D_TABLE_SIZE
Definition quad.h:174
static QUAD *const QUAD_2D_TABLE[]
Definition quad.h:175
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)

◆ projectPointToMasterPlane()

static MoFEMErrorCode ElasticTie::SetIntegrationOnTiePrismFaces::projectPointToMasterPlane ( const double *  master_coords,
const double *  point,
double *  projected_point 
)
inlinestaticprivate

Definition at line 390 of file ElasticTie.hpp.

392 {
394
395 // For the infinite master plane, the closest point is the orthogonal
396 // projection along the plane normal.
397 const double ax = master_coords[0];
398 const double ay = master_coords[1];
399 const double az = master_coords[2];
400 const double bx = master_coords[3];
401 const double by = master_coords[4];
402 const double bz = master_coords[5];
403 const double cx = master_coords[6];
404 const double cy = master_coords[7];
405 const double cz = master_coords[8];
406
407 const double abx = bx - ax;
408 const double aby = by - ay;
409 const double abz = bz - az;
410 const double acx = cx - ax;
411 const double acy = cy - ay;
412 const double acz = cz - az;
413
414 const double nx = aby * acz - abz * acy;
415 const double ny = abz * acx - abx * acz;
416 const double nz = abx * acy - aby * acx;
417 const double n_norm_sq = nx * nx + ny * ny + nz * nz;
418 if (n_norm_sq <= std::numeric_limits<double>::epsilon()) {
419 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
420 "Degenerated master triangle plane");
421 }
422
423 const double px = point[0] - ax;
424 const double py = point[1] - ay;
425 const double pz = point[2] - az;
426 const double signed_distance = (px * nx + py * ny + pz * nz) / n_norm_sq;
427 projected_point[0] = point[0] - signed_distance * nx;
428 projected_point[1] = point[1] - signed_distance * ny;
429 projected_point[2] = point[2] - signed_distance * nz;
430
432 }

◆ projectSlavePointsToMasterPlane()

static MoFEMErrorCode ElasticTie::SetIntegrationOnTiePrismFaces::projectSlavePointsToMasterPlane ( const double *  master_coords,
const MatrixDouble &  slave_global_coords,
MatrixDouble &  master_global_coords 
)
inlinestaticprivate

Definition at line 434 of file ElasticTie.hpp.

436 {
438
439 // The weak form is integrated on the slave surface. Each slave Gauss point
440 // is paired with its orthogonal projection on the infinite plane defined
441 // by the master triangle.
442 master_global_coords.resize(slave_global_coords.size1(), 3, false);
443 for (size_t gg = 0; gg != slave_global_coords.size1(); ++gg) {
444 CHKERR projectPointToMasterPlane(master_coords,
445 &slave_global_coords(gg, 0),
446 &master_global_coords(gg, 0));
447 }
448
450 }
static MoFEMErrorCode projectPointToMasterPlane(const double *master_coords, const double *point, double *projected_point)

◆ refineQuadrature()

static MoFEMErrorCode ElasticTie::SetIntegrationOnTiePrismFaces::refineQuadrature ( FlatPrismElementForcesAndSourcesCore &  fe,
const int  refinement_levels,
MatrixDouble &  ref_gauss_pts 
)
inlinestaticprivate

Definition at line 452 of file ElasticTie.hpp.

454 {
456
457 constexpr int num_nodes = 3;
458 moab::Core moab_ref;
459 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
460 EntityHandle nodes[num_nodes];
461 for (int nn = 0; nn != num_nodes; ++nn)
462 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
463
464 EntityHandle tri;
465 CHKERR moab_ref.create_element(MBTRI, nodes, num_nodes, tri);
466 MoFEM::CoreTmp<-1> mofem_ref_core(moab_ref, PETSC_COMM_SELF, -2);
467 MoFEM::Interface &m_field_ref = mofem_ref_core;
468
469 {
470 Range tris(tri, tri);
471 Range edges;
472 // Force MOAB to materialise the triangle edges before the bit-ref
473 // database is seeded. The working reference-refinement snippets all do
474 // this, and the side-number lookup below verifies that MOAB sees a
475 // consistent local edge numbering on the temporary reference triangle.
476 CHKERR m_field_ref.get_moab().get_adjacencies(
477 tris, 1, true, edges, moab::Interface::UNION);
478 for (auto edge : edges) {
479 int side_number = -1, sense = 0, offset = 0;
480 CHKERR moab_ref.side_number(tri, edge, side_number, sense, offset);
481 }
482 CHKERR m_field_ref.getInterface<BitRefManager>()->setBitRefLevel(
483 tris, BitRefLevel().set(0), false, VERBOSE);
484 }
485
486 auto *m_ref = m_field_ref.getInterface<MeshRefinement>();
487 for (int ll = 0; ll != refinement_levels; ++ll) {
488 Range tris;
489 CHKERR m_field_ref.getInterface<BitRefManager>()
490 ->getEntitiesByTypeAndRefLevel(BitRefLevel().set(ll),
491 BitRefLevel().set(), MBTRI, tris);
492
493 Range edges;
494 CHKERR moab_ref.get_adjacencies(tris, 1, true, edges,
495 moab::Interface::UNION);
496
497 const BitRefLevel child_bit = BitRefLevel().set(ll + 1);
498 CHKERR m_ref->addVerticesInTheMiddleOfEdges(edges, child_bit);
499 CHKERR m_ref->refineTris(tris, child_bit, QUIET, false);
500 }
501
502 Range tris;
503 CHKERR m_field_ref.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
504 BitRefLevel().set(refinement_levels), BitRefLevel().set(), MBTRI, tris);
505
506 MatrixDouble ref_coords(tris.size(), 9, false);
507 int tt = 0;
508 for (auto tit = tris.begin(); tit != tris.end(); ++tit, ++tt) {
509 int num_conn;
510 const EntityHandle *conn;
511 CHKERR moab_ref.get_connectivity(*tit, conn, num_conn, false);
512 CHKERR moab_ref.get_coords(conn, num_conn, &ref_coords(tt, 0));
513 }
514
515 const size_t nb_gauss_pts = fe.gaussPts.size2();
516 MatrixDouble shape_n(nb_gauss_pts, 3, false);
517 CHKERR ShapeMBTRI(&shape_n(0, 0), &fe.gaussPts(0, 0), &fe.gaussPts(1, 0),
518 nb_gauss_pts);
519 ref_gauss_pts.resize(3, nb_gauss_pts * ref_coords.size1(), false);
520 int gg = 0;
521 for (size_t rr = 0; rr != ref_coords.size1(); ++rr) {
522 double *tri_coords = &ref_coords(rr, 0);
524 CHKERR Tools::getTriNormal(tri_coords, &t_normal(0));
525 const double det = t_normal.l2();
526 for (size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
527 for (int dd = 0; dd != 2; ++dd) {
528 ref_gauss_pts(dd, gg) =
529 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
530 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
531 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
532 }
533 ref_gauss_pts(2, gg) = fe.gaussPts(2, ggg) * det;
534 }
535 }
536
538 }
@ QUIET
@ VERBOSE
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ setBaseQuadrature()

static MoFEMErrorCode ElasticTie::SetIntegrationOnTiePrismFaces::setBaseQuadrature ( FlatPrismElementForcesAndSourcesCore &  fe,
const int  rule 
)
inlinestaticprivate

Definition at line 376 of file ElasticTie.hpp.

377 {
379 const size_t nb_gauss_pts = QUAD_2D_TABLE[rule]->npoints;
380 fe.gaussPts.resize(3, nb_gauss_pts, false);
381 cblas_dcopy(nb_gauss_pts, &QUAD_2D_TABLE[rule]->points[1], 3,
382 &fe.gaussPts(0, 0), 1);
383 cblas_dcopy(nb_gauss_pts, &QUAD_2D_TABLE[rule]->points[2], 3,
384 &fe.gaussPts(1, 0), 1);
385 cblas_dcopy(nb_gauss_pts, QUAD_2D_TABLE[rule]->weights, 1,
386 &fe.gaussPts(2, 0), 1);
388 }
int npoints
Definition quad.h:29

Member Data Documentation

◆ funRule

FunRule ElasticTie::SetIntegrationOnTiePrismFaces::funRule = [](int p) { return 2 * p + 1; }

Definition at line 240 of file ElasticTie.hpp.

240{ return 2 * p + 1; };

◆ mapRefCoords

std::map<std::pair<int, int>, MatrixDouble> ElasticTie::SetIntegrationOnTiePrismFaces::mapRefCoords
inlinestaticprivate

Definition at line 540 of file ElasticTie.hpp.

◆ tieRefLevel

int ElasticTie::SetIntegrationOnTiePrismFaces::tieRefLevel = 1

Definition at line 241 of file ElasticTie.hpp.


The documentation for this struct was generated from the following file: