10 boost::shared_ptr<ForcesAndSourcesCore> this_ele_ptr,
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),
26 auto check = [&](
auto &b,
auto &
m) {
27 return ((
bit & b).any()) && ((
bit &
m) ==
bit);
53 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
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),
71 boost::shared_ptr<ForcesAndSourcesCore> parent_ele_ptr,
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),
88 const bool error_if_no_base) {
89 int count_meshset_sides = 0;
92 auto check = [](
auto &b,
auto &
m,
auto &
bit) {
93 return ((
bit & b).any()) && ((
bit &
m) ==
bit);
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());
111 auto set_child_data_vertex = [&](
auto &parent_data,
auto &child_data,
112 int node,
int num_nodes) {
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();
123 if (parent_data.dOfs.size()) {
125 auto &field_entities = parent_data.getFieldEntities();
126 auto &vertex_entity = field_entities[node];
128 const auto nb_coeffs = vertex_entity->getNbOfCoeffs();
130 child_data.fieldEntities.resize(1,
false);
131 child_data.fieldEntities[0] = vertex_entity;
133 if (parent_data.dOfs.size() != nb_coeffs * num_nodes)
135 "Inconsistent number of DOFs and vertices %d != %d",
136 parent_data.dOfs.size(), nb_coeffs * num_nodes);
141 if (parent_data.iNdices.size()) {
144 if (parent_data.dOfs.size() != parent_data.iNdices.size())
146 "Inconsistent size of DOFs %d != %d",
147 parent_data.dOfs.size(), parent_data.iNdices.size());
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);
156 for (
auto dd = node * nb_coeffs;
dd != (node + 1) * nb_coeffs;
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];
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);
170 for (
auto dd = node * nb_coeffs;
dd != (node + 1) * nb_coeffs;
172 child_data.dOfs[DD] = parent_data.dOfs[
dd];
173 child_data.fieldData[DD] = parent_data.fieldData[
dd];
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();
201 for (
auto derivative = 0; derivative != BaseDerivatives::LastDerivative;
207 auto &child_base = child_data.getNSharedPtr(
211 child_base = boost::make_shared<MatrixDouble>();
212 child_base->swap(*parent_base);
220 auto set_child_base_vertex = [](
auto &parent_data,
auto &child_data,
int node,
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();
236 for (
auto derivative = 0; derivative != BaseDerivatives::LastDerivative;
242 auto &child_base = child_data.getNSharedPtr(
246 const auto num_bases_per_node = parent_base->size2() / num_nodes;
247 if (parent_base->size2() % num_nodes) {
249 "Inconsistent nb of base functions and nodes mod(%d, %d)",
250 parent_base->size2(), num_nodes);
254 child_base = boost::make_shared<MatrixDouble>(parent_base->size1(),
257 child_base->resize(parent_base->size1(), num_bases_per_node,
false);
259 for (
auto gg = 0; gg != parent_base->size1(); ++gg) {
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);
277 auto switch_off_dofs_children = [&](
auto &parent_ent_data,
auto &child_data) {
279 for (
auto i : parent_ent_data.getIndices()) {
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()) {
286 std::distance(child_ent_data.getIndices().begin(), it);
288 child_ent_data.getFieldDofs()[dof_idx]->getBitRefLevel();
290 child_ent_data.getIndices()[dof_idx] = -1;
291 child_ent_data.getLocalIndices()[dof_idx] = -1;
292 child_ent_data.getFieldData()[dof_idx] = 0;
303 auto do_work_parent_hook = [&](
DataOperator *op_ptr,
int side,
309 auto &field_entities = data.getFieldEntities();
314 <<
"Add entity data to meshset "
315 <<
"side/type: " << side <<
"/" << CN::EntityTypeName(
type)
321 for (
auto field_ent : field_entities) {
323 <<
"Parent field entity bit: " << field_ent->getBitRefLevel() <<
" "
329 const auto nb_ents = field_entities.size();
330 const auto nb_nodes = data.getEntDataBitRefLevel().size();
333 if (
type == MBVERTEX &&
334 nb_nodes != up_op_ptr->getNumberOfNodesOnElement()) {
337 "Inconsistency between bit ref levels and number of nodes %d != %d",
338 nb_nodes, up_op_ptr->getNumberOfNodesOnElement());
342 auto get_child_meshset =
344 auto &data_on_meshset = entities_field_data.
dataOnEntities[MBENTITYSET];
345 if (data_on_meshset.size() < count_meshset_sides) {
348 data_on_meshset.transfer(data_on_meshset.end(),
353 count_meshset_sides);
356 return entities_field_data
361 for (
auto node = 0; node != nb_nodes; ++node) {
362 auto &bit_ent = data.getEntDataBitRefLevel()[node];
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,
371 CHKERR set_child_base_entity(data, child_data_meshset);
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(
388 if (
type == MBENTITYSET)
389 CHKERR switch_off_dofs_children(
393 if (
type == MBVERTEX &&
394 nb_ents != up_op_ptr->getNumberOfNodesOnElement()) {
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) {
401 "Code can handle only one entity");
404 for (
auto node = 0; node != nb_nodes; ++node) {
405 auto &bit_ent = data.getEntDataBitRefLevel()[node];
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,
414 CHKERR set_child_data_entity(data, child_data_meshset);
431 auto loop_parent_fe = [&]() {
435 parentElePtr->getOpPtrVector().back().doWorkRhsHook = do_work_parent_hook;
442 if (
getGaussPts().size1() != parent_gauss_pts.size1()) {
444 <<
"Calling element: "
445 << boost::typeindex::type_id_runtime(*parentElePtr).pretty_name();
447 MOFEM_LOG(
"SELF", Sev::error) << parent_gauss_pts;
449 "Wrong number of weights");
451 if (
getGaussPts().size2() != parent_gauss_pts.size2()) {
453 <<
"Calling element: "
454 << boost::typeindex::type_id_runtime(*parentElePtr).pretty_name();
456 "Wrong number of integration points");
470 <<
"Number of meshset entities "
474 auto &data_on_meshset = entities_field_data.
dataOnEntities[MBENTITYSET];
475 auto it = data_on_meshset.begin();
478 if (count_meshset_sides < data_on_meshset.size()) {
479 for (
auto s = 0; s != count_meshset_sides; ++s)
485 auto set_up_derivative_ent_data = [&](
auto &entities_field_data,
486 auto &derivative_entities_field_data) {
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));
505 CHKERR set_up_derivative_ent_data(
513 for (
auto &data : entities_field_data.
dataOnEntities[MBENTITYSET]) {
514 for (
auto dof : data.getFieldDofs()) {
515 auto &bit_dof = dof->getBitRefLevel();
517 auto ent = dof->getEnt();
518 if (side_table.find(ent) == side_table.end()) {
520 "Adjacency not found");