13 #include <petscerror.h> 14 #include <petsc/private/dmimpl.h> 26 #include "libmesh/nonlinear_implicit_system.h" 27 #include "libmesh/nonlinear_solver.h" 28 #include "libmesh/petsc_macro.h" 29 #include "libmesh/petsc_vector.h" 30 #include "libmesh/petsc_matrix.h" 31 #include "libmesh/dof_map.h" 32 #include "libmesh/preconditioner.h" 33 #include "libmesh/elem_side_builder.h" 35 template <
typename I1,
typename I2>
37 checkSize(
const std::string & split_name,
const I1 split_size,
const I2 size_expected_by_parent)
39 if (libMesh::cast_int<libMesh::numeric_index_type>(split_size) !=
40 libMesh::cast_int<libMesh::numeric_index_type>(size_expected_by_parent))
44 libMesh::cast_int<libMesh::numeric_index_type>(split_size),
45 " but the parent split expected size ",
46 libMesh::cast_int<libMesh::numeric_index_type>(size_expected_by_parent),
47 ". Make sure that you have non-overlapping complete sets for variables and " 48 "blocks as well as consistency in sides/unsides, contacts/uncontacts, etc.");
56 std::map<std::string, unsigned int> *
_var_ids;
75 typedef std::pair<BoundaryID, BoundaryID>
ContactID;
95 std::map<std::string, SplitInfo> *
_splits;
106 void checkChildSize(DM child, PetscInt child_size,
const std::string & child_name);
113 if (
split.second._dm == child)
115 mooseAssert(
split.first == child_name,
"These should match");
116 PetscInt parent_expected_size;
117 auto ierr = ISGetLocalSize(
split.second._rembedding, &parent_expected_size);
120 checkSize(child_name, child_size, parent_expected_size);
134 PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
135 ierr = PetscObjectTypeCompare((PetscObject)dm, DMMOOSE, &ismoose);
138 LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
140 "Got DM of type %s, not of type %s",
141 ((PetscObject)dm)->type_name,
143 PetscFunctionReturn(0);
148 std::vector<std::pair<std::string, std::string>> & contact_names,
149 std::vector<PetscBool> & displaced)
159 contact_names.push_back(it.second);
162 PetscFunctionReturn(0);
167 std::vector<std::pair<std::string, std::string>> & uncontact_names,
168 std::vector<PetscBool> & displaced)
178 uncontact_names.push_back(it.second);
181 PetscFunctionReturn(0);
193 for (
const auto & it : *(dmm->
_side_ids))
194 side_names.push_back(it.first);
195 PetscFunctionReturn(0);
208 side_names.push_back(it.first);
209 PetscFunctionReturn(0);
222 block_names.push_back(it.first);
223 PetscFunctionReturn(0);
235 for (
const auto & it : *(dmm->
_var_ids))
236 var_names.push_back(it.first);
237 PetscFunctionReturn(0);
249 SETERRQ(((PetscObject)dm)->comm,
250 PETSC_ERR_ARG_WRONGSTATE,
251 "Cannot reset the NonlinearSystem after DM has been set up.");
254 PetscFunctionReturn(0);
266 SETERRQ(((PetscObject)dm)->comm,
267 PETSC_ERR_ARG_WRONGSTATE,
268 "Cannot reset the MOOSE DM name after DM has been set up.");
270 *dmm->
_name = dm_name;
271 PetscFunctionReturn(0);
283 SETERRQ(((PetscObject)dm)->comm,
284 PETSC_ERR_ARG_WRONGSTATE,
285 "Cannot reset the parent DM after the child DM has been set up.");
289 PetscFunctionReturn(0);
302 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Not for an already setup DM");
305 std::set<std::string> processed_vars;
306 for (
const auto & var_name : vars)
308 const auto *
const var =
316 processed_vars.insert(var_name);
319 dmm->
_vars =
new std::set<std::string>(std::move(processed_vars));
320 PetscFunctionReturn(0);
333 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Not for an already setup DM");
336 dmm->
_blocks =
new std::set<std::string>(blocks);
337 PetscFunctionReturn(0);
350 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Not for an already setup DM");
353 dmm->
_sides =
new std::set<std::string>(sides);
354 PetscFunctionReturn(0);
367 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Not for an already setup DM");
370 dmm->
_unsides =
new std::set<std::string>(unsides);
371 PetscFunctionReturn(0);
384 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Not for an already setup DM");
388 PetscFunctionReturn(0);
393 const std::vector<std::pair<std::string, std::string>> & contacts,
394 const std::vector<PetscBool> & displaced)
403 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Not for an already setup DM");
404 if (contacts.size() != displaced.size())
405 LIBMESH_SETERRQ2(PETSC_COMM_SELF,
407 "Nonmatching sizes of the contact and displaced arrays: %" LIBMESH_PETSCINT_FMT
408 " != %" LIBMESH_PETSCINT_FMT,
409 static_cast<PetscInt>(contacts.size()),
410 static_cast<PetscInt>(displaced.size()));
414 dmm->
_contacts =
new std::set<DM_Moose::ContactName>();
415 for (
unsigned int i = 0; i < contacts.size(); ++i)
420 PetscFunctionReturn(0);
425 const std::vector<std::pair<std::string, std::string>> & uncontacts,
426 const std::vector<PetscBool> & displaced)
435 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Not for an already setup DM");
436 if (uncontacts.size() != displaced.size())
440 "Nonmatching sizes of the uncontact and displaced arrays: %" LIBMESH_PETSCINT_FMT
441 " != %" LIBMESH_PETSCINT_FMT,
442 static_cast<PetscInt>(uncontacts.size()),
443 static_cast<PetscInt>(displaced.size()));
447 dmm->
_uncontacts =
new std::set<DM_Moose::ContactName>();
448 for (
unsigned int i = 0; i < uncontacts.size(); ++i)
453 PetscFunctionReturn(0);
466 PetscFunctionReturn(0);
481 for (
auto & it : *(dmm->
_splits))
483 ierr = DMDestroy(&(it.second._dm));
485 ierr = ISDestroy(&(it.second._rembedding));
489 dmm->
_splits = LIBMESH_PETSC_NULLPTR;
496 dmm->
_splits =
new std::map<std::string, DM_Moose::SplitInfo>();
497 dmm->
_splitlocs =
new std::multimap<std::string, unsigned int>();
498 for (
unsigned int i = 0; i < split_names.size(); ++i)
501 info.
_dm = LIBMESH_PETSC_NULLPTR;
502 info._rembedding = LIBMESH_PETSC_NULLPTR;
503 std::string
name = split_names[i];
507 PetscFunctionReturn(0);
519 if (!dm->setupcalled)
520 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"DM not set up");
526 std::string sname = lit.first;
527 unsigned int sloc = lit.second;
528 split_names[sloc] = sname;
530 PetscFunctionReturn(0);
533 static PetscErrorCode
541 PetscFunctionReturn(0);
570 DofMap & dofmap = dmm->
_nl->
system().get_dof_map();
572 std::vector<dof_id_type> node_indices;
573 auto process_nodal_dof_indices =
574 [&dofmap, &node_indices](
const Node & node,
575 const unsigned int var_num,
576 std::set<dof_id_type> & local_indices,
577 std::set<dof_id_type> *
const nonlocal_indices =
nullptr)
579 dofmap.dof_indices(&node, node_indices, var_num);
580 for (
const auto index : node_indices)
582 if (index >= dofmap.first_dof() && index < dofmap.end_dof())
583 local_indices.insert(index);
584 else if (nonlocal_indices)
585 nonlocal_indices->insert(index);
589 auto process_elem_dof_indices =
590 [&dofmap](
const std::vector<dof_id_type> & elem_indices,
591 std::set<dof_id_type> & local_indices,
592 std::set<dof_id_type> *
const nonlocal_indices =
nullptr)
594 for (
const auto index : elem_indices)
596 if (index >= dofmap.first_dof() && index < dofmap.end_dof())
597 local_indices.insert(index);
598 else if (nonlocal_indices)
599 nonlocal_indices->insert(index);
603 std::set<dof_id_type> indices;
604 std::set<dof_id_type> unindices;
605 std::set<dof_id_type> cached_indices;
606 std::set<dof_id_type> cached_unindices;
607 auto & lm_mesh = dmm->
_nl->
system().get_mesh();
609 for (
const auto & vit : *(dmm->
_var_ids))
611 unsigned int v = vit.second;
617 for (
const auto & elem :
as_range(lm_mesh.active_local_subdomain_elements_begin(b),
618 lm_mesh.active_local_subdomain_elements_end(b)))
621 std::vector<dof_id_type> evindices;
622 dofmap.dof_indices(elem, evindices, v);
623 process_elem_dof_indices(evindices, indices);
628 bool is_on_current_block =
false;
629 for (
auto & node : lm_mesh.local_node_ptr_range())
631 const unsigned int n_comp = node->n_comp(dmm->
_nl->
system().number(), v);
637 auto node_to_elem_pair = node_to_elem_map.find(node->id());
638 is_on_current_block =
false;
639 for (
const auto & elem_num : node_to_elem_pair->second)
643 Elem & neighbor_elem = lm_mesh.elem_ref(elem_num);
644 if (neighbor_elem.subdomain_id() == b)
646 is_on_current_block =
true;
651 if (!is_on_current_block)
654 process_nodal_dof_indices(*node, v, indices);
675 for (
const auto & bnode : bnodes)
681 const Node * node = bnode->_node;
682 process_nodal_dof_indices(*node, v, indices);
690 for (
const auto & bnode : bnodes)
695 const Node * node = bnode->_node;
696 process_nodal_dof_indices(*node, v, unindices);
701 std::set<BoundaryID> eligible_bids;
704 eligible_bids.insert(bid);
707 for (
const auto & bnode : bnodes)
710 if (eligible_bids.count(boundary_id))
712 const Node * node = bnode->_node;
713 process_nodal_dof_indices(*node, v, unindices);
718 auto process_contact_all_nodes =
719 [dmm, process_nodal_dof_indices, v](
const auto & contact_names,
720 auto & indices_to_insert_to)
722 std::set<boundary_id_type> bc_id_set;
724 for (
const auto & [contact_bid_pair, contact_bname_pair] : contact_names)
727 bc_id_set.insert(contact_bid_pair.first);
728 bc_id_set.insert(contact_bid_pair.second);
732 for (
const auto & belem : range)
734 const Elem * elem_bdry = belem->_elem;
735 const auto side = belem->_side;
738 if (bc_id_set.find(boundary_id) == bc_id_set.end())
741 for (
const auto node_idx : elem_bdry->node_index_range())
742 if (elem_bdry->is_node_on_side(node_idx, side))
743 process_nodal_dof_indices(elem_bdry->node_ref(node_idx), v, indices_to_insert_to);
747 auto process_contact_some_nodes =
748 [dmm, process_nodal_dof_indices, v, &dofmap, &lm_mesh, process_elem_dof_indices](
749 const auto & contact_names,
750 auto & indices_to_insert_to,
751 auto & nonlocal_indices_to_insert_to)
753 std::vector<dof_id_type> evindices;
754 for (
const auto & it : contact_names)
760 std::shared_ptr<DisplacedProblem> displaced_problem =
762 if (!displaced_problem)
764 std::ostringstream
err;
765 err <<
"Cannot use a displaced uncontact (" << it.second.first <<
"," 766 << it.second.second <<
") with an undisplaced problem";
769 locator = displaced_problem->geomSearchData()._penetration_locators[it.first];
776 auto lend = locator->_penetration_info.end();
777 for (
auto lit = locator->_penetration_info.begin(); lit != lend; ++lit)
783 Node & secondary_node = lm_mesh.node_ref(secondary_node_num);
784 process_nodal_dof_indices(
785 secondary_node, v, indices_to_insert_to, &nonlocal_indices_to_insert_to);
789 const Elem * primary_side = pinfo->
_side;
790 dofmap.dof_indices(primary_side, evindices, v);
791 process_elem_dof_indices(
792 evindices, indices_to_insert_to, &nonlocal_indices_to_insert_to);
804 process_contact_some_nodes(*dmm->
_contact_names, indices, cached_indices);
812 process_contact_some_nodes(*dmm->
_uncontact_names, unindices, cached_unindices);
815 std::vector<dof_id_type> local_vec_indices(cached_indices.size());
816 std::copy(cached_indices.begin(), cached_indices.end(), local_vec_indices.begin());
820 for (
const auto & dof : local_vec_indices)
821 if (dof >= dofmap.first_dof() && dof < dofmap.end_dof())
824 local_vec_indices.clear();
825 local_vec_indices.resize(cached_unindices.size());
826 std::copy(cached_unindices.begin(), cached_unindices.end(), local_vec_indices.begin());
830 for (
const auto & dof : local_vec_indices)
831 if (dof >= dofmap.first_dof() && dof < dofmap.end_dof())
832 unindices.insert(dof);
834 std::set<dof_id_type> dindices;
835 std::set_difference(indices.begin(),
839 std::inserter(dindices, dindices.end()));
841 ierr = PetscMalloc(
sizeof(PetscInt) * dindices.size(), &darray);
844 for (
const auto & dof : dindices)
849 ierr = ISCreateGeneral(
850 ((PetscObject)dm)->comm, dindices.size(), darray, PETSC_OWN_POINTER, &dmm->
_embedding);
861 ierr = DMCreateGlobalVector(dm, &v);
863 ierr = VecGetOwnershipRange(v, &low, &high);
865 ierr = ISCreateStride(((PetscObject)dm)->comm, (high - low), low, 1, &dmm->
_embedding);
873 PetscFunctionReturn(0);
876 static PetscErrorCode
878 DM dm, PetscInt * len,
char *** namelist, IS ** islist, DM ** dmlist)
885 PetscInt split_size_sum = 0;
889 PetscFunctionReturn(0);
893 ierr = PetscMalloc(*len *
sizeof(
char *), namelist);
898 ierr = PetscMalloc(*len *
sizeof(IS), islist);
903 ierr = PetscMalloc(*len *
sizeof(DM), dmlist);
908 unsigned int d = dit.second;
909 std::string dname = dit.first;
915 ierr = PetscObjectSetOptionsPrefix((PetscObject)dinfo.
_dm, ((PetscObject)dm)->prefix);
917 std::string suffix = std::string(
"fieldsplit_") + dname +
"_";
918 ierr = PetscObjectAppendOptionsPrefix((PetscObject)dinfo.
_dm, suffix.c_str());
923 ierr = DMSetFromOptions(dinfo.
_dm);
929 ierr = PetscStrallocpy(dname.c_str(), (*namelist) + d);
936 IS dembedding, lembedding;
942 ierr = ISEmbed(dembedding, dmm->
_embedding, PETSC_TRUE, &lembedding);
944 const PetscInt * lindices;
945 PetscInt len, dlen, llen, *rindices, off, i;
946 ierr = ISGetLocalSize(dembedding, &dlen);
948 ierr = ISGetLocalSize(lembedding, &llen);
952 ((PetscObject)dm)->comm, PETSC_ERR_PLIB,
"Failed to embed split %u", d);
953 ierr = ISDestroy(&dembedding);
956 ierr = PetscMalloc(llen *
sizeof(PetscInt), &rindices);
958 ierr = ISGetIndices(lembedding, &lindices);
960 ierr = PetscMemcpy(rindices, lindices, llen *
sizeof(PetscInt));
962 ierr = ISDestroy(&lembedding);
969 ierr = MPI_Scan(&len,
972 #ifdef PETSC_USE_64BIT_INDICES
978 ((PetscObject)dm)->comm);
982 for (i = 0; i < llen; ++i)
984 ierr = ISCreateGeneral(
985 ((PetscObject)dm)->comm, llen, rindices, PETSC_OWN_POINTER, &(dinfo.
_rembedding));
998 split_size_sum += is_size;
1002 ierr = PetscObjectReference((PetscObject)dinfo.
_dm);
1004 (*dmlist)[d] = dinfo.
_dm;
1008 mooseAssert(islist,
"What does it even mean if this is NULL?");
1017 PetscFunctionReturn(0);
1020 static PetscErrorCode
1022 DM dm, PetscInt * len,
char *** namelist, IS ** innerislist, IS ** outerislist, DM ** dmlist)
1024 PetscErrorCode
ierr;
1030 *outerislist = LIBMESH_PETSC_NULLPTR;
1033 PetscFunctionReturn(0);
1036 static PetscErrorCode
1039 PetscErrorCode
ierr;
1048 PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(nl->
system().solution.get());
1049 PetscVector<Number> X_global(x, nl->
comm()), R(r, nl->
comm());
1055 X_global.swap(X_sys);
1057 X_global.swap(X_sys);
1063 nl->
system().get_dof_map().enforce_constraints_exactly(nl->
system(),
1064 nl->
system().current_local_solution.get());
1073 std::ostringstream
err;
1074 err <<
"ERROR: cannot specifiy both a function and object to compute the Residual!" 1080 std::ostringstream
err;
1081 err <<
"ERROR: cannot specifiy both a function and object to compute the combined Residual & " 1100 std::ostringstream
err;
1101 err <<
"No suitable residual computation routine found";
1105 PetscFunctionReturn(0);
1108 static PetscErrorCode
1112 PetscErrorCode
ierr;
1117 PetscFunctionReturn(0);
1120 static PetscErrorCode
1123 PetscErrorCode
ierr;
1130 PetscMatrix<Number> the_pc(pc, nl->
comm());
1131 PetscMatrix<Number> Jac(jac, nl->
comm());
1132 PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(nl->
system().solution.get());
1133 PetscVector<Number> X_global(x, nl->
comm());
1136 the_pc.attach_dof_map(nl->
system().get_dof_map());
1137 Jac.attach_dof_map(nl->
system().get_dof_map());
1143 X_global.swap(X_sys);
1145 X_global.swap(X_sys);
1151 nl->
system().get_dof_map().enforce_constraints_exactly(nl->
system(),
1152 nl->
system().current_local_solution.get());
1161 std::ostringstream
err;
1162 err <<
"ERROR: cannot specifiy both a function and object to compute the Jacobian!" 1168 std::ostringstream
err;
1169 err <<
"ERROR: cannot specifiy both a function and object to compute the combined Residual & " 1187 *(nl->
system().current_local_solution.get()),
1193 std::ostringstream
err;
1194 err <<
"No suitable Jacobian routine or object";
1199 PetscFunctionReturn(0);
1202 static PetscErrorCode
1206 PetscErrorCode
ierr;
1211 PetscFunctionReturn(0);
1214 static PetscErrorCode
1217 PetscErrorCode
ierr;
1224 PetscVector<Number> XL(xl, nl->
comm());
1225 PetscVector<Number> XU(xu, nl->
comm());
1227 ierr = VecSet(xl, PETSC_NINFINITY);
1229 ierr = VecSet(xu, PETSC_INFINITY);
1237 ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG,
"No bounds calculation in this Moose object");
1238 PetscFunctionReturn(0);
1241 static PetscErrorCode
1244 PetscErrorCode
ierr;
1251 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"No Moose system set for DM_Moose");
1254 PetscVector<Number> * pv =
dynamic_cast<PetscVector<Number> *
>(nv);
1262 ierr = VecCreate(((PetscObject)v)->comm, x);
1266 ierr = VecSetSizes(*x, n, PETSC_DETERMINE);
1268 ierr = VecSetType(*x, ((PetscObject)v)->type_name);
1270 ierr = VecSetFromOptions(*x);
1272 ierr = VecSetUp(*x);
1277 ierr = VecDuplicate(v, x);
1281 #if PETSC_RELEASE_LESS_THAN(3, 13, 0) 1282 ierr = PetscObjectCompose((PetscObject)*x,
"DM", (PetscObject)dm);
1285 ierr = VecSetDM(*x, dm);
1288 PetscFunctionReturn(0);
1291 static PetscErrorCode
1294 PetscErrorCode
ierr;
1302 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"No Moose system set for DM_Moose");
1303 ierr = DMGetMatType(dm, &type);
1313 DofMap & dof_map = dmm->
_nl->
system().get_dof_map();
1314 PetscInt M,
N, m, n;
1316 M = dof_map.n_dofs();
1318 m =
static_cast<PetscInt
>(dof_map.n_dofs_on_processor(dmm->
_nl->
system().processor_id()));
1320 ierr = PetscObjectGetComm((PetscObject)dm, &comm);
1322 ierr = MatCreate(comm, A);
1324 ierr = MatSetSizes(*A, m, n, M,
N);
1326 ierr = MatSetType(*A, type);
1331 const std::vector<numeric_index_type> & n_nz = dof_map.get_n_nz();
1332 const std::vector<numeric_index_type> & n_oz = dof_map.get_n_oz();
1333 ierr = MatSeqAIJSetPreallocation(*A, 0, (PetscInt *)(n_nz.empty() ? NULL : &n_nz[0]));
1335 ierr = MatMPIAIJSetPreallocation(*A,
1337 (PetscInt *)(n_nz.empty() ? NULL : &n_nz[0]),
1339 (PetscInt *)(n_oz.empty() ? NULL : &n_oz[0]));
1343 ierr = MatSetUp(*A);
1345 PetscFunctionReturn(0);
1348 static PetscErrorCode
1351 PetscErrorCode
ierr;
1353 const char *
name, *prefix;
1357 ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);
1361 ierr = PetscObjectGetName((PetscObject)dm, &
name);
1363 ierr = PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix);
1365 ierr = PetscViewerASCIIPrintf(viewer,
"DM Moose with name %s and prefix %s\n",
name, prefix);
1367 ierr = PetscViewerASCIIPrintf(viewer,
"variables:");
1369 for (
const auto & vit : *(dmm->
_var_ids))
1371 ierr = PetscViewerASCIIPrintf(viewer,
"(%s,%u) ", vit.first.c_str(), vit.second);
1374 ierr = PetscViewerASCIIPrintf(viewer,
"\n");
1376 ierr = PetscViewerASCIIPrintf(viewer,
"blocks:");
1380 ierr = PetscViewerASCIIPrintf(viewer,
"(%s,%d) ", bit.first.c_str(), bit.second);
1383 ierr = PetscViewerASCIIPrintf(viewer,
"\n");
1388 ierr = PetscViewerASCIIPrintf(viewer,
"sides:");
1390 for (
const auto & sit : *(dmm->
_side_ids))
1392 ierr = PetscViewerASCIIPrintf(viewer,
"(%s,%d) ", sit.first.c_str(), sit.second);
1395 ierr = PetscViewerASCIIPrintf(viewer,
"\n");
1401 ierr = PetscViewerASCIIPrintf(viewer,
"unsides:");
1405 ierr = PetscViewerASCIIPrintf(viewer,
"(%s,%d) ", sit.first.c_str(), sit.second);
1408 ierr = PetscViewerASCIIPrintf(viewer,
"\n");
1414 ierr = PetscViewerASCIIPrintf(viewer,
"contacts:");
1418 ierr = PetscViewerASCIIPrintf(
1419 viewer,
"(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str());
1423 ierr = PetscViewerASCIIPrintf(viewer,
"displaced) ");
1428 ierr = PetscViewerASCIIPrintf(viewer,
"undisplaced) ");
1432 ierr = PetscViewerASCIIPrintf(viewer,
"\n");
1438 ierr = PetscViewerASCIIPrintf(viewer,
"_uncontacts:");
1442 ierr = PetscViewerASCIIPrintf(
1443 viewer,
"(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str());
1447 ierr = PetscViewerASCIIPrintf(viewer,
"displaced) ");
1452 ierr = PetscViewerASCIIPrintf(viewer,
"undisplaced) ");
1456 ierr = PetscViewerASCIIPrintf(viewer,
"\n");
1462 ierr = PetscViewerASCIIPrintf(viewer,
"Field decomposition:");
1467 std::string dname = dit.first;
1468 ierr = PetscViewerASCIIPrintf(viewer,
" %s", dname.c_str());
1471 ierr = PetscViewerASCIIPrintf(viewer,
"\n");
1476 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
"Non-ASCII viewers are not supported");
1478 PetscFunctionReturn(0);
1481 static PetscErrorCode
1484 PetscErrorCode
ierr;
1491 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"No Moose system set for DM_Moose");
1496 libmesh_parallel_only(
mesh.comm());
1497 for (
const auto & elem :
mesh.active_element_ptr_range())
1498 blocks.insert(elem->subdomain_id());
1500 mesh.comm().set_union(blocks);
1501 PetscFunctionReturn(0);
1504 static PetscErrorCode
1507 PetscErrorCode
ierr;
1514 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"No Moose system set for DM_Moose");
1517 DofMap & dofmap = dmm->
_nl->
system().get_dof_map();
1535 dmm->
_sides = LIBMESH_PETSC_NULLPTR;
1552 dmm->
_unsides = LIBMESH_PETSC_NULLPTR;
1563 const auto colon_pos =
name.find(
":");
1564 auto unside_name =
name.substr(0, colon_pos);
1565 auto var_name =
name.substr(colon_pos + 1);
1567 bool var_found =
false;
1568 for (
unsigned int v = 0; v < dofmap.n_variables(); ++v)
1570 const auto & vname = dofmap.variable(v).name();
1571 if (vname == var_name)
1579 mooseError(
"No variable named '", var_name,
"' found");
1590 for (
const auto & cpair : *(dmm->
_contacts))
1596 cpair.first, cpair.second);
1602 std::ostringstream
err;
1603 err <<
"Problem retrieving contact for PenetrationLocator with primary " << cpair.first
1604 <<
" and secondary " << cpair.second;
1624 cpair.first, cpair.second);
1630 std::ostringstream
err;
1631 err <<
"Problem retrieving uncontact for PenetrationLocator with primary " << cpair.first
1632 <<
" and secondary " << cpair.second;
1649 for (
unsigned int v = 0; v < dofmap.n_variables(); ++v)
1651 std::string vname = dofmap.variable(v).name();
1654 dmm->
_var_ids->insert(std::pair<std::string, unsigned int>(vname, v));
1655 dmm->
_var_names->insert(std::pair<unsigned int, std::string>(v, vname));
1657 if (dmm->
_var_ids->size() == dofmap.n_variables())
1664 dmm->
_vars = LIBMESH_PETSC_NULLPTR;
1669 std::set<subdomain_id_type> blocks;
1673 SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_PLIB,
"No mesh blocks found.");
1675 for (
const auto & bid : blocks)
1677 std::string bname =
mesh.subdomain_name(bid);
1678 if (!bname.length())
1683 std::ostringstream ss;
1707 && dmm->
_blocks->find(std::to_string(bid)) == dmm->
_blocks->end()))
1710 dmm->
_block_ids->insert(std::make_pair(bname, bid));
1714 if (dmm->
_block_ids->size() == blocks.size())
1721 dmm->
_blocks = LIBMESH_PETSC_NULLPTR;
1727 name +=
"_" + vit.second;
1732 name +=
"_" + bit.second;
1738 name +=
"_" + sit.second;
1744 name +=
"_" + sit.second;
1748 name +=
"_contacts";
1750 name +=
"_primary_" + cit.second.first +
"_secondary_" + cit.second.second;
1754 name +=
"_uncontacts";
1756 name +=
"_primary_" + cit.second.first +
"_secondary_" + cit.second.second;
1758 ierr = PetscObjectSetName((PetscObject)dm,
name.c_str());
1760 PetscFunctionReturn(0);
1766 PetscErrorCode
ierr;
1771 ierr = PetscObjectTypeCompare((PetscObject)dm, DMMOOSE, &ismoose);
1774 PetscFunctionReturn(0);
1776 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"No Moose system set for DM_Moose");
1779 for (
auto & it : *(dmm->
_splits))
1790 dm->setupcalled = PETSC_FALSE;
1791 PetscFunctionReturn(0);
1794 static PetscErrorCode
1797 PetscErrorCode
ierr;
1804 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"No Moose system set for DM_Moose");
1807 const char *
name, *prefix;
1810 ierr = PetscObjectGetName((PetscObject)dm, &
name);
1812 ierr = PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix);
1814 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1815 "DM Moose with name %s and prefix %s\n",
1822 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1823 "\thas a trivial embedding\n");
1830 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1831 "\thas embedding defined by IS:\n");
1833 ierr = ISView(embedding, PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm));
1835 ierr = ISDestroy(&embedding);
1854 PetscFunctionReturn(0);
1857 #if !PETSC_VERSION_LESS_THAN(3, 18, 0) 1860 #elif !PETSC_VERSION_LESS_THAN(3, 7, 0) 1868 PetscErrorCode
ierr;
1875 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"No Moose system set for DM_Moose");
1879 #if !PETSC_VERSION_LESS_THAN(3, 18, 0) 1880 PetscOptionsBegin(((PetscObject)dm)->comm, ((PetscObject)dm)->prefix,
"DMMoose options",
"DM");
1882 ierr = PetscOptionsBegin(
1883 ((PetscObject)dm)->comm, ((PetscObject)dm)->prefix,
"DMMoose options",
"DM");
1885 std::string opt, help;
1886 PetscInt maxvars = dmm->
_nl->
system().get_dof_map().n_variables();
1888 std::set<std::string> varset;
1889 PetscInt nvars = maxvars;
1890 ierr = PetscMalloc(maxvars *
sizeof(
char *), &vars);
1892 opt =
"-dm_moose_vars";
1893 help =
"Variables in DMMoose";
1894 ierr = PetscOptionsStringArray(
1895 opt.c_str(), help.c_str(),
"DMMooseSetVars", vars, &nvars, LIBMESH_PETSC_NULLPTR);
1897 for (PetscInt i = 0; i < nvars; ++i)
1899 varset.insert(std::string(vars[i]));
1900 ierr = PetscFree(vars[i]);
1903 ierr = PetscFree(vars);
1911 std::set<subdomain_id_type> meshblocks;
1914 PetscInt maxblocks = meshblocks.size();
1916 ierr = PetscMalloc(maxblocks *
sizeof(
char *), &blocks);
1918 std::set<std::string> blockset;
1919 PetscInt nblocks = maxblocks;
1920 opt =
"-dm_moose_blocks";
1921 help =
"Blocks in DMMoose";
1922 ierr = PetscOptionsStringArray(
1923 opt.c_str(), help.c_str(),
"DMMooseSetBlocks", blocks, &nblocks, LIBMESH_PETSC_NULLPTR);
1925 for (PetscInt i = 0; i < nblocks; ++i)
1927 blockset.insert(std::string(blocks[i]));
1928 ierr = PetscFree(blocks[i]);
1931 ierr = PetscFree(blocks);
1933 if (blockset.size())
1939 dmm->
_nl->
system().get_mesh().get_boundary_info().get_global_boundary_ids().size();
1941 ierr = PetscMalloc(maxsides * maxvars *
sizeof(
char *), &sides);
1943 PetscInt nsides = maxsides;
1944 std::set<std::string> sideset;
1947 opt =
"-dm_moose_sides";
1948 help =
"Sides to include in DMMoose";
1949 ierr = PetscOptionsStringArray(
1950 opt.c_str(), help.c_str(),
"DMMooseSetSides", sides, &nsides, LIBMESH_PETSC_NULLPTR);
1952 for (PetscInt i = 0; i < nsides; ++i)
1954 sideset.insert(std::string(sides[i]));
1955 ierr = PetscFree(sides[i]);
1965 opt =
"-dm_moose_unsides";
1966 help =
"Sides to exclude from DMMoose";
1968 ierr = PetscOptionsStringArray(
1969 opt.c_str(), help.c_str(),
"DMMooseSetUnSides", sides, &nsides, LIBMESH_PETSC_NULLPTR);
1972 for (PetscInt i = 0; i < nsides; ++i)
1974 sideset.insert(std::string(sides[i]));
1975 ierr = PetscFree(sides[i]);
1985 opt =
"-dm_moose_unside_by_var";
1986 help =
"Sides to exclude from DMMoose on a by-var basis";
1987 nsides = maxsides * maxvars;
1988 ierr = PetscOptionsStringArray(
1989 opt.c_str(), help.c_str(),
"DMMooseSetUnSideByVar", sides, &nsides, LIBMESH_PETSC_NULLPTR);
1992 for (PetscInt i = 0; i < nsides; ++i)
1994 sideset.insert(std::string(sides[i]));
1995 ierr = PetscFree(sides[i]);
2004 ierr = PetscFree(sides);
2008 if (displaced_problem)
2009 maxcontacts = PetscMax(
2010 maxcontacts, (PetscInt)displaced_problem->geomSearchData()._penetration_locators.size());
2012 std::vector<DM_Moose::ContactName> contacts;
2013 std::vector<PetscBool> contact_displaced;
2014 PetscInt ncontacts = 0;
2015 opt =
"-dm_moose_ncontacts";
2017 "Number of contacts to include in DMMoose. For each <n> < " 2018 "dm_moose_contacts\n\t-dm_moose_contact_<n> is a comma-separated <primary>,<secondary> pair " 2019 "defining the contact surfaces" 2020 "\t-dm_moose_contact_<n>_displaced <bool> determines whether the contact is defined on " 2021 "the displaced mesh or not";
2022 ierr = PetscOptionsInt(opt.c_str(),
2024 "DMMooseSetContacts",
2027 LIBMESH_PETSC_NULLPTR);
2029 if (ncontacts > maxcontacts)
2030 LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
2032 "Number of requested contacts %" LIBMESH_PETSCINT_FMT
2033 " exceeds the maximum number of contacts %" LIBMESH_PETSCINT_FMT,
2036 for (PetscInt i = 0; i < ncontacts; ++i)
2039 char * primary_secondary[2];
2041 std::ostringstream oopt, ohelp;
2042 oopt <<
"-dm_moose_contact_" << i;
2043 ohelp <<
"Primary and secondary for contact " << i;
2044 ierr = PetscOptionsStringArray(oopt.str().c_str(),
2045 ohelp.str().c_str(),
2046 "DMMooseSetContacts",
2049 LIBMESH_PETSC_NULLPTR);
2053 ((PetscObject)dm)->comm,
2055 "Expected 2 sideset IDs (primary & secondary) for contact %" LIBMESH_PETSCINT_FMT
2056 ", got %" LIBMESH_PETSCINT_FMT
" instead",
2060 std::string(primary_secondary[1])));
2061 ierr = PetscFree(primary_secondary[0]);
2063 ierr = PetscFree(primary_secondary[1]);
2067 PetscBool displaced = PETSC_FALSE;
2068 std::ostringstream oopt, ohelp;
2069 oopt <<
"-dm_moose_contact_" << i <<
"_displaced";
2070 ohelp <<
"Whether contact " << i <<
" is determined using displaced mesh or not";
2071 ierr = PetscOptionsBool(oopt.str().c_str(),
2072 ohelp.str().c_str(),
2073 "DMMooseSetContacts",
2076 LIBMESH_PETSC_NULLPTR);
2078 contact_displaced.push_back(displaced);
2081 if (contacts.size())
2087 std::ostringstream oopt, ohelp;
2088 PetscBool is_include_all_nodes;
2089 oopt <<
"-dm_moose_includeAllContactNodes";
2090 ohelp <<
"Whether to include all nodes on the contact surfaces into the subsolver";
2091 ierr = PetscOptionsBool(oopt.str().c_str(),
2092 ohelp.str().c_str(),
2095 &is_include_all_nodes,
2096 LIBMESH_PETSC_NULLPTR);
2100 std::vector<DM_Moose::ContactName> uncontacts;
2101 std::vector<PetscBool> uncontact_displaced;
2102 PetscInt nuncontacts = 0;
2103 opt =
"-dm_moose_nuncontacts";
2105 "Number of contacts to exclude from DMMoose. For each <n> < " 2106 "dm_moose_contacts\n\t-dm_moose_contact_<n> is a comma-separated <primary>,<secondary> pair " 2107 "defining the contact surfaces" 2108 "\t-dm_moose_contact_<n>_displaced <bool> determines whether the contact is defined on " 2109 "the displaced mesh or not";
2110 ierr = PetscOptionsInt(opt.c_str(),
2112 "DMMooseSetUnContacts",
2115 LIBMESH_PETSC_NULLPTR);
2117 if (nuncontacts > maxcontacts)
2118 LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
2120 "Number of requested uncontacts %" LIBMESH_PETSCINT_FMT
2121 " exceeds the maximum number of contacts %" LIBMESH_PETSCINT_FMT,
2124 for (PetscInt i = 0; i < nuncontacts; ++i)
2127 char * primary_secondary[2];
2129 std::ostringstream oopt, ohelp;
2130 oopt <<
"-dm_moose_uncontact_" << i;
2131 ohelp <<
"Primary and secondary for uncontact " << i;
2132 ierr = PetscOptionsStringArray(oopt.str().c_str(),
2133 ohelp.str().c_str(),
2134 "DMMooseSetUnContacts",
2137 LIBMESH_PETSC_NULLPTR);
2141 ((PetscObject)dm)->comm,
2143 "Expected 2 sideset IDs (primary & secondary) for uncontact %" LIBMESH_PETSCINT_FMT
2144 ", got %" LIBMESH_PETSCINT_FMT
" instead",
2148 std::string(primary_secondary[1])));
2149 ierr = PetscFree(primary_secondary[0]);
2151 ierr = PetscFree(primary_secondary[1]);
2155 PetscBool displaced = PETSC_FALSE;
2156 std::ostringstream oopt, ohelp;
2157 oopt <<
"-dm_moose_uncontact_" << i <<
"_displaced";
2158 ohelp <<
"Whether uncontact " << i <<
" is determined using displaced mesh or not";
2159 ierr = PetscOptionsBool(oopt.str().c_str(),
2160 ohelp.str().c_str(),
2161 "DMMooseSetUnContact",
2164 LIBMESH_PETSC_NULLPTR);
2166 uncontact_displaced.push_back(displaced);
2169 if (uncontacts.size())
2175 PetscInt nsplits = 0;
2178 const char * fdhelp =
"Number of named fieldsplits defined by the DM.\n\ 2179 \tNames of fieldsplits are defined by -dm_moose_fieldsplit_names <splitname1> <splitname2> ...\n\ 2180 \tEach split can be configured with its own variables, blocks and sides, as any DMMoose";
2181 ierr = PetscOptionsInt(
2182 "-dm_moose_nfieldsplits", fdhelp,
"DMMooseSetSplitNames", nsplits, &nsplits, NULL);
2186 PetscInt nnsplits = nsplits;
2187 std::vector<std::string> split_names;
2189 ierr = PetscMalloc(nsplits *
sizeof(
char *), &splitnames);
2191 ierr = PetscOptionsStringArray(
"-dm_moose_fieldsplit_names",
2192 "Names of fieldsplits defined by the DM",
2193 "DMMooseSetSplitNames",
2196 LIBMESH_PETSC_NULLPTR);
2200 for (PetscInt i = 0; i < nsplits; ++i)
2202 std::ostringstream s;
2204 split_names.push_back(s.str());
2207 else if (nsplits != nnsplits)
2208 LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
2210 "Expected %" LIBMESH_PETSCINT_FMT
2211 " fieldsplit names, got %" LIBMESH_PETSCINT_FMT
" instead",
2216 for (PetscInt i = 0; i < nsplits; ++i)
2218 split_names.push_back(std::string(splitnames[i]));
2219 ierr = PetscFree(splitnames[i]);
2223 ierr = PetscFree(splitnames);
2228 ierr = PetscOptionsBool(
"-dm_moose_print_embedding",
2229 "Print IS embedding DM's dofs",
2233 LIBMESH_PETSC_NULLPTR);
2239 PetscFunctionReturn(0);
2242 static PetscErrorCode
2246 PetscErrorCode
ierr;
2279 for (
auto & sit : *(dmm->
_splits))
2281 ierr = DMDestroy(&(sit.second._dm));
2283 ierr = ISDestroy(&(sit.second._rembedding));
2292 ierr = PetscFree(dm->data);
2294 PetscFunctionReturn(0);
2300 PetscErrorCode
ierr;
2303 ierr = DMCreate(comm, dm);
2305 ierr = DMSetType(*dm, DMMOOSE);
2311 PetscFunctionReturn(0);
2318 PetscErrorCode
ierr;
2322 PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2323 #if PETSC_RELEASE_LESS_THAN(3, 18, 0) 2324 ierr = PetscNewLog(dm, &dmm);
2326 #else // PetscNewLog was deprecated 2327 ierr = PetscNew(&dmm);
2332 dmm->
_name =
new (std::string);
2333 dmm->
_var_ids =
new (std::map<std::string, unsigned int>);
2334 dmm->
_block_ids =
new (std::map<std::string, subdomain_id_type>);
2335 dmm->
_var_names =
new (std::map<unsigned int, std::string>);
2336 dmm->
_block_names =
new (std::map<unsigned int, std::string>);
2337 dmm->
_side_ids =
new (std::map<std::string, BoundaryID>);
2338 dmm->
_side_names =
new (std::map<BoundaryID, std::string>);
2339 dmm->
_unside_ids =
new (std::map<std::string, BoundaryID>);
2340 dmm->
_unside_names =
new (std::map<BoundaryID, std::string>);
2342 dmm->
_contact_names =
new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2343 dmm->
_uncontact_names =
new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2347 dmm->
_splits =
new (std::map<std::string, DM_Moose::SplitInfo>);
2352 dm->ops->createlocalvector = 0;
2353 dm->ops->getcoloring = 0;
2355 dm->ops->createinterpolation = 0;
2357 dm->ops->refine = 0;
2358 dm->ops->coarsen = 0;
2359 #if PETSC_RELEASE_LESS_THAN(3, 12, 0) 2360 dm->ops->getinjection = 0;
2361 dm->ops->getaggregates = 0;
2363 dm->ops->createinjection = 0;
2373 PetscFunctionReturn(0);
2378 #define __FUNCT__ "SNESUpdateDMMoose" 2390 PetscErrorCode
ierr;
2393 const char * prefix;
2402 ierr = SNESGetDM(snes, &dm);
2408 ierr = SNESGetKSP(snes, &ksp);
2411 ierr = PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
2413 ierr = PetscObjectGetComm((PetscObject)ksp, &comm);
2415 ierr = PCCreate(comm, &pc);
2417 ierr = PCSetDM(pc, dm);
2419 ierr = PCSetOptionsPrefix(pc, prefix);
2421 ierr = PCSetFromOptions(pc);
2423 ierr = KSPSetPC(ksp, pc);
2425 ierr = PCDestroy(&pc);
2428 PetscFunctionReturn(0);
2434 static PetscBool DMMooseRegisterAllCalled = PETSC_FALSE;
2435 PetscErrorCode
ierr;
2438 if (!DMMooseRegisterAllCalled)
2442 DMMooseRegisterAllCalled = PETSC_TRUE;
2444 PetscFunctionReturn(0);
PetscErrorCode DMMooseRegisterAll()
std::string name(const ElemQuality q)
static PetscErrorCode DMSetUp_Moose(DM dm)
std::set< ContactName > * _uncontacts
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
PetscErrorCode DMMooseGetBlocks(DM dm, std::vector< std::string > &block_names)
std::map< std::pair< BoundaryID, BoundaryID >, PenetrationLocator * > _penetration_locators
PetscErrorCode DMMooseSetContacts(DM dm, const std::vector< std::pair< std::string, std::string >> &contacts, const std::vector< PetscBool > &displaced)
void(* residual)(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)
std::set< std::pair< BoundaryID, unsigned int > > * _unside_by_var_set
PetscErrorCode DMMooseSetVariables(DM dm, const std::set< std::string > &vars)
NonlinearImplicitSystem::ComputeResidualandJacobian * residual_and_jacobian_object
std::map< BoundaryID, std::string > * _side_names
virtual NonlinearSolver< Number > * nonlinearSolver()=0
PetscErrorCode DMMooseGetUnSides(DM dm, std::vector< std::string > &side_names)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Data structure used to hold penetration information.
std::map< ContactName, PetscBool > * _contact_displaced
PetscErrorCode DMMooseGetNonlinearSystem(DM dm, NonlinearSystemBase *&nl)
TestClass subdomain_id_type
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > ConstBndElemRange
PetscErrorCode DMMooseSetUnContacts(DM dm, const std::vector< std::pair< std::string, std::string >> &uncontacts, const std::vector< PetscBool > &displaced)
std::map< std::string, BoundaryID > * _side_ids
bool _include_all_contact_nodes
std::string * _name
The name of this DM.
PetscErrorCode SNESUpdateDMMoose(SNES snes, PetscInt iteration)
static PetscErrorCode DMMooseGetMeshBlocks_Private(DM dm, std::set< subdomain_id_type > &blocks)
void checkSize(const std::string &split_name, const I1 split_size, const I2 size_expected_by_parent)
std::map< ContactName, PetscBool > * _uncontact_displaced
const Parallel::Communicator & comm() const
PetscErrorCode DMMooseReset(DM dm)
PetscErrorCode DMMooseGetUnContacts(DM dm, std::vector< std::pair< std::string, std::string >> &uncontact_names, std::vector< PetscBool > &displaced)
PetscErrorCode DMMooseSetNonlinearSystem(DM dm, NonlinearSystemBase &nl)
NonlinearImplicitSystem::ComputeResidual * residual_object
void(* jacobian)(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)
static PetscErrorCode DMSetUp_Moose_Pre(DM dm)
std::set< std::string > * _sides
virtual GeometricSearchData & geomSearchData() override
static PetscErrorCode DMVariableBounds_Moose(DM dm, Vec xl, Vec xu)
std::map< std::string, unsigned int > * _var_ids
std::map< unsigned int, std::string > * _var_names
EXTERN_C_BEGIN PetscErrorCode DMCreate_Moose(DM dm)
Nonlinear system to be solved.
static PetscErrorCode DMMooseJacobian(DM dm, Vec x, Mat jac, Mat pc)
PenetrationLocator & getPenetrationLocator(const BoundaryName &primary, const BoundaryName &secondary, Order order=FIRST)
const sys_type & system() const
PetscErrorCode DMMooseGetContacts(DM dm, std::vector< std::pair< std::string, std::string >> &contact_names, std::vector< PetscBool > &displaced)
NonlinearImplicitSystem::ComputeJacobian * jacobian_object
void libmesh_ignore(const Args &...)
static PetscErrorCode SNESJacobian_DMMoose(SNES, Vec x, Mat jac, Mat pc, void *ctx)
FEProblemBase & _fe_problem
static PetscErrorCode DMView_Moose(DM dm, PetscViewer viewer)
std::map< ContactID, ContactName > * _uncontact_names
NonlinearImplicitSystem::ComputeBounds * bounds_object
boundary_id_type BoundaryID
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
std::set< ContactName > * _contacts
PetscErrorCode DMMooseGetSplitNames(DM dm, std::vector< std::string > &split_names)
PetscErrorCode DMMooseSetParentDM(DM dm, DM_Moose *parent)
std::set< std::string > * _unside_by_var
std::map< std::string, SplitInfo > * _splits
static PetscErrorCode DMCreateFieldDecomposition_Moose(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
virtual bool hasVariable(const std::string &var_name) const
Query a system for a variable.
std::pair< BoundaryID, BoundaryID > ContactID
std::set< std::string > * _unsides
std::set< std::string > * _vars
virtual MooseVariableScalar & getScalarVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a scalar variable with specified number.
static PetscErrorCode DMMooseGetEmbedding_Private(DM dm, IS *embedding)
static std::string arrayVariableComponent(const std::string &var_name, unsigned int i)
Returns the variable name of a component of an array variable.
std::map< std::string, BoundaryID > * _unside_ids
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
PetscErrorCode DMMooseGetSides(DM dm, std::vector< std::string > &side_names)
PetscBool _print_embedding
NonlinearSystemBase * _nl
PetscErrorCode DMMooseSetName(DM dm, const std::string &dm_name)
static PetscErrorCode SNESFunction_DMMoose(SNES, Vec x, Vec r, void *ctx)
PetscErrorCode DMMooseValidityCheck(DM dm)
virtual System & system() override
Get the reference to the libMesh system.
virtual MooseMesh & mesh()
PetscErrorCode DMMooseSetSides(DM dm, const std::set< std::string > &sides)
void(* bounds)(NumericVector< Number > &XL, NumericVector< Number > &XU, sys_type &S)
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
PetscErrorCode DMSetFromOptions_Moose(DM dm, PetscOptionItems *) PetscErrorCode DMSetFromOptions_Moose(PetscOptionItems *
PetscErrorCode DMCreateMoose(MPI_Comm comm, NonlinearSystemBase &nl, const std::string &dm_name, DM *dm)
Create a MOOSE DM.
std::map< std::string, subdomain_id_type > * _block_ids
void checkChildSize(DM child, PetscInt child_size, const std::string &child_name)
Check whether the size of the child matches the size we expect.
PetscErrorCode DMMooseSetUnSideByVar(DM dm, const std::set< std::string > &unside_by_var)
static PetscErrorCode DMMooseFunction(DM dm, Vec x, Vec r)
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > ConstBndNodeRange
Some useful StoredRange typedefs.
std::set< std::string > * _blocks
static PetscErrorCode DMCreateGlobalVector_Moose(DM dm, Vec *x)
PetscErrorCode DMMooseSetBlocks(DM dm, const std::set< std::string > &blocks)
std::map< ContactID, ContactName > * _contact_names
std::multimap< std::string, unsigned int > * _splitlocs
std::pair< std::string, std::string > ContactName
static PetscErrorCode DMDestroy_Moose(DM dm)
static PetscErrorCode DMCreateDomainDecomposition_Moose(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
PetscErrorCode DMMooseSetSplitNames(DM dm, const std::vector< std::string > &split_names)
static PetscErrorCode DMCreateMatrix_Moose(DM dm, Mat *A)
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
PetscErrorCode DMMooseSetUnSides(DM dm, const std::set< std::string > &unsides)
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
PetscErrorCode DMMooseGetVariables(DM dm, std::vector< std::string > &var_names)
std::map< BoundaryID, std::string > * _unside_names
const std::map< dof_id_type, std::vector< dof_id_type > > & nodeToElemMap()
If not already created, creates a map from every node to all elements to which they are connected...
void(* matvec)(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)
std::map< unsigned int, std::string > * _block_names