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" 37 template <
typename I1,
typename I2>
39 checkSize(
const std::string & split_name,
const I1 split_size,
const I2 size_expected_by_parent)
41 if (libMesh::cast_int<libMesh::numeric_index_type>(split_size) !=
42 libMesh::cast_int<libMesh::numeric_index_type>(size_expected_by_parent))
46 libMesh::cast_int<libMesh::numeric_index_type>(split_size),
47 " but the parent split expected size ",
48 libMesh::cast_int<libMesh::numeric_index_type>(size_expected_by_parent),
49 ". Make sure that you have non-overlapping complete sets for variables and " 50 "blocks as well as consistency in sides/unsides, contacts/uncontacts, etc.");
58 std::map<std::string, unsigned int> *
_var_ids;
77 typedef std::pair<BoundaryID, BoundaryID>
ContactID;
97 std::map<std::string, SplitInfo> *
_splits;
108 void checkChildSize(DM child, PetscInt child_size,
const std::string & child_name);
114 for (
const auto &
split : *_splits)
115 if (
split.second._dm == child)
117 mooseAssert(
split.first == child_name,
"These should match");
118 PetscInt parent_expected_size;
119 auto ierr = ISGetLocalSize(
split.second._rembedding, &parent_expected_size);
122 checkSize(child_name, child_size, parent_expected_size);
135 PetscValidHeaderSpecific(
dm, DM_CLASSID, 1);
138 LIBMESH_SETERRQ2(((PetscObject)
dm)->comm,
140 "Got DM of type %s, not of type %s",
141 ((PetscObject)
dm)->type_name,
148 std::vector<std::pair<std::string, std::string>> & contact_names,
149 std::vector<PetscBool> & displaced)
156 contact_names.push_back(it.second);
164 std::vector<std::pair<std::string, std::string>> & uncontact_names,
165 std::vector<PetscBool> & displaced)
172 uncontact_names.push_back(it.second);
185 side_names.push_back(it.first);
196 side_names.push_back(it.first);
207 block_names.push_back(it.first);
217 for (
const auto & it : *(dmm->
_var_ids))
218 var_names.push_back(it.first);
228 SETERRQ(((PetscObject)
dm)->comm,
230 "Cannot reset the NonlinearSystem after DM has been set up.");
242 SETERRQ(((PetscObject)
dm)->comm,
244 "Cannot reset the MOOSE DM name after DM has been set up.");
246 *dmm->
_name = dm_name;
256 SETERRQ(((PetscObject)
dm)->comm,
258 "Cannot reset the parent DM after the child DM has been set up.");
276 std::set<std::string> processed_vars;
277 for (
const auto & var_name :
vars)
279 const auto *
const var =
285 processed_vars.insert(var->arrayVariableComponent(i));
287 processed_vars.insert(var_name);
290 dmm->
_vars =
new std::set<std::string>(std::move(processed_vars));
335 dmm->
_unsides =
new std::set<std::string>(unsides);
356 const std::vector<std::pair<std::string, std::string>> &
contacts,
357 const std::vector<PetscBool> & displaced)
365 if (
contacts.size() != displaced.size())
366 LIBMESH_SETERRQ2(PETSC_COMM_SELF,
368 "Nonmatching sizes of the contact and displaced arrays: %" LIBMESH_PETSCINT_FMT
369 " != %" LIBMESH_PETSCINT_FMT,
370 static_cast<PetscInt>(
contacts.size()),
371 static_cast<PetscInt>(displaced.size()));
375 dmm->
_contacts =
new std::set<DM_Moose::ContactName>();
376 for (
unsigned int i = 0; i <
contacts.size(); ++i)
386 const std::vector<std::pair<std::string, std::string>> &
uncontacts,
387 const std::vector<PetscBool> & displaced)
399 "Nonmatching sizes of the uncontact and displaced arrays: %" LIBMESH_PETSCINT_FMT
400 " != %" LIBMESH_PETSCINT_FMT,
402 static_cast<PetscInt>(displaced.size()));
406 dmm->
_uncontacts =
new std::set<DM_Moose::ContactName>();
407 for (
unsigned int i = 0; i <
uncontacts.size(); ++i)
434 for (
auto & it : *(dmm->
_splits))
440 dmm->
_splits = LIBMESH_PETSC_NULLPTR;
447 dmm->
_splits =
new std::map<std::string, DM_Moose::SplitInfo>();
448 dmm->
_splitlocs =
new std::multimap<std::string, unsigned int>();
449 for (
unsigned int i = 0; i < split_names.size(); ++i)
452 info.
_dm = LIBMESH_PETSC_NULLPTR;
453 info._rembedding = LIBMESH_PETSC_NULLPTR;
454 std::string
name = split_names[i];
467 if (!
dm->setupcalled)
474 std::string sname = lit.first;
475 unsigned int sloc = lit.second;
476 split_names[sloc] = sname;
481 static PetscErrorCode
519 std::vector<dof_id_type> node_indices;
520 auto process_nodal_dof_indices =
521 [&dofmap, &node_indices](
const Node & node,
522 const unsigned int var_num,
523 std::set<dof_id_type> & local_indices,
524 std::set<dof_id_type> *
const nonlocal_indices =
nullptr)
527 for (
const auto index : node_indices)
530 local_indices.insert(index);
531 else if (nonlocal_indices)
532 nonlocal_indices->insert(index);
536 auto process_elem_dof_indices =
537 [&dofmap](
const std::vector<dof_id_type> & elem_indices,
538 std::set<dof_id_type> & local_indices,
539 std::set<dof_id_type> *
const nonlocal_indices =
nullptr)
541 for (
const auto index : elem_indices)
544 local_indices.insert(index);
545 else if (nonlocal_indices)
546 nonlocal_indices->insert(index);
550 std::set<dof_id_type> indices;
551 std::set<dof_id_type> unindices;
552 std::set<dof_id_type> cached_indices;
553 std::set<dof_id_type> cached_unindices;
556 for (
const auto & vit : *(dmm->
_var_ids))
558 unsigned int v = vit.second;
564 for (
const auto & elem :
as_range(lm_mesh.active_local_subdomain_elements_begin(b),
565 lm_mesh.active_local_subdomain_elements_end(b)))
568 std::vector<dof_id_type> evindices;
570 process_elem_dof_indices(evindices, indices);
575 bool is_on_current_block =
false;
576 for (
auto & node : lm_mesh.local_node_ptr_range())
578 const unsigned int n_comp = node->n_comp(dmm->
_nl->
system().
number(), v);
584 auto node_to_elem_pair = node_to_elem_map.find(node->id());
585 is_on_current_block =
false;
586 for (
const auto & elem_num : node_to_elem_pair->second)
590 Elem & neighbor_elem = lm_mesh.elem_ref(elem_num);
593 is_on_current_block =
true;
598 if (!is_on_current_block)
601 process_nodal_dof_indices(*node, v, indices);
622 for (
const auto & bnode : bnodes)
628 const Node * node = bnode->_node;
629 process_nodal_dof_indices(*node, v, indices);
637 for (
const auto & bnode : bnodes)
642 const Node * node = bnode->_node;
643 process_nodal_dof_indices(*node, v, unindices);
648 std::set<BoundaryID> eligible_bids;
651 eligible_bids.insert(bid);
654 for (
const auto & bnode : bnodes)
657 if (eligible_bids.count(boundary_id))
659 const Node * node = bnode->_node;
660 process_nodal_dof_indices(*node, v, unindices);
665 auto process_contact_all_nodes =
666 [dmm, process_nodal_dof_indices, v](
const auto & contact_names,
667 auto & indices_to_insert_to)
669 std::set<boundary_id_type> bc_id_set;
671 for (
const auto & [contact_bid_pair, contact_bname_pair] : contact_names)
674 bc_id_set.insert(contact_bid_pair.first);
675 bc_id_set.insert(contact_bid_pair.second);
679 for (
const auto & belem : range)
681 const Elem * elem_bdry = belem->_elem;
682 const auto side = belem->_side;
685 if (bc_id_set.find(boundary_id) == bc_id_set.end())
690 process_nodal_dof_indices(elem_bdry->
node_ref(node_idx), v, indices_to_insert_to);
694 auto process_contact_some_nodes =
695 [dmm, process_nodal_dof_indices, v, &dofmap, &lm_mesh, process_elem_dof_indices](
696 const auto & contact_names,
697 auto & indices_to_insert_to,
698 auto & nonlocal_indices_to_insert_to)
700 std::vector<dof_id_type> evindices;
701 for (
const auto & it : contact_names)
711 std::ostringstream
err;
712 err <<
"Cannot use a displaced uncontact (" << it.second.first <<
"," 713 << it.second.second <<
") with an undisplaced problem";
723 auto lend = locator->_penetration_info.end();
724 for (
auto lit = locator->_penetration_info.begin(); lit != lend; ++lit)
730 Node & secondary_node = lm_mesh.node_ref(secondary_node_num);
731 process_nodal_dof_indices(
732 secondary_node, v, indices_to_insert_to, &nonlocal_indices_to_insert_to);
736 const Elem * primary_side = pinfo->
_side;
737 dofmap.dof_indices(primary_side, evindices, v);
738 process_elem_dof_indices(
739 evindices, indices_to_insert_to, &nonlocal_indices_to_insert_to);
751 process_contact_some_nodes(*dmm->
_contact_names, indices, cached_indices);
759 process_contact_some_nodes(*dmm->
_uncontact_names, unindices, cached_unindices);
762 std::vector<dof_id_type> local_vec_indices(cached_indices.size());
763 std::copy(cached_indices.begin(), cached_indices.end(), local_vec_indices.begin());
767 for (
const auto & dof : local_vec_indices)
771 local_vec_indices.clear();
772 local_vec_indices.resize(cached_unindices.size());
773 std::copy(cached_unindices.begin(), cached_unindices.end(), local_vec_indices.begin());
777 for (
const auto & dof : local_vec_indices)
779 unindices.insert(dof);
781 std::set<dof_id_type> dindices;
782 std::set_difference(indices.begin(),
786 std::inserter(dindices, dindices.end()));
790 for (
const auto & dof : dindices)
796 ((PetscObject)
dm)->comm, dindices.size(), darray, PETSC_OWN_POINTER, &dmm->
_embedding));
809 ISCreateStride(((PetscObject)
dm)->comm, (high - low), low, 1, &dmm->
_embedding));
818 static PetscErrorCode
820 DM
dm, PetscInt * len,
char *** namelist, IS ** islist, DM ** dmlist)
826 PetscInt split_size_sum = 0;
840 unsigned int d = dit.second;
841 std::string dname = dit.first;
847 PetscObjectSetOptionsPrefix((PetscObject)dinfo.
_dm, ((PetscObject)
dm)->prefix));
848 std::string suffix = std::string(
"fieldsplit_") + dname +
"_";
860 IS dembedding, lembedding;
866 const PetscInt * lindices;
867 PetscInt len, dlen, llen, *rindices, off, i;
872 ((PetscObject)
dm)->comm, PETSC_ERR_PLIB,
"Failed to embed split %u", d);
886 #ifdef PETSC_USE_64BIT_INDICES
892 ((PetscObject)
dm)->comm);
895 for (i = 0; i < llen; ++i)
898 ((PetscObject)
dm)->comm, llen, rindices, PETSC_OWN_POINTER, &(dinfo.
_rembedding)));
909 split_size_sum += is_size;
914 (*dmlist)[d] = dinfo.
_dm;
918 mooseAssert(islist,
"What does it even mean if this is NULL?");
930 static PetscErrorCode
932 DM
dm, PetscInt * len,
char *** namelist, IS ** innerislist, IS ** outerislist, DM ** dmlist)
938 *outerislist = LIBMESH_PETSC_NULLPTR;
943 static PetscErrorCode
959 X_global.
swap(X_sys);
961 X_global.swap(X_sys);
977 std::ostringstream
err;
978 err <<
"ERROR: cannot specifiy both a function and object to compute the Residual!" 984 std::ostringstream
err;
985 err <<
"ERROR: cannot specifiy both a function and object to compute the combined Residual & " 1000 nl->
nonlinearSolver()->residual_and_jacobian_object->residual_and_jacobian(
1004 std::ostringstream
err;
1005 err <<
"No suitable residual computation routine found";
1012 static PetscErrorCode
1022 static PetscErrorCode
1043 X_global.
swap(X_sys);
1045 X_global.swap(X_sys);
1061 std::ostringstream
err;
1062 err <<
"ERROR: cannot specifiy both a function and object to compute the Jacobian!" 1068 std::ostringstream
err;
1069 err <<
"ERROR: cannot specifiy both a function and object to compute the combined Residual & " 1086 nl->
nonlinearSolver()->residual_and_jacobian_object->residual_and_jacobian(
1093 std::ostringstream
err;
1094 err <<
"No suitable Jacobian routine or object";
1102 static PetscErrorCode
1112 static PetscErrorCode
1131 ((PetscObject)
dm)->comm, PETSC_ERR_ARG_WRONG,
"No bounds calculation in this Moose object");
1135 static PetscErrorCode
1164 #if PETSC_RELEASE_LESS_THAN(3, 13, 0) 1172 static PetscErrorCode
1192 PetscInt M,
N, m, n;
1205 const std::vector<numeric_index_type> & n_nz = dof_map.
get_n_nz();
1206 const std::vector<numeric_index_type> & n_oz = dof_map.
get_n_oz();
1207 LibmeshPetscCallQ(MatSeqAIJSetPreallocation(*A, 0, (PetscInt *)(n_nz.empty() ? NULL : &n_nz[0])));
1210 (PetscInt *)(n_nz.empty() ? NULL : &n_nz[0]),
1212 (PetscInt *)(n_oz.empty() ? NULL : &n_oz[0])));
1219 static PetscErrorCode
1223 const char *
name, *prefix;
1227 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
1233 PetscViewerASCIIPrintf(viewer,
"DM Moose with name %s and prefix %s\n",
name, prefix));
1235 for (
const auto & vit : *(dmm->
_var_ids))
1237 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer,
"(%s,%u) ", vit.first.c_str(), vit.second));
1243 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer,
"(%s,%d) ", bit.first.c_str(), bit.second));
1250 for (
const auto & sit : *(dmm->
_side_ids))
1253 PetscViewerASCIIPrintf(viewer,
"(%s,%d) ", sit.first.c_str(), sit.second));
1264 PetscViewerASCIIPrintf(viewer,
"(%s,%d) ", sit.first.c_str(), sit.second));
1275 viewer,
"(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str()));
1290 viewer,
"(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str()));
1305 std::string dname = dit.first;
1312 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
"Non-ASCII viewers are not supported");
1317 static PetscErrorCode
1330 libmesh_parallel_only(
mesh.
comm());
1331 for (
const auto & elem :
mesh.active_element_ptr_range())
1332 blocks.insert(elem->subdomain_id());
1338 static PetscErrorCode
1367 dmm->
_sides = LIBMESH_PETSC_NULLPTR;
1384 dmm->
_unsides = LIBMESH_PETSC_NULLPTR;
1395 const auto colon_pos =
name.find(
":");
1396 auto unside_name =
name.substr(0, colon_pos);
1397 auto var_name =
name.substr(colon_pos + 1);
1399 bool var_found =
false;
1400 for (
unsigned int v = 0; v < dofmap.
n_variables(); ++v)
1403 if (vname == var_name)
1411 mooseError(
"No variable named '", var_name,
"' found");
1422 for (
const auto & cpair : *(dmm->
_contacts))
1428 cpair.first, cpair.second);
1434 std::ostringstream
err;
1435 err <<
"Problem retrieving contact for PenetrationLocator with primary " << cpair.first
1436 <<
" and secondary " << cpair.second;
1456 cpair.first, cpair.second);
1462 std::ostringstream
err;
1463 err <<
"Problem retrieving uncontact for PenetrationLocator with primary " << cpair.first
1464 <<
" and secondary " << cpair.second;
1481 for (
unsigned int v = 0; v < dofmap.
n_variables(); ++v)
1486 dmm->
_var_ids->insert(std::pair<std::string, unsigned int>(vname, v));
1487 dmm->
_var_names->insert(std::pair<unsigned int, std::string>(v, vname));
1496 dmm->
_vars = LIBMESH_PETSC_NULLPTR;
1501 std::set<subdomain_id_type>
blocks;
1504 SETERRQ(((PetscObject)
dm)->comm, PETSC_ERR_PLIB,
"No mesh blocks found.");
1506 for (
const auto & bid :
blocks)
1509 if (!bname.length())
1514 std::ostringstream ss;
1538 && dmm->
_blocks->find(std::to_string(bid)) == dmm->
_blocks->end()))
1541 dmm->
_block_ids->insert(std::make_pair(bname, bid));
1552 dmm->
_blocks = LIBMESH_PETSC_NULLPTR;
1558 name +=
"_" + vit.second;
1563 name +=
"_" + bit.second;
1569 name +=
"_" + sit.second;
1575 name +=
"_" + sit.second;
1579 name +=
"_contacts";
1581 name +=
"_primary_" + cit.second.first +
"_secondary_" + cit.second.second;
1585 name +=
"_uncontacts";
1587 name +=
"_primary_" + cit.second.first +
"_secondary_" + cit.second.second;
1606 for (
auto & it : *(dmm->
_splits))
1613 dm->setupcalled = PETSC_FALSE;
1617 static PetscErrorCode
1628 const char *
name, *prefix;
1634 "DM Moose with name %s and prefix %s\n",
1640 "\thas a trivial embedding\n"));
1645 "\thas embedding defined by IS:\n"));
1664 #if !PETSC_VERSION_LESS_THAN(3, 23, 0) 1667 #elif !PETSC_VERSION_LESS_THAN(3, 18, 0) 1670 #elif !PETSC_VERSION_LESS_THAN(3, 7, 0) 1687 #if !PETSC_VERSION_LESS_THAN(3, 18, 0) 1691 ((PetscObject)
dm)->comm, ((PetscObject)
dm)->prefix,
"DMMoose options",
"DM"));
1699 opt =
"-dm_moose_vars";
1700 help =
"Variables in DMMoose";
1702 opt.c_str(),
help.c_str(),
"DMMooseSetVars",
vars, &
nvars, LIBMESH_PETSC_NULLPTR));
1719 opt =
"-dm_moose_blocks";
1720 help =
"Blocks in DMMoose";
1723 for (PetscInt i = 0; i <
nblocks; ++i)
1739 opt =
"-dm_moose_sides";
1740 help =
"Sides to include in DMMoose";
1742 opt.c_str(),
help.c_str(),
"DMMooseSetSides",
sides, &
nsides, LIBMESH_PETSC_NULLPTR));
1743 for (PetscInt i = 0; i <
nsides; ++i)
1752 opt =
"-dm_moose_unsides";
1753 help =
"Sides to exclude from DMMoose";
1756 opt.c_str(),
help.c_str(),
"DMMooseSetUnSides",
sides, &
nsides, LIBMESH_PETSC_NULLPTR));
1758 for (PetscInt i = 0; i <
nsides; ++i)
1767 opt =
"-dm_moose_unside_by_var";
1768 help =
"Sides to exclude from DMMoose on a by-var basis";
1771 opt.c_str(),
help.c_str(),
"DMMooseSetUnSideByVar",
sides, &
nsides, LIBMESH_PETSC_NULLPTR));
1773 for (PetscInt i = 0; i <
nsides; ++i)
1788 std::vector<DM_Moose::ContactName>
contacts;
1790 PetscInt ncontacts = 0;
1791 opt =
"-dm_moose_ncontacts";
1793 "Number of contacts to include in DMMoose. For each <n> < " 1794 "dm_moose_contacts\n\t-dm_moose_contact_<n> is a comma-separated <primary>,<secondary> pair " 1795 "defining the contact surfaces" 1796 "\t-dm_moose_contact_<n>_displaced <bool> determines whether the contact is defined on " 1797 "the displaced mesh or not";
1800 "DMMooseSetContacts",
1803 LIBMESH_PETSC_NULLPTR));
1805 LIBMESH_SETERRQ2(((PetscObject)
dm)->comm,
1807 "Number of requested contacts %" LIBMESH_PETSCINT_FMT
1808 " exceeds the maximum number of contacts %" LIBMESH_PETSCINT_FMT,
1811 for (PetscInt i = 0; i < ncontacts; ++i)
1814 char * primary_secondary[2];
1816 std::ostringstream oopt, ohelp;
1817 oopt <<
"-dm_moose_contact_" << i;
1818 ohelp <<
"Primary and secondary for contact " << i;
1820 ohelp.str().c_str(),
1821 "DMMooseSetContacts",
1824 LIBMESH_PETSC_NULLPTR));
1827 ((PetscObject)
dm)->comm,
1829 "Expected 2 sideset IDs (primary & secondary) for contact %" LIBMESH_PETSCINT_FMT
1830 ", got %" LIBMESH_PETSCINT_FMT
" instead",
1834 std::string(primary_secondary[1])));
1839 PetscBool displaced = PETSC_FALSE;
1840 std::ostringstream oopt, ohelp;
1841 oopt <<
"-dm_moose_contact_" << i <<
"_displaced";
1842 ohelp <<
"Whether contact " << i <<
" is determined using displaced mesh or not";
1844 ohelp.str().c_str(),
1845 "DMMooseSetContacts",
1848 LIBMESH_PETSC_NULLPTR));
1855 std::ostringstream oopt, ohelp;
1857 oopt <<
"-dm_moose_includeAllContactNodes";
1858 ohelp <<
"Whether to include all nodes on the contact surfaces into the subsolver";
1860 ohelp.str().c_str(),
1864 LIBMESH_PETSC_NULLPTR));
1870 opt =
"-dm_moose_nuncontacts";
1872 "Number of contacts to exclude from DMMoose. For each <n> < " 1873 "dm_moose_contacts\n\t-dm_moose_contact_<n> is a comma-separated <primary>,<secondary> pair " 1874 "defining the contact surfaces" 1875 "\t-dm_moose_contact_<n>_displaced <bool> determines whether the contact is defined on " 1876 "the displaced mesh or not";
1879 "DMMooseSetUnContacts",
1882 LIBMESH_PETSC_NULLPTR));
1884 LIBMESH_SETERRQ2(((PetscObject)
dm)->comm,
1886 "Number of requested uncontacts %" LIBMESH_PETSCINT_FMT
1887 " exceeds the maximum number of contacts %" LIBMESH_PETSCINT_FMT,
1893 char * primary_secondary[2];
1895 std::ostringstream oopt, ohelp;
1896 oopt <<
"-dm_moose_uncontact_" << i;
1897 ohelp <<
"Primary and secondary for uncontact " << i;
1899 ohelp.str().c_str(),
1900 "DMMooseSetUnContacts",
1903 LIBMESH_PETSC_NULLPTR));
1906 ((PetscObject)
dm)->comm,
1908 "Expected 2 sideset IDs (primary & secondary) for uncontact %" LIBMESH_PETSCINT_FMT
1909 ", got %" LIBMESH_PETSCINT_FMT
" instead",
1913 std::string(primary_secondary[1])));
1918 PetscBool displaced = PETSC_FALSE;
1919 std::ostringstream oopt, ohelp;
1920 oopt <<
"-dm_moose_uncontact_" << i <<
"_displaced";
1921 ohelp <<
"Whether uncontact " << i <<
" is determined using displaced mesh or not";
1923 ohelp.str().c_str(),
1924 "DMMooseSetUnContact",
1927 LIBMESH_PETSC_NULLPTR));
1937 const char *
fdhelp =
"Number of named fieldsplits defined by the DM.\n\ 1938 \tNames of fieldsplits are defined by -dm_moose_fieldsplit_names <splitname1> <splitname2> ...\n\ 1939 \tEach split can be configured with its own variables, blocks and sides, as any DMMoose";
1945 std::vector<std::string> split_names;
1949 "Names of fieldsplits defined by the DM",
1950 "DMMooseSetSplitNames",
1953 LIBMESH_PETSC_NULLPTR));
1956 for (PetscInt i = 0; i <
nsplits; ++i)
1958 std::ostringstream s;
1960 split_names.push_back(s.str());
1964 LIBMESH_SETERRQ2(((PetscObject)
dm)->comm,
1966 "Expected %" LIBMESH_PETSCINT_FMT
1967 " fieldsplit names, got %" LIBMESH_PETSCINT_FMT
" instead",
1972 for (PetscInt i = 0; i <
nsplits; ++i)
1974 split_names.push_back(std::string(splitnames[i]));
1982 "Print IS embedding DM's dofs",
1986 LIBMESH_PETSC_NULLPTR));
1993 static PetscErrorCode
2029 for (
auto & sit : *(dmm->
_splits))
2061 PetscValidHeaderSpecific(
dm, DM_CLASSID, 1);
2062 #if PETSC_RELEASE_LESS_THAN(3, 18, 0) 2064 #else // PetscNewLog was deprecated 2069 dmm->
_name =
new (std::string);
2070 dmm->
_var_ids =
new (std::map<std::string, unsigned int>);
2071 dmm->
_block_ids =
new (std::map<std::string, subdomain_id_type>);
2072 dmm->
_var_names =
new (std::map<unsigned int, std::string>);
2073 dmm->
_block_names =
new (std::map<unsigned int, std::string>);
2074 dmm->
_side_ids =
new (std::map<std::string, BoundaryID>);
2075 dmm->
_side_names =
new (std::map<BoundaryID, std::string>);
2076 dmm->
_unside_ids =
new (std::map<std::string, BoundaryID>);
2077 dmm->
_unside_names =
new (std::map<BoundaryID, std::string>);
2079 dmm->
_contact_names =
new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2080 dmm->
_uncontact_names =
new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2084 dmm->
_splits =
new (std::map<std::string, DM_Moose::SplitInfo>);
2089 dm->ops->createlocalvector = 0;
2090 dm->ops->getcoloring = 0;
2092 dm->ops->createinterpolation = 0;
2094 dm->ops->refine = 0;
2095 dm->ops->coarsen = 0;
2096 #if PETSC_RELEASE_LESS_THAN(3, 12, 0) 2097 dm->ops->getinjection = 0;
2098 dm->ops->getaggregates = 0;
2100 dm->ops->createinjection = 0;
2115 #define __FUNCT__ "SNESUpdateDMMoose" 2129 const char * prefix;
2158 static PetscBool DMMooseRegisterAllCalled = PETSC_FALSE;
2161 if (!DMMooseRegisterAllCalled)
2164 DMMooseRegisterAllCalled = PETSC_TRUE;
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
dof_id_type end_dof(const processor_id_type proc) const
PetscErrorCode DMMooseSetContacts(DM dm, const std::vector< std::pair< std::string, std::string >> &contacts, const std::vector< PetscBool > &displaced)
const std::vector< dof_id_type > & get_n_oz() const
std::set< std::pair< BoundaryID, unsigned int > > * _unside_by_var_set
PetscErrorCode DMMooseSetVariables(DM dm, const std::set< std::string > &vars)
std::map< BoundaryID, std::string > * _side_names
std::shared_ptr< DisplacedProblem > displaced_problem
std::set< std::string > varset
std::set< std::string > sideset
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
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
std::vector< DM_Moose::ContactName > uncontacts
PetscErrorCode DMMooseGetNonlinearSystem(DM dm, NonlinearSystemBase *&nl)
PetscBool is_include_all_nodes
PetscErrorCode DMMooseSetUnContacts(DM dm, const std::vector< std::pair< std::string, std::string >> &uncontacts, const std::vector< PetscBool > &displaced)
PetscErrorCode DMSetFromOptions_Moose(DM dm, PetscOptionItems) PetscErrorCode DMSetFromOptions_Moose(DM dm
std::map< std::string, BoundaryID > * _side_ids
bool _include_all_contact_nodes
std::string * _name
The name of this DM.
std::set< std::string > blockset
PetscErrorCode SNESUpdateDMMoose(SNES snes, PetscInt iteration)
static PetscErrorCode DMMooseGetMeshBlocks_Private(DM dm, std::set< subdomain_id_type > &blocks)
PetscErrorCode PetscOptionItems *PetscErrorCode DM dm
void checkSize(const std::string &split_name, const I1 split_size, const I2 size_expected_by_parent)
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const=0
std::map< ContactName, PetscBool > * _uncontact_displaced
const Parallel::Communicator & comm() const
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver()=0
dof_id_type n_dofs(const unsigned int vn) const
std::vector< PetscBool > uncontact_displaced
PetscErrorCode DMMooseReset(DM dm)
PetscErrorCode DMMooseGetUnContacts(DM dm, std::vector< std::pair< std::string, std::string >> &uncontact_names, std::vector< PetscBool > &displaced)
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
PetscErrorCode DMMooseSetNonlinearSystem(DM dm, NonlinearSystemBase &nl)
const BoundaryInfo & get_boundary_info() const
const MeshBase & get_mesh() const
static PetscErrorCode DMSetUp_Moose_Pre(DM dm)
const Variable & variable(const unsigned int c) const override
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
virtual void swap(NumericVector< T > &v) override
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)
PetscErrorCode DMMooseGetContacts(DM dm, std::vector< std::pair< std::string, std::string >> &contact_names, std::vector< PetscBool > &displaced)
void libmesh_ignore(const Args &...)
FEProblemBase & feProblem()
static PetscErrorCode SNESJacobian_DMMoose(SNES, Vec x, Mat jac, Mat pc, void *ctx)
unsigned int number() const
const Node & node_ref(const unsigned int i) const
static PetscErrorCode DMView_Moose(DM dm, PetscViewer viewer)
std::map< ContactID, ContactName > * _uncontact_names
unsigned int n_variables() const override
boundary_id_type BoundaryID
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
std::set< ContactName > * _contacts
std::unique_ptr< NumericVector< Number > > solution
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::string & subdomain_name(subdomain_id_type id)
OStreamProxy err(std::cerr)
dof_id_type n_dofs_on_processor(const processor_id_type proc) const
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)
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
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
subdomain_id_type subdomain_id() const
NonlinearSystemBase * _nl
PetscErrorCode DMMooseSetName(DM dm, const std::string &dm_name)
static PetscErrorCode SNESFunction_DMMoose(SNES, Vec x, Vec r, void *ctx)
const std::vector< dof_id_type > & get_n_nz() const
PetscErrorCode DMMooseValidityCheck(DM dm)
const std::set< boundary_id_type > & get_global_boundary_ids() const
PetscErrorCode DMMooseSetSides(DM dm, const std::set< std::string > &sides)
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
PetscErrorCode DMCreateMoose(MPI_Comm comm, NonlinearSystemBase &nl, const std::string &dm_name, DM *dm)
Create a MOOSE DM.
std::unique_ptr< NumericVector< Number > > current_local_solution
std::map< std::string, subdomain_id_type > * _block_ids
IntRange< unsigned short > node_index_range() const
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)
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
const std::string & name() const
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
std::set< subdomain_id_type > meshblocks
const std::string & name() const
dof_id_type first_dof(const processor_id_type proc) const
std::set< std::string > * _blocks
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
static PetscErrorCode DMCreateGlobalVector_Moose(DM dm, Vec *x)
processor_id_type processor_id() const
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
const DofMap & get_dof_map() const
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)
for(PetscInt i=0;i< nvars;++i)
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
PetscOptionsBegin(((PetscObject) dm) ->comm,((PetscObject) dm) ->prefix, "DMMoose options", "DM")
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
PenetrationLocator & getPenetrationLocator(const BoundaryName &primary, const BoundaryName &secondary, libMesh::Order order=libMesh::FIRST)
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 enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
void set_union(T &data, const unsigned int root_id) const
std::map< unsigned int, std::string > * _block_names
virtual libMesh::System & system() override
Get the reference to the libMesh system.