v0.16.0
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 85 of file ElasticTie.hpp.

Member Typedef Documentation

◆ FunRule

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

Definition at line 87 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 93 of file ElasticTie.hpp.

◆ SetIntegrationOnTiePrismFaces() [3/3]

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

Definition at line 96 of file ElasticTie.hpp.

97 : 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 99 of file ElasticTie.hpp.

100 {
102
103 auto fe_ptr = static_cast<FlatPrismElementForcesAndSourcesCore *>(fe_raw_ptr);
104 const int rule = funRule(std::max(order_data, std::max(order_row, order_col)));
105
106 if (tieRefLevel < 0) {
107 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
108 "-tie_ref_level has to be >= 0");
109 }
110
111 if (rule < 0 || rule >= QUAD_2D_TABLE_SIZE) {
112 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
113 "Triangle quadrature rule %d is not available for TIE prism face "
114 "integration",
115 rule);
116 }
117
118 if (QUAD_2D_TABLE[rule]->dim != 2) {
119 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
120 "Expected 2D quadrature for TIE prism face integration");
121 }
122
123 if (QUAD_2D_TABLE[rule]->order < rule) {
124 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
125 "Wrong quadrature order %d < %d for TIE prism face integration",
126 QUAD_2D_TABLE[rule]->order, rule);
127 }
128
129 CHKERR setBaseQuadrature(*fe_ptr, rule);
130
131 if (tieRefLevel > 0) {
132 const auto cache_key = std::make_pair(rule, tieRefLevel);
133 auto it = mapRefCoords.find(cache_key);
134 if (it == mapRefCoords.end()) {
135 MatrixDouble ref_gauss_pts;
136 CHKERR refineQuadrature(*fe_ptr, tieRefLevel, ref_gauss_pts);
137 mapRefCoords[cache_key].swap(ref_gauss_pts);
138 it = mapRefCoords.find(cache_key);
139 }
140 fe_ptr->gaussPts = it->second;
141 }
142
143 const MatrixDouble slave_gauss_pts = fe_ptr->gaussPts;
144 const auto nb_gauss_pts = slave_gauss_pts.size2();
145
146 auto &moab = fe_ptr->mField.get_moab();
147 auto get_prism_face_coords = [&](const int side, std::array<double, 9> &coords) {
149 const EntityHandle prism = fe_ptr->getFEEntityHandle();
150 const EntityHandle *prism_conn = nullptr;
151 int num_prism_nodes = 0;
152 CHKERR moab.get_connectivity(prism, prism_conn, num_prism_nodes, true);
153 if (num_prism_nodes != 6) {
154 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
155 "TIE prism is expected to have 6 nodes");
156 }
157
158 std::array<EntityHandle, 3> face_conn;
159 switch (side) {
160 case SLAVE_FACE_SIDE:
161 face_conn = {prism_conn[0], prism_conn[1], prism_conn[2]};
162 break;
163 case MASTER_FACE_SIDE:
164 face_conn = {prism_conn[3], prism_conn[4], prism_conn[5]};
165 break;
166 default:
167 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
168 "Unsupported TIE prism triangle side %d", side);
169 }
170
171 CHKERR moab.get_coords(face_conn.data(), 3, coords.data());
173 };
174
175 std::array<double, 9> slave_coords; // nodal coords
176 std::array<double, 9> master_coords; // nodal coords
177 CHKERR get_prism_face_coords(SLAVE_FACE_SIDE, slave_coords);
178 CHKERR get_prism_face_coords(MASTER_FACE_SIDE, master_coords);
179
180 MatrixDouble slave_global_coords(nb_gauss_pts, 3, false); // gp coords
181 MatrixDouble master_global_coords(nb_gauss_pts, 3, false); //gp coords
182 MatrixDouble slave_shape(nb_gauss_pts, 3, false);
183 CHKERR ShapeMBTRI(&slave_shape(0, 0), &slave_gauss_pts(0, 0),
184 &slave_gauss_pts(1, 0), nb_gauss_pts);
185 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
186 for (int dd = 0; dd != 3; ++dd) {
187 slave_global_coords(gg, dd) =
188 slave_shape(gg, 0) * slave_coords[0 + dd] +
189 slave_shape(gg, 1) * slave_coords[3 + dd] +
190 slave_shape(gg, 2) * slave_coords[6 + dd];
191 }
192 }
193
194 CHKERR projectSlavePointsToMasterPlane(master_coords.data(),
195 slave_global_coords,
196 master_global_coords);
197
198 MatrixDouble master_local_coords(nb_gauss_pts, 2, false);
199 CHKERR Tools::getLocalCoordinatesOnReferenceThreeNodeTri(
200 master_coords.data(), &master_global_coords(0, 0),
201 master_global_coords.size1(), &master_local_coords(0, 0));
202
203 MatrixDouble combined_gauss_pts(3, 2 * nb_gauss_pts, false);
204 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
205 const bool valid_master_point =
206 isInsideReferenceTriangle(master_local_coords(gg, 0),
207 master_local_coords(gg, 1));
208 const double paired_weight = valid_master_point ? slave_gauss_pts(2, gg) : 0.;
209
210 combined_gauss_pts(0, gg) = slave_gauss_pts(0, gg);
211 combined_gauss_pts(1, gg) = slave_gauss_pts(1, gg);
212 combined_gauss_pts(2, gg) = paired_weight;
213
214 combined_gauss_pts(0, gg + nb_gauss_pts) = master_local_coords(gg, 0);
215 combined_gauss_pts(1, gg + nb_gauss_pts) = master_local_coords(gg, 1);
216 combined_gauss_pts(2, gg + nb_gauss_pts) = paired_weight;
217 }
218 fe_ptr->gaussPts.swap(combined_gauss_pts);
219
221 }
#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 238 of file ElasticTie.hpp.

