23 boost::shared_ptr<FEMethod> fe_ptr,
24 bool is_spatial_positions)
25 : mField(m_field), fePtr(fe_ptr), isSpatialPositions(is_spatial_positions) {
29 Interface &m_field,
const char *file_name,
const char *options) {
38 constexpr
bool is_debug =
false;
44 CHKERR moab.get_entities_by_handle(0, all_ents,
false);
46 auto print_range_on_procs = [&](
const Range &range, std::string name) {
49 << name <<
" on proc [" << m_field.
get_comm_rank() <<
"] : \n"
54 auto save_range_to_file = [&](
const Range range, std::string name =
"part") {
58 ss <<
"out_" << name <<
"_" << rr <<
".vtk";
59 MOFEM_LOG(
"SELF", Sev::inform) <<
"Save debug part mesh " << ss.str();
61 CHKERR moab.create_meshset(MESHSET_SET, meshset);
62 CHKERR moab.add_entities(meshset, range);
64 CHKERR moab.write_file(ss.str().c_str(),
"VTK",
"", &meshset, 1);
65 CHKERR moab.delete_entities(&meshset, 1);
68 auto master_meshset_ptr =
70 std::regex((boost::format(
"%s(.*)") %
"MPC_(.*)_LINKS").str()));
71 Range mpc_ents, links_ents;
72 for (
auto m : master_meshset_ptr) {
75 CHKERR moab.get_entities_by_handle(
m->getMeshset(), ents,
true);
77 links_ents.merge(ents);
78 for (
auto &link : links_ents) {
80 CHKERR moab.get_connectivity(&link, 1, verts,
true);
81 mpc_ents.merge(verts);
89 save_range_to_file(all_ents,
"all_ents");
90 print_range_on_procs(mpc_ents,
"mpc_ents");
91 print_range_on_procs(links_ents,
"links_ents");
93 const int dim =
simple->getDim();
98 pcomm =
new ParallelComm(&moab, PETSC_COMM_WORLD);
100 Tag part_tag = pcomm->part_tag();
101 Range tagged_sets, proc_ents, off_proc_ents, all_proc_ents;
103 CHKERR moab.get_entities_by_type_and_tag(0, MBENTITYSET, &part_tag, NULL, 1,
104 tagged_sets, moab::Interface::UNION);
105 print_range_on_procs(tagged_sets,
"tagged_sets");
106 for (
auto &mit : tagged_sets) {
108 CHKERR moab.tag_get_data(part_tag, &mit, 1, &part);
111 CHKERR moab.get_entities_by_dimension(mit, dim, proc_ents,
true);
112 CHKERR moab.get_entities_by_handle(mit, all_proc_ents,
true);
114 CHKERR moab.get_entities_by_handle(mit, off_proc_ents,
true);
118 print_range_on_procs(proc_ents,
"proc_ents");
120 save_range_to_file(proc_ents);
121 save_range_to_file(off_proc_ents,
"all_proc_ents");
122 all_proc_ents = subtract(all_proc_ents, links_ents);
125 CHKERR moab.get_entities_by_handle(0, all_tets,
true);
129 CHKERR skin.find_skin(0, all_tets.subset_by_dimension(dim),
false, tets_skin);
133 Range proc_ents_skin[4];
134 CHKERR skin.find_skin(0, proc_ents,
false, proc_ents_skin[dim - 1]);
137 Range skin_verts, verts_to_add, edges_to_add;
138 CHKERR moab.get_connectivity(proc_ents_skin[dim - 1],
140 for (
auto &link : links_ents) {
142 CHKERR moab.get_connectivity(&link, 1, verts);
143 for (
auto &vert : verts)
144 if (skin_verts.find(vert) != skin_verts.end()) {
145 edges_to_add.insert(link);
146 verts_to_add.merge(verts);
151 proc_ents_skin[dim - 1] = subtract(proc_ents_skin[dim - 1], tets_skin);
157 CHKERR moab.get_adjacencies(proc_ents_skin[2], 1,
false, proc_ents_skin[1],
158 moab::Interface::UNION);
161 CHKERR moab.get_connectivity(proc_ents_skin[1], adj_ents,
true);
162 proc_ents_skin[0].merge(adj_ents);
164 proc_ents_skin[1].merge(edges_to_add);
165 proc_ents_skin[0].merge(verts_to_add);
167 print_range_on_procs(edges_to_add,
"edges_to_add");
168 print_range_on_procs(verts_to_add,
"verts_to_add");
174 save_range_to_file(proc_ents,
"proc_ents");
175 save_range_to_file(off_proc_ents,
"off_proc_ents");
177 all_tets = off_proc_ents;
179 if (edges_to_add.empty())
180 all_tets.merge(links_ents);
182 save_range_to_file(proc_ents_skin[0],
"proc_ents_skin0");
183 save_range_to_file(proc_ents_skin[1],
"proc_ents_skin1");
185 for (
int dd = dim;
dd >= 0; --
dd) {
186 all_tets = subtract(all_tets, proc_ents_skin[
dd]);
188 print_range_on_procs(proc_ents,
"proc_ents");
191 CHKERR moab.get_entities_by_type(0, MBENTITYSET, meshsets,
true);
192 for (
auto m : meshsets) {
193 CHKERR moab.remove_entities(
m, all_tets);
196 print_range_on_procs(all_tets.subset_by_dimension(2),
"all_tets to delete");
197 save_range_to_file(all_tets.subset_by_dimension(2),
"part_delete");
200 for (
int dd = dim;
dd > 0; --
dd) {
201 CHKERR moab.delete_entities(all_tets.subset_by_dimension(
dd));
207 CHKERR moab.get_entities_by_handle(0, all_ents);
208 std::vector<unsigned char> pstat_tag(all_ents.size(), 0);
209 save_range_to_file(all_ents,
"all_ents_part");
210 CHKERR moab.tag_set_data(pcomm->pstatus_tag(), all_ents,
211 &*pstat_tag.begin());
214 Range all_ents_before;
215 CHKERR moab.get_entities_by_handle(0, all_ents_before);
216 save_range_to_file(all_ents_before,
"all_ents_part_before");
218 CHKERR pcomm->resolve_shared_ents(0, proc_ents, dim, -1, proc_ents_skin);
220 Range all_ents_after;
221 CHKERR moab.get_entities_by_handle(0, all_ents_after);
222 save_range_to_file(all_ents_after,
"all_ents_part_after");
229 vector<std::string> field_names) {
236 std::array<double, 9> def;
237 std::fill(def.begin(), def.end(), 0);
239 auto get_tag = [&](
const std::string name,
size_t size) {
241 size = size <= 1 ? 1 : (size <= 3 ? 3 : 9);
242 CHKERR post_proc_mesh_interface.tag_get_handle(
243 name.c_str(), size, MB_TYPE_DOUBLE,
th, MB_TAG_CREAT | MB_TAG_SPARSE,
249 auto master_meshset_ptr =
251 std::regex((boost::format(
"%s(.*)") %
"MPC_(.*)_LINKS").str()));
253 for (
auto m : master_meshset_ptr) {
255 CHKERR m_field.
get_moab().get_entities_by_type(
m->getMeshset(), MBEDGE,
257 links_ents.merge(ents);
260 if(links_ents.empty()) {
265 std::vector<EntityHandle> p_links_edges(links_ents.size());
266 std::vector<EntityHandle> o_nodes(links_ents.size() * 2);
267 std::vector<EntityHandle> p_nodes(links_ents.size() * 2);
270 for (
auto &link : links_ents) {
272 CHKERR m_field.
get_moab().get_connectivity(&link, 1, verts,
true);
273 ublas::vector<EntityHandle> edge_conn(2);
275 for (
auto &vert : verts) {
279 CHKERR post_proc_mesh_interface.create_vertex(&coords[0], edge_conn[gg]);
280 o_nodes[
dd * 2 + gg] = vert;
281 p_nodes[
dd * 2 + gg] = edge_conn[gg];
285 CHKERR post_proc_mesh_interface.create_element(MBEDGE, &edge_conn[0], 2,
286 p_links_edges[
dd++]);
293 for (
auto field : field_names) {
296 Tag tag = get_tag(field, nb_coefficients);
299 for (
auto &node : o_nodes) {
303 if (eit != field_ents_by_uid.end()) {
304 noalias(data) = (*eit)->getEntFieldData();
306 auto ent = p_nodes[gg++];
307 post_proc_mesh_interface.tag_set_data(tag, &ent, 1, &*data.begin());
318 if (isSpatialPositions) {
323 <<
"EssentialPreProc<MPCsType> has no effect here. ";
331 : mField(m_field), fePtr(fe_ptr), vDiag(diag), vLhs(lhs), vAO(ao) {}
337 if (
auto fe_ptr = fePtr.lock()) {
339 auto bc_mng = mField.getInterface<
BcManager>();
341 const auto problem_name = fe_ptr->problemPtr->getName();
342 bool do_assembly =
false;
343 for (
auto bc : bc_mng->getBcMapByBlockName()) {
344 if (
auto mpc_bc = bc.second->mpcPtr) {
346 auto &bc_id = bc.first;
348 auto regex_str = (boost::format(
"%s_(.*)") % problem_name).str();
349 if (std::regex_match(bc_id, std::regex(regex_str))) {
354 auto get_field_coeffs = [&](
auto field_name) {
355 auto field_ptr = mField.get_field_structure(
field_name);
356 return field_ptr->getNbOfCoeffs();
359 const auto nb_field_coeffs = get_field_coeffs(
field_name);
360 constexpr
auto max_nb_dofs_per_node = 6;
362 if (nb_field_coeffs > max_nb_dofs_per_node)
364 <<
"MultiPointConstraints PreProcLhs<MPCsType>: support only "
365 "up to 6 dofs per node.";
367 <<
"Apply MultiPointConstraints PreProc<MPCsType>: "
368 << problem_name <<
"_" <<
field_name <<
"_" << block_name;
370 auto mpc_type = mpc_bc->mpcType;
378 "MPC type not implemented");
382 auto master_verts = mpc_bc->mpcMasterEnts.subset_by_type(MBVERTEX);
383 auto slave_verts = mpc_bc->mpcSlaveEnts.subset_by_type(MBVERTEX);
385 auto prb_name = fe_ptr->problemPtr->getName();
386 auto get_flag = [&](
int idx) {
return (&mpc_bc->data.flag1)[idx]; };
388 <<
"Size of master nodes: " << mpc_bc->mpcMasterEnts.size()
389 <<
" Size of slave nodes : " << mpc_bc->mpcSlaveEnts.size();
391 if (mpc_bc->mpcMasterEnts.size() > mpc_bc->mpcSlaveEnts.size()) {
393 <<
"Size of master nodes < Size of slave nodes : "
394 << mpc_bc->mpcMasterEnts.size() <<
" > " << mpc_bc->mpcSlaveEnts.size();
399 auto add_is = [](
auto is1,
auto is2) {
411 for (
int dd = 0;
dd != nb_field_coeffs;
dd++) {
414 CHKERR is_mng->isCreateProblemFieldAndRank(
417 CHKERR is_mng->isCreateProblemFieldAndRank(
420 CHKERR is_mng->isCreateProblemFieldAndRank(
423 CHKERR is_mng->isCreateProblemFieldAndRank(
429 if (!mpc_bc->isReprocitical) {
430 if (!is_xyz_row_sum) {
431 is_xyz_row_sum = is_s_row[
dd];
433 is_xyz_row_sum = add_is(is_xyz_row_sum, is_s_row[
dd]);
444 CHKERR MatGetType(B, &typem);
445 CHKERR MatSetOption(B, MAT_NEW_NONZERO_LOCATIONS, PETSC_TRUE);
446 PetscBool is_mat_baij = PETSC_FALSE;
447 PetscObjectTypeCompare((PetscObject)B, MATMPIBAIJ, &is_mat_baij);
449 CHKERR MatSetOption(B, MAT_USE_HASH_TABLE, PETSC_TRUE);
450 if ((*fe_ptr->matAssembleSwitch) && !vLhs) {
451 if (*fe_ptr->matAssembleSwitch) {
452 CHKERR MatAssemblyBegin(B, MAT_FLUSH_ASSEMBLY);
453 CHKERR MatAssemblyEnd(B, MAT_FLUSH_ASSEMBLY);
454 *fe_ptr->matAssembleSwitch =
false;
459 MOFEM_LOG(
"WORLD", Sev::error) <<
"No support for AO yet";
462 CHKERR MatZeroRowsIS(B, is_xyz_row_sum, 0, PETSC_NULL,
465 auto set_mat_values = [&](
auto row_is,
auto col_is,
double val,
double perturb = 0) {
467 const int *row_index_ptr;
468 CHKERR ISGetIndices(row_is, &row_index_ptr);
469 const int *col_index_ptr;
470 CHKERR ISGetIndices(col_is, &col_index_ptr);
471 int row_size, col_size;
472 CHKERR ISGetLocalSize(row_is, &row_size);
473 CHKERR ISGetLocalSize(col_is, &col_size);
476 fill(locMat.data().begin(), locMat.data().end(), 0.0);
477 for (
int i = 0;
i != row_size;
i++)
478 for (
int j = 0;
j != col_size;
j++)
479 if (
i ==
j || col_size == 1)
482 if (mpc_bc->isReprocitical) {
485 col_index_ptr, &*locMat.data().begin(),
489 col_index_ptr, &*locMat.data().begin(),
493 CHKERR ISRestoreIndices(row_is, &row_index_ptr);
494 CHKERR ISRestoreIndices(col_is, &col_index_ptr);
499 for (
int dd = 0;
dd != nb_field_coeffs;
dd++) {
502 if (!mpc_bc->isReprocitical) {
503 CHKERR set_mat_values(is_s_row[
dd], is_s_col[
dd], vDiag);
504 CHKERR set_mat_values(is_s_row[
dd], is_m_col[
dd], -vDiag);
508 auto &pn = mpc_bc->mPenalty;
509 CHKERR set_mat_values(is_s_row[
dd], is_s_col[
dd], vDiag, pn);
510 CHKERR set_mat_values(is_s_row[
dd], is_m_col[
dd], -vDiag, pn);
511 CHKERR set_mat_values(is_m_row[
dd], is_m_col[
dd], vDiag, pn);
512 CHKERR set_mat_values(is_m_row[
dd], is_s_col[
dd], -vDiag, pn);
521 CHKERR MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);
522 CHKERR MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);
527 "Can not lock shared pointer");
535 : mField(m_field), fePtr(fe_ptr), vDiag(diag), vRhs(rhs) {}
541 if (
auto fe_method_ptr = fePtr.lock()) {
543 auto bc_mng = mField.getInterface<
BcManager>();
546 const auto problem_name = fe_method_ptr->problemPtr->getName();
548 for (
auto bc : bc_mng->getBcMapByBlockName()) {
549 if (
auto mpc_bc = bc.second->mpcPtr) {
551 auto &bc_id = bc.first;
553 auto regex_str = (boost::format(
"%s_(.*)") % problem_name).str();
554 if (std::regex_match(bc_id, std::regex(regex_str))) {
559 auto get_field_coeffs = [&](
auto field_name) {
560 auto field_ptr = mField.get_field_structure(
field_name);
561 return field_ptr->getNbOfCoeffs();
564 const auto nb_field_coeffs = get_field_coeffs(
field_name);
565 constexpr
auto max_nb_dofs_per_node = 6;
567 if (nb_field_coeffs > max_nb_dofs_per_node)
569 <<
"MultiPointConstraints PreProcLhs<MPCsType>: support only "
570 "up to 6 dofs per node for now.";
573 <<
"Apply MultiPointConstraints PreProc<MPCsType>: "
574 << problem_name <<
"_" <<
field_name <<
"_" << block_name;
576 auto mpc_type = mpc_bc->mpcType;
584 "MPC type not implemented");
587 auto master_verts = mpc_bc->mpcMasterEnts.subset_by_type(MBVERTEX);
588 auto slave_verts = mpc_bc->mpcSlaveEnts.subset_by_type(MBVERTEX);
590 auto prb_name = fe_method_ptr->problemPtr->getName();
592 auto get_flag = [&](
int idx) {
return (&mpc_bc->data.flag1)[idx]; };
597 for (
int dd = 0;
dd != nb_field_coeffs;
dd++) {
600 CHKERR is_mng->isCreateProblemFieldAndRankLocal(
602 CHKERR is_mng->isCreateProblemFieldAndRankLocal(
610 if (
auto fe_ptr = fePtr.lock()) {
611 auto snes_ctx = fe_ptr->snes_ctx;
612 auto ts_ctx = fe_ptr->ts_ctx;
616 const int contrb = mpc_bc->isReprocitical ? 1 : 0;
620 if (fe_ptr->vecAssembleSwitch) {
621 if ((*fe_ptr->vecAssembleSwitch) && !vRhs) {
622 CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
623 CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
626 *fe_ptr->vecAssembleSwitch =
false;
630 auto vec_set_values = [&](
auto is_xyz_m,
auto is_xyz_s,
double val) {
632 const int *m_index_ptr;
633 CHKERR ISGetIndices(is_xyz_m, &m_index_ptr);
634 const int *s_index_ptr;
635 CHKERR ISGetIndices(is_xyz_s, &s_index_ptr);
637 CHKERR ISGetLocalSize(is_xyz_m, &size_m);
639 CHKERR ISGetLocalSize(is_xyz_s, &size_s);
655 CHKERR vec_mng->setLocalGhostVector(problem_name,
ROW,
656 tmp_x, INSERT_VALUES,
661 CHKERR VecGetArrayRead(tmp_x, &u);
663 if (size_m && size_s) {
664 for (
auto i = 0;
i != size_s; ++
i) {
665 auto m_idx = size_m == 1 ? 0 :
i;
666 f[s_index_ptr[
i]] = val * (
v[s_index_ptr[
i]] -
v[m_index_ptr[m_idx]]) +
f[s_index_ptr[
i]] * contrb ;
669 CHKERR VecRestoreArrayRead(x, &
v);
670 CHKERR VecRestoreArrayRead(tmp_x, &u);
672 if (size_m && size_s)
673 for (
auto i = 0;
i != size_s; ++
i) {
674 f[s_index_ptr[
i]] = 0;
679 CHKERR ISRestoreIndices(is_xyz_m, &m_index_ptr);
680 CHKERR ISRestoreIndices(is_xyz_s, &s_index_ptr);
685 for (
int dd = 0;
dd != nb_field_coeffs;
dd++)
688 if (!mpc_bc->isReprocitical) {
689 CHKERR vec_set_values(is_m[
dd], is_s[
dd], vDiag);
691 auto &pn = mpc_bc->mPenalty;
692 CHKERR vec_set_values(is_m[
dd], is_s[
dd], pn);
693 CHKERR vec_set_values(is_s[
dd], is_m[
dd], pn);
709 "Can not lock shared pointer");