v0.15.0
Loading...
Searching...
No Matches
ContactPrismElementForcesAndSourcesCore.cpp
Go to the documentation of this file.
1/** \file ContactPrismElementForcesAndSourcesCore.cpp
2
3\brief Implementation of contact prism element
4
5*/
6
7namespace MoFEM {
8
11 : ForcesAndSourcesCore(m_field),
12 dataOnMaster{
13
14 nullptr,
15 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // NOFIELD
16 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // H1
17 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // HCURL
18 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // HDIV
19 boost::make_shared<EntitiesFieldData>(MBENTITYSET) // L2
20
21 },
22 dataOnSlave{
23
24 nullptr,
25 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // NOFIELD
26 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // H1
27 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // HCURL
28 boost::make_shared<EntitiesFieldData>(MBENTITYSET), // HDIV
29 boost::make_shared<EntitiesFieldData>(MBENTITYSET) // L2
30
31 },
32 derivedDataOnMaster{
33
34 nullptr,
35 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[NOFIELD]),
36 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[H1]),
37 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[HCURL]),
38 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[HDIV]),
39 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[L2])
40
41 },
42 derivedDataOnSlave{
43
44 nullptr,
45 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[NOFIELD]),
46 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[H1]),
47 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[HCURL]),
48 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[HDIV]),
49 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[L2])
50
51 },
52 dataH1Master(*dataOnMaster[H1].get()),
53 dataH1Slave(*dataOnSlave[H1].get()),
54 dataNoFieldSlave(*dataOnSlave[NOFIELD].get()),
55 dataNoFieldMaster(*dataOnMaster[NOFIELD].get()),
56 dataHcurlMaster(*dataOnMaster[HCURL].get()),
57 dataHcurlSlave(*dataOnSlave[HCURL].get()),
58 dataHdivMaster(*dataOnMaster[HDIV].get()),
59 dataL2Master(*dataOnMaster[L2].get()),
60 dataHdivSlave(*dataOnSlave[HDIV].get()),
61 dataL2Slave(*dataOnSlave[L2].get()), opContravariantTransform() {
62
64 boost::shared_ptr<BaseFunction>(new TriPolynomialBase());
65
66 // Data on elements for proper spaces
67 dataOnMaster[H1]->setElementType(MBTRI);
68 derivedDataOnMaster[H1]->setElementType(MBTRI);
69 dataOnSlave[H1]->setElementType(MBTRI);
70 derivedDataOnSlave[H1]->setElementType(MBTRI);
71
72 dataOnMaster[HDIV]->setElementType(MBTRI);
73 derivedDataOnMaster[HDIV]->setElementType(MBTRI);
74 dataOnSlave[HDIV]->setElementType(MBTRI);
75 derivedDataOnSlave[HDIV]->setElementType(MBTRI);
76
77 dataOnMaster[NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
79 dataOnSlave[NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
81
82 derivedDataOnMaster[NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
84 derivedDataOnSlave[NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
86
88 "Problem with creation data on element");
89}
90
94
95 if (rule < QUAD_2D_TABLE_SIZE) {
96 if (QUAD_2D_TABLE[rule]->dim != 2) {
97 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "wrong dimension");
98 }
99 if (QUAD_2D_TABLE[rule]->order < rule) {
100 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
101 "wrong order %d != %d", QUAD_2D_TABLE[rule]->order, rule);
102 }
104 // For master and slave
105 gaussPtsMaster.resize(3, nbGaussPts, false);
106 gaussPtsSlave.resize(3, nbGaussPts, false);
107
108 cblas_dcopy(nbGaussPts, &QUAD_2D_TABLE[rule]->points[1], 3,
109 &gaussPtsMaster(0, 0), 1);
110 cblas_dcopy(nbGaussPts, &QUAD_2D_TABLE[rule]->points[2], 3,
111 &gaussPtsMaster(1, 0), 1);
112 cblas_dcopy(nbGaussPts, QUAD_2D_TABLE[rule]->weights, 1,
113 &gaussPtsMaster(2, 0), 1);
114
116
117 dataH1Master.dataOnEntities[MBVERTEX][0].getN(NOBASE).resize(nbGaussPts, 3,
118 false);
119
120 dataH1Slave.dataOnEntities[MBVERTEX][0].getN(NOBASE).resize(nbGaussPts, 3,
121 false);
122
123 double *shape_ptr_master =
124 &*dataH1Master.dataOnEntities[MBVERTEX][0].getN(NOBASE).data().begin();
125 cblas_dcopy(3 * nbGaussPts, QUAD_2D_TABLE[rule]->points, 1,
126 shape_ptr_master, 1);
127 double *shape_ptr_slave =
128 &*dataH1Slave.dataOnEntities[MBVERTEX][0].getN(NOBASE).data().begin();
129 cblas_dcopy(3 * nbGaussPts, QUAD_2D_TABLE[rule]->points, 1, shape_ptr_slave,
130 1);
131 } else {
132 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
133 "rule > quadrature order %d < %d", rule, QUAD_2D_TABLE_SIZE);
134 nbGaussPts = 0;
135 }
136
138}
139
142
143 if (numeredEntFiniteElementPtr->getEntType() != MBPRISM)
145
149
151 auto get_coord_and_normal = [&]() {
153 int num_nodes;
154 const EntityHandle *conn;
155 CHKERR mField.get_moab().get_connectivity(ent, conn, num_nodes, true);
156 coords.resize(num_nodes * 3, false);
157 CHKERR mField.get_moab().get_coords(conn, num_nodes,
158 &*coords.data().begin());
159 normal.resize(6, false);
160
162 &tangentSlaveTwo}) {
163 v->resize(3);
164 v->clear();
165 }
166
169
170 auto get_vec_ptr = [](VectorDouble &vec_double, int r = 0) {
172 &vec_double(r + 0), &vec_double(r + 1), &vec_double(r + 2));
173 };
174
175 auto t_coords_master = get_vec_ptr(coords);
176 auto t_coords_slave = get_vec_ptr(coords, 9);
177 auto t_normal_master = get_vec_ptr(normal);
178 auto t_normal_slave = get_vec_ptr(normal, 3);
179
180 auto t_t1_master = get_vec_ptr(tangentMasterOne);
181 auto t_t2_master = get_vec_ptr(tangentMasterTwo);
182 auto t_t1_slave = get_vec_ptr(tangentSlaveOne);
183 auto t_t2_slave = get_vec_ptr(tangentSlaveTwo);
184
185 const double *diff_ptr = Tools::diffShapeFunMBTRI.data();
187 &diff_ptr[0], &diff_ptr[1]);
188
189 FTensor::Index<'i', 3> i;
190 FTensor::Index<'j', 3> j;
191 FTensor::Index<'k', 3> k;
192
194
195 for (int nn = 0; nn != 3; ++nn) {
196 t_t1_master(i) += t_coords_master(i) * t_diff(N0);
197 t_t1_slave(i) += t_coords_slave(i) * t_diff(N0);
198 ++t_coords_master;
199 ++t_coords_slave;
200 ++t_diff;
201 }
202
203 aRea[0] = sqrt(t_normal_master(i) * t_normal_master(i)) / 2.;
204 aRea[1] = sqrt(t_normal_slave(i) * t_normal_slave(i)) / 2.;
205
206 t_t2_master(j) =
207 FTensor::levi_civita(i, j, k) * t_normal_master(k) * t_t1_master(i);
208 t_t2_slave(j) =
209 FTensor::levi_civita(i, j, k) * t_normal_slave(k) * t_t1_slave(i);
210
212 };
213 CHKERR get_coord_and_normal();
214
216
217 // H1
218 if ((dataH1.spacesOnEntities[MBVERTEX]).test(H1)) {
219 CHKERR getEntitySense<MBEDGE>(dataH1);
220 CHKERR getEntityDataOrder<MBEDGE>(dataH1, H1);
221 CHKERR getEntitySense<MBTRI>(dataH1);
222 CHKERR getEntityDataOrder<MBTRI>(dataH1, H1);
223 }
224
225 // Hcurl
226 if ((dataH1.spacesOnEntities[MBEDGE]).test(HCURL)) {
227 CHKERR getEntitySense<MBEDGE>(data_curl);
228 CHKERR getEntityDataOrder<MBEDGE>(data_curl, HCURL);
229 CHKERR getEntitySense<MBTRI>(data_curl);
230 CHKERR getEntityDataOrder<MBTRI>(data_curl, HCURL);
231 }
232
233 // Hdiv
234 if ((dataH1.spacesOnEntities[MBTRI]).test(HDIV)) {
235 CHKERR getEntitySense<MBTRI>(data_div);
236 CHKERR getEntityDataOrder<MBTRI>(data_div, HDIV);
239 data_div.spacesOnEntities[MBTRI].set(HDIV);
240 }
241
242 // L2
243 if ((dataH1.spacesOnEntities[MBTRI]).test(L2)) {
244 CHKERR getEntitySense<MBTRI>(data_l2);
245 CHKERR getEntityDataOrder<MBTRI>(data_l2, L2);
246 }
247
248 auto clean_data = [](EntitiesFieldData &data) {
250 data.bAse.reset();
251 for (EntityType t = MBVERTEX; t != MBMAXTYPE; ++t) {
252 data.spacesOnEntities[t].reset();
253 data.basesOnEntities[t].reset();
254 }
255 for (int s = 0; s != LASTSPACE; ++s)
256 data.basesOnSpaces[s].reset();
257
259 };
260
261 auto copy_data = [](EntitiesFieldData &data, EntitiesFieldData &copy_data,
262 const int shift) {
264
265 if (shift != 0 && shift != 6) {
266 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
267 "Wrong shift for contact prism element");
268 }
269
270 data.bAse = copy_data.bAse;
271 for (auto t : {MBVERTEX, MBEDGE, MBTRI}) {
272 data.spacesOnEntities[t] = copy_data.spacesOnEntities[t];
273 data.basesOnEntities[t] = copy_data.basesOnEntities[t];
274 data.basesOnSpaces[t] = copy_data.basesOnSpaces[t];
275 data.brokenBasesOnSpaces[t] = copy_data.brokenBasesOnSpaces[t];
276 }
277
278 for (int ii = 0; ii != 3; ++ii) {
279 data.dataOnEntities[MBEDGE][ii].getSense() =
280 copy_data.dataOnEntities[MBEDGE][ii + shift].getSense();
281 data.dataOnEntities[MBEDGE][ii].getOrder() =
282 copy_data.dataOnEntities[MBEDGE][ii + shift].getOrder();
283 }
284
285 if (shift == 0) {
286 data.dataOnEntities[MBTRI][0].getSense() =
287 copy_data.dataOnEntities[MBTRI][3].getSense();
288 data.dataOnEntities[MBTRI][0].getOrder() =
289 copy_data.dataOnEntities[MBTRI][3].getOrder();
290 } else {
291 data.dataOnEntities[MBTRI][0].getSense() =
292 copy_data.dataOnEntities[MBTRI][4].getSense();
293 data.dataOnEntities[MBTRI][0].getOrder() =
294 copy_data.dataOnEntities[MBTRI][4].getOrder();
295 }
296
298 };
299
300 auto copy_data_hdiv = [](EntitiesFieldData &data,
301 EntitiesFieldData &copy_data, const int shift) {
303
304 if (shift != 3 && shift != 4) {
305 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
306 "Wrong shift for contact prism element");
307 }
308
309 data.bAse = copy_data.bAse;
310
311 for (auto t : {MBVERTEX, MBTRI}) {
312 data.spacesOnEntities[t] = copy_data.spacesOnEntities[MBVERTEX];
313 data.basesOnEntities[t] = copy_data.basesOnEntities[MBVERTEX];
314 data.basesOnSpaces[t] = copy_data.basesOnSpaces[MBVERTEX];
315 }
316
317 auto &cpy_ent_dat = copy_data.dataOnEntities[MBTRI][shift];
318 auto &ent_dat = data.dataOnEntities[MBTRI][0];
319 ent_dat.getBase() = cpy_ent_dat.getBase();
320 ent_dat.getSpace() = cpy_ent_dat.getSpace();
321 ent_dat.getSense() = ent_dat.getSense();
322 ent_dat.getOrder() = cpy_ent_dat.getOrder();
323
325 };
326
327 CHKERR clean_data(dataH1Slave);
328 CHKERR copy_data(dataH1Slave, dataH1, 6);
329 CHKERR clean_data(dataH1Master);
330 CHKERR copy_data(dataH1Master, dataH1, 0);
331
332 int order_data = getMaxDataOrder();
333 int order_row = getMaxRowOrder();
334 int order_col = getMaxColOrder(); // maybe two different rules?
335 int rule = getRule(order_row, order_col, order_data);
336
337 if (rule >= 0) {
338
340
341 } else {
342
343 // Master-Slave
344 if (gaussPtsMaster.size2() != gaussPtsSlave.size2())
345 SETERRQ(
346 PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
347 "Number of Gauss Points at Master triangle is different than slave");
348
349 CHKERR setGaussPts(order_row, order_col, order_data);
350 nbGaussPts = gaussPtsMaster.size2();
351 dataH1Master.dataOnEntities[MBVERTEX][0].getN(NOBASE).resize(nbGaussPts, 3,
352 false);
353 dataH1Slave.dataOnEntities[MBVERTEX][0].getN(NOBASE).resize(nbGaussPts, 3,
354 false);
355
356 if (nbGaussPts) {
357 CHKERR Tools::shapeFunMBTRI<1>(&*dataH1Master.dataOnEntities[MBVERTEX][0]
358 .getN(NOBASE)
359 .data()
360 .begin(),
361 &gaussPtsMaster(0, 0),
362 &gaussPtsMaster(1, 0), nbGaussPts);
363
364 CHKERR Tools::shapeFunMBTRI<1>(
365 &*dataH1Slave.dataOnEntities[MBVERTEX][0].getN(NOBASE).data().begin(),
366 &gaussPtsSlave(0, 0), &gaussPtsSlave(1, 0), nbGaussPts);
367 }
368 }
369
370 if (nbGaussPts == 0)
372
373 // Get coordinates on slave and master
374 {
375 coordsAtGaussPtsMaster.resize(nbGaussPts, 3, false);
376 coordsAtGaussPtsSlave.resize(nbGaussPts, 3, false);
377 for (int gg = 0; gg < nbGaussPts; gg++) {
378 for (int dd = 0; dd < 3; dd++) {
379 coordsAtGaussPtsMaster(gg, dd) = cblas_ddot(
380 3, &dataH1Master.dataOnEntities[MBVERTEX][0].getN(NOBASE)(gg, 0), 1,
381 &coords[dd], 3);
382 coordsAtGaussPtsSlave(gg, dd) = cblas_ddot(
383 3, &dataH1Slave.dataOnEntities[MBVERTEX][0].getN(NOBASE)(gg, 0), 1,
384 &coords[9 + dd], 3);
385 }
386 }
387 }
388
389 for (int space = HCURL; space != LASTSPACE; ++space)
390 if (dataOnElement[space]) {
391
392 dataH1Master.dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE) =
393 dataOnMaster[H1]->dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE);
394 dataH1Slave.dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE) =
395 dataOnSlave[H1]->dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE);
396
397 if (space == HDIV) {
398
399 if (dataH1.spacesOnEntities[MBTRI].test(HDIV)) {
400
401 CHKERR clean_data(dataHdivSlave);
402 CHKERR copy_data_hdiv(dataHdivSlave, data_div, 4);
403 CHKERR clean_data(dataHdivMaster);
404 CHKERR copy_data_hdiv(dataHdivMaster, data_div, 3);
405
406 dataHdivMaster.dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE) =
407 dataOnMaster[H1]->dataOnEntities[MBVERTEX][0].getNSharedPtr(
408 NOBASE);
409 dataHdivSlave.dataOnEntities[MBVERTEX][0].getNSharedPtr(NOBASE) =
410 dataOnSlave[H1]->dataOnEntities[MBVERTEX][0].getNSharedPtr(
411 NOBASE);
412 }
413 }
414 }
415
416 for (int b = AINSWORTH_LEGENDRE_BASE; b != LASTBASE; b++) {
417 if (dataH1.bAse.test(b)) {
418 switch (static_cast<FieldApproximationBase>(b)) {
421 if (dataH1.spacesOnEntities[MBVERTEX].test(H1)) {
423 -> getValue(
425 boost::shared_ptr<BaseFunctionCtx>(new EntPolynomialBaseCtx(
427 static_cast<FieldApproximationBase>(b), NOBASE)));
428
430 -> getValue(
432 boost::shared_ptr<BaseFunctionCtx>(new EntPolynomialBaseCtx(
434 static_cast<FieldApproximationBase>(b), NOBASE)));
435 }
436 break;
438 if (dataH1.spacesOnEntities[MBTRI].test(HDIV)) {
439
441 -> getValue(
443 boost::shared_ptr<BaseFunctionCtx>(new EntPolynomialBaseCtx(
445 static_cast<FieldApproximationBase>(b), NOBASE)));
447 -> getValue(
449 boost::shared_ptr<BaseFunctionCtx>(new EntPolynomialBaseCtx(
451 static_cast<FieldApproximationBase>(b), NOBASE)));
452
458 }
459
460 if (dataH1.spacesOnEntities[MBEDGE].test(HCURL)) {
461 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
462 "Not yet implemented");
463 }
464 if (dataH1.spacesOnEntities[MBTET].test(L2)) {
465 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
466 "Not yet implemented");
467 }
468 break;
469 default:
470 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
471 "Not yet implemented");
472 }
473 }
474 }
475
476 // Iterate over operators
478
480}
481
484
485 constexpr std::array<UserDataOperator::OpType, 2> types{
486 UserDataOperator::OPROW, UserDataOperator::OPCOL};
487 std::array<std::string, 2> last_eval_field_name{std::string(), std::string()};
488
489 auto oit = opPtrVector.begin();
490 auto hi_oit = opPtrVector.end();
491
492 for (; oit != hi_oit; oit++) {
493
494 oit->setPtrFE(this);
495
496 if (oit->opType == UserDataOperator::OPSPACE) {
497
498 // Set field
499 switch (oit->sPace) {
500 case NOSPACE:
501 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Unknown space");
502 case NOFIELD:
503 case H1:
504 case HCURL:
505 case HDIV:
506 case L2:
507 break;
508 default:
509 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
510 "Not implemented for this space <%s>",
511 FieldSpaceNames[oit->sPace]);
512 }
513
514 // Reseat all data which all field dependent
515 dataOnMaster[oit->sPace]->resetFieldDependentData();
516 dataOnSlave[oit->sPace]->resetFieldDependentData();
517
518 // Run operator
519 try {
520 CHKERR oit->opRhs(*dataOnMaster[oit->sPace], false);
521 CHKERR oit->opRhs(*dataOnSlave[oit->sPace], false);
522 }
523 CATCH_OP_ERRORS(*oit);
524
525 } else {
526 boost::shared_ptr<EntitiesFieldData> op_master_data[2];
527 boost::shared_ptr<EntitiesFieldData> op_slave_data[2];
528
529 for (int ss = 0; ss != 2; ss++) {
530
531 const std::string field_name =
532 !ss ? oit->rowFieldName : oit->colFieldName;
533 const Field *field_struture = mField.get_field_structure(field_name);
534 const BitFieldId data_id = field_struture->getId();
535 const FieldSpace space = field_struture->getSpace();
536 op_master_data[ss] =
537 !ss ? dataOnMaster[space] : derivedDataOnMaster[space];
538 op_slave_data[ss] =
539 !ss ? dataOnSlave[space] : derivedDataOnSlave[space];
540
541 if ((oit->getNumeredEntFiniteElementPtr()->getBitFieldIdData() &
542 data_id)
543 .none())
544 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
545 "no data field < %s > on finite element < %s >",
546 field_name.c_str(), getFEName().c_str());
547
548 if (oit->getOpType() & types[ss] ||
549 oit->getOpType() & UserDataOperator::OPROWCOL) {
550
551 switch (space) {
552 case NOSPACE:
553 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "unknown space");
554 break;
555 case NOFIELD:
556 case H1:
557 case HCURL:
558 case HDIV:
559 case L2:
560 break;
561 default:
562 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
563 "Not implemented for this space <%s>",
564 FieldSpaceNames[space]);
565 }
566
567 if (last_eval_field_name[ss] != field_name) {
568 CHKERR getEntityFieldData(*op_master_data[ss], *op_slave_data[ss],
569 field_name, MBEDGE);
570
571 if (!ss) {
572 struct Extractor {
573 boost::weak_ptr<EntityCacheNumeredDofs>
574 operator()(boost::shared_ptr<FieldEntity> &e) {
575 return e->entityCacheRowDofs;
576 }
577 };
578
579 CHKERR getEntityIndices(*op_master_data[ss], *op_slave_data[ss],
580 field_name, getRowFieldEnts(), MBEDGE,
581 MBPRISM, Extractor());
582 } else {
583 struct Extractor {
584 boost::weak_ptr<EntityCacheNumeredDofs>
585 operator()(boost::shared_ptr<FieldEntity> &e) {
586 return e->entityCacheColDofs;
587 }
588 };
589 CHKERR getEntityIndices(*op_master_data[ss], *op_slave_data[ss],
590 field_name, getRowFieldEnts(), MBEDGE,
591 MBPRISM, Extractor());
592 }
593
594 switch (space) {
595 case NOSPACE:
596 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
597 "unknown space");
598 break;
599 case H1: {
600
601 auto get_indices = [&](auto &master, auto &slave, auto &ents,
602 auto &&ex) {
603 return getNodesIndices(
604 field_name, ents,
605 master.dataOnEntities[MBVERTEX][0].getIndices(),
606 master.dataOnEntities[MBVERTEX][0].getLocalIndices(),
607 slave.dataOnEntities[MBVERTEX][0].getIndices(),
608 slave.dataOnEntities[MBVERTEX][0].getLocalIndices(), ex);
609 };
610
611 auto get_data = [&](EntitiesFieldData &master_data,
612 EntitiesFieldData &slave_data) {
613 return getNodesFieldData(
615 master_data.dataOnEntities[MBVERTEX][0].getFieldData(),
616 slave_data.dataOnEntities[MBVERTEX][0].getFieldData(),
617 master_data.dataOnEntities[MBVERTEX][0].getFieldDofs(),
618 slave_data.dataOnEntities[MBVERTEX][0].getFieldDofs(),
619 master_data.dataOnEntities[MBVERTEX][0].getFieldEntities(),
620 slave_data.dataOnEntities[MBVERTEX][0].getFieldEntities(),
621 master_data.dataOnEntities[MBVERTEX][0].getSpace(),
622 slave_data.dataOnEntities[MBVERTEX][0].getSpace(),
623 master_data.dataOnEntities[MBVERTEX][0].getBase(),
624 slave_data.dataOnEntities[MBVERTEX][0].getBase());
625 };
626
627 if (!ss) {
628
629 struct Extractor {
630 boost::weak_ptr<EntityCacheNumeredDofs>
631 operator()(boost::shared_ptr<FieldEntity> &e) {
632 return e->entityCacheRowDofs;
633 }
634 };
635
636 CHKERR get_indices(*op_master_data[ss], *op_slave_data[ss],
637 getRowFieldEnts(), Extractor());
638 } else {
639 struct Extractor {
640 boost::weak_ptr<EntityCacheNumeredDofs>
641 operator()(boost::shared_ptr<FieldEntity> &e) {
642 return e->entityCacheColDofs;
643 }
644 };
645
646 CHKERR get_indices(*op_master_data[ss], *op_slave_data[ss],
647 getColFieldEnts(), Extractor());
648 }
649
650 CHKERR get_data(*op_master_data[ss], *op_slave_data[ss]);
651
652 } break;
653 case HCURL:
654 case HDIV:
655 case L2:
656 break;
657 case NOFIELD:
658 if (!getNinTheLoop()) {
659 // NOFIELD data are the same for each element, can be
660 // retrieved only once
661 const auto bit_number = mField.get_field_bit_number(field_name);
662 if (!ss) {
663 CHKERR getNoFieldRowIndices(*op_master_data[ss], bit_number);
664 CHKERR getNoFieldRowIndices(*op_slave_data[ss], bit_number);
665 } else {
666 CHKERR getNoFieldColIndices(*op_master_data[ss], bit_number);
667 CHKERR getNoFieldColIndices(*op_slave_data[ss], bit_number);
668 }
669 CHKERR getNoFieldFieldData(*op_master_data[ss], bit_number);
670 CHKERR getNoFieldFieldData(*op_slave_data[ss], bit_number);
671 }
672 break;
673 default:
674 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
675 "Not implemented for this space <%s>",
676 FieldSpaceNames[space]);
677 }
678 last_eval_field_name[ss] = field_name;
679 }
680 }
681 }
682
683 int type;
684
685 if (UserDataOperator *cast_oit =
686 dynamic_cast<UserDataOperator *>(&*oit)) {
687 type = cast_oit->getFaceType();
688 if (((oit->getOpType() & UserDataOperator::OPROW) ||
689 (oit->getOpType() & UserDataOperator::OPCOL)) &&
690 ((type & UserDataOperator::FACEMASTERMASTER) ||
691 (type & UserDataOperator::FACEMASTERSLAVE) ||
692 (type & UserDataOperator::FACESLAVEMASTER) ||
693 (type & UserDataOperator::FACESLAVESLAVE))) {
694 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
695 "Wrong combination of FaceType and OpType, OPROW or OPCOL "
696 "combined with face-face OpType");
697 }
698
699 if ((oit->getOpType() & UserDataOperator::OPROWCOL) &&
700 ((type & UserDataOperator::FACEMASTER) ||
701 (type & UserDataOperator::FACESLAVE))) {
702 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
703 "Wrong combination of FaceType and OpType, OPROWCOL "
704 "combined with face-face OpType");
705 }
706
707 if (!type) {
708 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
709 "Face type is not set");
710 }
711 } else {
712 type = UserDataOperator::FACEMASTER | UserDataOperator::FACESLAVE |
713 UserDataOperator::FACEMASTERMASTER |
714 UserDataOperator::FACEMASTERSLAVE |
715 UserDataOperator::FACESLAVEMASTER |
716 UserDataOperator::FACESLAVESLAVE;
717 }
718
719 if (oit->getOpType() & UserDataOperator::OPROW &&
720 (type & UserDataOperator::FACEMASTER)) {
721 try {
722 CHKERR oit->opRhs(*op_master_data[0], false);
723 }
724 CATCH_OP_ERRORS(*oit);
725 }
726
727 if (oit->getOpType() & UserDataOperator::OPROW &&
728 (type & UserDataOperator::FACESLAVE)) {
729 try {
730 CHKERR oit->opRhs(*op_slave_data[0], false);
731 }
732 CATCH_OP_ERRORS(*oit);
733 }
734
735 if (oit->getOpType() & UserDataOperator::OPCOL &&
736 (type & UserDataOperator::FACEMASTER)) {
737 try {
738 CHKERR oit->opRhs(*op_master_data[1], false);
739 }
740 CATCH_OP_ERRORS(*oit);
741 }
742
743 if (oit->getOpType() & UserDataOperator::OPCOL &&
744 (type & UserDataOperator::FACESLAVE)) {
745 try {
746 CHKERR oit->opRhs(*op_slave_data[1], false);
747 }
748 CATCH_OP_ERRORS(*oit);
749 }
750
751 if (oit->getOpType() & UserDataOperator::OPROWCOL &&
752 (type & UserDataOperator::FACEMASTERMASTER)) {
753 try {
754 CHKERR oit->opLhs(*op_master_data[0], *op_master_data[1]);
755 }
756 CATCH_OP_ERRORS(*oit);
757 }
758
759 if (oit->getOpType() & UserDataOperator::OPROWCOL &&
760 (type & UserDataOperator::FACEMASTERSLAVE)) {
761 try {
762 CHKERR oit->opLhs(*op_master_data[0], *op_slave_data[1]);
763 }
764 CATCH_OP_ERRORS(*oit);
765 }
766
767 if (oit->getOpType() & UserDataOperator::OPROWCOL &&
768 (type & UserDataOperator::FACESLAVEMASTER)) {
769 try {
770 CHKERR oit->opLhs(*op_slave_data[0], *op_master_data[1]);
771 }
772 CATCH_OP_ERRORS(*oit);
773 }
774
775 if (oit->getOpType() & UserDataOperator::OPROWCOL &&
776 (type & UserDataOperator::FACESLAVESLAVE)) {
777 try {
778 CHKERR oit->opLhs(*op_slave_data[0], *op_slave_data[1]);
779 }
780 CATCH_OP_ERRORS(*oit);
781 }
782 }
783 }
785}
786
788 EntitiesFieldData &master_data, EntitiesFieldData &slave_data,
789 const std::string &field_name, const EntityType type_lo,
790 const EntityType type_hi) const {
792
793 auto reset_data = [type_lo, type_hi](auto &data) {
794 for (EntityType t = type_lo; t != type_hi; ++t) {
795 for (auto &dat : data.dataOnEntities[t]) {
796 dat.getOrder() = 0;
797 dat.getBase() = NOBASE;
798 dat.getSpace() = NOSPACE;
799 dat.getFieldData().resize(0, false);
800 dat.getFieldDofs().resize(0, false);
801 dat.getFieldEntities().resize(0, false);
802 }
803 }
804 };
805 reset_data(master_data);
806 reset_data(slave_data);
807
808 auto &field_ents = getDataFieldEnts();
809 auto bit_number = mField.get_field_bit_number(field_name);
810 const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
811 bit_number, get_id_for_min_type(type_lo));
812 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
813 cmp_uid_lo);
814 if (lo != field_ents.end()) {
815 const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
816 bit_number, get_id_for_max_type(type_hi));
817 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid, cmp_uid_hi);
818 if (lo != hi) {
819 for (auto it = lo; it != hi; ++it)
820 if (auto e = it->lock()) {
821
822 auto get_data = [&](auto &data, auto type, auto side) {
823 auto &dat = data.dataOnEntities[type][side];
824 auto &ent_field_dofs = dat.getFieldDofs();
825 auto &ent_field_data = dat.getFieldData();
826 dat.getFieldEntities().resize(1, false);
827 dat.getFieldEntities()[0] = e.get();
828 dat.getBase() = e->getApproxBase();
829 dat.getSpace() = e->getSpace();
830 const int ent_order = e->getMaxOrder();
831 dat.getOrder() =
832 dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
833 const auto dof_ent_field_data = e->getEntFieldData();
834 const int nb_dofs_on_ent = e->getNbDofsOnEnt();
835 ent_field_data.resize(nb_dofs_on_ent, false);
836 noalias(ent_field_data) = e->getEntFieldData();
837 ent_field_dofs.resize(nb_dofs_on_ent, false);
838 std::fill(ent_field_dofs.begin(), ent_field_dofs.end(), nullptr);
839 if (auto cache = e->entityCacheDataDofs.lock()) {
840 for (auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
841 ent_field_dofs[(*dit)->getEntDofIdx()] =
842 reinterpret_cast<FEDofEntity *>((*dit).get());
843 }
844 }
845 };
846
847 const EntityType type = e->getEntType();
848 const int side = e->getSideNumberPtr()->side_number;
849
850 switch (type) {
851 case MBEDGE:
852
853 if (side < 3)
854 get_data(master_data, type, side);
855 else if (side > 5)
856 get_data(slave_data, type, side - 6);
857
858 break;
859 case MBTRI:
860
861 if (side == 3)
862 get_data(master_data, type, 0);
863 if (side == 4)
864 get_data(slave_data, type, 0);
865
866 break;
867 default:
868 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
869 "Entity type not implemented (FIXME)");
870 };
871
872 const int brother_side = e->getSideNumberPtr()->brother_side_number;
873 if (brother_side != -1)
874 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
875 "Case with brother side not implemented (FIXME)");
876 }
877 }
878 }
879
881}
882
884 const std::string field_name, VectorDouble &master_nodes_data,
885 VectorDouble &slave_nodes_data, VectorDofs &master_nodes_dofs,
886 VectorDofs &slave_nodes_dofs,
887
888 VectorFieldEntities &master_field_entities,
889 VectorFieldEntities &slave_field_entities,
890
891 FieldSpace &master_space, FieldSpace &slave_space,
892 FieldApproximationBase &master_base,
893 FieldApproximationBase &slave_base) const {
895
896 auto set_zero = [](auto &nodes_data, auto &nodes_dofs, auto &field_entities) {
897 nodes_data.resize(0, false);
898 nodes_dofs.resize(0, false);
899 field_entities.resize(0, false);
900 };
901 set_zero(master_nodes_data, master_nodes_dofs, master_field_entities);
902 set_zero(slave_nodes_data, slave_nodes_dofs, slave_field_entities);
903
904 auto field_it = fieldsPtr->get<FieldName_mi_tag>().find(field_name);
905 if (field_it != fieldsPtr->get<FieldName_mi_tag>().end()) {
906
907 auto bit_number = (*field_it)->getBitNumber();
908 const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
909 master_space = slave_space = (*field_it)->getSpace();
910 master_base = slave_base = (*field_it)->getApproxBase();
911
912 auto &field_ents = getDataFieldEnts();
913 const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
914 bit_number, get_id_for_min_type<MBVERTEX>());
915 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
916 cmp_uid_lo);
917 if (lo != field_ents.end()) {
918 const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
919 bit_number, get_id_for_max_type<MBVERTEX>());
920 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid, cmp_uid_hi);
921 if (lo != hi) {
922
923 int nb_dofs = 0;
924 for (auto it = lo; it != hi; ++it) {
925 if (auto e = it->lock()) {
926 nb_dofs += e->getEntFieldData().size();
927 }
928 }
929
930 if (nb_dofs) {
931
932 auto init_set = [&](auto &nodes_data, auto &nodes_dofs,
933 auto &field_entities) {
934 constexpr int num_nodes = 3;
935 const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
936 nodes_data.resize(max_nb_dofs, false);
937 nodes_dofs.resize(max_nb_dofs, false);
938 field_entities.resize(num_nodes, false);
939 nodes_data.clear();
940 fill(nodes_dofs.begin(), nodes_dofs.end(), nullptr);
941 fill(field_entities.begin(), field_entities.end(), nullptr);
942 };
943
944 init_set(master_nodes_data, master_nodes_dofs, master_field_entities);
945 init_set(slave_nodes_data, slave_nodes_dofs, slave_field_entities);
946
947 for (auto it = lo; it != hi; ++it) {
948 if (auto e = it->lock()) {
949
950 const auto &sn = e->getSideNumberPtr();
951 int side = sn->side_number;
952
953 auto set_data = [&](auto &nodes_data, auto &nodes_dofs,
954 auto &field_entities, int side, int pos) {
955 field_entities[side] = e.get();
956 if (auto cache = e->entityCacheDataDofs.lock()) {
957 for (auto dit = cache->loHi[0]; dit != cache->loHi[1];
958 ++dit) {
959 const auto dof_idx = (*dit)->getEntDofIdx();
960 nodes_data[pos + dof_idx] = (*dit)->getFieldData();
961 nodes_dofs[pos + dof_idx] =
962 reinterpret_cast<FEDofEntity *>((*dit).get());
963 }
964 }
965 };
966
967 if (side < 3)
968 set_data(master_nodes_data, master_nodes_dofs,
969 master_field_entities, side, side * nb_dofs_on_vert);
970 else
971 set_data(slave_nodes_data, slave_nodes_dofs,
972 slave_field_entities, (side - 3),
973 (side - 3) * nb_dofs_on_vert);
974
975 const int brother_side = sn->brother_side_number;
976 if (brother_side != -1)
977 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
978 "Not implemented (FIXME please)");
979 }
980 }
981 }
982 }
983 }
984 }
985
987}
988
989template <typename EXTRACTOR>
991 EntitiesFieldData &master_data, EntitiesFieldData &slave_data,
992 const std::string &field_name, FieldEntity_vector_view &ents_field,
993 const EntityType type_lo, const EntityType type_hi,
994 EXTRACTOR &&extractor) const {
996
997 auto clear_data = [type_lo, type_hi](auto &data) {
998 for (EntityType t = type_lo; t != type_hi; ++t) {
999 for (auto &d : data.dataOnEntities[t]) {
1000 d.getIndices().resize(0, false);
1001 d.getLocalIndices().resize(0, false);
1002 }
1003 }
1004 };
1005
1006 clear_data(master_data);
1007 clear_data(slave_data);
1008
1009 auto bit_number = mField.get_field_bit_number(field_name);
1010 const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
1011 bit_number, get_id_for_min_type(type_lo));
1012 auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
1013 cmp_uid_lo);
1014 if (lo != ents_field.end()) {
1015 const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
1016 bit_number, get_id_for_max_type(type_hi));
1017 auto hi = std::upper_bound(lo, ents_field.end(), hi_uid, cmp_uid_hi);
1018 if (lo != hi) {
1019
1020 std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
1021
1022 for (auto it = lo; it != hi; ++it)
1023 if (auto e = it->lock()) {
1024
1025 const EntityType type = e->getEntType();
1026 const int side = e->getSideNumberPtr()->side_number;
1027 const int brother_side = e->getSideNumberPtr()->brother_side_number;
1028 if (brother_side != -1)
1029 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1030 "Not implemented case");
1031
1032 auto get_indices = [&](auto &data, const auto type, const auto side) {
1033 if (auto cache = extractor(e).lock()) {
1034 for (auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
1035 auto &dof = (**dit);
1036 auto &dat = data.dataOnEntities[type][side];
1037 auto &ent_field_indices = dat.getIndices();
1038 auto &ent_field_local_indices = dat.getLocalIndices();
1039 if (ent_field_indices.empty()) {
1040 const int nb_dofs_on_ent = dof.getNbDofsOnEnt();
1041 ent_field_indices.resize(nb_dofs_on_ent, false);
1042 ent_field_local_indices.resize(nb_dofs_on_ent, false);
1043 std::fill(ent_field_indices.data().begin(),
1044 ent_field_indices.data().end(), -1);
1045 std::fill(ent_field_local_indices.data().begin(),
1046 ent_field_local_indices.data().end(), -1);
1047 }
1048 const int idx = dof.getEntDofIdx();
1049 ent_field_indices[idx] = dof.getPetscGlobalDofIdx();
1050 ent_field_local_indices[idx] = dof.getPetscLocalDofIdx();
1051 }
1052 }
1053 };
1054
1055 switch (type) {
1056 case MBEDGE:
1057
1058 if (side < 3)
1059 get_indices(master_data, type, side);
1060 else if (side > 5)
1061 get_indices(slave_data, type, side - 6);
1062
1063 break;
1064 case MBTRI:
1065
1066 if (side == 3)
1067 get_indices(master_data, type, 0);
1068 if (side == 4)
1069 get_indices(slave_data, type, 0);
1070
1071 break;
1072 default:
1073 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1074 "Entity type not implemented");
1075 }
1076 }
1077 }
1078 }
1079
1081}
1082
1083template <typename EXTRACTOR>
1085 const std::string field_name, FieldEntity_vector_view &ents_field,
1086 VectorInt &master_nodes_indices, VectorInt &master_local_nodes_indices,
1087 VectorInt &slave_nodes_indices, VectorInt &slave_local_nodes_indices,
1088 EXTRACTOR &&extractor) const {
1090
1091 master_nodes_indices.resize(0, false);
1092 master_local_nodes_indices.resize(0, false);
1093 slave_nodes_indices.resize(0, false);
1094 slave_local_nodes_indices.resize(0, false);
1095
1096 auto field_it = fieldsPtr->get<FieldName_mi_tag>().find(field_name);
1097 if (field_it != fieldsPtr->get<FieldName_mi_tag>().end()) {
1098
1099 auto bit_number = (*field_it)->getBitNumber();
1100 const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
1101
1102 const auto lo_uid = FieldEntity::getLocalUniqueIdCalculate(
1103 bit_number, get_id_for_min_type<MBVERTEX>());
1104 auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
1105 cmp_uid_lo);
1106 if (lo != ents_field.end()) {
1107 const auto hi_uid = FieldEntity::getLocalUniqueIdCalculate(
1108 bit_number, get_id_for_max_type<MBVERTEX>());
1109 auto hi = std::upper_bound(lo, ents_field.end(), hi_uid, cmp_uid_hi);
1110 if (lo != hi) {
1111
1112 int nb_dofs = 0;
1113 for (auto it = lo; it != hi; ++it) {
1114 if (auto e = it->lock()) {
1115 if (auto cache = extractor(e).lock()) {
1116 nb_dofs += std::distance(cache->loHi[0], cache->loHi[1]);
1117 }
1118 }
1119 }
1120
1121 if (nb_dofs) {
1122
1123 constexpr int num_nodes = 3;
1124 const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
1125
1126 auto set_vec_size = [&](auto &nodes_indices,
1127 auto &local_nodes_indices) {
1128 nodes_indices.resize(max_nb_dofs, false);
1129 local_nodes_indices.resize(max_nb_dofs, false);
1130 std::fill(nodes_indices.begin(), nodes_indices.end(), -1);
1131 std::fill(local_nodes_indices.begin(), local_nodes_indices.end(),
1132 -1);
1133 };
1134
1135 set_vec_size(master_nodes_indices, master_local_nodes_indices);
1136 set_vec_size(slave_nodes_indices, slave_local_nodes_indices);
1137
1138 for (auto it = lo; it != hi; ++it) {
1139 if (auto e = it->lock()) {
1140
1141 const int side = e->getSideNumberPtr()->side_number;
1142 const int brother_side =
1143 e->getSideNumberPtr()->brother_side_number;
1144 if (brother_side != -1)
1145 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1146 "Not implemented case");
1147
1148 auto get_indices = [&](auto &nodes_indices,
1149 auto &local_nodes_indices,
1150 const auto side) {
1151 if (auto cache = extractor(e).lock()) {
1152 for (auto dit = cache->loHi[0]; dit != cache->loHi[1];
1153 ++dit) {
1154 const int idx = (*dit)->getPetscGlobalDofIdx();
1155 const int local_idx = (*dit)->getPetscLocalDofIdx();
1156 const int pos =
1157 side * nb_dofs_on_vert + (*dit)->getDofCoeffIdx();
1158 nodes_indices[pos] = idx;
1159 local_nodes_indices[pos] = local_idx;
1160 }
1161 }
1162 };
1163
1164 if (side < 3)
1165 get_indices(master_nodes_indices, master_local_nodes_indices,
1166 side);
1167 else if (side > 2)
1168 get_indices(slave_nodes_indices, slave_local_nodes_indices,
1169 side - 3);
1170 else
1171 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1172 "Impossible case");
1173 }
1174 }
1175 }
1176 }
1177 }
1178 }
1179
1181}
1182
1184ContactPrismElementForcesAndSourcesCore::UserDataOperator::loopSideVolumes(
1185 const string fe_name,
1187 const int side_type, const EntityHandle ent_for_side) {
1188 return loopSide(fe_name, &fe_method, side_type, ent_for_side);
1189}
1190
1191} // namespace MoFEM
#define CATCH_OP_ERRORS(OP)
FieldApproximationBase
approximation base
Definition definitions.h:58
@ LASTBASE
Definition definitions.h:69
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ AINSWORTH_LOBATTO_BASE
Definition definitions.h:62
@ NOBASE
Definition definitions.h:59
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
FieldSpace
approximation spaces
Definition definitions.h:82
@ L2
field with C-1 continuity
Definition definitions.h:88
@ LASTSPACE
FieldSpace in [ 0, LASTSPACE )
Definition definitions.h:89
@ NOFIELD
scalar or vector of scalars describe (no true field)
Definition definitions.h:84
@ H1
continuous field
Definition definitions.h:85
@ NOSPACE
Definition definitions.h:83
@ HCURL
field with continuous tangents
Definition definitions.h:86
@ HDIV
field with continuous normal traction
Definition definitions.h:87
@ CONTINUOUS
Regular field.
static const char *const FieldSpaceNames[]
Definition definitions.h:92
#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
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int order
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITFIELDID_SIZE > BitFieldId
Field Id.
Definition Types.hpp:42
UBlasVector< int > VectorInt
Definition Types.hpp:67
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
static auto cmp_uid_lo(const boost::weak_ptr< FieldEntity > &a, const UId &b)
EntityHandle get_id_for_max_type()
static auto cmp_uid_hi(const UId &b, const boost::weak_ptr< FieldEntity > &a)
EntityHandle get_id_for_min_type()
ublas::vector< FieldEntity *, FieldEntAllocator > VectorFieldEntities
std::vector< boost::weak_ptr< FieldEntity > > FieldEntity_vector_view
Field_multiIndex::index< FieldName_mi_tag >::type::iterator field_it
ublas::vector< FEDofEntity *, DofsAllocator > VectorDofs
constexpr double t
plate stiffness
Definition plate.cpp:58
constexpr auto field_name
#define QUAD_2D_TABLE_SIZE
Definition quad.h:174
static QUAD *const QUAD_2D_TABLE[]
Definition quad.h:175
const Field_multiIndex * fieldsPtr
raw pointer to fields container
int getNinTheLoop() const
get number of evaluated element in the loop
MoFEMErrorCode operator()()
function is run for every finite element
VectorDouble normal
vector storing vector normal to master or slave element
MoFEMErrorCode getEntityIndices(EntitiesFieldData &master_data, EntitiesFieldData &slave_data, const std::string &field_name, FieldEntity_vector_view &ents_field, const EntityType type_lo, const EntityType type_hi, EXTRACTOR &&extractor) const
function that gets entity indices.
MoFEMErrorCode getNodesIndices(const std::string field_name, FieldEntity_vector_view &ents_field, VectorInt &master_nodes_indices, VectorInt &master_local_nodes_indices, VectorInt &slave_nodes_indices, VectorInt &slave_local_nodes_indices, EXTRACTOR &&extractor) const
function that gets nodes indices.
const std::array< boost::shared_ptr< EntitiesFieldData >, LASTSPACE > derivedDataOnSlave
const std::array< boost::shared_ptr< EntitiesFieldData >, LASTSPACE > dataOnMaster
Entity data on element entity rows fields.
std::array< double, 2 > aRea
Array storing master and slave faces areas.
const std::array< boost::shared_ptr< EntitiesFieldData >, LASTSPACE > derivedDataOnMaster
Entity data on element entity columns fields.
MoFEMErrorCode getNodesFieldData(const std::string field_name, VectorDouble &master_nodes_data, VectorDouble &slave_nodes_data, VectorDofs &master_nodes_dofs, VectorDofs &slave_nodes_dofs, VectorFieldEntities &master_field_entities, VectorFieldEntities &slave_field_entities, FieldSpace &master_space, FieldSpace &slave_space, FieldApproximationBase &master_base, FieldApproximationBase &slave_base) const
function that gets nodes field data.
MoFEMErrorCode getEntityFieldData(EntitiesFieldData &master_data, EntitiesFieldData &slave_data, const std::string &field_name, const EntityType type_lo=MBVERTEX, const EntityType type_hi=MBPOLYHEDRON) const
function that gets entity field data.
const std::array< boost::shared_ptr< EntitiesFieldData >, LASTSPACE > dataOnSlave
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode opRhs(EntitiesFieldData &data, const bool error_if_no_base=false)
Deprecated interface functions.
this class derive data form other data structure
Class used to pass element data to calculate base functions on tet,triangle,edge.
Data on single entity (This is passed as argument to DataOperator::doWork)
data structure for finite element entity
std::array< std::bitset< LASTSPACE >, MBMAXTYPE > spacesOnEntities
spaces on entity types
std::bitset< LASTBASE > bAse
bases on element
std::array< boost::ptr_vector< EntData >, MBMAXTYPE > dataOnEntities
std::array< std::bitset< LASTBASE >, LASTSPACE > basesOnSpaces
base on spaces
std::array< std::bitset< LASTBASE >, LASTSPACE > brokenBasesOnSpaces
base on spaces
std::array< std::bitset< LASTBASE >, MBMAXTYPE > basesOnEntities
bases on entity types
keeps information about indexed dofs for the finite element
auto & getRowFieldEnts() const
auto getFEName() const
get finite element name
const FieldEntity_vector_view & getDataFieldEnts() const
boost::shared_ptr< const NumeredEntFiniteElement > numeredEntFiniteElementPtr
auto & getColFieldEnts() const
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
MultiIndex Tag for field name.
Provide data structure for (tensor) field approximation.
FieldSpace getSpace() const
Get field approximation space.
const BitFieldId & getId() const
Get unique field id.
MoFEMErrorCode loopSide(const string &fe_name, ForcesAndSourcesCore *side_fe, const size_t dim, const EntityHandle ent_for_side=0, boost::shared_ptr< Range > fe_range=nullptr, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy, AdjCache *adj_cache=nullptr)
User calls this function to loop over elements on the side of face. This function calls finite elemen...
structure to get information form mofem into EntitiesFieldData
int getMaxRowOrder() const
Get max order of approximation for field in rows.
auto & getUserPolynomialBase()
Get the User Polynomial Base object.
MoFEMErrorCode getSpacesAndBaseOnEntities(EntitiesFieldData &data) const
Get field approximation space and base on entities.
MoFEMErrorCode getNoFieldRowIndices(EntitiesFieldData &data, const int bit_number) const
get col NoField indices
virtual MoFEMErrorCode setGaussPts(int order_row, int order_col, int order_data)
set user specific integration rule
virtual int getRule(int order_row, int order_col, int order_data)
another variant of getRule
boost::ptr_deque< UserDataOperator > opPtrVector
Vector of finite element users data operators.
const std::array< boost::shared_ptr< EntitiesFieldData >, LASTSPACE > dataOnElement
Entity data on element entity rows fields.
int getMaxColOrder() const
Get max order of approximation for field in columns.
MoFEMErrorCode getNoFieldColIndices(EntitiesFieldData &data, const int bit_number) const
get col NoField indices
int getMaxDataOrder() const
Get max order of approximation for data fields.
MoFEMErrorCode getNoFieldFieldData(const int bit_number, VectorDouble &ent_field_data, VectorDofs &ent_field_dofs, VectorFieldEntities &ent_field) const
Get field data on nodes.
MoFEMErrorCode createDataOnElement(EntityType type)
Create a entity data on element object.
int normalShift
Shift in vector for linear geometry.
static constexpr std::array< double, 6 > diffShapeFunMBTRI
Definition Tools.hpp:104
static MoFEMErrorCode getTriNormal(const double *coords, double *normal, double *d_normal=nullptr)
Get the Tri Normal objectGet triangle normal.
Definition Tools.cpp:353
Calculate base functions on triangle.
Base volume element used to integrate on contact surface (could be extended to other volume elements)...
int npoints
Definition quad.h:29