240 {
242
243 // For the infinite master plane, the closest point is the orthogonal
244 // projection along the plane normal.
245 const double ax = master_coords[0];
246 const double ay = master_coords[1];
247 const double az = master_coords[2];
248 const double bx = master_coords[3];
249 const double by = master_coords[4];
250 const double bz = master_coords[5];
251 const double cx = master_coords[6];
252 const double cy = master_coords[7];
253 const double cz = master_coords[8];
254
255 const double abx = bx - ax;
256 const double aby = by - ay;
257 const double abz = bz - az;
258 const double acx = cx - ax;
259 const double acy = cy - ay;
260 const double acz = cz - az;
261
262 const double nx = aby * acz - abz * acy;
263 const double ny = abz * acx - abx * acz;
264 const double nz = abx * acy - aby * acx;
265 const double n_norm_sq = nx * nx + ny * ny + nz * nz;
266 if (n_norm_sq <= std::numeric_limits<double>::epsilon()) {
267 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
268 "Degenerated master triangle plane");
269 }
270
271 const double px = point[0] - ax;
272 const double py = point[1] - ay;
273 const double pz = point[2] - az;
274 const double signed_distance = (px * nx + py * ny + pz * nz) / n_norm_sq;
275 projected_point[0] = point[0] - signed_distance * nx;
276 projected_point[1] = point[1] - signed_distance * ny;
277 projected_point[2] = point[2] - signed_distance * nz;
278
280 }

◆ projectSlavePointsToMasterPlane()

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

Definition at line 282 of file ElasticTie.hpp.

284 {
286
287 // The weak form is integrated on the slave surface. Each slave Gauss point
288 // is paired with its orthogonal projection on the infinite plane defined
289 // by the master triangle.
290 master_global_coords.resize(slave_global_coords.size1(), 3, false);
291 for (size_t gg = 0; gg != slave_global_coords.size1(); ++gg) {
292 CHKERR projectPointToMasterPlane(master_coords,
293 &slave_global_coords(gg, 0),
294 &master_global_coords(gg, 0));
295 }
296
298 }
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 300 of file ElasticTie.hpp.

