8 #define FieldCoreFunctionBegin \
10 MOFEM_LOG_CHANNEL("WORLD"); \
11 MOFEM_LOG_CHANNEL("SYNC"); \
12 MOFEM_LOG_FUNCTION(); \
13 MOFEM_LOG_TAG("WORLD", "FieldCore"); \
14 MOFEM_LOG_TAG("SYNC", "FieldCore");
20 auto miit = set.find(name);
21 if (miit == set.end()) {
23 " > not in database (top tip: check spelling)");
25 return (*miit)->getId();
30 auto miit = set.find(name);
31 if (miit == set.end())
33 " > not in database (top tip: check spelling)");
34 return (*miit)->getBitNumber();
39 auto miit = set.find(
id);
40 if (miit == set.end())
41 THROW_MESSAGE(
"field not in database (top tip: check spelling)");
42 return (*miit)->getName();
47 auto miit = set.find(
id);
48 if (miit == set.end())
49 THROW_MESSAGE(
"field not in database (top tip: check spelling)");
50 return (*miit)->meshSet;
54 return get_field_meshset(get_field_id(name));
72 std::string(
"field < " + name +
73 " > not in database (top tip: check spelling)")
87 CHKERR get_moab().get_entities_by_dimension(meshset, dim, ents,
true);
96 CHKERR get_moab().get_entities_by_type(meshset,
type, ents,
true);
104 CHKERR get_moab().get_entities_by_handle(meshset, ents,
true);
112 const TagType tag_type,
const enum MoFEMTypes bh,
124 auto add_meshset_to_partition = [&](
auto meshset) {
126 const void *tag_vals[] = {&rAnk};
127 ParallelComm *pcomm = ParallelComm::get_pcomm(
128 &get_moab(), get_basic_entity_data_ptr()->pcommID);
129 Tag part_tag = pcomm->part_tag();
131 CHKERR get_moab().get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag,
132 tag_vals, 1, tagged_sets,
133 moab::Interface::UNION);
134 for (
auto s : tagged_sets)
135 CHKERR get_moab().add_entities(s, &meshset, 1);
139 auto create_tags = [&](
auto meshset,
auto id) {
141 CHKERR get_moab().tag_set_data(th_FieldId, &meshset, 1, &
id);
143 CHKERR get_moab().tag_set_data(th_FieldSpace, &meshset, 1, &space);
145 CHKERR get_moab().tag_set_data(th_FieldContinuity, &meshset, 1,
148 CHKERR get_moab().tag_set_data(th_FieldBase, &meshset, 1, &base);
151 void const *tag_data[] = {name.c_str()};
153 tag_sizes[0] = name.size();
154 CHKERR get_moab().tag_set_by_ptr(th_FieldName, &meshset, 1, tag_data,
159 const std::string tag_rank_name =
"_Field_Rank_" + name;
160 CHKERR get_moab().tag_get_handle(tag_rank_name.c_str(), 1, MB_TYPE_INTEGER,
161 th_rank, MB_TAG_CREAT | MB_TAG_SPARSE,
163 CHKERR get_moab().tag_set_data(th_rank, &meshset, 1, &nb_of_coefficients);
173 const std::string name_data_prefix(
"_App_Data_");
174 void const *tag_prefix_data[] = {name_data_prefix.c_str()};
175 int tag_prefix_sizes[1];
176 tag_prefix_sizes[0] = name_data_prefix.size();
177 CHKERR get_moab().tag_set_by_ptr(th_FieldName_DataNamePrefix, &meshset, 1,
178 tag_prefix_data, tag_prefix_sizes);
179 Tag th_app_order, th_field_data, th_field_data_vert;
183 const std::string tag_approx_order_name =
"_App_Order_" + name;
184 CHKERR get_moab().tag_get_handle(
185 tag_approx_order_name.c_str(), 1, MB_TYPE_INTEGER, th_app_order,
186 MB_TAG_CREAT | MB_TAG_SPARSE, &def_approx_order);
189 std::string tag_data_name = name_data_prefix + name;
190 const int def_len = 0;
191 CHKERR get_moab().tag_get_handle(
192 tag_data_name.c_str(), def_len, MB_TYPE_DOUBLE, th_field_data,
193 MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_SPARSE, NULL);
194 std::string tag_data_name_verts = name_data_prefix + name +
"_V";
196 def_vert_data.clear();
197 CHKERR get_moab().tag_get_handle(
198 tag_data_name_verts.c_str(), nb_of_coefficients, MB_TYPE_DOUBLE,
199 th_field_data_vert, MB_TAG_CREAT | tag_type, &*def_vert_data.begin());
202 const std::string name_data_prefix(
"_App_Data");
203 void const *tag_prefix_data[] = {name_data_prefix.c_str()};
204 int tag_prefix_sizes[1];
205 tag_prefix_sizes[0] = name_data_prefix.size();
206 CHKERR get_moab().tag_set_by_ptr(th_FieldName_DataNamePrefix, &meshset, 1,
207 tag_prefix_data, tag_prefix_sizes);
208 Tag th_app_order, th_field_data, th_field_data_vert;
212 const std::string tag_approx_order_name =
"_App_Order_" + name;
213 CHKERR get_moab().tag_get_handle(
214 tag_approx_order_name.c_str(), 1, MB_TYPE_INTEGER, th_app_order,
215 MB_TAG_CREAT | MB_TAG_SPARSE, &def_approx_order);
218 std::string tag_data_name = name_data_prefix + name;
219 const int def_len = 0;
220 CHKERR get_moab().tag_get_handle(
221 tag_data_name.c_str(), def_len, MB_TYPE_DOUBLE, th_field_data,
222 MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_SPARSE, NULL);
223 std::string tag_data_name_verts = name_data_prefix + name +
"V";
225 def_vert_data.clear();
226 CHKERR get_moab().tag_get_handle(
227 tag_data_name_verts.c_str(), nb_of_coefficients, MB_TYPE_DOUBLE,
228 th_field_data_vert, MB_TAG_CREAT | tag_type, &*def_vert_data.begin());
241 "field is <%s> in database", name.c_str());
246 CHKERR get_moab().create_meshset(MESHSET_SET, meshset);
247 CHKERR add_meshset_to_partition(meshset);
257 "Maximal number of fields exceeded");
261 CHKERR create_tags(meshset,
id);
263 auto p = fIelds.insert(boost::make_shared<Field>(moab, meshset));
265 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Add field " << **p.first;
267 <<
"Field " << (*p.first)->getName() <<
" core value < "
268 << this->
getValue() <<
" > field value ( "
269 <<
static_cast<int>((*p.first)->getBitNumber()) <<
" )";
274 "field not inserted %s (top tip, it could be already "
276 Field(moab, meshset).getName().c_str());
285 const std::string name,
const FieldSpace space,
291 std::pair<EntityType,
297 const TagType tag_type,
const enum MoFEMTypes bh,
int verb) {
305 "field <%s> not in database", name.c_str());
307 for(
auto &p : list_dof_side_map) {
308 auto &data_side_map = (*fit)->getDofSideMap()[p.first];
309 CHKERR p.second(data_side_map);
318 const TagType tag_type,
const enum MoFEMTypes bh,
320 return this->addField(name, space,
CONTINUOUS, base, nb_of_coefficients,
325 const std::string &name,
int verb) {
337 idm = get_field_meshset(name);
339 CHKERR get_moab().tag_get_data(th_FieldSpace, &idm, 1, &space);
341 CHKERR get_moab().tag_get_data(th_FieldContinuity, &idm, 1, &continuity);
343 switch (continuity) {
349 "sorry, unknown continuity added to entity");
352 std::vector<int> nb_ents_on_dim(3, 0);
355 CHKERR get_moab().add_entities(idm, ents);
358 CHKERR get_moab().add_entities(idm, ents);
361 for (
int dd = 0;
dd != dim; ++
dd) {
363 CHKERR get_moab().get_adjacencies(ents,
dd,
false, adj_ents,
364 moab::Interface::UNION);
367 CHKERR get_moab().get_connectivity(ents, topo_nodes,
true);
369 CHKERR get_moab().get_connectivity(ents, mid_nodes,
false);
370 mid_nodes = subtract(mid_nodes, topo_nodes);
371 adj_ents = subtract(adj_ents, mid_nodes);
373 CHKERR get_moab().add_entities(idm, adj_ents);
374 nb_ents_on_dim[
dd] = adj_ents.size();
378 CHKERR get_moab().add_entities(idm, ents);
381 for (
int dd = 1;
dd != dim; ++
dd) {
383 CHKERR get_moab().get_adjacencies(ents,
dd,
false, adj_ents,
384 moab::Interface::UNION);
385 CHKERR get_moab().add_entities(idm, adj_ents);
386 nb_ents_on_dim[
dd] = adj_ents.size();
390 CHKERR get_moab().add_entities(idm, ents);
395 CHKERR get_moab().get_adjacencies(ents, 2,
false, adj_ents,
396 moab::Interface::UNION);
397 CHKERR get_moab().add_entities(idm, adj_ents);
398 nb_ents_on_dim[2] = adj_ents.size();
403 "sorry, unknown space added to entity");
407 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"add entities to field " << name;
408 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"\tnb. add ents " << ents.size();
409 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"\tnb. add faces " << nb_ents_on_dim[2];
410 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"\tnb. add edges " << nb_ents_on_dim[1];
411 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"\tnb. add nodes " << nb_ents_on_dim[0];
417 const std::string &name,
420 Range ents_dim = ents.subset_by_dimension(dim);
421 CHKERR addEntsToFieldByDim(ents_dim, dim, name, verb);
427 const EntityType
type,
428 const std::string &name,
431 Range ents_type = ents.subset_by_type(
type);
432 if (!ents_type.empty()) {
433 const int dim = get_moab().dimension_from_handle(ents_type[0]);
434 CHKERR addEntsToFieldByDim(ents_type, dim, name, verb);
442 const std::string &name,
443 const bool recursive,
int verb) {
446 CHKERR get_moab().get_entities_by_dimension(meshset, dim, ents, recursive);
447 CHKERR addEntsToFieldByDim(ents, dim, name, verb);
453 const EntityType
type,
454 const std::string &name,
455 const bool recursive,
int verb) {
458 CHKERR get_moab().get_entities_by_type(meshset,
type, ents, recursive);
460 const int dim = get_moab().dimension_from_handle(ents[0]);
461 CHKERR addEntsToFieldByDim(ents, dim, name, verb);
468 const double coords[],
469 int size,
int verb) {
477 auto create_vertices = [&]() {
480 vector<double *> arrays_coord;
482 ReadUtilIface *iface;
483 CHKERR get_moab().query_interface(iface);
484 CHKERR iface->get_node_coords(3, size, 0, startv, arrays_coord);
485 verts.insert(startv, startv + size - 1);
486 for (
int n = 0;
n != size; ++
n)
487 for (
auto d : {0, 1, 2})
488 arrays_coord[
d][
n] = coords[3 *
n +
d];
493 auto add_verts_to_field = [&]() {
496 CHKERR get_moab().add_entities(field_meshset, verts);
501 CHKERR add_verts_to_field();
516 const auto field_meshset = field_ptr->getMeshset();
517 const auto bit_number = field_ptr->getBitNumber();
520 Range ents_of_id_meshset;
521 CHKERR get_moab().get_entities_by_handle(field_meshset, ents_of_id_meshset,
523 Range field_ents = intersect(ents, ents_of_id_meshset);
526 "change nb. of ents for order in the field <%s> %d",
527 field_ptr->getName().c_str(), field_ents.size(), ents.size());
537 std::copy(eiit, hi_eiit, std::back_inserter(ents_id_view));
542 "current nb. of ents in the multi index field <%s> %d",
543 field_ptr->getName().c_str(), ents_id_view.size());
546 int nb_ents_set_order_up = 0;
547 int nb_ents_set_order_down = 0;
548 int nb_ents_set_order_new = 0;
553 for (
auto pit = field_ents.const_pair_begin();
554 pit != field_ents.const_pair_end(); pit++) {
561 switch (field_ptr->getSpace()) {
565 if (
type == MBVERTEX)
567 "Hcurl space on vertices makes no sense");
571 if (
type == MBVERTEX)
573 "Hdiv space on vertices makes no sense");
577 "Hdiv space on edges makes no sense");
585 Range ents_in_database;
586 auto vit = ents_id_view.get<1>().lower_bound(first);
587 auto hi_vit = ents_id_view.get<1>().upper_bound(second);
589 for (; vit != hi_vit; ++vit) {
590 ents_in_database.insert(vit->get()->getEnt());
593 (*vit)->getMaxOrder();
595 if (old_approximation_order !=
order) {
597 FieldEntity_multiIndex::iterator miit =
598 entsFields.get<
Unique_mi_tag>().find((*vit)->getLocalUniqueId());
600 if ((*miit)->getMaxOrder() <
order)
601 nb_ents_set_order_up++;
602 if ((*miit)->getMaxOrder() >
order)
603 nb_ents_set_order_down++;
609 bool can_change_size =
true;
619 can_change_size =
false;
620 for (; dit != hi_dit; dit++) {
621 if ((*dit)->getDofOrder() >
order) {
622 bool success = dofsField.modify(dofsField.project<0>(dit),
626 "modification unsuccessful");
632 entsFields.modify(entsFields.project<0>(miit),
633 can_change_size ? modify_order_size_change
634 : modify_order_no_size_change);
637 "modification unsuccessful");
642 Range new_ents = subtract(
Range(first, second), ents_in_database);
643 for (Range::const_pair_iterator pit = new_ents.const_pair_begin();
644 pit != new_ents.const_pair_end(); ++pit) {
645 const auto first = pit->first;
646 const auto second = pit->second;
647 const auto ent_type = get_moab().type_from_handle(first);
649 if (!field_ptr->getFieldOrderTable()[ent_type])
651 "Number of degrees of freedom for entity %s for %s space on "
654 moab::CN::EntityTypeName(ent_type),
655 field_ptr->getSpaceName().c_str(),
656 field_ptr->getApproxBaseName().c_str());
658 auto get_nb_dofs_on_order = [&](
const int order) {
659 return order >= 0 ? (field_ptr->getFieldOrderTable()[ent_type])(
order)
662 const int nb_dofs_on_order = get_nb_dofs_on_order(
order);
663 if (nb_dofs_on_order ||
order == -1) {
665 const int field_rank = field_ptr->getNbOfCoeffs();
666 const int nb_dofs = nb_dofs_on_order * field_rank;
670 refinedEntities.get<
Ent_mi_tag>().lower_bound(first);
672 auto create_tags_for_max_order = [&](
const Range &ents) {
675 std::vector<ApproximationOrder> o_vec(ents.size(),
order);
676 CHKERR get_moab().tag_set_data(field_ptr->th_AppOrder, ents,
682 auto create_tags_for_data = [&](
const Range &ents) {
687 if (ent_type == MBVERTEX) {
688 std::vector<FieldData> d_vec(nb_dofs * ents.size(), 0);
689 CHKERR get_moab().tag_set_data(field_ptr->th_FieldDataVerts,
690 ents, &*d_vec.begin());
692 std::vector<int> tag_size(ents.size(), nb_dofs);
693 std::vector<FieldData> d_vec(nb_dofs, 0);
694 std::vector<void const *> d_vec_ptr(ents.size(),
696 CHKERR get_moab().tag_set_by_ptr(field_ptr->th_FieldData, ents,
706 auto get_ents_in_ref_ent = [&](
auto miit_ref_ent) {
707 auto hi = refinedEntities.get<
Ent_mi_tag>().upper_bound(second);
709 for (; miit_ref_ent != hi; ++miit_ref_ent)
710 in.insert(miit_ref_ent->get()->getEnt());
714 auto get_ents_max_order = [&](
const Range &ents) {
715 boost::shared_ptr<std::vector<const void *>> vec(
716 new std::vector<const void *>());
717 vec->resize(ents.size());
718 CHKERR get_moab().tag_get_by_ptr(field_ptr->th_AppOrder, ents,
723 auto get_ents_field_data_vector_adaptor =
724 [&](
const Range &ents,
725 boost::shared_ptr<std::vector<const void *>> &ents_max_orders) {
727 boost::shared_ptr<std::vector<double *>> vec(
728 new std::vector<double *>());
729 vec->reserve(ents.size());
731 if (
order >= 0 && nb_dofs == 0) {
733 for (
int i = 0;
i != ents.size(); ++
i)
734 vec->emplace_back(
nullptr);
736 moab::ErrorCode
rval;
737 std::vector<int> tag_size(ents.size());
738 std::vector<const void *> d_vec_ptr(ents.size());
741 if (ent_type == MBVERTEX)
742 rval = get_moab().tag_get_by_ptr(field_ptr->th_FieldDataVerts,
743 ents, &*d_vec_ptr.begin(),
746 rval = get_moab().tag_get_by_ptr(field_ptr->th_FieldData,
747 ents, &*d_vec_ptr.begin(),
750 auto cast = [](
auto p) {
756 if (
rval == MB_SUCCESS) {
758 auto tit = d_vec_ptr.begin();
759 auto oit = ents_max_orders->begin();
760 for (
auto sit = tag_size.begin(); sit != tag_size.end();
762 vec->emplace_back(cast(*tit));
766 for (
int i = 0;
i != ents.size(); ++
i)
767 vec->emplace_back(
nullptr);
772 auto oit = ents_max_orders->begin();
773 auto dit = vec->begin();
774 for (
auto eit = ents.begin(); eit != ents.end();
775 ++eit, ++oit, ++dit) {
777 const int ent_order =
779 const int ent_nb_dofs = get_nb_dofs_on_order(ent_order);
784 if (ent_type == MBVERTEX) {
785 rval = get_moab().tag_get_by_ptr(
786 field_ptr->th_FieldDataVerts, &*eit, 1, &ret_val,
789 rval = get_moab().tag_get_by_ptr(
790 field_ptr->th_FieldData, &*eit, 1, &ret_val,
792 if (
rval != MB_SUCCESS) {
794 const int set_tag_size[] = {ent_nb_dofs * field_rank};
795 std::array<FieldData, MAX_DOFS_ON_ENTITY> set_d_vec;
796 std::fill(set_d_vec.begin(),
797 &set_d_vec[set_tag_size[0]], 0);
798 const void *set_d_vec_ptr[] = {set_d_vec.data()};
799 CHKERR get_moab().tag_set_by_ptr(
800 field_ptr->th_FieldData, &*eit, 1, set_d_vec_ptr,
802 rval = get_moab().tag_get_by_ptr(
803 field_ptr->th_FieldData, &*eit, 1, &ret_val,
806 if (
rval != MB_SUCCESS) {
811 <<
"Error is triggered in MOAB, field tag data "
812 "for same reason can not be for accessed.";
814 <<
"Set order: " <<
order;
816 <<
"Nb. dofs on entity for given order: "
820 << moab::CN::EntityTypeName(ent_type);
822 <<
"Field: " << *field_ptr;
827 const_cast<FieldData *&
>(*dit) = cast(ret_val);
835 auto ents_in_ref_ent = get_ents_in_ref_ent(miit_ref_ent);
837 CHKERR create_tags_for_max_order(ents_in_ref_ent);
838 CHKERR create_tags_for_data(ents_in_ref_ent);
839 auto ents_max_order = get_ents_max_order(ents_in_ref_ent);
840 auto ent_field_data =
841 get_ents_field_data_vector_adaptor(ents_in_ref_ent, ents_max_order);
844 auto ents_array = boost::make_shared<std::vector<FieldEntity>>();
849 ents_array->reserve(second - first + 1);
850 auto vit_max_order = ents_max_order->begin();
851 auto vit_field_data = ent_field_data->begin();
852 for (
int i = 0;
i != ents_in_ref_ent.size(); ++
i) {
854 ents_array->emplace_back(
855 field_ptr, *miit_ref_ent,
856 boost::shared_ptr<double *const>(ent_field_data,
858 boost::shared_ptr<const int>(
859 ents_max_order,
static_cast<const int *
>(*vit_max_order)));
864 if (!ents_array->empty())
865 if ((*ents_array)[0].getFieldRawPtr() != field_ptr.get())
867 "Get field ent poiter and field pointer do not match for "
869 field_ptr->getName().c_str());
870 nb_ents_set_order_new += ents_array->size();
874 if (ents_in_ref_ent.size() < (second - first + 1)) {
875 Range ents_not_in_database =
876 subtract(
Range(first, second), ents_in_ref_ent);
877 std::vector<const void *> vec_bits(ents_not_in_database.size());
878 CHKERR get_moab().tag_get_by_ptr(
879 get_basic_entity_data_ptr()->th_RefBitLevel, ents_not_in_database,
881 auto cast = [](
auto p) {
884 for (
auto v : vec_bits)
887 "Try to add entities which are not seeded or added to "
892 auto hint = entsFields.end();
893 for (
auto &
v : *ents_array)
894 hint = entsFields.emplace_hint(hint, ents_array, &
v);
901 "nb. of entities in field <%s> for which order was "
902 "increased %d (order %d)",
903 field_ptr->getName().c_str(), nb_ents_set_order_up,
order);
905 "nb. of entities in field <%s> for which order was "
906 "reduced %d (order %d)",
907 field_ptr->getName().c_str(), nb_ents_set_order_down,
order);
910 "nb. of entities in field <%s> for which order set %d (order %d)",
911 field_ptr->getName().c_str(), nb_ents_set_order_new,
order);
920 "nb. of ents in the multi index field <%s> %d",
921 field_ptr->getName().c_str(), std::distance(eiit, hi_eiit));
945 <<
"Field " << (*field_it)->getName() <<
" core value < "
946 << this->
getValue() <<
" > field value ( "
947 <<
static_cast<int>((*field_it)->getBitNumber()) <<
" )"
948 <<
" nb. of ents " << ents.size();
963 CHKERR get_moab().get_entities_by_type(meshset,
type, ents);
964 CHKERR this->set_field_order(ents,
id,
order, verb);
968 const EntityType
type,
969 const std::string &name,
975 CHKERR this->set_field_order(meshset,
type, get_field_id(name),
order, verb);
984 CHKERR this->set_field_order(ents, get_field_id(name),
order, verb);
997 CHKERR this->set_field_order(ents,
id,
order, verb);
1011 CHKERR this->set_field_order(ents, get_field_id(name),
order, verb);
1017 std::map<EntityType, int> &dof_counter,
1021 const auto bit_number = field_ptr->getBitNumber();
1025 CHKERR get_moab().get_entities_by_handle(field_ptr->getMeshset(), ents,
1028 MOFEM_LOG_C(
"SYNC", Sev::noisy,
"Ents in field %s meshset %d\n",
1029 field_ptr->getName().c_str(), ents.size());
1038 std::copy(eiit, hi_eiit, std::back_inserter(ents_id_view));
1041 boost::shared_ptr<const int> zero_order(
new const int(0));
1043 for (
auto ent : ents) {
1045 auto ref_ent_it = refinedEntities.get<
Ent_mi_tag>().find(ent);
1046 if (ref_ent_it == refinedEntities.get<
Ent_mi_tag>().end())
1048 "Entity is not in MoFEM database, entities in field meshset need "
1049 "to be seeded (i.e. bit ref level add to them)");
1051 auto add_dofs = [&](
auto field_eit) {
1057 auto p = dofsField.insert(
1058 boost::make_shared<DofEntity>(field_eit, 0, rank, rank));
1060 dof_counter[MBENTITYSET]++;
1063 "Dof expected to be created");
1069 auto field_ent_it = ents_id_view.get<1>().find(ent);
1070 if (field_ent_it == ents_id_view.get<1>().end()) {
1072 auto p = entsFields.insert(
1074 boost::make_shared<FieldEntity>(
1075 field_ptr, *ref_ent_it,
1078 boost::shared_ptr<const int>(zero_order, zero_order.get()))
1082 if ((*p.first)->getFieldRawPtr() != field_ptr.get())
1084 "Get field ent poiter and field pointer do not match for "
1086 field_ptr->getName().c_str());
1090 "Entity should be created");
1092 CHKERR add_dofs(*(p.first));
1103 CHKERR add_dofs(*field_ent_it);
1112 for (; lo_dof != hi_dof; lo_dof++)
1113 MOFEM_LOG(
"SYNC", Sev::noisy) << **lo_dof;
1122 std::map<EntityType, int> &dof_counter,
int verb) {
1135 <<
"Field " << (*field_it)->getName() <<
" core value < "
1136 << this->
getValue() <<
" > field value () "
1137 << (*field_it)->getBitNumber() <<
" )";
1139 CHKERR this->buildFieldForNoFieldImpl(*
field_it, dof_counter, verb);
1145 const BitFieldId id, std::map<EntityType, int> &dof_counter,
1146 std::map<EntityType, int> &inactive_dof_counter,
int verb) {
1157 const int bit_number =
field_it->get()->getBitNumber();
1158 const int rank =
field_it->get()->getNbOfCoeffs();
1161 Range ents_of_id_meshset;
1162 CHKERR get_moab().get_entities_by_handle((*field_it)->meshSet,
1163 ents_of_id_meshset,
false);
1165 MOFEM_LOG_C(
"SYNC", Sev::noisy,
"Ents in field %s meshset %d",
1166 (*field_it)->getName().c_str(), ents_of_id_meshset.size());
1169 for (
auto p_eit = ents_of_id_meshset.pair_begin();
1170 p_eit != ents_of_id_meshset.pair_end(); ++p_eit) {
1179 auto feit = entsFields.get<
Unique_mi_tag>().lower_bound(lo_uid);
1182 auto hi_feit = entsFields.get<
Unique_mi_tag>().upper_bound(hi_uid);
1186 auto dit = dofsField.get<
Unique_mi_tag>().lower_bound(lo_uid);
1187 auto hi_dit = dofsField.get<
Unique_mi_tag>().upper_bound(hi_uid);
1191 boost::shared_ptr<std::vector<DofEntity>> dofs_array =
1192 boost::make_shared<std::vector<DofEntity>>(std::vector<DofEntity>());
1194 int nb_dofs_on_ents = 0;
1195 for (
auto tmp_feit = feit; tmp_feit != hi_feit; ++tmp_feit) {
1196 nb_dofs_on_ents += rank * tmp_feit->get()->getOrderNbDofs(
1197 tmp_feit->get()->getMaxOrder());
1201 dofs_array->reserve(nb_dofs_on_ents);
1204 for (; feit != hi_feit; ++feit) {
1208 for (
int oo = 0; oo <= feit->get()->getMaxOrder(); ++oo) {
1210 for (
int dd = 0;
dd < feit->get()->getOrderNbDofsDiff(oo); ++
dd) {
1212 for (
int rr = 0; rr < rank; ++rr, ++DD) {
1213 dofs_array->emplace_back(*feit, oo, rr, DD);
1214 ++dof_counter[feit->get()->getEntType()];
1218 if (DD > feit->get()->getNbDofsOnEnt()) {
1219 std::ostringstream ss;
1220 ss <<
"rank " << rAnk <<
" ";
1221 ss << **feit << std::endl;
1223 "Expected number of DOFs on entity not equal to number added "
1224 "to database (DD = %d != %d = "
1225 "feit->get()->getNbDofsOnEnt())\n"
1227 DD, feit->get()->getNbDofsOnEnt(), ss.str().c_str());
1232 int dofs_field_size0 = dofsField.size();
1233 auto hint = dofsField.end();
1234 for (
auto &
v : *dofs_array)
1235 hint = dofsField.emplace_hint(hint, dofs_array, &
v);
1238 field_it->get()->getDofSequenceContainer().push_back(dofs_array);
1241 if (PetscUnlikely(
static_cast<int>(dofs_array.use_count()) !=
1242 static_cast<int>(dofs_array->size() + 1))) {
1244 "Wrong use count %d != %d", dofs_array.use_count(),
1245 dofs_array->size() + 1);
1247 if (dofs_field_size0 + dofs_array->size() != dofsField.size()) {
1249 "Wrong number of inserted DOFs %d != %d", dofs_array->size(),
1250 dofsField.size() - dofs_field_size0);
1262 MOFEM_LOG(
"SYNC", Sev::verbose) <<
"Build field " << field->getName();
1264 std::map<EntityType, int> dof_counter;
1265 std::map<EntityType, int> inactive_dof_counter;
1269 if (field->getApproxBase() ==
USER_BASE)
1270 CHKERR field->rebuildDofsOrderMap();
1272 switch (field->getSpace()) {
1274 CHKERR this->buildFieldForNoField(field->getId(), dof_counter, verb);
1280 CHKERR this->buildFieldForL2H1HcurlHdiv(field->getId(), dof_counter,
1281 inactive_dof_counter, verb);
1288 int nb_added_dofs = 0;
1289 int nb_inactive_added_dofs = 0;
1290 for (
auto const &it : dof_counter) {
1292 <<
"Nb. of dofs (" << moab::CN::EntityTypeName(it.first) <<
") "
1293 << it.second <<
" (inactive " << inactive_dof_counter[it.first]
1295 nb_added_dofs += it.second;
1296 nb_inactive_added_dofs += inactive_dof_counter[it.first];
1299 <<
"Nb. added dofs " << nb_added_dofs <<
" (number of inactive dofs "
1300 << nb_inactive_added_dofs <<
" )";
1324 CHKERR this->buildField(field, verb);
1326 *buildMoFEM = 1 << 0;
1328 MOFEM_LOG(
"SYNC", Sev::verbose) <<
"Number of dofs " << dofsField.size();
1342 MOFEM_LOG(
"SYNC", Sev::inform) <<
"List DOFs:";
1343 for (; dit != hi_dit; dit++)
1352 MOFEM_LOG(
"SYNC", Sev::inform) <<
"List Fields:";
1354 MOFEM_LOG(
"SYNC", Sev::inform) << *miit;
1360 FieldEntityByUId::iterator
1365 FieldEntityByUId::iterator
1370 DofEntityByUId::iterator
1375 DofEntityByUId::iterator
1380 DofEntityByUId::iterator
1387 DofEntityByUId::iterator
1394 DofEntityByUId::iterator
1396 const EntityType
type)
const {
1401 DofEntityByUId::iterator
1403 const EntityType
type)
const {
1414 "field not found < %s >", name.c_str());
1418 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
1420 auto count_field_ents = [&]() {
1421 auto bit_number = (*it)->getBitNumber();
1426 return std::distance(low_eit, hi_eit);
1429 if (count_field_ents() > (
unsigned int)num_entities) {
1431 "not equal number of entities in meshset and field multiindex "
1440 if (it->getSpace() ==
NOFIELD)
1445 CHKERR get_moab().get_number_entities_by_handle(meshset, num_entities);
1447 auto count_field_ents = [&]() {
1448 auto bit_number = it->getBitNumber();
1453 return std::distance(low_eit, hi_eit);
1456 if (count_field_ents() > (
unsigned int)num_entities) {
1458 "not equal number of entities in meshset and field "
1459 "multiindex < %s >",
1460 it->getName().c_str());