15 {
16
17bool Core::check_problem(const string name) {
18 Problem_multiIndex::index<Problem_mi_tag>::type::iterator pit;
19 pit = pRoblems.get<Problem_mi_tag>().find(name);
20 if (pit == pRoblems.get<Problem_mi_tag>().end()) {
21 return false;
22 }
23 return true;
24}
25
26MoFEMErrorCode Core::addProblem(
const BitProblemId
id,
const std::string &name,
27 int verb) {
29
30 if (verb == -1)
31 verb = verbose;
33 CHKERR get_moab().create_meshset(MESHSET_SET, meshset);
34 CHKERR get_moab().tag_set_data(th_ProblemId, &meshset, 1, &
id);
35
36
37
38
39 auto add_meshset_to_partition = [&](auto meshset) {
41 const void *tag_vals[] = {&rAnk};
42 ParallelComm *pcomm = ParallelComm::get_pcomm(
43 &get_moab(), get_basic_entity_data_ptr()->pcommID);
44 Tag part_tag = pcomm->part_tag();
46 CHKERR get_moab().get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag,
47 tag_vals, 1, tagged_sets,
48 moab::Interface::UNION);
49 for (auto s : tagged_sets)
50 CHKERR get_moab().add_entities(s, &meshset, 1);
52 };
53 CHKERR add_meshset_to_partition(meshset);
54
55 void const *tag_data[] = {name.c_str()};
56 int tag_sizes[1];
57 tag_sizes[0] = name.size();
58 CHKERR get_moab().tag_set_by_ptr(th_ProblemName, &meshset, 1, tag_data,
59 tag_sizes);
60
61 auto p = pRoblems.insert(Problem(moab, meshset));
62 if (!p.second) {
65 MOFEM_LOG(
"SELF", Sev::error) <<
"Following problem can not be added:";
67 << "Problem " << name << " id(" << id.to_ulong() << ") " << id
68 << " added meshset " << meshset;
69 MOFEM_LOG(
"SELF", Sev::error) <<
"List of problems already in databse:";
70 for (auto &p : pRoblems) {
72 << p.getName() << " id(" << p.getId().to_ulong() << ") " << id
73 << " on meshset " << p.meshset;
74 }
76 }
77
78 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Add problem " << name;
79
81}
82
84 int verb) {
86 if (verb == -1)
87 verb = verbose;
88 auto miit = pRoblems.get<Problem_mi_tag>().find(name);
89 if (miit == pRoblems.get<Problem_mi_tag>().end()) {
90
91 int p_shift = 0;
92 for (; pRoblems.get<BitProblemId_mi_tag>().find(
BitProblemId().
set(
93 p_shift)) != pRoblems.get<BitProblemId_mi_tag>().end();
94 ++p_shift) {
95 }
96
98 CHKERR addProblem(
id, name, verb);
99
102 name.c_str());
103 }
105}
106
109 auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
110 if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
111 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"no such problem like < %s >",
112 name.c_str());
113 }
115 pRoblems.get<Problem_mi_tag>().erase(p_miit);
116 CHKERR get_moab().delete_entities(&meshset, 1);
118}
119
120BitProblemId Core::getBitProblemId(
const std::string &name)
const {
121 auto p_miit = pRoblems.get<Problem_mi_tag>().find(name);
122 if (p_miit == pRoblems.get<Problem_mi_tag>().end()) {
124 }
125 return p_miit->getId();
126}
127
130 typedef Problem_multiIndex::index<BitProblemId_mi_tag>::type ProblemById;
131 const ProblemById &set_id = pRoblems.get<BitProblemId_mi_tag>();
132 ProblemById::iterator miit = set_id.begin();
133 for (; miit != set_id.end(); miit++) {
134 std::ostringstream ss;
135 ss << *miit << std::endl;
136 PetscPrintf(mofemComm, "%s", ss.str().c_str());
137 }
139}
140
142Core::modify_problem_add_finite_element(const std::string name_problem,
143 const std::string &fe_name) {
145 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
146 ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
147 ProblemsByName::iterator miit = set.find(name_problem);
148 if (miit == set.end()) {
149 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"this problem <%s> is not there",
150 name_problem.c_str());
151 }
152 BitFEId f_id = getBitFEId(fe_name);
153 bool success = set.modify(miit, ProblemFiniteElementChangeBitAdd(f_id));
154 if (!success)
156 "modification unsuccessful");
158}
159
161Core::modify_problem_unset_finite_element(const std::string name_problem,
162 const std::string &fe_name) {
164 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
165 ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
166 ProblemsByName::iterator miit = set.find(name_problem);
167 if (miit == set.end()) {
168 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"this problem <%s> is not there",
169 name_problem.c_str());
170 }
171 BitFEId f_id = getBitFEId(fe_name);
172 bool success = set.modify(miit, ProblemFiniteElementChangeBitUnSet(f_id));
173 if (!success)
175 "modification unsuccessful");
177}
178
180Core::modify_problem_ref_level_add_bit(const std::string &name_problem,
181 const BitRefLevel &
bit) {
183 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
184 ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
185 ProblemsByName::iterator miit = set.find(name_problem);
186 std::ostringstream ss;
187 ss << name_problem;
188 if (miit == set.end())
189 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"this problem <%s> is there",
190 ss.str().c_str());
191 bool success =
set.modify(miit, ProblemChangeRefLevelBitAdd(
bit));
192 if (!success)
193 SETERRQ(PETSC_COMM_SELF, 1, "modification unsuccessful");
195}
196
198Core::modify_problem_ref_level_set_bit(const std::string &name_problem,
199 const BitRefLevel &
bit) {
201 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
202 ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
203 ProblemsByName::iterator miit = set.find(name_problem);
204 std::ostringstream ss;
205 ss << name_problem;
206 if (miit == set.end())
207 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"this problem <%s> is there",
208 ss.str().c_str());
209 bool success =
set.modify(miit, ProblemChangeRefLevelBitSet(
bit));
210 if (!success)
212 "modification unsuccessful");
214}
215
217Core::modify_problem_mask_ref_level_add_bit(const std::string &name_problem,
218 const BitRefLevel &
bit) {
220 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
221 ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
222 ProblemsByName::iterator miit = set.find(name_problem);
223 if (miit == set.end()) {
224 std::ostringstream ss;
225 ss << name_problem;
226 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"this problem <%s> is there",
227 ss.str().c_str());
228 }
229 bool success =
set.modify(miit, ProblemChangeRefLevelBitDofMaskAdd(
bit));
230 if (!success)
232 "modification unsuccessful");
234}
235
237Core::modify_problem_mask_ref_level_set_bit(const std::string &name_problem,
238 const BitRefLevel &
bit) {
240 ProblemsByName;
241 ProblemsByName &set = pRoblems.get<Problem_mi_tag>();
242 ProblemsByName::iterator miit = set.find(name_problem);
243 if (miit == set.end()) {
244 std::ostringstream ss;
245 ss << name_problem;
246 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"this problem <%s> is there",
247 ss.str().c_str());
248 }
249 bool success =
set.modify(miit, ProblemChangeRefLevelBitDofMaskSet(
bit));
250 if (!success)
252 "modification unsuccessful");
254}
255
258 if (verb == -1)
259 verb = verbose;
260 Problem_multiIndex::iterator p_miit = pRoblems.begin();
261 for (; p_miit != pRoblems.end(); p_miit++) {
262 CHKERR getInterface<ProblemsManager>()->buildProblemOnDistributedMesh(
263 const_cast<Problem *>(&*p_miit), verb);
264 }
266}
267
268MoFEMErrorCode Core::clear_problem(
const std::string problem_name,
int verb) {
270 if (verb == -1)
271 verb = verbose;
272 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
273 ProblemsByName &prob_by_name = pRoblems.get<Problem_mi_tag>();
274 ProblemsByName::iterator p_miit = prob_by_name.find(problem_name);
275 if (p_miit == prob_by_name.end()) {
277 "problem < %s > not found, (top tip: check spelling)",
278 problem_name.c_str());
279 }
280
281 bool success = prob_by_name.modify(p_miit, ProblemZeroNbRowsChange());
282 if (!success)
284 "modification unsuccessful");
285
286 success = prob_by_name.modify(p_miit, ProblemZeroNbColsChange());
287 if (!success)
289 "modification unsuccessful");
290
291 success =
292 prob_by_name.modify(p_miit, ProblemClearNumeredFiniteElementsChange());
293 if (!success)
295 "modification unsuccessful");
296
297 success = prob_by_name.modify(p_miit, ProblemClearSubProblemData());
298 if (!success)
300 "modification unsuccessful");
301 success = prob_by_name.modify(p_miit, ProblemClearComposedProblemData());
302 if (!success)
304 "modification unsuccessful");
305 if (p_miit->getRowDofsSequence())
306 p_miit->getRowDofsSequence()->clear();
307 if (p_miit->getColDofsSequence())
308 p_miit->getColDofsSequence()->clear();
309 if (p_miit->getSubData())
310 p_miit->getSubData().reset();
311 if (p_miit->getComposedProblemsData())
312 p_miit->getComposedProblemsData().reset();
314}
315
318 if (verb == -1)
319 verb = verbose;
320 if (!((*buildMoFEM) & BUILD_FIELD))
322 if (!((*buildMoFEM) & BUILD_FE))
324 if (!((*buildMoFEM) & BUILD_ADJ))
326
327 Problem_multiIndex::iterator p_miit = pRoblems.begin();
328 for (; p_miit != pRoblems.end(); p_miit++) {
329 Problem *problem_ptr = const_cast<Problem *>(&*p_miit);
330 CHKERR getInterface<ProblemsManager>()->buildProblem(problem_ptr,
false,
331 verb);
332 }
333 *buildMoFEM |= BUILD_PROBLEM;
335}
336
339 if (verb == -1)
340 verb = verbose;
341
342 for (auto p_miit = pRoblems.begin(); p_miit != pRoblems.end(); p_miit++)
343 CHKERR clear_problem(p_miit->getName(), verb);
345}
346
347#define SET_BASIC_METHOD(METHOD, PROBLEM_PTR) \
348 { \
349 METHOD.rAnk = rAnk; \
350 METHOD.sIze = sIze; \
351 METHOD.problemPtr = PROBLEM_PTR; \
352 METHOD.fieldsPtr = &fIelds; \
353 METHOD.refinedEntitiesPtr = &refinedEntities; \
354 METHOD.entitiesPtr = &entsFields; \
355 METHOD.dofsPtr = &dofsField; \
356 METHOD.refinedFiniteElementsPtr = &refinedFiniteElements; \
357 METHOD.finiteElementsPtr = &finiteElements; \
358 METHOD.finiteElementsEntitiesPtr = &entsFiniteElements; \
359 METHOD.adjacenciesPtr = &entFEAdjacencies; \
360 }
361
362MoFEMErrorCode Core::problem_basic_method_preProcess(
const Problem *problem_ptr,
363 BasicMethod &method,
364 int verb) {
366 if (verb == -1)
367 verb = verbose;
368
370 PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
371 CHKERR method.preProcess();
372 PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
374}
375
377Core::problem_basic_method_preProcess(const std::string &problem_name,
378 BasicMethod &method, int verb) {
380 if (verb == -1)
381 verb = verbose;
382 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
383
384 ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
385 ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
386 if (p_miit == pRoblems_set.end())
387 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"problem is not in database %s",
388 problem_name.c_str());
389 CHKERR problem_basic_method_preProcess(&*p_miit, method, verb);
391}
392
394Core::problem_basic_method_postProcess(const Problem *problem_ptr,
395 BasicMethod &method, int verb) {
398
399 PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
400 CHKERR method.postProcess();
401 PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
402
404}
405
407Core::problem_basic_method_postProcess(const std::string &problem_name,
408 BasicMethod &method, int verb) {
410 if (verb == -1)
411 verb = verbose;
412 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
413
414
415 ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
416 ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
417 if (p_miit == pRoblems_set.end())
418 SETERRQ(mofemComm, 1, "problem is not in database %s",
419 problem_name.c_str());
420
421 CHKERR problem_basic_method_postProcess(&*p_miit, method, verb);
422
424}
425
427 const Problem *problem_ptr,
const std::string &fe_name,
FEMethod &method,
428 int lower_rank, int upper_rank,
429 boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr,
MoFEMTypes bh,
430 CacheTupleWeakPtr cache_ptr, int verb) {
433 verb = verbose;
434
436 if (!cache_ptr.use_count()) {
437 tmp_cache_ptr = boost::make_shared<CacheTuple>();
438 CHKERR cache_problem_entities(problem_ptr->getName(), tmp_cache_ptr);
439 method.cacheWeakPtr = tmp_cache_ptr;
440 } else {
441 method.cacheWeakPtr = cache_ptr;
442 }
443
444 if (!fe_ptr)
445 fe_ptr = problem_ptr->numeredFiniteElementsPtr;
446
447 auto miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().lower_bound(
448 boost::make_tuple(fe_name, lower_rank));
449 auto hi_miit = fe_ptr->get<Composite_Name_And_Part_mi_tag>().upper_bound(
450 boost::make_tuple(fe_name, upper_rank));
451
452 if (miit == hi_miit && (bh &
MF_EXIST)) {
453 if (!check_finite_element(fe_name)) {
455 fe_name.c_str());
456 }
457 }
458
459 method.feName = fe_name;
460 method.loopSize =
461 std::distance(miit, hi_miit);
462 method.loHiFERank = std::make_pair(lower_rank, upper_rank);
463
465
466 PetscLogEventBegin(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
467 CHKERR method.preProcess();
468 PetscLogEventEnd(MOFEM_EVENT_preProcess, 0, 0, 0, 0);
469
470 PetscLogEventBegin(MOFEM_EVENT_operator, 0, 0, 0, 0);
471 for (int nn = 0; miit != hi_miit; miit++, nn++) {
472
473 method.nInTheLoop = nn;
474 method.numeredEntFiniteElementPtr = *miit;
475
476 if (method.exeTestHook) {
477 if (method.exeTestHook(&method)) {
479 }
480 } else {
482 }
483
484 }
485 PetscLogEventEnd(MOFEM_EVENT_operator, 0, 0, 0, 0);
486
487 PetscLogEventBegin(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
488 CHKERR method.postProcess();
489 PetscLogEventEnd(MOFEM_EVENT_postProcess, 0, 0, 0, 0);
490
492}
493
495 const std::string problem_name, const std::string &fe_name,
497 boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr,
MoFEMTypes bh,
498 CacheTupleWeakPtr cache_ptr, int verb) {
501 verb = verbose;
502
503 CHKERR loop_finite_elements(problem_name, fe_name, method, rAnk, rAnk, fe_ptr,
504 bh, cache_ptr, verb);
505
507}
508
510 const std::string problem_name, const std::string &fe_name,
511 FEMethod &method,
int lower_rank,
int upper_rank,
512 boost::shared_ptr<NumeredEntFiniteElement_multiIndex> fe_ptr,
MoFEMTypes bh,
513 CacheTupleWeakPtr cache_ptr, int verb) {
516 verb = verbose;
517
518 auto &prb_by_name = pRoblems.get<Problem_mi_tag>();
519 auto p_miit = prb_by_name.find(problem_name);
520 if (p_miit == prb_by_name.end())
522 problem_name.c_str());
523
524 CHKERR loop_finite_elements(&*p_miit, fe_name, method, lower_rank, upper_rank,
525 fe_ptr, bh, cache_ptr, verb);
526
528}
529
532 DofMethod &method, int lower_rank,
533 int upper_rank, int verb) {
536 typedef NumeredDofEntity_multiIndex::index<Unique_mi_tag>::type
537 NumeredDofsByUId;
538 NumeredDofsByUId *dofs;
539 switch (rc) {
541 dofs = &problem_ptr->numeredRowDofsPtr->get<Unique_mi_tag>();
542 break;
544 dofs = &problem_ptr->numeredColDofsPtr->get<Unique_mi_tag>();
545 break;
546 default:
548 }
549
551 if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
553 } else {
556 }
557
558 auto miit = dofs->lower_bound(
559 FieldEntity::getLoBitNumberUId((*field_it)->getBitNumber()));
560 auto hi_miit = dofs->upper_bound(
561 FieldEntity::getHiBitNumberUId((*field_it)->getBitNumber()));
562
563 method.loopSize = std::distance(miit, hi_miit);
564 method.loHiFERank = std::make_pair(lower_rank, upper_rank);
565
566 CHKERR method.preProcess();
567
568 int nn = 0;
569 for (; miit != hi_miit; miit++, nn++) {
570 if ((*miit)->getPart() >= lower_rank && (*miit)->getPart() <= upper_rank) {
571 method.nInTheLoop = nn;
572 method.dofPtr = miit->get()->getDofEntityPtr();
573 method.dofNumeredPtr = *miit;
575 }
576 }
577
578 CHKERR method.postProcess();
580}
581
583 const std::string &problem_name,
const std::string &
field_name,
585 DofMethod &method,
586 int lower_rank,
587
588 int upper_rank,
589 int verb
590) {
593 verb = verbose;
594 typedef Problem_multiIndex::index<Problem_mi_tag>::type ProblemsByName;
595
596 ProblemsByName &pRoblems_set = pRoblems.get<Problem_mi_tag>();
597 ProblemsByName::iterator p_miit = pRoblems_set.find(problem_name);
598 if (p_miit == pRoblems_set.end())
599 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"problem not in database %s",
600 problem_name.c_str());
602 verb);
604}
605
608 DofMethod &method, int verb) {
611 verb = verbose;
614}
615
617 int verb) {
620 verb = verbose;
622
624 if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
626 } else {
629 }
630
631 auto miit = dofsField.get<Unique_mi_tag>().lower_bound(
632 FieldEntity::getLoBitNumberUId((*field_it)->getBitNumber()));
633 auto hi_miit = dofsField.get<Unique_mi_tag>().upper_bound(
634 FieldEntity::getHiBitNumberUId((*field_it)->getBitNumber()));
635
636 method.loopSize = std::distance(miit, hi_miit);
637 method.loHiFERank = std::make_pair(0, get_comm_size());
638
639 CHKERR method.preProcess();
640 for (int nn = 0; miit != hi_miit; miit++, nn++) {
641 method.nInTheLoop = nn;
642 method.dofPtr = *miit;
644 }
645 CHKERR method.postProcess();
647}
648
651 EntityMethod &method, int lower_rank,
652 int upper_rank, int verb) {
655 verb = verbose;
656 decltype(problem_ptr->numeredRowDofsPtr) dofs;
657 switch (rc) {
659 dofs = problem_ptr->numeredRowDofsPtr;
660 break;
662 dofs = problem_ptr->numeredColDofsPtr;
663 break;
664 default:
666 "It works only with rows or columns");
667 }
668
670 if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
672 } else {
675 }
676
677 auto miit = dofs->lower_bound(
678 FieldEntity::getLoBitNumberUId((*field_it)->getBitNumber()));
679 auto hi_miit = dofs->upper_bound(
680 FieldEntity::getHiBitNumberUId((*field_it)->getBitNumber()));
681
682 using FieldEntity_view_multiIndex = multi_index_container<
683
684 boost::shared_ptr<FieldEntity>,
685 indexed_by<
686
687 ordered_unique<
688
689 tag<Ent_mi_tag>,
690 const_mem_fun<FieldEntity::interface_type_RefEntity,
EntityHandle,
691 &FieldEntity::getEnt>>
692
693 >>;
694
695 FieldEntity_view_multiIndex ents_view;
696 auto hint = ents_view.begin();
697 for (; miit != hi_miit; ++miit)
698 if ((*miit)->getPart() >= lower_rank && (*miit)->getPart() <= upper_rank)
699 ents_view.emplace_hint(hint, (*miit)->getFieldEntityPtr());
700
702
703 method.loopSize = ents_view.size();
704 method.loHiFERank = std::make_pair(lower_rank, upper_rank);
705
706 CHKERR method.preProcess();
707 method.nInTheLoop = 0;
708 for (auto &field_ent : ents_view) {
709 method.entPtr = field_ent;
711 ++method.nInTheLoop;
712 }
713 CHKERR method.postProcess();
715}
716
719 EntityMethod &method, int lower_rank,
720 int upper_rank, int verb) {
723 verb = verbose;
724
725 auto &prb = pRoblems.get<Problem_mi_tag>();
726 auto p_miit = prb.find(problem_name);
727 if (p_miit == prb.end())
728 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"problem not in database %s",
729 problem_name.c_str());
730 CHKERR loop_entities(&*p_miit,
field_name, rc, method, lower_rank, upper_rank,
731 verb);
733}
734
737 EntityMethod &method, int verb) {
738 return loop_entities(problem_name,
field_name, rc, method, rAnk, rAnk, verb);
739}
740
742 EntityMethod &method,
743 Range const *
const ents,
int verb) {
746 verb = verbose;
748
750 if (field_it != fIelds.get<FieldName_mi_tag>().end()) {
752 } else {
755 }
756
757 auto lo_eit = entsFields.get<Unique_mi_tag>().lower_bound(
758 FieldEntity::getLoBitNumberUId((*field_it)->getBitNumber()));
759 auto hi_eit = entsFields.get<Unique_mi_tag>().upper_bound(
760 FieldEntity::getHiBitNumberUId((*field_it)->getBitNumber()));
761
762 typedef multi_index_container<
763 boost::shared_ptr<FieldEntity>,
764 indexed_by<ordered_unique<
765 tag<Ent_mi_tag>, const_mem_fun<FieldEntity::interface_RefEntity,
767 FieldEntity_view_multiIndex;
768
769 FieldEntity_view_multiIndex ents_view;
770 ents_view.insert(lo_eit, hi_eit);
771
772 method.loopSize = ents_view.size();
773 method.loHiFERank = std::make_pair(0, get_comm_size());
774
775 CHKERR method.preProcess();
776 method.nInTheLoop = 0;
777
778 if (ents)
779 for (auto p = ents->const_pair_begin(); p != ents->const_pair_end(); ++p)
780 for (auto feit = ents_view.lower_bound(p->first);
781 feit != ents_view.upper_bound(p->second); ++feit) {
782 method.entPtr = *feit;
784 ++method.nInTheLoop;
785 }
786 else
787 for (auto &field_ent : ents_view) {
788 method.entPtr = field_ent;
790 ++method.nInTheLoop;
791 }
792
793 CHKERR method.postProcess();
795}
796
797MoFEMErrorCode Core::cache_problem_entities(
const std::string prb_name,
798 CacheTupleWeakPtr cache_weak_ptr) {
800
801 if (auto cache_ptr = cache_weak_ptr.lock()) {
802 auto p_miit = pRoblems.get<Problem_mi_tag>().find(prb_name);
803 if (p_miit == pRoblems.get<Problem_mi_tag>().end())
804 SETERRQ(PETSC_COMM_SELF,
MOFEM_NOT_FOUND,
"problem not in database %s",
805 prb_name.c_str());
806
807 const BitRefLevel &prb_bit = p_miit->getBitRefLevel();
808 const BitRefLevel &prb_mask = p_miit->getBitRefLevelMask();
809 const BitFEId &prb_fe_id = p_miit->getBitFEId();
810
811 auto &row_dofs = p_miit->numeredRowDofsPtr;
812 auto &col_dofs = p_miit->numeredColDofsPtr;
813
814 auto &cache_data = std::get<0>(*cache_ptr);
815 auto &cache_row = std::get<1>(*cache_ptr);
816 auto &cache_col = std::get<2>(*cache_ptr);
817
818 cache_row.resize(entsFields.size());
819 if (row_dofs != col_dofs)
820 cache_col.resize(entsFields.size());
821 cache_data.resize(entsFields.size());
822
823 size_t idx = 0;
824 for (auto it = entsFields.begin(); it != entsFields.end(); ++it, ++idx) {
825
826 const auto uid = (*it)->getLocalUniqueId();
827 auto r = entFEAdjacencies.get<Unique_mi_tag>().equal_range(uid);
828 for (
auto lo =
r.first; lo !=
r.second; ++lo) {
829
830 if ((lo->getBitFEId() & prb_fe_id).any()) {
831
832 const BitRefLevel &fe_bit = lo->entFePtr->getBitRefLevel();
833
834
835 if (((fe_bit & prb_mask) != fe_bit) || ((fe_bit & prb_bit).none()))
836 continue;
837
838 auto cache_numered_dofs = [&](auto &numered_dofs, auto &cache_vec,
839 auto &ent_cache) {
840 auto dit = numered_dofs->lower_bound(uid);
841 decltype(dit) hi_dit;
842 if (dit != numered_dofs->end())
843 hi_dit = numered_dofs->upper_bound(
845 else
846 hi_dit = dit;
847
848 ent_cache = boost::shared_ptr<EntityCacheNumeredDofs>(
849 cache_ptr, &(cache_vec[idx]));
850 cache_vec[idx].loHi = {dit, hi_dit};
851 };
852
853 auto cache_dofs = [&](auto &dofs, auto &cache_vec, auto &ent_cache) {
854 auto dit = dofs.lower_bound(uid);
855 decltype(dit) hi_dit;
856 if (dit != dofs.end())
857 hi_dit = dofs.upper_bound(
859 else
860 hi_dit = dit;
861
862 ent_cache = boost::shared_ptr<EntityCacheDofs>(cache_ptr,
863 &(cache_vec[idx]));
864 cache_vec[idx].loHi = {dit, hi_dit};
865 };
866
867 cache_numered_dofs(row_dofs, cache_row, (*it)->entityCacheRowDofs);
868 if (row_dofs != col_dofs) {
869 if (cache_col.size() != entsFields.size())
870 cache_col.resize(entsFields.size());
871 cache_numered_dofs(col_dofs, cache_col, (*it)->entityCacheColDofs);
872 } else {
873 (*it)->entityCacheColDofs = (*it)->entityCacheRowDofs;
874 }
875
876 cache_dofs(dofsField, cache_data, (*it)->entityCacheDataDofs);
877
878 break;
879 }
880 }
881 }
882 } else {
884 }
885
887}
888
889}
#define ProblemCoreFunctionBegin
#define SET_BASIC_METHOD(METHOD, PROBLEM_PTR)
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_ATTRIBUTES(channel, bit)
Add attributes to channel.
#define MOFEM_LOG_FUNCTION()
Set scope.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITFEID_SIZE > BitFEId
Finite element Id.
std::bitset< BITPROBLEMID_SIZE > BitProblemId
Problem Id.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Field_multiIndex::index< FieldName_mi_tag >::type::iterator field_it
boost::shared_ptr< CacheTuple > CacheTupleSharedPtr
constexpr auto field_name