302 {
304
305 constexpr int num_nodes = 3;
306 moab::Core moab_ref;
307 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
308 EntityHandle nodes[num_nodes];
309 for (int nn = 0; nn != num_nodes; ++nn)
310 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
311
312 EntityHandle tri;
313 CHKERR moab_ref.create_element(MBTRI, nodes, num_nodes, tri);
314 MoFEM::CoreTmp<-1> mofem_ref_core(moab_ref, PETSC_COMM_SELF, -2);
315 MoFEM::Interface &m_field_ref = mofem_ref_core;
316
317 {
318 Range tris(tri, tri);
319 Range edges;
320 // Force MOAB to materialise the triangle edges before the bit-ref
321 // database is seeded. The working reference-refinement snippets all do
322 // this, and the side-number lookup below verifies that MOAB sees a
323 // consistent local edge numbering on the temporary reference triangle.
324 CHKERR m_field_ref.get_moab().get_adjacencies(
325 tris, 1, true, edges, moab::Interface::UNION);
326 for (auto edge : edges) {
327 int side_number = -1, sense = 0, offset = 0;
328 CHKERR moab_ref.side_number(tri, edge, side_number, sense, offset);
329 }
330 CHKERR m_field_ref.getInterface<BitRefManager>()->setBitRefLevel(
331 tris, BitRefLevel().set(0), false, VERBOSE);
332 }
333
334 auto *m_ref = m_field_ref.getInterface<MeshRefinement>();
335 for (int ll = 0; ll != refinement_levels; ++ll) {
336 Range tris;
337 CHKERR m_field_ref.getInterface<BitRefManager>()
338 ->getEntitiesByTypeAndRefLevel(BitRefLevel().set(ll),
339 BitRefLevel().set(), MBTRI, tris);
340
341 Range edges;
342 CHKERR moab_ref.get_adjacencies(tris, 1, true, edges,
343 moab::Interface::UNION);
344
345 const BitRefLevel child_bit = BitRefLevel().set(ll + 1);
346 CHKERR m_ref->addVerticesInTheMiddleOfEdges(edges, child_bit);
347 CHKERR m_ref->refineTris(tris, child_bit, QUIET, false);
348 }
349
350 Range tris;
351 CHKERR m_field_ref.getInterface<BitRefManager>()->getEntitiesByTypeAndRefLevel(
352 BitRefLevel().set(refinement_levels), BitRefLevel().set(), MBTRI, tris);
353
354 MatrixDouble ref_coords(tris.size(), 9, false);
355 int tt = 0;
356 for (auto tit = tris.begin(); tit != tris.end(); ++tit, ++tt) {
357 int num_conn;
358 const EntityHandle *conn;
359 CHKERR moab_ref.get_connectivity(*tit, conn, num_conn, false);
360 CHKERR moab_ref.get_coords(conn, num_conn, &ref_coords(tt, 0));
361 }
362
363 const size_t nb_gauss_pts = fe.gaussPts.size2();
364 MatrixDouble shape_n(nb_gauss_pts, 3, false);
365 CHKERR ShapeMBTRI(&shape_n(0, 0), &fe.gaussPts(0, 0), &fe.gaussPts(1, 0),
366 nb_gauss_pts);
367 ref_gauss_pts.resize(3, nb_gauss_pts * ref_coords.size1(), false);
368 int gg = 0;
369 for (size_t rr = 0; rr != ref_coords.size1(); ++rr) {
370 double *tri_coords = &ref_coords(rr, 0);
372 CHKERR Tools::getTriNormal(tri_coords, &t_normal(0));
373 const double det = t_normal.l2();
374 for (size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
375 for (int dd = 0; dd != 2; ++dd) {
376 ref_gauss_pts(dd, gg) =
377 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
378 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
379 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
380 }
381 ref_gauss_pts(2, gg) = fe.gaussPts(2, ggg) * det;
382 }
383 }
384
386 }
@ 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 224 of file ElasticTie.hpp.

225 {
227 const size_t nb_gauss_pts = QUAD_2D_TABLE[rule]->npoints;
228 fe.gaussPts.resize(3, nb_gauss_pts, false);
229 cblas_dcopy(nb_gauss_pts, &QUAD_2D_TABLE[rule]->points[1], 3,
230 &fe.gaussPts(0, 0), 1);
231 cblas_dcopy(nb_gauss_pts, &QUAD_2D_TABLE[rule]->points[2], 3,
232 &fe.gaussPts(1, 0), 1);
233 cblas_dcopy(nb_gauss_pts, QUAD_2D_TABLE[rule]->weights, 1,
234 &fe.gaussPts(2, 0), 1);
236 }
int npoints
Definition quad.h:29

Member Data Documentation

◆ funRule

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

Definition at line 88 of file ElasticTie.hpp.

88{ return 2 * p + 1; };

◆ mapRefCoords

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

Definition at line 388 of file ElasticTie.hpp.

◆ tieRefLevel

int ElasticTie::SetIntegrationOnTiePrismFaces::tieRefLevel = 1

Definition at line 89 of file ElasticTie.hpp.


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