33 Vec vecsToMapFrom[] = PETSC_NULLPTR,
34 Vec vecsToMapTo[] = PETSC_NULLPTR);
35 MoFEMErrorCode
reSetUp(std::vector<std::string> L2Fields,
36 std::vector<int> L2Oders,
37 std::vector<std::string> H1Fields,
38 std::vector<int> H1Orders,
39 std::vector<std::string> HdivFields,
40 std::vector<int> HdivOrders, BitRefLevel bIt);
47 boost::shared_ptr<DomainEle>
feRhs;
48 boost::shared_ptr<DomainEle>
feLhs;
52 BitRefLevel parent_bit, BitRefLevel child_bit);
53 MoFEMErrorCode
projectResults(BitRefLevel parent_bit, BitRefLevel child_bit);
56 BitRefLevel parent_bit, BitRefLevel child_bit,
57 PetscInt numVecs, Vec vecsToMapFrom[],
83 SmartPetscObj<DM> &intermediate_dm,
84 BitRefLevel parent_bit,
85 BitRefLevel child_bit) {
88 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"Set up sub DM for mapping";
94 auto create_sub_dm = [&]() {
97 auto create_impl = [&]() {
99 CHKERR DMSetType(sub_dm,
"DMMOFEM");
100 CHKERR DMMoFEMCreateSubDM(sub_dm, intermediate_dm,
"SUB_MAPPING");
101 CHKERR DMMoFEMAddElement(sub_dm,
simple->getDomainFEName());
102 CHKERR DMMoFEMSetSquareProblem(sub_dm, PETSC_TRUE);
103 CHKERR DMMoFEMSetDestroyProblem(sub_dm, PETSC_TRUE);
105 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"Created sub DM";
108 auto ref_entities_ptr = boost::make_shared<Range>();
109 auto child_mask = parent_bit;
111 child_bit, child_mask.flip(),
SPACE_DIM, *ref_entities_ptr);
116 moab::Interface::UNION);
117 ref_entities_ptr->merge(edges);
121 verts, moab::Interface::UNION);
122 ref_entities_ptr->merge(verts);
124 for (
auto f : {
"U",
"FLUX"}) {
125 CHKERR DMMoFEMAddSubFieldRow(sub_dm, f, ref_entities_ptr);
126 CHKERR DMMoFEMAddSubFieldCol(sub_dm, f, ref_entities_ptr);
130 parent_bit | child_bit);
132 BitRefLevel().set());
135 CHKERR DMSubDMSetUp_MoFEM(sub_dm);
146 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"Set up sub DM for mapping <= done";
151 std::vector<int> L2_orders,
152 std::vector<std::string> H1_fields,
153 std::vector<int> H1_orders,
154 std::vector<std::string> Hdiv_fields,
155 std::vector<int> Hdiv_orders,
161 auto add_ents_order_to_field =
163 const std::initializer_list<std::string> &f,
164 const std::initializer_list<EntityType> &
t,
int _order) {
175 for (
size_t i = 0;
i < L2_fields.size(); ++
i) {
179 for (
size_t i = 0;
i < H1_fields.size(); ++
i) {
180 CHKERR add_ents_order_to_field(
m_field, {H1_fields[
i]}, {MBTRI, MBEDGE},
185 for (
size_t i = 0;
i < Hdiv_fields.size(); ++
i) {
186 CHKERR add_ents_order_to_field(
m_field, {Hdiv_fields[
i]}, {MBTRI, MBEDGE},
194 BitRefLevel().set(), MBTRI, faces);
196 CHKERR skin.find_skin(0, faces,
false, skin_edges);
200 auto filter_blocks = [&](
auto skin) {
201 bool is_contact_block =
false;
206 (boost::format(
"%s(.*)") %
"CONTACT").str()
215 <<
"Find contact block set: " <<
m->getName();
216 auto meshset =
m->getMeshset();
217 Range contact_meshset_range;
219 meshset,
SPACE_DIM - 1, contact_meshset_range,
true);
222 contact_meshset_range);
223 contact_range.merge(contact_meshset_range);
225 if (is_contact_block) {
227 <<
"Nb entities in contact surface: " << contact_range.size();
229 skin = intersect(skin, contact_range);
234 auto sigma_trace_ents = filter_blocks(skin_edges);
242 simple->getDomainFEName());
244 skin_edges, MBEDGE,
simple->getBoundaryFEName());
254 BitRefLevel child_bit) {
257 feRhs->getOpPtrVector().clear();
258 feLhs->getOpPtrVector().clear();
260 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"Cleared FEs";
264 auto vol_rule = [](int, int,
int ao) {
return 2 * ao +
geom_order; };
266 feRhs->getRuleHook = vol_rule;
267 feLhs->getRuleHook = vol_rule;
272 auto get_child_op = [&](
auto &pip) {
274 new OpLoopThis<DomainEle>(
m_field,
simple->getDomainFEName(), child_bit,
275 parent_bit.flip(), Sev::noisy);
276 auto fe_child_ptr = op_this_child->getThisFEPtr();
277 fe_child_ptr->getRuleHook = [](int, int,
int p) {
return -1; };
280 child_bit, parent_bit.flip(), MBEDGE, child_edges);
282 CHKERR setDGSetIntegrationPoints<2>(
283 fe_child_ptr->setRuleHook, [](
int,
int,
int p) { return 2 * p; },
284 boost::make_shared<Range>(child_edges));
285 pip.push_back(op_this_child);
291 auto get_field_eval_op = [&](
auto fe_child_ptr) {
296 auto field_eval_data = field_eval_ptr->getData<
DomainEle>();
299 field_eval_data,
simple->getDomainFEName(), parent_bit,
300 BitRefLevel().set());
303 auto new_T_ptr = boost::make_shared<MatrixDouble>();
304 auto old_T_ptr = boost::make_shared<MatrixDouble>();
305 auto new_TAU_ptr = boost::make_shared<MatrixDouble>();
306 auto old_TAU_ptr = boost::make_shared<MatrixDouble>();
307 auto new_EP_ptr = boost::make_shared<MatrixDouble>();
308 auto old_EP_ptr = boost::make_shared<MatrixDouble>();
310 auto new_U_ptr = boost::make_shared<MatrixDouble>();
311 auto old_U_ptr = boost::make_shared<MatrixDouble>();
312 auto new_flux_ptr = boost::make_shared<MatrixDouble>();
313 auto old_flux_ptr = boost::make_shared<MatrixDouble>();
315 if (
auto fe_eval_ptr = field_eval_data->feMethodPtr.lock()) {
316 fe_eval_ptr->getRuleHook = [](int, int,
int p) {
return -1; };
317 fe_eval_ptr->getOpPtrVector().push_back(
318 new OpCalculateVectorFieldValues<1>(
"T", old_T_ptr));
319 fe_eval_ptr->getOpPtrVector().push_back(
320 new OpCalculateVectorFieldValues<1>(
"TAU", old_TAU_ptr));
322 fe_eval_ptr->getOpPtrVector().push_back(
323 new OpCalculateVectorFieldValues<size_symm>(
"EP", old_EP_ptr));
324 fe_eval_ptr->getOpPtrVector().push_back(
325 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", old_U_ptr));
326 fe_eval_ptr->getOpPtrVector().push_back(
327 new OpCalculateHVecVectorField<3>(
"FLUX", old_flux_ptr));
331 "Field evaluator method pointer is expired");
334 auto op_ptr = field_eval_ptr->getDataOperator<
SPACE_DIM>(
337 {old_T_ptr, new_T_ptr},
338 {old_TAU_ptr, new_TAU_ptr},
339 {old_EP_ptr, new_EP_ptr},
340 {old_U_ptr, new_U_ptr},
341 {old_flux_ptr, new_flux_ptr}
347 fe_child_ptr->getOpPtrVector().push_back(op_ptr);
349 using FieldTupleVec = std::vector<
350 std::tuple<std::string, boost::shared_ptr<MatrixDouble>,
int>>;
352 return std::make_pair(
354 std::vector<std::pair<std::string, boost::shared_ptr<MatrixDouble>>>{
355 {
"T", new_T_ptr}, {
"TAU", new_TAU_ptr}, {
"EP", new_EP_ptr}},
357 std::vector<std::pair<std::string, boost::shared_ptr<MatrixDouble>>>{
358 {
"U", new_U_ptr}, {
"FLUX", new_flux_ptr}}
364 auto dg_projection_base = [&](
auto fe_child_ptr,
auto vec_data_ptr) {
367 auto entity_data_l2 = boost::make_shared<EntitiesFieldData>(MBENTITYSET);
368 auto mass_ptr = boost::make_shared<MatrixDouble>();
369 auto coeffs_ptr = boost::make_shared<MatrixDouble>();
371 constexpr int projection_order = 2;
373 for (
auto &[
field_name, data_ptr] : vec_data_ptr.first) {
375 fe_child_ptr->getOpPtrVector().push_back(
new OpDGProjectionMassMatrix(
378 fe_child_ptr->getOpPtrVector().push_back(
new OpDGProjectionCoefficients(
379 data_ptr, coeffs_ptr, mass_ptr, entity_data_l2,
384 op_set_coeffs->doWorkRhsHook =
385 [coeffs_ptr](DataOperator *base_op_ptr,
int side, EntityType type,
386 EntitiesFieldData::EntData &data) -> MoFEMErrorCode {
388 auto field_ents = data.getFieldEntities();
389 auto nb_dofs = data.getIndices().size();
390 if (!field_ents.size())
392 if (
auto e_ptr = field_ents[0]) {
393 auto field_ent_data = e_ptr->getEntFieldData();
394 std::copy(coeffs_ptr->data().data(),
395 coeffs_ptr->data().data() + nb_dofs,
396 field_ent_data.begin());
400 fe_child_ptr->getOpPtrVector().push_back(op_set_coeffs);
403 for (
auto &p : vec_data_ptr.second) {
405 auto data_ptr = p.second;
409 using OpDomainMass = FormsIntegrators<DomainEleOp>::Assembly<
414 fe_child_ptr->getOpPtrVector().push_back(
416 using OpVec = FormsIntegrators<DomainEleOp>::Assembly<
418 fe_child_ptr->getOpPtrVector().push_back(
424 using OpDomainMass = FormsIntegrators<DomainEleOp>::Assembly<
429 fe_child_ptr->getOpPtrVector().push_back(
431 using OpVec = FormsIntegrators<DomainEleOp>::Assembly<
433 fe_child_ptr->getOpPtrVector().push_back(
442 auto fe_child_ptr = get_child_op(
feRhs->getOpPtrVector());
445 CHKERR dg_projection_base(fe_child_ptr, get_field_eval_op(fe_child_ptr));
447 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"Before looping FEs";
448 CHKERR DMoFEMLoopFiniteElementsUpAndLowRank(
453 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"After looping RHS";
462 SmartPetscObj<DM> &sub_dm, SmartPetscObj<DM> &intermediate_dm,
463 BitRefLevel parent_bit, BitRefLevel child_bit, PetscInt num_vecs,
464 Vec vecs_to_map_from[], Vec vecs_to_map_to[]) {
469 auto post_proc = [&](
auto dm, std::string file_name) {
472 auto T_ptr = boost::make_shared<VectorDouble>();
473 auto TAU_ptr = boost::make_shared<VectorDouble>();
474 auto EP_ptr = boost::make_shared<MatrixDouble>();
476 auto U_ptr = boost::make_shared<MatrixDouble>();
477 auto FLUX_ptr = boost::make_shared<MatrixDouble>();
479 auto post_proc_fe = boost::make_shared<PostProcEle>(
m_field);
481 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
483 post_proc_fe->getOpPtrVector().push_back(
484 new OpCalculateScalarFieldValues(
"T", T_ptr));
485 post_proc_fe->getOpPtrVector().push_back(
486 new OpCalculateScalarFieldValues(
"TAU", TAU_ptr));
487 post_proc_fe->getOpPtrVector().push_back(
488 new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
"EP", EP_ptr));
489 post_proc_fe->getOpPtrVector().push_back(
490 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", U_ptr));
491 post_proc_fe->getOpPtrVector().push_back(
492 new OpCalculateHVecVectorField<3, SPACE_DIM>(
"FLUX", FLUX_ptr));
494 post_proc_fe->getOpPtrVector().push_back(
new OpPPMap(
495 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
497 {{
"T", T_ptr}, {
"TAU", TAU_ptr}},
499 {{
"U", U_ptr}, {
"FLUX", FLUX_ptr}},
509 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Just before looping post_proc_fe";
511 CHKERR DMoFEMLoopFiniteElementsUpAndLowRank(dm,
simple->getDomainFEName(),
514 auto &post_proc_moab = post_proc_fe->getPostProcMesh();
515 auto output_name =
"out_all_rank_" +
518 CHKERR post_proc_moab.write_file(output_name.c_str());
521 CHKERR DMoFEMLoopFiniteElementsUpAndLowRank(
524 auto &post_proc_moab = post_proc_fe->getPostProcMesh();
525 auto output_name =
"out_only_on_rank" +
528 CHKERR post_proc_moab.write_file(output_name.c_str());
534 auto null_fe = boost::shared_ptr<FEMethod>();
543 auto vec = createDMVector(sub_dm);
545 CHKERR VecGetSize(vec, &size);
546 SmartPetscObj<Mat> mat;
548 mat = createDMMatrix(sub_dm);
549 auto sol = createDMVector(sub_dm);
551 auto ksp = createKSP(m_field.get_comm());
552 CHKERR KSPSetOperators(ksp, mat, mat);
553 CHKERR KSPSetFromOptions(ksp);
559 PetscData::CtxSetF | PetscData::CtxSetA | PetscData::CtxSetB;
565 auto tmp_D = createDMVector(intermediate_dm);
566 CHKERR DMoFEMMeshToLocalVector(intermediate_dm, tmp_D, INSERT_VALUES,
568 CHKERR VecGhostUpdateBegin(tmp_D, INSERT_VALUES, SCATTER_FORWARD);
569 CHKERR VecGhostUpdateEnd(tmp_D, INSERT_VALUES, SCATTER_FORWARD);
571 for (
int i = 0;
i < num_vecs; ++
i) {
573 CHKERR VecGhostUpdateBegin(vecs_to_map_from[
i], INSERT_VALUES,
575 CHKERR VecGhostUpdateEnd(vecs_to_map_from[
i], INSERT_VALUES,
577 CHKERR DMoFEMMeshToGlobalVector(intermediate_dm, vecs_to_map_from[
i],
578 INSERT_VALUES, SCATTER_REVERSE);
581 CHKERR MatZeroEntries(mat);
582 CHKERR VecZeroEntries(vec);
583 CHKERR VecGhostUpdateBegin(vec, INSERT_VALUES, SCATTER_FORWARD);
584 CHKERR VecGhostUpdateEnd(vec, INSERT_VALUES, SCATTER_FORWARD);
586 CHKERR projectResults(parent_bit, child_bit);
589 CHKERR VecAssemblyBegin(vec);
590 CHKERR VecAssemblyEnd(vec);
591 CHKERR MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);
592 CHKERR MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);
594 CHKERR KSPSolve(ksp, vec, sol);
595 CHKERR VecGhostUpdateBegin(sol, INSERT_VALUES, SCATTER_FORWARD);
596 CHKERR VecGhostUpdateEnd(sol, INSERT_VALUES, SCATTER_FORWARD);
597 CHKERR DMoFEMMeshToGlobalVector(sub_dm, sol, INSERT_VALUES,
603 INSERT_VALUES, SCATTER_FORWARD);
604 CHKERR VecGhostUpdateBegin(vecs_to_map_to[
i], INSERT_VALUES,
606 CHKERR VecGhostUpdateEnd(vecs_to_map_to[
i], INSERT_VALUES, SCATTER_FORWARD);
608 CHKERR post_proc(intermediate_dm,
"map_" + std::to_string(
i));
614 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"Mapped thermoplastic state variables";