18 static auto cmp_uid_lo(
const boost::weak_ptr<FieldEntity> &
a,
const UId &b) {
19 if (
auto a_ptr =
a.lock()) {
20 if (a_ptr->getLocalUniqueId() < b)
29 static auto cmp_uid_hi(
const UId &b,
const boost::weak_ptr<FieldEntity> &
a) {
30 if (
auto a_ptr =
a.lock()) {
31 if (b < a_ptr->getLocalUniqueId())
43 mField(m_field), getRuleHook(0), setRuleHook(0),
46 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
47 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
48 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
49 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
50 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
51 boost::make_shared<EntitiesFieldData>(MBENTITYSET)
57 boost::make_shared<DerivedEntitiesFieldData>(
59 boost::make_shared<DerivedEntitiesFieldData>(dataOnElement[
H1]),
60 boost::make_shared<DerivedEntitiesFieldData>(
61 dataOnElement[
HCURL]),
62 boost::make_shared<DerivedEntitiesFieldData>(
64 boost::make_shared<DerivedEntitiesFieldData>(dataOnElement[
L2])
67 dataNoField(*dataOnElement[
NOFIELD].get()),
68 dataH1(*dataOnElement[
H1].get()), dataHcurl(*dataOnElement[
HCURL].get()),
69 dataHdiv(*dataOnElement[
HDIV].get()), dataL2(*dataOnElement[
L2].get()),
70 lastEvaluatedElementEntityType(MBMAXTYPE), sidePtrFE(
nullptr),
71 refinePtrFE(
nullptr) {
73 dataOnElement[
NOSPACE]->dataOnEntities[MBENTITYSET].push_back(
76 dataOnElement[
NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
78 derivedDataOnElement[
NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
85 const EntityType
type,
86 boost::ptr_vector<EntitiesFieldData::EntData> &data)
const {
91 if (sit != side_table.end()) {
93 for (; sit != hi_sit; ++sit) {
94 if (
const auto side_number = (*sit)->side_number; side_number >= 0) {
95 const int brother_side_number = (*sit)->brother_side_number;
96 const int sense = (*sit)->sense;
98 data[side_number].getSense() = sense;
99 if (brother_side_number != -1)
100 data[brother_side_number].getSense() = sense;
109 template <
typename ENTMULTIINDEX>
112 for (
auto ent_field_weak_ptr : multi_index)
113 if (
auto e = ent_field_weak_ptr.lock()) {
114 const int order = e->getMaxOrder();
115 max_order = (max_order <
order) ?
order : max_order;
123 if (
auto ptr = e.lock()) {
124 const int order = ptr->getMaxOrder();
125 max_order = (max_order <
order) ?
order : max_order;
141 boost::ptr_vector<EntitiesFieldData::EntData> &data)
const {
144 auto set_order = [&]() {
148 for (
unsigned int s = 0; s != data.size(); ++s)
149 data[s].getOrder() = 0;
154 r.first !=
r.second; ++
r.first) {
156 const auto field_bit_number = (*
r.first)->getBitNumber();
159 auto lo = std::lower_bound(data_field_ent.begin(), data_field_ent.end(),
161 if (lo != data_field_ent.end()) {
165 std::upper_bound(lo, data_field_ent.end(), hi_uid,
cmp_uid_hi);
166 for (; lo != hi; ++lo) {
168 if (
auto ptr = lo->lock()) {
171 auto sit = side_table.find(e.getEnt());
172 if (sit != side_table.end()) {
174 if (
const auto side_number = side->side_number;
177 auto &dat = data[side_number];
179 dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
183 "Entity on side of the element not found");
192 auto set_order_on_brother = [&]() {
197 if (sit != side_table.end()) {
199 for (; sit != hi_sit; ++sit) {
200 const int brother_side_number = (*sit)->brother_side_number;
201 if (brother_side_number != -1) {
202 const int side_number = (*sit)->side_number;
203 data[brother_side_number].getOrder() = data[side_number].getOrder();
211 CHKERR set_order_on_brother();
218 template <
typename EXTRACTOR>
222 EXTRACTOR &&extractor)
const {
230 if ((*field_it)->getBitNumber() != bit_number)
234 bit_number, get_id_for_min_type<MBVERTEX>());
235 auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
237 if (lo != ents_field.end()) {
239 bit_number, get_id_for_max_type<MBVERTEX>());
240 auto hi = std::upper_bound(lo, ents_field.end(), hi_uid,
cmp_uid_hi);
243 const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
244 const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
247 for (
auto it = lo; it != hi; ++it) {
248 if (
auto e = it->lock()) {
249 if (
auto cache = extractor(e).lock()) {
250 if (cache->loHi[0] != cache->loHi[1]) {
251 nb_dofs += std::distance(cache->loHi[0], cache->loHi[1]);
259 nodes_indices.resize(max_nb_dofs,
false);
260 local_nodes_indices.resize(max_nb_dofs,
false);
262 nodes_indices.resize(0,
false);
263 local_nodes_indices.resize(0,
false);
266 if (nb_dofs != max_nb_dofs) {
267 std::fill(nodes_indices.begin(), nodes_indices.end(), -1);
268 std::fill(local_nodes_indices.begin(), local_nodes_indices.end(), -1);
271 for (
auto it = lo; it != hi; ++it) {
272 if (
auto e = it->lock()) {
273 auto side_ptr = e->getSideNumberPtr();
274 if (
const auto side_number = side_ptr->side_number;
276 const auto brother_side_number = side_ptr->brother_side_number;
277 if (
auto cache = extractor(e).lock()) {
278 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
280 const int idx = dof.getPetscGlobalDofIdx();
281 const int local_idx = dof.getPetscLocalDofIdx();
283 side_number * nb_dofs_on_vert + dof.getDofCoeffIdx();
284 nodes_indices[pos] = idx;
285 local_nodes_indices[pos] = local_idx;
286 if (brother_side_number != -1) {
287 const int elem_idx = brother_side_number * nb_dofs_on_vert +
288 (*dit)->getDofCoeffIdx();
289 nodes_indices[elem_idx] = idx;
290 local_nodes_indices[elem_idx] = local_idx;
298 nodes_indices.resize(0,
false);
299 local_nodes_indices.resize(0,
false);
303 nodes_indices.resize(0,
false);
304 local_nodes_indices.resize(0,
false);
312 const int bit_number)
const {
315 boost::weak_ptr<EntityCacheNumeredDofs>
316 operator()(boost::shared_ptr<FieldEntity> &e) {
317 return e->entityCacheRowDofs;
329 const int bit_number)
const {
332 boost::weak_ptr<EntityCacheNumeredDofs>
333 operator()(boost::shared_ptr<FieldEntity> &e) {
334 return e->entityCacheColDofs;
344 template <
typename EXTRACTOR>
348 const EntityType type_hi, EXTRACTOR &&extractor)
const {
351 for (EntityType
t = type_lo;
t != type_hi; ++
t) {
353 dat.getIndices().resize(0,
false);
354 dat.getLocalIndices().resize(0,
false);
360 auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
362 if (lo != ents_field.end()) {
365 auto hi = std::upper_bound(lo, ents_field.end(), hi_uid,
cmp_uid_hi);
368 std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
370 for (
auto it = lo; it != hi; ++it)
371 if (
auto e = it->lock()) {
373 const EntityType
type = e->getEntType();
374 auto side_ptr = e->getSideNumberPtr();
375 if (
const auto side = side_ptr->side_number; side >= 0) {
376 const auto nb_dofs_on_ent = e->getNbDofsOnEnt();
377 const auto brother_side = side_ptr->brother_side_number;
379 auto &ent_field_indices = dat.getIndices();
380 auto &ent_field_local_indices = dat.getLocalIndices();
382 ent_field_indices.resize(nb_dofs_on_ent,
false);
383 ent_field_local_indices.resize(nb_dofs_on_ent,
false);
384 std::fill(ent_field_indices.data().begin(),
385 ent_field_indices.data().end(), -1);
386 std::fill(ent_field_local_indices.data().begin(),
387 ent_field_local_indices.data().end(), -1);
389 if (
auto cache = extractor(e).lock()) {
390 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
391 const int idx = (*dit)->getEntDofIdx();
392 ent_field_indices[idx] = (*dit)->getPetscGlobalDofIdx();
393 ent_field_local_indices[idx] = (*dit)->getPetscLocalDofIdx();
397 if (brother_side != -1) {
399 dat_brother.getIndices().resize(nb_dofs_on_ent,
false);
400 dat_brother.getLocalIndices().resize(nb_dofs_on_ent,
false);
401 noalias(dat_brother.getIndices()) = dat.getIndices();
402 noalias(dat_brother.getLocalIndices()) = dat.getLocalIndices();
414 const EntityType type_hi)
const {
417 boost::weak_ptr<EntityCacheNumeredDofs>
418 operator()(boost::shared_ptr<FieldEntity> &e) {
419 return e->entityCacheRowDofs;
429 const EntityType type_hi)
const {
432 boost::weak_ptr<EntityCacheNumeredDofs>
433 operator()(boost::shared_ptr<FieldEntity> &e) {
434 return e->entityCacheColDofs;
443 const int bit_number, boost::shared_ptr<FENumeredDofEntity_multiIndex> dofs,
450 indices.resize(std::distance(dit, hi_dit));
451 for (; dit != hi_dit; dit++) {
452 int idx = (*dit)->getPetscGlobalDofIdx();
453 indices[(*dit)->getDofCoeffIdx()] = idx;
460 const int bit_number)
const {
465 "data.dataOnEntities[MBENTITYSET] is empty");
475 const int bit_number)
const {
480 "data.dataOnEntities[MBENTITYSET] is empty");
499 nodes_indices.resize(field_struture->
getNbOfCoeffs() * num_nodes,
false);
500 std::fill(nodes_indices.begin(), nodes_indices.end(), -1);
504 auto siit = side_table.get<1>().lower_bound(boost::make_tuple(MBVERTEX, 0));
506 side_table.get<1>().lower_bound(boost::make_tuple(MBVERTEX, 10000));
509 for (; siit != hi_siit; siit++, nn++) {
510 if (siit->get()->side_number >= 0) {
517 for (; dit != hi_dit; dit++) {
518 nodes_indices[siit->get()->side_number * (*dit)->getNbOfCoeffs() +
519 (*dit)->getDofCoeffIdx()] =
520 (*dit)->getPetscGlobalDofIdx();
525 nodes_indices.resize(0,
false);
533 EntityType
type,
int side_number,
VectorInt &indices)
const {
541 side_table.get<1>().lower_bound(boost::make_tuple(
type, side_number));
543 side_table.get<1>().upper_bound(boost::make_tuple(
type, side_number));
545 for (; siit != hi_siit; siit++) {
546 if (siit->get()->side_number >= 0) {
554 indices.resize(std::distance(dit, hi_dit));
555 for (; dit != hi_dit; dit++) {
557 indices[(*dit)->getEntDofIdx()] = (*dit)->getPetscGlobalDofIdx();
573 EntityType
type,
int side_number,
576 type, side_number, indices);
587 EntityType
type,
int side_number,
590 type, side_number, indices);
600 for (
auto &dat : data->dataOnEntities) {
601 for (
auto &ent_dat : dat) {
602 ent_dat.getEntDataBitRefLevel().clear();
609 for (
auto it : field_ents) {
610 if (
auto e = it.lock()) {
613 const EntityType
type = e->getEntType();
614 const signed char side = e->getSideNumberPtr()->side_number;
617 if (
type == MBVERTEX) {
618 auto &dat = data->dataOnEntities[
type][0];
620 dat.getEntDataBitRefLevel()[side] = e->getBitRefLevel();
622 auto &dat = data->dataOnEntities[
type][side];
623 dat.getEntDataBitRefLevel().resize(1,
false);
624 dat.getEntDataBitRefLevel()[0] = e->getBitRefLevel();
630 auto &dat = data->dataOnEntities[MBENTITYSET][0];
631 dat.getEntDataBitRefLevel().resize(1,
false);
632 dat.getEntDataBitRefLevel()[0] = e->getBitRefLevel();
643 const int bit_number)
const {
645 auto get_nodes_field_data = [&](
VectorDouble &nodes_data,
652 nodes_data.resize(0,
false);
653 nodes_dofs.resize(0,
false);
654 field_entities.resize(0,
false);
661 if ((*field_it)->getBitNumber() != bit_number)
664 const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
665 space = (*field_it)->getSpace();
666 base = (*field_it)->getApproxBase();
670 bit_number, get_id_for_min_type<MBVERTEX>());
671 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
673 if (lo != field_ents.end()) {
675 bit_number, get_id_for_max_type<MBVERTEX>());
676 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid,
cmp_uid_hi);
680 for (
auto it = lo; it != hi; ++it) {
681 if (
auto e = it->lock()) {
682 if (
auto cache = e->entityCacheDataDofs.lock()) {
683 if (cache->loHi[0] != cache->loHi[1]) {
684 nb_dofs += std::distance(cache->loHi[0], cache->loHi[1]);
694 bb_node_order.resize(num_nodes,
false);
695 bb_node_order.clear();
696 const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
697 nodes_data.resize(max_nb_dofs,
false);
698 nodes_dofs.resize(max_nb_dofs,
false);
699 field_entities.resize(num_nodes,
false);
700 std::fill(nodes_data.begin(), nodes_data.end(), 0);
701 std::fill(nodes_dofs.begin(), nodes_dofs.end(),
nullptr);
702 std::fill(field_entities.begin(), field_entities.end(),
nullptr);
704 std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
706 for (
auto it = lo; it != hi; ++it) {
707 if (
auto e = it->lock()) {
708 const auto &sn = e->getSideNumberPtr();
711 if (
const auto side_number = sn->side_number;
713 const int brother_side_number = sn->brother_side_number;
715 field_entities[side_number] = e.get();
716 if (brother_side_number != -1) {
717 brother_ents_vec.emplace_back(e);
718 field_entities[side_number] = field_entities[side_number];
721 bb_node_order[side_number] = e->getMaxOrder();
722 int pos = side_number * nb_dofs_on_vert;
723 auto ent_filed_data_vec = e->getEntFieldData();
724 if (
auto cache = e->entityCacheDataDofs.lock()) {
725 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1];
727 const auto dof_idx = (*dit)->getEntDofIdx();
728 nodes_data[pos + dof_idx] = ent_filed_data_vec[dof_idx];
729 nodes_dofs[pos + dof_idx] =
737 for (
auto &it : brother_ents_vec) {
738 if (
const auto e = it.lock()) {
740 const int side_number = sn->side_number;
741 const int brother_side_number = sn->brother_side_number;
742 bb_node_order[brother_side_number] = bb_node_order[side_number];
743 int pos = side_number * nb_dofs_on_vert;
744 int brother_pos = brother_side_number * nb_dofs_on_vert;
745 for (
int ii = 0; ii != nb_dofs_on_vert; ++ii) {
746 nodes_data[brother_pos] = nodes_data[pos];
747 nodes_dofs[brother_pos] = nodes_dofs[pos];
761 return get_nodes_field_data(
772 const EntityType type_hi)
const {
774 for (EntityType
t = type_lo;
t != type_hi; ++
t) {
779 dat.getFieldData().resize(0,
false);
780 dat.getFieldDofs().resize(0,
false);
781 dat.getFieldEntities().resize(0,
false);
788 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
790 if (lo != field_ents.end()) {
793 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid,
cmp_uid_hi);
796 std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
798 for (
auto it = lo; it != hi; ++it)
799 if (
auto e = it->lock()) {
800 auto side_ptr = e->getSideNumberPtr();
801 if (
const auto side = side_ptr->side_number; side >= 0) {
802 const EntityType
type = e->getEntType();
804 auto &ent_field = dat.getFieldEntities();
805 auto &ent_field_dofs = dat.getFieldDofs();
806 auto &ent_field_data = dat.getFieldData();
808 const int brother_side = side_ptr->brother_side_number;
809 if (brother_side != -1)
810 brother_ents_vec.emplace_back(e);
812 dat.getBase() = e->getApproxBase();
813 dat.getSpace() = e->getSpace();
814 const int ent_order = e->getMaxOrder();
816 dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
818 auto ent_data = e->getEntFieldData();
819 ent_field_data.resize(ent_data.size(),
false);
820 noalias(ent_field_data) = ent_data;
821 ent_field_dofs.resize(ent_data.size(),
false);
822 std::fill(ent_field_dofs.begin(), ent_field_dofs.end(),
nullptr);
823 ent_field.resize(1,
false);
824 ent_field[0] = e.get();
825 if (
auto cache = e->entityCacheDataDofs.lock()) {
826 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
827 ent_field_dofs[(*dit)->getEntDofIdx()] =
834 for (
auto &it : brother_ents_vec) {
835 if (
const auto e = it.lock()) {
836 const EntityType
type = e->getEntType();
837 const int side = e->getSideNumberPtr()->side_number;
838 const int brother_side = e->getSideNumberPtr()->brother_side_number;
841 dat_brother.getBase() = dat.getBase();
842 dat_brother.getSpace() = dat.getSpace();
843 dat_brother.getOrder() = dat.getOrder();
844 dat_brother.getFieldData() = dat.getFieldData();
845 dat_brother.getFieldDofs() = dat.getFieldDofs();
846 dat_brother.getFieldEntities() = dat.getFieldEntities();
861 ent_field_data.resize(0,
false);
862 ent_field_dofs.resize(0,
false);
863 ent_field.resize(0,
false);
867 bit_number, get_id_for_min_type<MBVERTEX>());
868 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
870 if (lo != field_ents.end()) {
872 ent_field.resize(field_ents.size(),
false);
873 std::fill(ent_field.begin(), ent_field.end(),
nullptr);
876 bit_number, get_id_for_max_type<MBENTITYSET>());
877 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid,
cmp_uid_hi);
881 for (
auto it = lo; it != hi; ++it, ++side)
882 if (
auto e = it->lock()) {
884 const auto size = e->getNbDofsOnEnt();
885 ent_field_data.resize(size,
false);
886 ent_field_dofs.resize(size,
false);
887 ent_field[side] = e.get();
888 noalias(ent_field_data) = e->getEntFieldData();
890 if (
auto cache = e->entityCacheDataDofs.lock()) {
891 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
892 ent_field_dofs[(*dit)->getEntDofIdx()] =
905 const int bit_number)
const {
909 "No space to insert data");
929 const auto nb_faces = CN::NumSubEntities(
type, 2);
933 auto side_ptr_it = side_table.get<1>().lower_bound(
934 boost::make_tuple(CN::TypeDimensionMap[2].first, 0));
935 auto hi_side_ptr_it = side_table.get<1>().upper_bound(
936 boost::make_tuple(CN::TypeDimensionMap[2].second, 100));
938 for (; side_ptr_it != hi_side_ptr_it; ++side_ptr_it) {
939 const auto side = (*side_ptr_it)->side_number;
940 const auto sense = (*side_ptr_it)->sense;
941 const auto offset = (*side_ptr_it)->offset;
943 EntityType face_type;
946 CN::SubEntityVertexIndices(
type, 2, side, face_type, nb_nodes_face);
947 face_nodes.resize(nb_faces, nb_nodes_face);
948 face_nodes_order.resize(nb_faces, nb_nodes_face);
951 for (
int n = 0;
n != nb_nodes_face; ++
n)
952 face_nodes_order(side,
n) = (
n + offset) % nb_nodes_face;
954 for (
int n = 0;
n != nb_nodes_face; ++
n)
955 face_nodes_order(side,
n) =
956 (nb_nodes_face - (
n - offset) % nb_nodes_face) % nb_nodes_face;
958 for (
int n = 0;
n != nb_nodes_face; ++
n)
959 face_nodes(side,
n) = face_indices[face_nodes_order(side,
n)];
962 const auto face_ent = (*side_ptr_it)->ent;
968 nb_nodes_face,
true);
969 face_nodes.resize(nb_faces, nb_nodes_face);
970 for (
int nn = 0; nn != nb_nodes_face; ++nn) {
971 if (face_nodes(side, nn) !=
974 std::find(conn_ele, &conn_ele[num_nodes_ele], conn_face[nn]))) {
976 "Wrong face numeration");
996 for (EntityType
t = MBVERTEX;
t != MBMAXTYPE; ++
t) {
1010 if (
auto ptr = e.lock()) {
1012 const EntityType
type = ptr->getEntType();
1019 switch (continuity) {
1028 "Continuity not defined");
1031 data.
bAse.set(approx);
1039 "data fields ents not allocated on element");
1041 for (
auto space = 0; space !=
LASTSPACE; ++space)
1044 "Discontinuous and continuous bases on the same space");
1064 auto get_elem_base = [&](
auto base) {
1069 "Functions generating approximation base not defined");
1075 "Functions generating user approximation base not defined");
1080 auto get_ctx = [&](
auto space,
auto base,
auto continuity) {
1081 return boost::make_shared<EntPolynomialBaseCtx>(
1087 return elem_base->getValue(
gaussPts, ctx);
1090 for (
int space =
H1; space !=
LASTSPACE; ++space) {
1096 "Discontinuous and continuous bases on the same space");
1119 dataOnElement[space]->dataOnEntities[MBVERTEX][0].getDiffNSharedPtr(
1141 auto &bb_node_order = data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder();
1144 auto bit_number = field_ptr->getBitNumber();
1146 bit_number, get_id_for_min_type<MBVERTEX>());
1147 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
1149 if (lo != field_ents.end()) {
1151 bit_number, get_id_for_max_type<MBVERTEX>());
1152 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid,
cmp_uid_hi);
1155 for (
auto it = lo; it != hi; ++it)
1156 if (
auto first_e = it->lock()) {
1157 space = first_e->getSpace();
1158 base = first_e->getApproxBase();
1160 bb_node_order.resize(num_nodes,
false);
1161 bb_node_order.clear();
1163 std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
1165 for (; it != hi; ++it) {
1166 if (
auto e = it->lock()) {
1167 const auto &sn = e->getSideNumberPtr();
1168 const int side_number = sn->side_number;
1169 const int brother_side_number = sn->brother_side_number;
1170 if (brother_side_number != -1)
1171 brother_ents_vec.emplace_back(e);
1172 bb_node_order[side_number] = e->getMaxOrder();
1176 for (
auto &it : brother_ents_vec) {
1177 if (
const auto e = it.lock()) {
1178 const auto &sn = e->getSideNumberPtr();
1179 const int side_number = sn->side_number;
1180 const int brother_side_number = sn->brother_side_number;
1181 bb_node_order[brother_side_number] = bb_node_order[side_number];
1194 const EntityType type_lo,
1195 const EntityType type_hi) {
1197 for (EntityType
t = MBEDGE;
t != MBPOLYHEDRON; ++
t) {
1202 dat.getFieldData().resize(0,
false);
1203 dat.getFieldDofs().resize(0,
false);
1208 auto bit_number = field_ptr->getBitNumber();
1211 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
1213 if (lo != field_ents.end()) {
1216 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid,
cmp_uid_hi);
1218 std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
1219 for (; lo != hi; ++lo) {
1220 if (
auto e = lo->lock()) {
1221 if (
auto cache = e->entityCacheDataDofs.lock()) {
1222 if (cache->loHi[0] != cache->loHi[1]) {
1223 if (
const auto side = e->getSideNumberPtr()->side_number;
1225 const EntityType
type = e->getEntType();
1227 const int brother_side =
1228 e->getSideNumberPtr()->brother_side_number;
1229 if (brother_side != -1)
1230 brother_ents_vec.emplace_back(e);
1231 dat.getBase() = e->getApproxBase();
1232 dat.getSpace() = e->getSpace();
1233 const auto ent_order = e->getMaxOrder();
1235 dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
1242 for (
auto &ent_ptr : brother_ents_vec) {
1243 if (
auto e = ent_ptr.lock()) {
1244 const EntityType
type = e->getEntType();
1245 const int side = e->getSideNumberPtr()->side_number;
1246 const int brother_side = e->getSideNumberPtr()->brother_side_number;
1249 dat_brother.getBase() = dat.getBase();
1250 dat_brother.getSpace() = dat.getSpace();
1251 dat_brother.getOrder() = dat.getOrder();
1259 if (
auto ent_data_ptr = e.lock()) {
1261 auto space = ent_data_ptr->getSpace();
1262 for (EntityType
t = MBVERTEX;
t != MBPOLYHEDRON; ++
t) {
1264 for (
auto &ptr : dat.getBBAlphaIndicesByOrderArray())
1266 for (
auto &ptr : dat.getBBNByOrderArray())
1268 for (
auto &ptr : dat.getBBDiffNByOrderArray())
1276 auto check_space = [&](
const auto space) {
1279 for (
auto t = MBVERTEX;
t <= ele_type; ++
t) {
1285 for (
auto t = MBEDGE;
t <= ele_type; ++
t) {
1291 for (
auto t = MBTRI;
t <= ele_type; ++
t) {
1304 std::set<string> fields_list;
1306 if (
auto ent_data_ptr = e.lock()) {
1309 if (fields_list.find(
field_name) == fields_list.end()) {
1310 auto field_ptr = ent_data_ptr->getFieldRawPtr();
1311 auto space = ent_data_ptr->getSpace();
1315 if (check_space(space)) {
1317 if (ent_data_ptr->getContinuity() !=
CONTINUOUS)
1319 "Broken space not implemented");
1323 boost::make_shared<EntPolynomialBaseCtx>(
1341 for (
int space =
H1; space !=
LASTSPACE; ++space) {
1349 #define FUNCTION_NAME_WITH_OP_NAME(OP) \
1350 std::ostringstream ss; \
1351 ss << "(Calling user data operator " \
1352 << boost::typeindex::type_id_runtime(OP).pretty_name() << " rowField " \
1353 << (OP).rowFieldName << " colField " << (OP).colFieldName << ") "
1355 #define CATCH_OP_ERRORS(OP) \
1356 catch (MoFEMExceptionInitial const &ex) { \
1357 FUNCTION_NAME_WITH_OP_NAME(OP) << PETSC_FUNCTION_NAME; \
1358 return PetscError(PETSC_COMM_SELF, ex.lINE, ss.str().c_str(), __FILE__, \
1359 ex.errorCode, PETSC_ERROR_INITIAL, ex.what()); \
1361 catch (MoFEMExceptionRepeat const &ex) { \
1362 FUNCTION_NAME_WITH_OP_NAME(OP) << PETSC_FUNCTION_NAME; \
1363 return PetscError(PETSC_COMM_SELF, ex.lINE, ss.str().c_str(), __FILE__, \
1364 ex.errorCode, PETSC_ERROR_REPEAT, " "); \
1366 catch (MoFEMException const &ex) { \
1367 FUNCTION_NAME_WITH_OP_NAME(OP) << ex.errorMessage; \
1368 SETERRQ(PETSC_COMM_SELF, ex.errorCode, ss.str().c_str()); \
1370 catch (std::exception const &ex) { \
1371 std::string message("Error: " + std::string(ex.what()) + " at " + \
1372 boost::lexical_cast<std::string>(__LINE__) + " : " + \
1373 std::string(__FILE__) + " in " + \
1374 std::string(PETSC_FUNCTION_NAME)); \
1375 FUNCTION_NAME_WITH_OP_NAME(OP) << message; \
1376 SETERRQ(PETSC_COMM_SELF, MOFEM_STD_EXCEPTION_THROW, ss.str().c_str()); \
1385 std::array<const Field *, 3> field_struture;
1388 std::array<FieldSpace, 2> space;
1389 std::array<FieldApproximationBase, 2> base;
1391 constexpr std::array<UDO::OpType, 2> types = {UDO::OPROW, UDO::OPCOL};
1392 std::array<int, 2> last_eval_field_id = {0, 0};
1394 std::array<boost::shared_ptr<EntitiesFieldData>, 2> op_data;
1396 auto swap_bases = [&](
auto &op) {
1398 for (
size_t ss = 0; ss != 2; ++ss) {
1399 if (op.getOpType() & types[ss] || op.getOpType() & UDO::OPROWCOL) {
1416 auto evaluate_op_space = [&](
auto &op) {
1421 std::fill(last_eval_field_id.begin(), last_eval_field_id.end(), 0);
1439 for (EntityType
t = MBVERTEX;
t != MBMAXTYPE; ++
t) {
1441 e.getSpace() = op.sPace;
1451 "Not implemented for this space", op.sPace);
1458 auto set_op_entities_data = [&](
auto ss,
auto &op) {
1462 if ((op.getNumeredEntFiniteElementPtr()->getBitFieldIdData() &
1466 "no data field < %s > on finite element < %s >",
1474 for (
auto &data : op_data[ss]->dataOnEntities[MBENTITYSET]) {
1475 CHKERR data.resetFieldDependentData();
1478 auto get_data_for_nodes = [&]() {
1489 auto get_data_for_entities = [&]() {
1499 auto get_data_for_meshset = [&]() {
1510 switch (space[ss]) {
1512 CHKERR get_data_for_nodes();
1515 CHKERR get_data_for_entities();
1520 CHKERR get_data_for_nodes();
1523 CHKERR get_data_for_entities();
1530 CHKERR get_data_for_meshset();
1535 "not implemented for this space < %s >",
1542 auto evaluate_op_for_fields = [&](
auto &op) {
1545 if (op.getOpType() & UDO::OPROW) {
1547 CHKERR op.opRhs(*op_data[0],
false);
1552 if (op.getOpType() & UDO::OPCOL) {
1554 CHKERR op.opRhs(*op_data[1],
false);
1559 if (op.getOpType() & UDO::OPROWCOL) {
1561 CHKERR op.opLhs(*op_data[0], *op_data[1]);
1575 for (; oit != hi_oit; oit++) {
1579 CHKERR oit->setPtrFE(
this);
1581 if ((oit->opType & UDO::OPSPACE) == UDO::OPSPACE) {
1584 CHKERR evaluate_op_space(*oit);
1588 (oit->opType & (UDO::OPROW | UDO::OPCOL | UDO::OPROWCOL)) ==
1596 for (
size_t ss = 0; ss != 2; ss++) {
1601 "Not set Field name in operator %d (0-row, 1-column) in "
1604 (boost::typeindex::type_id_runtime(*oit).pretty_name())
1611 space[ss] = field_struture[ss]->getSpace();
1612 base[ss] = field_struture[ss]->getApproxBase();
1617 for (
size_t ss = 0; ss != 2; ss++) {
1619 if (oit->getOpType() & types[ss] ||
1620 oit->getOpType() & UDO::OPROWCOL) {
1621 if (last_eval_field_id[ss] != field_id[ss]) {
1622 CHKERR set_op_entities_data(ss, *oit);
1623 last_eval_field_id[ss] = field_id[ss];
1631 CHKERR evaluate_op_for_fields(*oit);
1637 for (
int i = 0;
i != 5; ++
i)
1638 if (oit->opType & (1 <<
i))
1639 MOFEM_LOG(
"SELF", Sev::error) << UDO::OpTypeNames[
i];
1641 "Impossible operator type");
1650 "OPROW",
" OPCOL",
"OPROWCOL",
"OPSPACE",
"OPLAST"};
1653 const std::string
field_name,
const EntityType
type,
const int side,
1670 const std::string
field_name,
const EntityType
type,
const int side,
1706 const auto *problem_ptr = getFEMethod()->problemPtr;
1708 problem_ptr->numeredFiniteElementsPtr->get<
Unique_mi_tag>();
1710 auto fe_miit = ptrFE->mField.get_finite_elements()
1713 if (fe_miit != ptrFE->mField.get_finite_elements()
1719 side_fe->
feName = fe_name;
1732 std::vector<boost::weak_ptr<NumeredEntFiniteElement>> fe_vec;
1733 auto get_numered_fe_ptr = [&](
auto &fe_uid,
Range &&adjacent_ents)
1734 -> std::vector<boost::weak_ptr<NumeredEntFiniteElement>> & {
1735 fe_vec.reserve(adjacent_ents.size());
1736 for (
auto fe_ent : adjacent_ents) {
1737 auto miit = numered_fe.find(
1739 if (miit != numered_fe.end()) {
1740 fe_vec.emplace_back(*miit);
1746 auto get_bit_entity_adjacency = [&]() {
1747 Range adjacent_ents;
1749 ent, side_dim, adjacent_ents);
1750 return adjacent_ents;
1753 auto get_adj = [&](
auto &fe_uid)
1754 -> std::vector<boost::weak_ptr<NumeredEntFiniteElement>> & {
1757 return (*adj_cache).at(ent);
1758 }
catch (
const std::out_of_range &) {
1759 return (*adj_cache)[ent] =
1760 get_numered_fe_ptr(fe_uid, get_bit_entity_adjacency());
1763 return get_numered_fe_ptr(fe_uid, get_bit_entity_adjacency());
1767 auto adj = get_adj((*fe_miit)->getFEUId());
1769 if (verb >=
VERBOSE && !adj.empty())
1770 MOFEM_LOG(
"SELF", sev) <<
"Number of side finite elements " << adj.size();
1774 for (
auto fe_weak_ptr : adj) {
1775 if (
auto fe_ptr = fe_weak_ptr.lock()) {
1778 <<
"Side finite element " <<
"(" << nn <<
"): " << *fe_ptr;
1798 MOFEM_LOG(
"SELF", sev) <<
"This finite element: "
1799 << *getNumeredEntFiniteElementPtr();
1801 this_fe->
feName = fe_name;
1832 auto fe_miit = fes.find(fe_name);
1833 if (fe_miit != fes.end()) {
1835 const auto *problem_ptr = getFEMethod()->problemPtr;
1837 problem_ptr->numeredFiniteElementsPtr->get<
Unique_mi_tag>();
1839 parent_fe->
feName = fe_name;
1849 const auto parent_ent = getNumeredEntFiniteElementPtr()->getParentEnt();
1851 parent_ent, (*fe_miit)->getFEUId()));
1852 if (miit != numered_fe.end()) {
1854 MOFEM_LOG(
"SELF", sev) <<
"Parent finite element: " << **miit;
1863 MOFEM_LOG(
"SELF", sev) <<
"Parent finite element: no parent";
1879 auto fe_miit = ptrFE->mField.get_finite_elements()
1882 if (fe_miit != ptrFE->mField.get_finite_elements()
1886 const auto *problem_ptr = getFEMethod()->problemPtr;
1887 auto &ref_ents = *getPtrFE()->mField.get_ref_ents();
1889 problem_ptr->numeredFiniteElementsPtr->get<
Unique_mi_tag>();
1891 const auto parent_ent = getNumeredEntFiniteElementPtr()->getEnt();
1892 const auto parent_type = getNumeredEntFiniteElementPtr()->getEntType();
1895 boost::make_tuple(parent_type, parent_ent));
1897 if (
auto size = std::distance(range.first, range.second)) {
1899 std::vector<EntityHandle> childs_vec;
1900 childs_vec.reserve(size);
1901 for (; range.first != range.second; ++range.first)
1902 childs_vec.emplace_back((*range.first)->getEnt());
1906 if ((childs_vec.back() - childs_vec.front() + 1) == size)
1907 childs =
Range(childs_vec.front(), childs_vec.back());
1909 childs.insert_list(childs_vec.begin(), childs_vec.end());
1911 child_fe->
feName = fe_name;
1927 for (
auto p = childs.pair_begin(); p != childs.pair_end(); ++p) {
1931 p->first, (*fe_miit)->getFEUId()));
1934 p->second, (*fe_miit)->getFEUId()));
1936 for (; miit != hi_miit; ++miit) {
1940 <<
"Child finite element " <<
"(" << nn <<
"): " << **miit;
1988 const std::string row_field_name,
const std::string col_field_name,
1989 const char type,
const bool symm)
1991 colFieldName(col_field_name), sPace(
LASTSPACE), ptrFE(nullptr) {}
2009 <<
"No method operator() overloaded on element entity on finite "
2011 << boost::typeindex::type_id_runtime(*this).pretty_name() <<
">";
2030 "User operator and finite element do not work together");