v0.14.0
Loading...
Searching...
No Matches
MeshProjectionDataOperators.cpp
Go to the documentation of this file.
1/** \file MeshProjectionDataOperators.cpp
2
3
4*/
5
6namespace MoFEM {
7
8OpRunParent::OpRunParent(boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
9 BitRefLevel bit_parent, BitRefLevel bit_parent_mask,
10 boost::shared_ptr<ForcesAndSourcesCore> this_ele_ptr,
11 BitRefLevel bit_this, BitRefLevel bit_this_mask,
12 int verb, Sev sev)
15 parentElePtr(parent_ele_ptr), bitParent(bit_parent),
16 bitParentMask(bit_parent_mask), thisElePtr(this_ele_ptr),
17 bitThis(bit_this), bitThisMask(bit_this_mask), verbosity(verb),
18 severityLevel(sev) {}
19
23
24 auto &bit = getFEMethod()->numeredEntFiniteElementPtr->getBitRefLevel();
25
26 auto check = [&](auto &b, auto &m) {
27 return ((bit & b).any()) && ((bit & m) == bit);
28 };
29
30 if (verbosity > QUIET) {
31 MOFEM_LOG_CHANNEL("SELF");
32 MOFEM_TAG_AND_LOG("SELF", severityLevel, "OpRunParent")
33 << "FE bit " << bit
34 << " check parent = " << check(bitParent, bitParentMask)
35 << " check this " << check(bitThis, bitThisMask);
36 }
37
38 if (check(bitParent, bitParentMask)) {
39 if (parentElePtr)
42
43 } else if (check(bitThis, bitThisMask)) {
44 if (thisElePtr)
46 }
47
49}
50
52 std::string field_name, OpType op_parent_type,
53 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
54 BitRefLevel bit_child, BitRefLevel bit_child_mask,
55 BitRefLevel bit_parent_ent, BitRefLevel bit_parent_ent_mask, int verb,
56 Sev sev)
58 fieldName(field_name), opParentType(op_parent_type),
59 parentElePtr(parent_ele_ptr), bitChild(bit_child),
60 bitChildMask(bit_child_mask), bitParentEnt(bit_parent_ent),
61 bitParentEntMask(bit_parent_ent_mask), verbosity(verb),
62 severityLevel(sev) {
63 // Push op to collect data
64 auto field_op =
66 parentElePtr->getOpPtrVector().push_back(field_op);
67}
68
70 FieldSpace space, OpType op_parent_type,
71 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
72 BitRefLevel bit_child, BitRefLevel bit_child_mask,
73 BitRefLevel bit_parent_ent, BitRefLevel bit_parent_ent_mask, int verb,
74 Sev sev)
75 : ForcesAndSourcesCore::UserDataOperator(space, op_parent_type),
76 fieldName(""), approxSpace(space), opParentType(op_parent_type),
77 parentElePtr(parent_ele_ptr), bitChild(bit_child),
78 bitChildMask(bit_child_mask), bitParentEnt(bit_parent_ent),
79 bitParentEntMask(bit_parent_ent_mask), verbosity(verb),
80 severityLevel(sev) {
81 // Push op to collect data
82 auto field_op =
84 parentElePtr->getOpPtrVector().push_back(field_op);
85}
86
88 const bool error_if_no_base) {
89 int count_meshset_sides = 0; // count number of data on parent element
91
92 auto check = [](auto &b, auto &m, auto &bit) {
93 return ((bit & b).any()) && ((bit & m) == bit);
94 };
95
96 auto set_child_data_entity = [](auto &parent_data, auto &child_data) {
98 child_data.getEntDataBitRefLevel() = parent_data.getEntDataBitRefLevel();
99 child_data.sPace = parent_data.getSpace();
100 child_data.bAse = parent_data.getBase();
101 child_data.sEnse = parent_data.getSense();
102 child_data.oRder = parent_data.getOrder();
103 child_data.iNdices.swap(parent_data.getIndices());
104 child_data.localIndices.swap(parent_data.getLocalIndices());
105 child_data.dOfs.swap(parent_data.getFieldDofs());
106 child_data.fieldData.swap(parent_data.getFieldData());
107 child_data.fieldEntities.swap(parent_data.getFieldEntities());
109 };
110
111 auto set_child_data_vertex = [&](auto &parent_data, auto &child_data,
112 int node, int num_nodes) {
114
115 child_data.getEntDataBitRefLevel().resize(1, false);
116 child_data.getEntDataBitRefLevel()[0] =
117 parent_data.getEntDataBitRefLevel()[node];
118 child_data.sPace = parent_data.getSpace();
119 child_data.bAse = parent_data.getBase();
120 child_data.sEnse = parent_data.getSense();
121 child_data.oRder = parent_data.getOrder();
122
123 if (parent_data.dOfs.size()) {
124
125 auto &field_entities = parent_data.getFieldEntities();
126 auto &vertex_entity = field_entities[node];
127
128 const auto nb_coeffs = vertex_entity->getNbOfCoeffs();
129
130 child_data.fieldEntities.resize(1, false);
131 child_data.fieldEntities[0] = vertex_entity;
132#ifndef NDEBUG
133 if (parent_data.dOfs.size() != nb_coeffs * num_nodes)
134 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
135 "Inconsistent number of DOFs and vertices %d != %d",
136 parent_data.dOfs.size(), nb_coeffs * num_nodes);
137#endif
138
139 // It could be a case that all DOFs on element are removed from the
140 // problem, the size of indices vector is zero.
141 if (parent_data.iNdices.size()) {
142
143#ifndef NDEBUG
144 if (parent_data.dOfs.size() != parent_data.iNdices.size())
145 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
146 "Inconsistent size of DOFs %d != %d",
147 parent_data.dOfs.size(), parent_data.iNdices.size());
148#endif
149
150 child_data.iNdices.resize(nb_coeffs, false);
151 child_data.localIndices.resize(nb_coeffs, false);
152 child_data.dOfs.resize(nb_coeffs, false);
153 child_data.fieldData.resize(nb_coeffs, false);
154
155 int DD = 0;
156 for (auto dd = node * nb_coeffs; dd != (node + 1) * nb_coeffs;
157 ++dd, ++DD) {
158 child_data.iNdices[DD] = parent_data.iNdices[dd];
159 child_data.localIndices[DD] = parent_data.localIndices[dd];
160 child_data.dOfs[DD] = parent_data.dOfs[dd];
161 child_data.fieldData[DD] = parent_data.fieldData[dd];
162 }
163 } else {
164
165 child_data.iNdices.clear();
166 child_data.localIndices.clear();
167 child_data.dOfs.resize(nb_coeffs, false);
168 child_data.fieldData.resize(nb_coeffs, false);
169 int DD = 0;
170 for (auto dd = node * nb_coeffs; dd != (node + 1) * nb_coeffs;
171 ++dd, ++DD) {
172 child_data.dOfs[DD] = parent_data.dOfs[dd];
173 child_data.fieldData[DD] = parent_data.fieldData[dd];
174 }
175
176 }
177 }
178
180 };
181
182 /**
183 * @brief swap child base
184 *
185 * @todo add swap for Bernstein-Bezier base
186 *
187 */
188 auto set_child_base_entity = [](auto &parent_data, auto &child_data) {
190 child_data.resetFieldDependentData();
191 child_data.getEntDataBitRefLevel() = parent_data.getEntDataBitRefLevel();
192 child_data.sPace = parent_data.getSpace();
193
194#ifndef NDEBUG
195 if (child_data.bAse == AINSWORTH_BERNSTEIN_BEZIER_BASE)
196 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Base not implemented");
197#endif
198
200 for (int b = AINSWORTH_LEGENDRE_BASE; b != LASTBASE; b++) {
201 for (auto derivative = 0; derivative != BaseDerivatives::LastDerivative;
202 ++derivative) {
203 auto parent_base =
204 parent_data.getNSharedPtr(static_cast<FieldApproximationBase>(b),
205 static_cast<BaseDerivatives>(derivative));
206 if (parent_base) {
207 auto &child_base = child_data.getNSharedPtr(
208 static_cast<FieldApproximationBase>(b),
209 static_cast<BaseDerivatives>(derivative));
210 if (!child_base)
211 child_base = boost::make_shared<MatrixDouble>();
212 child_base->swap(*parent_base);
213 }
214 }
215 }
216
218 };
219
220 auto set_child_base_vertex = [](auto &parent_data, auto &child_data, int node,
221 int num_nodes) {
223 child_data.resetFieldDependentData();
224 child_data.getEntDataBitRefLevel().resize(1, false);
225 child_data.getEntDataBitRefLevel()[0] =
226 parent_data.getEntDataBitRefLevel()[node];
227 child_data.sPace = parent_data.getSpace();
228
229#ifndef NDEBUG
230 if (child_data.bAse == AINSWORTH_BERNSTEIN_BEZIER_BASE)
231 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Base not implemented");
232#endif
233
235 for (int b = AINSWORTH_LEGENDRE_BASE; b != LASTBASE; b++) {
236 for (auto derivative = 0; derivative != BaseDerivatives::LastDerivative;
237 ++derivative) {
238 auto parent_base =
239 parent_data.getNSharedPtr(static_cast<FieldApproximationBase>(b),
240 static_cast<BaseDerivatives>(derivative));
241 if (parent_base) {
242 auto &child_base = child_data.getNSharedPtr(
243 static_cast<FieldApproximationBase>(b),
244 static_cast<BaseDerivatives>(derivative));
245
246 const auto num_bases_per_node = parent_base->size2() / num_nodes;
247 if (parent_base->size2() % num_nodes) {
248 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
249 "Inconsistent nb of base functions and nodes mod(%d, %d)",
250 parent_base->size2(), num_nodes);
251 }
252
253 if (!child_base)
254 child_base = boost::make_shared<MatrixDouble>(parent_base->size1(),
255 num_bases_per_node);
256 else
257 child_base->resize(parent_base->size1(), num_bases_per_node, false);
258
259 for (auto gg = 0; gg != parent_base->size1(); ++gg) {
260 int DD = 0;
261 for (auto dd = node * num_bases_per_node;
262 dd != (node + 1) * num_bases_per_node; ++dd, ++DD) {
263 (*child_base)(gg, DD) = (*parent_base)(gg, dd);
264 }
265 }
266 }
267 }
268 }
269
271 };
272
273 /**
274 * @brief if DOF is on children set -1 to its repetition on parent
275 *
276 */
277 auto switch_off_dofs_children = [&](auto &parent_ent_data, auto &child_data) {
279 for (auto i : parent_ent_data.getIndices()) {
280 if (i >= 0) {
281 for (auto &child_ent_data : child_data) {
282 auto it = std::find(child_ent_data.getIndices().begin(),
283 child_ent_data.getIndices().end(), i);
284 if (it != child_ent_data.getIndices().end()) {
285 const auto dof_idx =
286 std::distance(child_ent_data.getIndices().begin(), it);
287 auto &bit_dof =
288 child_ent_data.getFieldDofs()[dof_idx]->getBitRefLevel();
289 if (check(bitParentEnt, bitParentEntMask, bit_dof)) {
290 child_ent_data.getIndices()[dof_idx] = -1;
291 child_ent_data.getLocalIndices()[dof_idx] = -1;
292 child_ent_data.getFieldData()[dof_idx] = 0;
293 }
294 }
295 }
296 }
297 }
299 };
300
301 // that forces to run operator at last instance and collect data on
302 // entities
303 auto do_work_parent_hook = [&](DataOperator *op_ptr, int side,
304 EntityType type,
307
308 auto up_op_ptr = static_cast<UserDataOperator *>(op_ptr);
309 auto &field_entities = data.getFieldEntities();
310
311#ifndef NDEBUG
312 if (verbosity >= VERBOSE) {
313 MOFEM_LOG("SELF", severityLevel)
314 << "Add entity data to meshset "
315 << "side/type: " << side << "/" << CN::EntityTypeName(type)
316 << " op space/base: " << FieldSpaceNames[data.getSpace()] << "/"
317 << ApproximationBaseNames[data.getBase()]
318 << " OPSPACE: " << ((opParentType == OPSPACE) ? "Yes" : "No");
319 }
320 if (verbosity >= NOISY) {
321 for (auto field_ent : field_entities) {
322 MOFEM_LOG("SELF", severityLevel)
323 << "Parent field entity bit: " << field_ent->getBitRefLevel() << " "
324 << *field_ent;
325 }
326 }
327#endif
328
329 const auto nb_ents = field_entities.size();
330 const auto nb_nodes = data.getEntDataBitRefLevel().size();
331
332 // #ifndef NDEBUG
333 if (type == MBVERTEX &&
334 nb_nodes != up_op_ptr->getNumberOfNodesOnElement()) {
335 SETERRQ2(
336 PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
337 "Inconsistency between bit ref levels and number of nodes %d != %d",
338 nb_nodes, up_op_ptr->getNumberOfNodesOnElement());
339 }
340 // #endif
341
342 auto get_child_meshset =
343 [&](auto count_meshset_sides) -> MoFEM::EntitiesFieldData::EntData & {
344 auto &data_on_meshset = entities_field_data.dataOnEntities[MBENTITYSET];
345 if (data_on_meshset.size() < count_meshset_sides) {
346 if (poolEntsVector.size()) {
347 // transfer data from pool to data_on_meshset
348 data_on_meshset.transfer(data_on_meshset.end(),
350 } else {
351 // resize, no data on pool
352 entities_field_data.dataOnEntities[MBENTITYSET].resize(
353 count_meshset_sides);
354 }
355 }
356 return entities_field_data
357 .dataOnEntities[MBENTITYSET][count_meshset_sides - 1];
358 };
359
360 if (opParentType == OPSPACE) {
361 for (auto node = 0; node != nb_nodes; ++node) {
362 auto &bit_ent = data.getEntDataBitRefLevel()[node];
363 if (check(bitParentEnt, bitParentEntMask, bit_ent)) {
364 ++count_meshset_sides;
365 auto &child_data_meshset = get_child_meshset(count_meshset_sides);
366 if (type == MBVERTEX) {
367 const auto num_nodes = up_op_ptr->getNumberOfNodesOnElement();
368 CHKERR set_child_base_vertex(data, child_data_meshset, node,
369 num_nodes);
370 } else {
371 CHKERR set_child_base_entity(data, child_data_meshset);
372 }
373 }
374 }
375
376 } else {
377
378 {
379 boost::container::static_vector<EntityType, 128> ents_type;
380 ents_type.reserve(field_entities.size());
381 for (auto &field_entity : field_entities)
382 ents_type.push_back(field_entity->getEntType());
383 std::sort(ents_type.begin(), ents_type.end());
384 auto end = std::unique(ents_type.begin(), ents_type.end());
385 for (auto it_t = ents_type.begin(); it_t != end; ++it_t)
386 CHKERR switch_off_dofs_children(
387 data, entities_field_data.dataOnEntities[*it_t]);
388 if (type == MBENTITYSET)
389 CHKERR switch_off_dofs_children(
390 data, entities_field_data.dataOnEntities[type]);
391 }
392
393 if (type == MBVERTEX &&
394 nb_ents != up_op_ptr->getNumberOfNodesOnElement()) {
395 SETERRQ2(
396 PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
397 "Number of nodes is expected to much number of entities: %d != %d",
398 nb_ents, up_op_ptr->getNumberOfNodesOnElement());
399 } else if (type != MBVERTEX && nb_ents > 1) {
400 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
401 "Code can handle only one entity");
402 }
403
404 for (auto node = 0; node != nb_nodes; ++node) {
405 auto &bit_ent = data.getEntDataBitRefLevel()[node];
406 if (check(bitParentEnt, bitParentEntMask, bit_ent)) {
407 ++count_meshset_sides;
408 auto &child_data_meshset = get_child_meshset(count_meshset_sides);
409 if (type == MBVERTEX) {
410 const auto num_nodes = up_op_ptr->getNumberOfNodesOnElement();
411 CHKERR set_child_data_vertex(data, child_data_meshset, node,
412 num_nodes);
413 } else {
414 CHKERR set_child_data_entity(data, child_data_meshset);
415 }
416 }
417 }
418 }
419
421 };
422
423 // iterate parents collect data
424 auto &bit_fe = getFEMethod()->numeredEntFiniteElementPtr->getBitRefLevel();
425 if (check(bitChild, bitChildMask, bit_fe)) { // check if FE is on right bit
426
427 if (verbosity >= VERBOSE) {
428 MOFEM_LOG("SELF", severityLevel) << "Child FE bit: " << bit_fe;
429 }
430
431 auto loop_parent_fe = [&]() {
433
434 // execute do_work_parent_hook on parent element, and collect data.
435 parentElePtr->getOpPtrVector().back().doWorkRhsHook = do_work_parent_hook;
438
439#ifndef NDEBUG
440 if (parentElePtr->getLoopSize()) {
441 auto &parent_gauss_pts = parentElePtr->gaussPts;
442 if (getGaussPts().size1() != parent_gauss_pts.size1()) {
443 MOFEM_LOG("SELF", Sev::error)
444 << "Calling element: "
445 << boost::typeindex::type_id_runtime(*parentElePtr).pretty_name();
446 MOFEM_LOG("SELF", Sev::error) << getGaussPts();
447 MOFEM_LOG("SELF", Sev::error) << parent_gauss_pts;
448 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
449 "Wrong number of weights");
450 }
451 if (getGaussPts().size2() != parent_gauss_pts.size2()) {
452 MOFEM_LOG("SELF", Sev::error)
453 << "Calling element: "
454 << boost::typeindex::type_id_runtime(*parentElePtr).pretty_name();
455 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
456 "Wrong number of integration points");
457 }
458 }
459#endif
460
462 };
463
464 // iterate parent finite lents
465 CHKERR loop_parent_fe();
466 }
467
468 if (verbosity >= VERBOSE) {
469 MOFEM_LOG("SELF", severityLevel)
470 << "Number of meshset entities "
471 << entities_field_data.dataOnEntities[MBENTITYSET].size();
472 }
473
474 auto &data_on_meshset = entities_field_data.dataOnEntities[MBENTITYSET];
475 auto it = data_on_meshset.begin();
476
477 // transfer not used data on entities to pool, to be used later
478 if (count_meshset_sides < data_on_meshset.size()) {
479 for (auto s = 0; s != count_meshset_sides; ++s)
480 ++it;
481 poolEntsVector.transfer(poolEntsVector.end(), it, data_on_meshset.end(),
482 data_on_meshset);
483 }
484
485 auto set_up_derivative_ent_data = [&](auto &entities_field_data,
486 auto &derivative_entities_field_data) {
488
490 using DerivedEntData = DerivedEntitiesFieldData::DerivedEntData;
491
493 auto &ents_data = entities_field_data.dataOnEntities[MBENTITYSET];
494 auto &dev_ents_data =
495 derivative_entities_field_data.dataOnEntities[MBENTITYSET];
496 dev_ents_data.clear();
497 for (auto c = 0; c < ents_data.size(); ++c) {
498 boost::shared_ptr<EntData> ent_data_ptr(data_ptr, &ents_data[c]);
499 dev_ents_data.push_back(new DerivedEntData(ent_data_ptr));
500 }
502 };
503
504 if (opParentType == OPSPACE) {
505 CHKERR set_up_derivative_ent_data(
506 entities_field_data,
507 *(getPtrFE()->getDerivedDataOnElementBySpaceArray()[approxSpace]));
508 }
509
510#ifndef NDEBUG
511 auto &side_table =
512 getPtrFE()->numeredEntFiniteElementPtr->getSideNumberTable();
513 for (auto &data : entities_field_data.dataOnEntities[MBENTITYSET]) {
514 for (auto dof : data.getFieldDofs()) {
515 auto &bit_dof = dof->getBitRefLevel();
516 if (check(bitParentEnt, bitParentEntMask, bit_dof)) {
517 auto ent = dof->getEnt();
518 if (side_table.find(ent) == side_table.end()) {
519 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
520 "Adjacency not found");
521 }
522 }
523 }
524 }
525#endif
526
528}
529
530} // namespace MoFEM
ForcesAndSourcesCore::UserDataOperator UserDataOperator
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
Definition: LogManager.hpp:362
@ QUIET
Definition: definitions.h:208
@ NOISY
Definition: definitions.h:211
@ VERBOSE
Definition: definitions.h:209
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_BERNSTEIN_BEZIER_BASE
Definition: definitions.h:64
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
FieldSpace
approximation spaces
Definition: definitions.h:82
@ NOSPACE
Definition: definitions.h:83
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 ...
Definition: definitions.h:346
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
static const char *const ApproximationBaseNames[]
Definition: definitions.h:72
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
FTensor::Index< 'm', SPACE_DIM > m
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
SeverityLevel
Severity levels.
Definition: LogManager.hpp:33
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
auto bit
set bit
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition: Types.hpp:40
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
constexpr auto field_name
base operator to do operations at Gauss Pt. level
Derived ata on single entity (This is passed as argument to DataOperator::doWork)
Data on single entity (This is passed as argument to DataOperator::doWork)
data structure for finite element entity
std::array< boost::ptr_vector< EntData >, MBMAXTYPE > dataOnEntities
boost::shared_ptr< const NumeredEntFiniteElement > numeredEntFiniteElementPtr
MoFEMErrorCode loopParent(const string &fe_name, ForcesAndSourcesCore *parent_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
User calls this function to loop over parent elements. This function calls finite element with its op...
std::string getFEName() const
Get name of the element.
OpType
Controls loop over entities on element.
@ OPSPACE
operator do Work is execute on space data
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
MoFEMErrorCode loopThis(const string &fe_name, ForcesAndSourcesCore *this_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
User calls this function to loop over the same element using a different set of integration points....
structure to get information form mofem into EntitiesFieldData
auto & getDataOnElementBySpaceArray()
Get data on entities and space.
MoFEMErrorCode opRhs(EntitiesFieldData &data, const bool error_if_no_base=false)
boost::ptr_deque< EntitiesFieldData::EntData > poolEntsVector
boost::shared_ptr< ForcesAndSourcesCore > parentElePtr
OpAddParentEntData(std::string field_name, OpType op_parent_type, boost::shared_ptr< ForcesAndSourcesCore > parent_ele_ptr, BitRefLevel bit_child, BitRefLevel bit_child_mask, BitRefLevel bit_parent_ent, BitRefLevel bit_parent_ent_mask, int verb=QUIET, Sev sev=Sev::noisy)
Construct a new Op Add Parent Ent Data object.
boost::shared_ptr< ForcesAndSourcesCore > parentElePtr
boost::shared_ptr< ForcesAndSourcesCore > thisElePtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
OpRunParent(boost::shared_ptr< ForcesAndSourcesCore > parent_ele_ptr, BitRefLevel bit_parent, BitRefLevel bit_parent_mask, boost::shared_ptr< ForcesAndSourcesCore > this_ele_ptr, BitRefLevel bit_this, BitRefLevel bit_this_mask, int verb=QUIET, Sev sev=Sev::noisy)
Construct a new Op Run Parent object.