https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Functions | Variables
PetscDMMoose.C File Reference

Go to the source code of this file.

Classes

struct  DM_Moose
 
struct  DM_Moose::SplitInfo
 

Functions

template<typename I1 , typename I2 >
void checkSize (const std::string &split_name, const I1 split_size, const I2 size_expected_by_parent)
 
PetscErrorCode DMMooseValidityCheck (DM dm)
 
PetscErrorCode DMMooseGetContacts (DM dm, std::vector< std::pair< std::string, std::string > > &contact_names, std::vector< PetscBool > &displaced)
 
PetscErrorCode DMMooseGetUnContacts (DM dm, std::vector< std::pair< std::string, std::string > > &uncontact_names, std::vector< PetscBool > &displaced)
 
PetscErrorCode DMMooseGetSides (DM dm, std::vector< std::string > &side_names)
 
PetscErrorCode DMMooseGetUnSides (DM dm, std::vector< std::string > &side_names)
 
PetscErrorCode DMMooseGetBlocks (DM dm, std::vector< std::string > &block_names)
 
PetscErrorCode DMMooseGetVariables (DM dm, std::vector< std::string > &var_names)
 
PetscErrorCode DMMooseSetNonlinearSystem (DM dm, NonlinearSystemBase &nl)
 
PetscErrorCode DMMooseSetDofMap (DM dm, const DofMapBase &dof_map)
 
PetscErrorCode DMMooseSetSystem (DM dm, const System &system)
 
PetscErrorCode DMMooseSetName (DM dm, const std::string &dm_name)
 
PetscErrorCode DMMooseSetParentDM (DM dm, DM_Moose *parent)
 
PetscErrorCode DMMooseSetVariables (DM dm, const std::set< std::string > &vars)
 
PetscErrorCode DMMooseSetBlocks (DM dm, const std::set< std::string > &blocks)
 
PetscErrorCode DMMooseSetSides (DM dm, const std::set< std::string > &sides)
 
PetscErrorCode DMMooseSetUnSides (DM dm, const std::set< std::string > &unsides)
 
PetscErrorCode DMMooseSetUnSideByVar (DM dm, const std::set< std::string > &unside_by_var)
 
PetscErrorCode DMMooseSetContacts (DM dm, const std::vector< std::pair< std::string, std::string > > &contacts, const std::vector< PetscBool > &displaced)
 
PetscErrorCode DMMooseSetUnContacts (DM dm, const std::vector< std::pair< std::string, std::string > > &uncontacts, const std::vector< PetscBool > &displaced)
 
PetscErrorCode DMMooseGetNonlinearSystem (DM dm, NonlinearSystemBase *&nl)
 
PetscErrorCode DMMooseSetSplitNames (DM dm, const std::vector< std::string > &split_names)
 
PetscErrorCode DMMooseGetSplitNames (DM dm, std::vector< std::string > &split_names)
 
static PetscErrorCode DMMooseGetEmbedding_Private (DM dm, IS *embedding)
 
static PetscErrorCode DMCreateFieldDecomposition_Moose (DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
 
static PetscErrorCode DMCreateDomainDecomposition_Moose (DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
 
static PetscErrorCode DMMooseFunction (DM dm, Vec x, Vec r)
 
static PetscErrorCode SNESFunction_DMMoose (SNES, Vec x, Vec r, void *ctx)
 
static PetscErrorCode DMMooseJacobian (DM dm, Vec x, Mat jac, Mat pc)
 
static PetscErrorCode SNESJacobian_DMMoose (SNES, Vec x, Mat jac, Mat pc, void *ctx)
 
static PetscErrorCode DMVariableBounds_Moose (DM dm, Vec xl, Vec xu)
 
static PetscErrorCode DMCreateGlobalVector_Moose (DM dm, Vec *x)
 
static PetscErrorCode DMCreateMatrix_Moose (DM dm, Mat *A)
 
static PetscErrorCode DMView_Moose (DM dm, PetscViewer viewer)
 
static PetscErrorCode DMMooseGetMeshBlocks_Private (DM dm, std::set< subdomain_id_type > &blocks)
 
static PetscErrorCode DMSetUp_Moose_Pre (DM dm)
 
PetscErrorCode DMMooseReset (DM dm)
 
static PetscErrorCode DMSetUp_Moose (DM dm)
 
PetscErrorCode DMSetFromOptions_Moose (DM dm, PetscOptionItems) PetscErrorCode DMSetFromOptions_Moose(DM dm
 
PetscErrorCode PetscOptionItems *PetscErrorCode DMSetFromOptions_Moose (PetscOptionItems *, DM dm) PetscErrorCode DMSetFromOptions_Moose(PetscOptions *
 
 LibmeshPetscCallQ (DMMooseValidityCheck(dm))
 
 if (!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
 
 PetscOptionsBegin (((PetscObject) dm) ->comm,((PetscObject) dm) ->prefix, "DMMoose options", "DM")
 
 LibmeshPetscCallQ (PetscOptionsBegin(((PetscObject) dm) ->comm,((PetscObject) dm) ->prefix, "DMMoose options", "DM"))
 
 LibmeshPetscCallQ (PetscMalloc(maxvars *sizeof(char *), &vars))
 
 LibmeshPetscCallQ (PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetVars", vars, &nvars, LIBMESH_PETSC_NULLPTR))
 
 for (PetscInt i=0;i< nvars;++i)
 
 LibmeshPetscCallQ (PetscFree(vars))
 
 if (varset.size()) LibmeshPetscCallQ(DMMooseSetVariables(dm
 
 LibmeshPetscCallQ (DMMooseGetMeshBlocks_Private(dm, meshblocks))
 
 LibmeshPetscCallQ (PetscMalloc(maxblocks *sizeof(char *), &blocks))
 
 LibmeshPetscCallQ (PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetBlocks", blocks, &nblocks, LIBMESH_PETSC_NULLPTR))
 
 LibmeshPetscCallQ (PetscFree(blocks))
 
 if (blockset.size()) LibmeshPetscCallQ(DMMooseSetBlocks(dm
 
 LibmeshPetscCallQ (PetscMalloc(maxsides *maxvars *sizeof(char *), &sides))
 
 LibmeshPetscCallQ (PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetSides", sides, &nsides, LIBMESH_PETSC_NULLPTR))
 
 if (sideset.size()) LibmeshPetscCallQ(DMMooseSetSides(dm
 
 LibmeshPetscCallQ (PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetUnSides", sides, &nsides, LIBMESH_PETSC_NULLPTR))
 
sideset clear ()
 
 LibmeshPetscCallQ (PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetUnSideByVar", sides, &nsides, LIBMESH_PETSC_NULLPTR))
 
 LibmeshPetscCallQ (PetscFree(sides))
 
 if (displaced_problem)
 
 if (contacts.size()) LibmeshPetscCallQ(DMMooseSetContacts(dm
 
 LibmeshPetscCallQ (PetscOptionsInt(opt.c_str(), help.c_str(), "DMMooseSetUnContacts", nuncontacts, &nuncontacts, LIBMESH_PETSC_NULLPTR))
 
 if (LIBMESH_SETERRQ2(nuncontacts, maxcontacts)
 
 if (uncontacts.size()) LibmeshPetscCallQ(DMMooseSetUnContacts(dm
 
 LibmeshPetscCallQ (PetscOptionsInt("-dm_moose_nfieldsplits", fdhelp, "DMMooseSetSplitNames", nsplits, &nsplits, NULL))
 
 if (nsplits)
 
 LibmeshPetscCallQ (PetscOptionsBool("-dm_moose_print_embedding", "Print IS embedding DM's dofs", "DMMoose", dmm->_print_embedding, &dmm->_print_embedding, LIBMESH_PETSC_NULLPTR))
 
 PetscOptionsEnd ()
 
 LibmeshPetscCallQ (DMSetUp_Moose_Pre(dm))
 
 PetscFunctionReturn (PETSC_SUCCESS)
 
static PetscErrorCode DMDestroy_Moose (DM dm)
 
PetscErrorCode DMCreateMoose (MPI_Comm comm, NonlinearSystemBase &nl, const DofMapBase &dof_map, const System &system, const std::string &dm_name, DM *dm)
 Create a MOOSE DM.
 
EXTERN_C_BEGIN PetscErrorCode DMCreate_Moose (DM dm)
 
PetscErrorCode SNESUpdateDMMoose (SNES snes, PetscInt iteration)
 
PetscErrorCode DMMooseRegisterAll ()
 

Variables

PetscErrorCode PetscOptionItems *PetscErrorCode DM dm
 
 PetscFunctionBegin
 
 PETSC_ERR_ARG_WRONGSTATE
 
No Moose system set for DM_Moose
 
std::string opt = "-dm_moose_vars"
 
std::string help = "Variables in DMMoose"
 
PetscInt maxvars = dmm->_dof_map->n_variables()
 
char ** vars
 
std::set< std::string > varset
 
PetscInt nvars = maxvars
 
std::set< subdomain_id_typemeshblocks
 
PetscInt maxblocks = meshblocks.size()
 
char ** blocks
 
std::set< std::string > blockset
 
PetscInt nblocks = maxblocks
 
PetscInt maxsides = dmm->_system->get_mesh().get_boundary_info().get_global_boundary_ids().size()
 
char ** sides
 
PetscInt nsides = maxsides
 
std::set< std::string > sideset
 
PetscInt maxcontacts = dmm->_nl->feProblem().geomSearchData()._penetration_locators.size()
 
std::shared_ptr< DisplacedProblemdisplaced_problem = dmm->_nl->feProblem().getDisplacedProblem()
 
 contacts
 
 contact_displaced
 
PetscBool is_include_all_nodes
 
oopt<< "-dm_moose_includeAllContactNodes";ohelp<< "Whether to include all nodes on the contact surfaces into the subsolver";LibmeshPetscCallQ(PetscOptionsBool(oopt.str().c_str(), ohelp.str().c_str(), "", PETSC_FALSE, &is_include_all_nodes, LIBMESH_PETSC_NULLPTR));dmm-> _include_all_contact_nodes = is_include_all_nodes
 
std::vector< DM_Moose::ContactNameuncontacts
 
std::vector< PetscBool > uncontact_displaced
 
PetscInt nuncontacts = 0
 
PetscInt nsplits = 0
 
const char * fdhelp
 

Function Documentation

◆ checkSize()

template<typename I1 , typename I2 >
void checkSize ( const std::string &  split_name,
const I1  split_size,
const I2  size_expected_by_parent 
)

Definition at line 39 of file PetscDMMoose.C.

40{
41 if (libMesh::cast_int<libMesh::numeric_index_type>(split_size) !=
42 libMesh::cast_int<libMesh::numeric_index_type>(size_expected_by_parent))
43 mooseError("Split '",
44 split_name,
45 "' has size ",
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.");
51}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311

Referenced by DM_Moose::checkChildSize(), and DMCreateFieldDecomposition_Moose().

◆ clear()

sideset clear ( )

◆ DMCreate_Moose()

EXTERN_C_BEGIN PetscErrorCode DMCreate_Moose ( DM  dm)

Definition at line 2080 of file PetscDMMoose.C.

2081{
2082 DM_Moose * dmm;
2083
2085 PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2086#if PETSC_RELEASE_LESS_THAN(3, 18, 0)
2087 LibmeshPetscCallQ(PetscNewLog(dm, &dmm));
2088#else // PetscNewLog was deprecated
2089 LibmeshPetscCallQ(PetscNew(&dmm));
2090#endif
2091 dm->data = dmm;
2092
2093 dmm->_name = new (std::string);
2094 dmm->_var_ids = new (std::map<std::string, unsigned int>);
2095 dmm->_block_ids = new (std::map<std::string, subdomain_id_type>);
2096 dmm->_var_names = new (std::map<unsigned int, std::string>);
2097 dmm->_block_names = new (std::map<unsigned int, std::string>);
2098 dmm->_side_ids = new (std::map<std::string, BoundaryID>);
2099 dmm->_side_names = new (std::map<BoundaryID, std::string>);
2100 dmm->_unside_ids = new (std::map<std::string, BoundaryID>);
2101 dmm->_unside_names = new (std::map<BoundaryID, std::string>);
2102 dmm->_unside_by_var_set = new (std::set<std::pair<BoundaryID, unsigned int>>);
2103 dmm->_contact_names = new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2104 dmm->_uncontact_names = new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2105 dmm->_contact_displaced = new (std::map<DM_Moose::ContactName, PetscBool>);
2106 dmm->_uncontact_displaced = new (std::map<DM_Moose::ContactName, PetscBool>);
2107
2108 dmm->_splits = new (std::map<std::string, DM_Moose::SplitInfo>);
2109
2110 dmm->_print_embedding = PETSC_FALSE;
2111
2112 dm->ops->createglobalvector = DMCreateGlobalVector_Moose;
2113 dm->ops->createlocalvector = 0; // DMCreateLocalVector_Moose;
2114 dm->ops->getcoloring = 0; // DMGetColoring_Moose;
2115 dm->ops->creatematrix = DMCreateMatrix_Moose;
2116 dm->ops->createinterpolation = 0; // DMCreateInterpolation_Moose;
2117
2118 dm->ops->refine = 0; // DMRefine_Moose;
2119 dm->ops->coarsen = 0; // DMCoarsen_Moose;
2120#if PETSC_RELEASE_LESS_THAN(3, 12, 0)
2121 dm->ops->getinjection = 0; // DMGetInjection_Moose;
2122 dm->ops->getaggregates = 0; // DMGetAggregates_Moose;
2123#else
2124 dm->ops->createinjection = 0;
2125#endif
2126
2127 dm->ops->createfielddecomposition = DMCreateFieldDecomposition_Moose;
2128 dm->ops->createdomaindecomposition = DMCreateDomainDecomposition_Moose;
2129
2130 dm->ops->destroy = DMDestroy_Moose;
2131 dm->ops->view = DMView_Moose;
2132 dm->ops->setfromoptions = DMSetFromOptions_Moose;
2133 dm->ops->setup = DMSetUp_Moose;
2134 PetscFunctionReturn(PETSC_SUCCESS);
2135}
PetscErrorCode PetscOptionItems *PetscErrorCode DM dm
static PetscErrorCode DMCreateGlobalVector_Moose(DM dm, Vec *x)
static PetscErrorCode DMCreateDomainDecomposition_Moose(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
static PetscErrorCode DMView_Moose(DM dm, PetscViewer viewer)
static PetscErrorCode DMDestroy_Moose(DM dm)
static PetscErrorCode DMSetUp_Moose(DM dm)
PetscFunctionBegin
static PetscErrorCode DMCreateMatrix_Moose(DM dm, Mat *A)
static PetscErrorCode DMCreateFieldDecomposition_Moose(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
PetscErrorCode DMSetFromOptions_Moose(DM dm, PetscOptionItems) PetscErrorCode DMSetFromOptions_Moose(DM dm
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
std::string * _name
The name of this DM.
std::map< BoundaryID, std::string > * _side_names
std::map< std::string, BoundaryID > * _side_ids
std::map< std::string, BoundaryID > * _unside_ids
std::map< unsigned int, std::string > * _var_names
std::map< BoundaryID, std::string > * _unside_names
PetscBool _print_embedding
std::map< ContactID, ContactName > * _uncontact_names
std::set< std::pair< BoundaryID, unsigned int > > * _unside_by_var_set
std::map< std::string, SplitInfo > * _splits
std::map< std::string, subdomain_id_type > * _block_ids
std::map< unsigned int, std::string > * _block_names
std::map< ContactName, PetscBool > * _uncontact_displaced
std::map< std::string, unsigned int > * _var_ids
std::map< ContactName, PetscBool > * _contact_displaced
std::map< ContactID, ContactName > * _contact_names

Referenced by DMMooseRegisterAll().

◆ DMCreateDomainDecomposition_Moose()

static PetscErrorCode DMCreateDomainDecomposition_Moose ( DM  dm,
PetscInt *  len,
char ***  namelist,
IS **  innerislist,
IS **  outerislist,
DM **  dmlist 
)
static

Definition at line 960 of file PetscDMMoose.C.

962{
964 /* Use DMCreateFieldDecomposition_Moose() to obtain everything but outerislist, which is currently
965 * LIBMESH_PETSC_NULLPTR. */
966 if (outerislist)
967 *outerislist = LIBMESH_PETSC_NULLPTR; /* FIX: allow mesh-based overlap. */
968 LibmeshPetscCallQ(DMCreateFieldDecomposition_Moose(dm, len, namelist, innerislist, dmlist));
969 PetscFunctionReturn(PETSC_SUCCESS);
970}

Referenced by DMCreate_Moose().

◆ DMCreateFieldDecomposition_Moose()

static PetscErrorCode DMCreateFieldDecomposition_Moose ( DM  dm,
PetscInt *  len,
char ***  namelist,
IS **  islist,
DM **  dmlist 
)
static

Definition at line 849 of file PetscDMMoose.C.

851{
852 DM_Moose * dmm = (DM_Moose *)(dm->data);
853
855
856 PetscInt split_size_sum = 0;
857
858 /* Only called after DMSetUp(). */
859 if (!dmm->_splitlocs)
860 PetscFunctionReturn(PETSC_SUCCESS);
861 *len = dmm->_splitlocs->size();
862 if (namelist)
863 LibmeshPetscCallQ(PetscMalloc(*len * sizeof(char *), namelist));
864 if (islist)
865 LibmeshPetscCallQ(PetscMalloc(*len * sizeof(IS), islist));
866 if (dmlist)
867 LibmeshPetscCallQ(PetscMalloc(*len * sizeof(DM), dmlist));
868 for (const auto & dit : *(dmm->_splitlocs))
869 {
870 unsigned int d = dit.second;
871 std::string dname = dit.first;
872 DM_Moose::SplitInfo & dinfo = (*dmm->_splits)[dname];
873 if (!dinfo._dm)
874 {
876 ((PetscObject)dm)->comm, *dmm->_nl, *dmm->_dof_map, *dmm->_system, dname, &dinfo._dm));
878 PetscObjectSetOptionsPrefix((PetscObject)dinfo._dm, ((PetscObject)dm)->prefix));
879 std::string suffix = std::string("fieldsplit_") + dname + "_";
880 LibmeshPetscCallQ(PetscObjectAppendOptionsPrefix((PetscObject)dinfo._dm, suffix.c_str()));
882 }
883 LibmeshPetscCallQ(DMSetFromOptions(dinfo._dm));
884 LibmeshPetscCallQ(DMSetUp(dinfo._dm));
885 if (namelist)
886 LibmeshPetscCallQ(PetscStrallocpy(dname.c_str(), (*namelist) + d));
887 if (islist)
888 {
889 if (!dinfo._rembedding)
890 {
891 IS dembedding, lembedding;
893 if (dmm->_embedding)
894 {
895 // Create a relative embedding into the parent's index space.
896 LibmeshPetscCallQ(ISEmbed(dembedding, dmm->_embedding, PETSC_TRUE, &lembedding));
897 const PetscInt * lindices;
898 PetscInt len, dlen, llen, *rindices, off, i;
899 LibmeshPetscCallQ(ISGetLocalSize(dembedding, &dlen));
900 LibmeshPetscCallQ(ISGetLocalSize(lembedding, &llen));
901 if (llen != dlen)
902 LIBMESH_SETERRQ1(
903 ((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Failed to embed split %u", d);
904 LibmeshPetscCallQ(ISDestroy(&dembedding));
905 // Convert local embedding to global (but still relative) embedding
906 LibmeshPetscCallQ(PetscMalloc(llen * sizeof(PetscInt), &rindices));
907 LibmeshPetscCallQ(ISGetIndices(lembedding, &lindices));
908 LibmeshPetscCallQ(PetscMemcpy(rindices, lindices, llen * sizeof(PetscInt)));
909 LibmeshPetscCallQ(ISDestroy(&lembedding));
910 // We could get the index offset from a corresponding global vector, but subDMs don't yet
911 // have global vectors
912 LibmeshPetscCallQ(ISGetLocalSize(dmm->_embedding, &len));
913
914 MPI_Scan(&len,
915 &off,
916 1,
917#ifdef PETSC_USE_64BIT_INDICES
918 MPI_LONG_LONG_INT,
919#else
920 MPI_INT,
921#endif
922 MPI_SUM,
923 ((PetscObject)dm)->comm);
924
925 off -= len;
926 for (i = 0; i < llen; ++i)
927 rindices[i] += off;
928 LibmeshPetscCallQ(ISCreateGeneral(
929 ((PetscObject)dm)->comm, llen, rindices, PETSC_OWN_POINTER, &(dinfo._rembedding)));
930 }
931 else
932 {
933 dinfo._rembedding = dembedding;
934 }
935 }
936 LibmeshPetscCallQ(PetscObjectReference((PetscObject)(dinfo._rembedding)));
937 (*islist)[d] = dinfo._rembedding;
938 PetscInt is_size;
939 LibmeshPetscCallQ(ISGetLocalSize(dinfo._rembedding, &is_size));
940 split_size_sum += is_size;
941 }
942 if (dmlist)
943 {
944 LibmeshPetscCallQ(PetscObjectReference((PetscObject)dinfo._dm));
945 (*dmlist)[d] = dinfo._dm;
946 }
947 }
948
949 mooseAssert(islist, "What does it even mean if this is NULL?");
950
951 if (dmm->_parent)
952 dmm->_parent->checkChildSize(dm, split_size_sum, *dmm->_name);
953 else
954 checkSize(*dmm->_name, split_size_sum, dmm->_dof_map->n_local_dofs());
955
956 PetscFunctionReturn(PETSC_SUCCESS);
957}
PetscErrorCode DMMooseSetParentDM(DM dm, DM_Moose *parent)
void checkSize(const std::string &split_name, const I1 split_size, const I2 size_expected_by_parent)
static PetscErrorCode DMMooseGetEmbedding_Private(DM dm, IS *embedding)
PetscErrorCode DMCreateMoose(MPI_Comm comm, NonlinearSystemBase &nl, const DofMapBase &dof_map, const System &system, const std::string &dm_name, DM *dm)
Create a MOOSE DM.
dof_id_type n_local_dofs() const
std::multimap< std::string, unsigned int > * _splitlocs
DM_Moose * _parent
NonlinearSystemBase * _nl
void checkChildSize(DM child, PetscInt child_size, const std::string &child_name)
Check whether the size of the child matches the size we expect.
const DofMapBase * _dof_map
const System * _system

Referenced by DMCreate_Moose(), and DMCreateDomainDecomposition_Moose().

◆ DMCreateGlobalVector_Moose()

static PetscErrorCode DMCreateGlobalVector_Moose ( DM  dm,
Vec *  x 
)
static

Definition at line 1165 of file PetscDMMoose.C.

1166{
1167 DM_Moose * dmm = (DM_Moose *)(dm->data);
1168
1171 if (!dmm->_nl)
1172 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1173
1174 NumericVector<Number> * nv = (dmm->_system->solution).get();
1175 PetscVector<Number> * pv = dynamic_cast<PetscVector<Number> *>(nv);
1176 Vec v = pv->vec();
1177 /* Unfortunately, currently this does not produce a ghosted vector, so nonlinear subproblem solves
1178 aren't going to be easily available.
1179 Should work fine for getting vectors out for linear subproblem solvers. */
1180 if (dmm->_embedding)
1181 {
1182 PetscInt n;
1183 LibmeshPetscCallQ(VecCreate(((PetscObject)v)->comm, x));
1184 LibmeshPetscCallQ(ISGetLocalSize(dmm->_embedding, &n));
1185 LibmeshPetscCallQ(VecSetSizes(*x, n, PETSC_DETERMINE));
1186 LibmeshPetscCallQ(VecSetType(*x, ((PetscObject)v)->type_name));
1187 LibmeshPetscCallQ(VecSetFromOptions(*x));
1188 LibmeshPetscCallQ(VecSetUp(*x));
1189 }
1190 else
1191 LibmeshPetscCallQ(VecDuplicate(v, x));
1192
1193#if PETSC_RELEASE_LESS_THAN(3, 13, 0)
1194 LibmeshPetscCallQ(PetscObjectCompose((PetscObject)*x, "DM", (PetscObject)dm));
1195#else
1196 LibmeshPetscCallQ(VecSetDM(*x, dm));
1197#endif
1198 PetscFunctionReturn(PETSC_SUCCESS);
1199}
PETSC_ERR_ARG_WRONGSTATE
PetscErrorCode DMMooseValidityCheck(DM dm)
std::unique_ptr< NumericVector< Number > > solution
const Elem & get(const ElemType type_in)

Referenced by DMCreate_Moose().

◆ DMCreateMatrix_Moose()

static PetscErrorCode DMCreateMatrix_Moose ( DM  dm,
Mat *  A 
)
static

Definition at line 1202 of file PetscDMMoose.C.

1203{
1204 DM_Moose * dmm = (DM_Moose *)(dm->data);
1205 MatType type;
1206
1209 if (!dmm->_nl)
1210 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1211 LibmeshPetscCallQ(DMGetMatType(dm, &type));
1212
1213 /*
1214 The simplest thing for now: compute the sparsity_pattern using dof_map and init the matrix using
1215 that info.
1216 TODO: compute sparsity restricted to this DM's blocks, variables and sides.
1217 Even fancier: compute the sparsity of the coupling of a contact secondary to the contact primary.
1218 In any event, here we are in control of the matrix type and structure.
1219 */
1220 const auto & dof_map = *dmm->_dof_map;
1221 PetscInt M, N, m, n;
1222 MPI_Comm comm;
1223 M = dof_map.n_dofs();
1224 N = M;
1225 m = static_cast<PetscInt>(dof_map.n_local_dofs());
1226 n = m;
1227 LibmeshPetscCallQ(PetscObjectGetComm((PetscObject)dm, &comm));
1228 LibmeshPetscCallQ(MatCreate(comm, A));
1229 LibmeshPetscCallQ(MatSetSizes(*A, m, n, M, N));
1230 LibmeshPetscCallQ(MatSetType(*A, type));
1231 /* TODO: set the prefix for *A and MatSetFromOptions(*A)? Might override the type and other
1232 * settings made here. */
1233 LibmeshPetscCallQ(MatSetUp(*A));
1234 PetscFunctionReturn(PETSC_SUCCESS);
1235}

Referenced by DMCreate_Moose().

◆ DMCreateMoose()

PetscErrorCode DMCreateMoose ( MPI_Comm  comm,
NonlinearSystemBase nl,
const libMesh::DofMapBase dof_map,
const libMesh::System system,
const std::string &  dm_name,
DM *  dm 
)

Create a MOOSE DM.

Parameters
commThe communicator that the DM should use
nlThe nonlinear system context that the DM is associated with
dof_mapA reference to the DoFMap, which you can get from the system
dm_nameA name to associate with the DM
dmA pointer to the PETSc DM

Definition at line 2061 of file PetscDMMoose.C.

2067{
2069 LibmeshPetscCallQ(DMCreate(comm, dm));
2070 LibmeshPetscCallQ(DMSetType(*dm, DMMOOSE));
2075 PetscFunctionReturn(PETSC_SUCCESS);
2076}
PetscErrorCode DMMooseSetSystem(DM dm, const System &system)
PetscErrorCode DMMooseSetName(DM dm, const std::string &dm_name)
PetscErrorCode DMMooseSetNonlinearSystem(DM dm, NonlinearSystemBase &nl)
PetscErrorCode DMMooseSetDofMap(DM dm, const DofMapBase &dof_map)

Referenced by FieldSplitPreconditionerTempl< Base >::createMooseDM(), and DMCreateFieldDecomposition_Moose().

◆ DMDestroy_Moose()

static PetscErrorCode DMDestroy_Moose ( DM  dm)
static

Definition at line 2011 of file PetscDMMoose.C.

2012{
2013 DM_Moose * dmm = (DM_Moose *)(dm->data);
2014
2016 delete dmm->_name;
2017 if (dmm->_vars)
2018 delete dmm->_vars;
2019 delete dmm->_var_ids;
2020 delete dmm->_var_names;
2021 if (dmm->_blocks)
2022 delete dmm->_blocks;
2023 delete dmm->_block_ids;
2024 delete dmm->_block_names;
2025 if (dmm->_sides)
2026 delete dmm->_sides;
2027 delete dmm->_side_ids;
2028 delete dmm->_side_names;
2029 if (dmm->_unsides)
2030 delete dmm->_unsides;
2031 delete dmm->_unside_ids;
2032 delete dmm->_unside_names;
2033 if (dmm->_unside_by_var)
2034 delete dmm->_unside_by_var;
2035 delete dmm->_unside_by_var_set;
2036 if (dmm->_contacts)
2037 delete dmm->_contacts;
2038 delete dmm->_contact_names;
2039 delete dmm->_contact_displaced;
2040 if (dmm->_uncontacts)
2041 delete dmm->_uncontacts;
2042 delete dmm->_uncontact_names;
2043 delete dmm->_uncontact_displaced;
2044 if (dmm->_splits)
2045 {
2046 for (auto & sit : *(dmm->_splits))
2047 {
2048 LibmeshPetscCallQ(DMDestroy(&(sit.second._dm)));
2049 LibmeshPetscCallQ(ISDestroy(&(sit.second._rembedding)));
2050 }
2051 delete dmm->_splits;
2052 }
2053 if (dmm->_splitlocs)
2054 delete dmm->_splitlocs;
2055 LibmeshPetscCallQ(ISDestroy(&dmm->_embedding));
2056 LibmeshPetscCallQ(PetscFree(dm->data));
2057 PetscFunctionReturn(PETSC_SUCCESS);
2058}
std::set< ContactName > * _contacts
std::set< std::string > * _sides
std::set< std::string > * _unsides
std::set< std::string > * _blocks
std::set< ContactName > * _uncontacts
std::set< std::string > * _vars
std::set< std::string > * _unside_by_var

Referenced by DMCreate_Moose().

◆ DMMooseFunction()

static PetscErrorCode DMMooseFunction ( DM  dm,
Vec  x,
Vec  r 
)
static

Definition at line 973 of file PetscDMMoose.C.

974{
978
979 NonlinearSystemBase * nl = NULL;
981 PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(nl->system().solution.get());
982 PetscVector<Number> X_global(x, nl->comm()), R(r, nl->comm());
983
984 // Use the system's update() to get a good local version of the
985 // parallel solution. system.update() does change the residual vector,
986 // so there's no reason to swap PETSc's residual into the system for
987 // this step.
988 X_global.swap(X_sys);
989 nl->system().update();
990 X_global.swap(X_sys);
991
992 // Enforce constraints (if any) exactly on the
993 // current_local_solution. This is the solution vector that is
994 // actually used in the computation of the residual below, and is
995 // not locked by debug-enabled PETSc the way that "x" is.
997 nl->system().current_local_solution.get());
998
999 // Zero the residual vector before assembling
1000 R.zero();
1001
1002 // if the user has provided both function pointers and objects only the pointer
1003 // will be used, so catch that as an error
1004 if (nl->nonlinearSolver()->residual && nl->nonlinearSolver()->residual_object)
1005 {
1006 std::ostringstream err;
1007 err << "ERROR: cannot specifiy both a function and object to compute the Residual!"
1008 << std::endl;
1009 mooseError(err.str());
1010 }
1011 if (nl->nonlinearSolver()->matvec && nl->nonlinearSolver()->residual_and_jacobian_object)
1012 {
1013 std::ostringstream err;
1014 err << "ERROR: cannot specifiy both a function and object to compute the combined Residual & "
1015 "Jacobian!"
1016 << std::endl;
1017 mooseError(err.str());
1018 }
1019 if (nl->nonlinearSolver()->residual != NULL)
1020 nl->nonlinearSolver()->residual(
1021 *(nl->system().current_local_solution.get()), R, nl->nonlinearSolver()->system());
1022 else if (nl->nonlinearSolver()->residual_object != NULL)
1023 nl->nonlinearSolver()->residual_object->residual(
1024 *(nl->system().current_local_solution.get()), R, nl->nonlinearSolver()->system());
1025 else if (nl->nonlinearSolver()->matvec != NULL)
1026 nl->nonlinearSolver()->matvec(
1027 *(nl->system().current_local_solution.get()), &R, NULL, nl->nonlinearSolver()->system());
1028 else if (nl->nonlinearSolver()->residual_and_jacobian_object != NULL)
1029 nl->nonlinearSolver()->residual_and_jacobian_object->residual_and_jacobian(
1030 *(nl->system().current_local_solution.get()), &R, NULL, nl->nonlinearSolver()->system());
1031 else
1032 {
1033 std::ostringstream err;
1034 err << "No suitable residual computation routine found";
1035 mooseError(err.str());
1036 }
1037 R.close();
1038 PetscFunctionReturn(PETSC_SUCCESS);
1039}
PetscErrorCode DMMooseGetNonlinearSystem(DM dm, NonlinearSystemBase *&nl)
Nonlinear system to be solved.
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver()=0
virtual libMesh::System & system() override
Get the reference to the libMesh system.
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
const Parallel::Communicator & comm() const
std::unique_ptr< NumericVector< Number > > current_local_solution
virtual void update()
const DofMap & get_dof_map() const
libmesh_assert(ctx)
OStreamProxy err(std::cerr)

Referenced by SNESFunction_DMMoose().

◆ DMMooseGetBlocks()

PetscErrorCode DMMooseGetBlocks ( DM  dm,
std::vector< std::string > &  block_names 
)

Definition at line 203 of file PetscDMMoose.C.

204{
207 DM_Moose * dmm = (DM_Moose *)dm->data;
208 for (const auto & it : *(dmm->_block_ids))
209 block_names.push_back(it.first);
210 PetscFunctionReturn(PETSC_SUCCESS);
211}

◆ DMMooseGetContacts()

PetscErrorCode DMMooseGetContacts ( DM  dm,
std::vector< std::pair< std::string, std::string > > &  contact_names,
std::vector< PetscBool > &  displaced 
)

Definition at line 149 of file PetscDMMoose.C.

152{
155 DM_Moose * dmm = (DM_Moose *)dm->data;
156 for (const auto & it : *(dmm->_contact_names))
157 {
158 contact_names.push_back(it.second);
159 displaced.push_back((*dmm->_contact_displaced)[it.second]);
160 }
161 PetscFunctionReturn(PETSC_SUCCESS);
162}

◆ DMMooseGetEmbedding_Private()

static PetscErrorCode DMMooseGetEmbedding_Private ( DM  dm,
IS *  embedding 
)
static

Definition at line 512 of file PetscDMMoose.C.

513{
514 DM_Moose * dmm = (DM_Moose *)dm->data;
515
517 if (!embedding)
518 PetscFunctionReturn(PETSC_SUCCESS);
519 if (!dmm->_embedding)
520 {
521 // The rules interpreting the coexistence of blocks (un)sides/(un)contacts are these
522 // [sides and contacts behave similarly, so 'sides' means 'sides/contacts']
523 // ['ANY' means 'not NONE' and covers 'ALL' as well, unless there is a specific 'ALL' clause,
524 // which overrides 'ANY'; 'NOT ALL' means not ALL and not NONE]
525 // [there are always some blocks, since by default 'ALL' is assumed, unless it is overridden by
526 // a specific list, which implies ANY]
527 // In general,
528 // (1) ALL blocks and ANY sides are interpreted as the INTERSECTION of blocks and sides,
529 // equivalent to just the sides (since ALL blocks are assumed to be a cover).
530 // (2) NOT ALL blocks and ANY or NO sides are interpreted as the UNION of blocks and sides.
531 // (3a) ANY unsides and ANY blocks are interpreted as the DIFFERENCE of blocks and unsides.
532 // (3b) ANY unsides and ANY sides are interpreted as the DIFFERENCE of sides and unsides.
533 // (4) NO unsides means NO DIFFERENCE is needed.
534 // The result is easily computed by first computing the result of (1 & 2) followed by difference
535 // with the result of (3 & 4).
536 // To simply (1 & 2) observe the following:
537 // - The intersection is computed only if ALL blocks and ANY sides, and the result is the sides,
538 // so block dofs do not need to be computed.
539 // - Otherwise the union is computed, and initially consists of the blocks' dofs, to which the
540 // sides' dofs are added, if ANY.
541 // - The result is called 'indices'
542 // To satisfy (3 & 4) simply cmpute subtrahend set 'unindices' as all of the unsides' dofs:
543 // Then take the set difference of 'indices' and 'unindices', putting the result in 'dindices'.
544 if (!dmm->_all_vars || !dmm->_all_blocks || !dmm->_nosides || !dmm->_nounsides ||
545 !dmm->_nounside_by_var || !dmm->_nocontacts || !dmm->_nouncontacts)
546 {
547 auto & dofmap = *dmm->_dof_map;
548 // Put this outside the lambda scope to avoid constant memory reallocation
549 std::vector<dof_id_type> node_indices;
550 auto process_nodal_dof_indices =
551 [&dofmap, &node_indices](const Node & node,
552 const unsigned int var_num,
553 std::set<dof_id_type> & local_indices,
554 std::set<dof_id_type> * const nonlocal_indices = nullptr)
555 {
556 dofmap.dof_indices(&node, node_indices, var_num);
557 for (const auto index : node_indices)
558 {
559 if (index >= dofmap.first_dof() && index < dofmap.end_dof())
560 local_indices.insert(index);
561 else if (nonlocal_indices)
562 nonlocal_indices->insert(index);
563 }
564 };
565
566 auto process_elem_dof_indices =
567 [&dofmap](const std::vector<dof_id_type> & elem_indices,
568 std::set<dof_id_type> & local_indices,
569 std::set<dof_id_type> * const nonlocal_indices = nullptr)
570 {
571 for (const auto index : elem_indices)
572 {
573 if (index >= dofmap.first_dof() && index < dofmap.end_dof())
574 local_indices.insert(index);
575 else if (nonlocal_indices)
576 nonlocal_indices->insert(index);
577 }
578 };
579
580 std::set<dof_id_type> indices;
581 std::set<dof_id_type> unindices;
582 std::set<dof_id_type> cached_indices;
583 std::set<dof_id_type> cached_unindices;
584 auto & lm_mesh = dmm->_system->get_mesh();
585 const auto & node_to_elem_map = dmm->_nl->feProblem().mesh().nodeToElemMap();
586 for (const auto & vit : *(dmm->_var_ids))
587 {
588 unsigned int v = vit.second;
589 // Iterate only over this DM's blocks.
590 if (!dmm->_all_blocks || (dmm->_nosides && dmm->_nocontacts))
591 for (const auto & bit : *(dmm->_block_ids))
592 {
593 subdomain_id_type b = bit.second;
594 for (const auto & elem : as_range(lm_mesh.active_local_subdomain_elements_begin(b),
595 lm_mesh.active_local_subdomain_elements_end(b)))
596 {
597 // Get the degree of freedom indices for the given variable off the current element.
598 std::vector<dof_id_type> evindices;
599 dofmap.dof_indices(elem, evindices, v);
600 process_elem_dof_indices(evindices, indices);
601 }
602
603 // Sometime, we own nodes but do not own the elements the nodes are connected to
604 {
605 bool is_on_current_block = false;
606 for (auto & node : lm_mesh.local_node_ptr_range())
607 {
608 const unsigned int n_comp = node->n_comp(dmm->_system->number(), v);
609
610 // skip it if no dof
611 if (!n_comp)
612 continue;
613
614 auto node_to_elem_pair = node_to_elem_map.find(node->id());
615 is_on_current_block = false;
616 for (const auto & elem_num : node_to_elem_pair->second)
617 {
618 // if one of incident elements belongs to a block, we consider
619 // the node lives in the block
620 const Elem & neighbor_elem = lm_mesh.elem_ref(elem_num);
621 if (neighbor_elem.subdomain_id() == b)
622 {
623 is_on_current_block = true;
624 break;
625 }
626 }
627 // we add indices for the current block only
628 if (!is_on_current_block)
629 continue;
630
631 process_nodal_dof_indices(*node, v, indices);
632 }
633 }
634 }
635
636 // Iterate over the sides from this split.
637 if (dmm->_side_ids->size())
638 {
639 // For some reason the following may return an empty node list
640 // std::vector<dof_id_type> snodes;
641 // std::vector<boundary_id_type> sides;
642 // dmm->nl->system().get_mesh().get_boundary_info().build_node_list(snodes, sides);
643 // // FIXME: make an array of (snode,side) pairs, sort on side and use std::lower_bound
644 // from <algorithm>
645 // for (dof_id_type i = 0; i < sides.size(); ++i) {
646 // boundary_id_type s = sides[i];
647 // if (!dmm->sidenames->count(s)) continue;
648 // const Node& node = dmm->nl->system().get_mesh().node_ref(snodes[i]);
649 // // determine v's dof on node and insert into indices
650 // }
651 ConstBndNodeRange & bnodes = *dmm->_nl->mesh().getBoundaryNodeRange();
652 for (const auto & bnode : bnodes)
653 {
654 BoundaryID boundary_id = bnode->_bnd_id;
655 if (dmm->_side_names->find(boundary_id) == dmm->_side_names->end())
656 continue;
657
658 const Node * node = bnode->_node;
659 process_nodal_dof_indices(*node, v, indices);
660 }
661 }
662
663 // Iterate over the sides excluded from this split.
664 if (dmm->_unside_ids->size())
665 {
666 ConstBndNodeRange & bnodes = *dmm->_nl->mesh().getBoundaryNodeRange();
667 for (const auto & bnode : bnodes)
668 {
669 BoundaryID boundary_id = bnode->_bnd_id;
670 if (dmm->_unside_names->find(boundary_id) == dmm->_unside_names->end())
671 continue;
672 const Node * node = bnode->_node;
673 process_nodal_dof_indices(*node, v, unindices);
674 }
675 }
676 if (dmm->_unside_by_var_set->size())
677 {
678 std::set<BoundaryID> eligible_bids;
679 for (const auto & [bid, var] : *(dmm->_unside_by_var_set))
680 if (var == v)
681 eligible_bids.insert(bid);
682
683 ConstBndNodeRange & bnodes = *dmm->_nl->mesh().getBoundaryNodeRange();
684 for (const auto & bnode : bnodes)
685 {
686 BoundaryID boundary_id = bnode->_bnd_id;
687 if (eligible_bids.count(boundary_id))
688 {
689 const Node * node = bnode->_node;
690 process_nodal_dof_indices(*node, v, unindices);
691 }
692 }
693 }
694
695 auto process_contact_all_nodes =
696 [dmm, process_nodal_dof_indices, v](const auto & contact_names,
697 auto & indices_to_insert_to)
698 {
699 std::set<boundary_id_type> bc_id_set;
700 // loop over contacts
701 for (const auto & [contact_bid_pair, contact_bname_pair] : contact_names)
702 {
703 libmesh_ignore(contact_bname_pair);
704 bc_id_set.insert(contact_bid_pair.first); // primary
705 bc_id_set.insert(contact_bid_pair.second); // secondary
706 }
707 // loop over boundary elements
708 ConstBndElemRange & range = *dmm->_nl->feProblem().mesh().getBoundaryElementRange();
709 for (const auto & belem : range)
710 {
711 const Elem * elem_bdry = belem->_elem;
712 const auto side = belem->_side;
713 BoundaryID boundary_id = belem->_bnd_id;
714
715 if (bc_id_set.find(boundary_id) == bc_id_set.end())
716 continue;
717
718 for (const auto node_idx : elem_bdry->node_index_range())
719 if (elem_bdry->is_node_on_side(node_idx, side))
720 process_nodal_dof_indices(elem_bdry->node_ref(node_idx), v, indices_to_insert_to);
721 }
722 };
723
724 auto process_contact_some_nodes =
725 [dmm, process_nodal_dof_indices, v, &dofmap, &lm_mesh, process_elem_dof_indices](
726 const auto & contact_names,
727 auto & indices_to_insert_to,
728 auto & nonlocal_indices_to_insert_to)
729 {
730 std::vector<dof_id_type> evindices;
731 for (const auto & it : contact_names)
732 {
733 PetscBool displaced = (*dmm->_uncontact_displaced)[it.second];
734 PenetrationLocator * locator;
735 if (displaced)
736 {
737 std::shared_ptr<DisplacedProblem> displaced_problem =
738 dmm->_nl->feProblem().getDisplacedProblem();
740 {
741 std::ostringstream err;
742 err << "Cannot use a displaced uncontact (" << it.second.first << ","
743 << it.second.second << ") with an undisplaced problem";
744 mooseError(err.str());
745 }
746 locator = displaced_problem->geomSearchData()._penetration_locators[it.first];
747 }
748 else
749 locator = dmm->_nl->feProblem().geomSearchData()._penetration_locators[it.first];
750
751 evindices.clear();
752 // penetration locator
753 auto lend = locator->_penetration_info.end();
754 for (auto lit = locator->_penetration_info.begin(); lit != lend; ++lit)
755 {
756 const dof_id_type secondary_node_num = lit->first;
757 PenetrationInfo * pinfo = lit->second;
758 if (pinfo && pinfo->isCaptured())
759 {
760 const Node & secondary_node = lm_mesh.node_ref(secondary_node_num);
761 process_nodal_dof_indices(
762 secondary_node, v, indices_to_insert_to, &nonlocal_indices_to_insert_to);
763
764 // indices for primary element
765 evindices.clear();
766 const Elem * primary_side = pinfo->_side;
767 dofmap.dof_indices(primary_side, evindices, v);
768 process_elem_dof_indices(
769 evindices, indices_to_insert_to, &nonlocal_indices_to_insert_to);
770 } // if pinfo
771 } // for penetration
772 } // for contact name
773 };
774
775 // Include all nodes on the contact surfaces
776 if (dmm->_contact_names->size() && dmm->_include_all_contact_nodes)
777 process_contact_all_nodes(*dmm->_contact_names, indices);
778
779 // Iterate over the contacts included in this split.
780 if (dmm->_contact_names->size() && !(dmm->_include_all_contact_nodes))
781 process_contact_some_nodes(*dmm->_contact_names, indices, cached_indices);
782
783 // Exclude all nodes on the contact surfaces
784 if (dmm->_uncontact_names->size() && dmm->_include_all_contact_nodes)
785 process_contact_all_nodes(*dmm->_uncontact_names, unindices);
786
787 // Iterate over the contacts excluded from this split.
788 if (dmm->_uncontact_names->size() && !(dmm->_include_all_contact_nodes))
789 process_contact_some_nodes(*dmm->_uncontact_names, unindices, cached_unindices);
790 } // variables
791
792 std::vector<dof_id_type> local_vec_indices(cached_indices.size());
793 std::copy(cached_indices.begin(), cached_indices.end(), local_vec_indices.begin());
794 if (dmm->_contact_names->size() && !(dmm->_include_all_contact_nodes))
795 dmm->_nl->feProblem().mesh().comm().allgather(local_vec_indices, false);
796 // insert indices
797 for (const auto & dof : local_vec_indices)
798 if (dof >= dofmap.first_dof() && dof < dofmap.end_dof())
799 indices.insert(dof);
800
801 local_vec_indices.clear();
802 local_vec_indices.resize(cached_unindices.size());
803 std::copy(cached_unindices.begin(), cached_unindices.end(), local_vec_indices.begin());
804 if (dmm->_uncontact_names->size() && !(dmm->_include_all_contact_nodes))
805 dmm->_nl->feProblem().mesh().comm().allgather(local_vec_indices, false);
806 // insert unindices
807 for (const auto & dof : local_vec_indices)
808 if (dof >= dofmap.first_dof() && dof < dofmap.end_dof())
809 unindices.insert(dof);
810
811 std::set<dof_id_type> dindices;
812 std::set_difference(indices.begin(),
813 indices.end(),
814 unindices.begin(),
815 unindices.end(),
816 std::inserter(dindices, dindices.end()));
817 PetscInt * darray;
818 LibmeshPetscCallQ(PetscMalloc(sizeof(PetscInt) * dindices.size(), &darray));
819 dof_id_type i = 0;
820 for (const auto & dof : dindices)
821 {
822 darray[i] = dof;
823 ++i;
824 }
825 LibmeshPetscCallQ(ISCreateGeneral(
826 ((PetscObject)dm)->comm, dindices.size(), darray, PETSC_OWN_POINTER, &dmm->_embedding));
827 }
828 else
829 {
830 // if (dmm->allblocks && dmm->allvars && dmm->nosides && dmm->nounsides && dmm->nocontacts &&
831 // dmm->nouncontacts)
832 // DMCreateGlobalVector is defined()
833 Vec v;
834 PetscInt low, high;
835
836 LibmeshPetscCallQ(DMCreateGlobalVector(dm, &v));
837 LibmeshPetscCallQ(VecGetOwnershipRange(v, &low, &high));
839 ISCreateStride(((PetscObject)dm)->comm, (high - low), low, 1, &dmm->_embedding));
840 }
841 }
842 LibmeshPetscCallQ(PetscObjectReference((PetscObject)(dmm->_embedding)));
843 *embedding = dmm->_embedding;
844
845 PetscFunctionReturn(PETSC_SUCCESS);
846}
boundary_id_type BoundaryID
std::shared_ptr< DisplacedProblem > displaced_problem
Data structure used to hold penetration information.
const Elem * _side
bool isCaptured() const
std::map< dof_id_type, PenetrationInfo * > & _penetration_info
Data structure of nodes and their associated penetration information.
subdomain_id_type subdomain_id() const
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
void libmesh_ignore(const Args &...)
if(subdm)
uint8_t dof_id_type

Referenced by DMCreateFieldDecomposition_Moose(), and DMSetUp_Moose().

◆ DMMooseGetMeshBlocks_Private()

static PetscErrorCode DMMooseGetMeshBlocks_Private ( DM  dm,
std::set< subdomain_id_type > &  blocks 
)
static

Definition at line 1336 of file PetscDMMoose.C.

1337{
1338 DM_Moose * dmm = (DM_Moose *)(dm->data);
1339
1342 if (!dmm->_nl)
1343 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1344
1345 const MeshBase & mesh = dmm->_system->get_mesh();
1346 /* The following effectively is a verbatim copy of MeshBase::n_subdomains(). */
1347 // This requires an inspection on every processor
1348 libmesh_parallel_only(mesh.comm());
1349 for (const auto & elem : mesh.active_element_ptr_range())
1350 blocks.insert(elem->subdomain_id());
1351 // Some subdomains may only live on other processors
1353 PetscFunctionReturn(PETSC_SUCCESS);
1354}
char ** blocks
void set_union(T &data, const unsigned int root_id) const
const MeshBase & get_mesh() const
MeshBase & mesh

Referenced by DMSetUp_Moose_Pre().

◆ DMMooseGetNonlinearSystem()

PetscErrorCode DMMooseGetNonlinearSystem ( DM  dm,
NonlinearSystemBase *&  nl 
)

Definition at line 446 of file PetscDMMoose.C.

447{
450 DM_Moose * dmm = (DM_Moose *)(dm->data);
451 nl = dmm->_nl;
452 PetscFunctionReturn(PETSC_SUCCESS);
453}

Referenced by DMMooseFunction(), DMMooseJacobian(), and DMVariableBounds_Moose().

◆ DMMooseGetSides()

PetscErrorCode DMMooseGetSides ( DM  dm,
std::vector< std::string > &  side_names 
)

Definition at line 181 of file PetscDMMoose.C.

182{
185 DM_Moose * dmm = (DM_Moose *)dm->data;
186 for (const auto & it : *(dmm->_side_ids))
187 side_names.push_back(it.first);
188 PetscFunctionReturn(PETSC_SUCCESS);
189}

◆ DMMooseGetSplitNames()

PetscErrorCode DMMooseGetSplitNames ( DM  dm,
std::vector< std::string > &  split_names 
)

Definition at line 492 of file PetscDMMoose.C.

493{
496 DM_Moose * dmm = (DM_Moose *)(dm->data);
497 if (!dm->setupcalled)
498 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM not set up");
499 split_names.clear();
500 split_names.reserve(dmm->_splitlocs->size());
501 if (dmm->_splitlocs && dmm->_splitlocs->size())
502 for (const auto & lit : *(dmm->_splitlocs))
503 {
504 std::string sname = lit.first;
505 unsigned int sloc = lit.second;
506 split_names[sloc] = sname;
507 }
508 PetscFunctionReturn(PETSC_SUCCESS);
509}

◆ DMMooseGetUnContacts()

PetscErrorCode DMMooseGetUnContacts ( DM  dm,
std::vector< std::pair< std::string, std::string > > &  uncontact_names,
std::vector< PetscBool > &  displaced 
)

Definition at line 165 of file PetscDMMoose.C.

168{
171 DM_Moose * dmm = (DM_Moose *)dm->data;
172 for (const auto & it : *(dmm->_uncontact_names))
173 {
174 uncontact_names.push_back(it.second);
175 displaced.push_back((*dmm->_uncontact_displaced)[it.second]);
176 }
177 PetscFunctionReturn(PETSC_SUCCESS);
178}

◆ DMMooseGetUnSides()

PetscErrorCode DMMooseGetUnSides ( DM  dm,
std::vector< std::string > &  side_names 
)

Definition at line 192 of file PetscDMMoose.C.

193{
196 DM_Moose * dmm = (DM_Moose *)dm->data;
197 for (const auto & it : *(dmm->_unside_ids))
198 side_names.push_back(it.first);
199 PetscFunctionReturn(PETSC_SUCCESS);
200}

◆ DMMooseGetVariables()

PetscErrorCode DMMooseGetVariables ( DM  dm,
std::vector< std::string > &  var_names 
)

Definition at line 214 of file PetscDMMoose.C.

215{
218 DM_Moose * dmm = (DM_Moose *)(dm->data);
219 for (const auto & it : *(dmm->_var_ids))
220 var_names.push_back(it.first);
221 PetscFunctionReturn(PETSC_SUCCESS);
222}

◆ DMMooseJacobian()

static PetscErrorCode DMMooseJacobian ( DM  dm,
Vec  x,
Mat  jac,
Mat  pc 
)
static

Definition at line 1052 of file PetscDMMoose.C.

1053{
1054 NonlinearSystemBase * nl = NULL;
1055
1058
1059 PetscMatrix<Number> the_pc(pc, nl->comm());
1060 PetscMatrix<Number> Jac(jac, nl->comm());
1061 PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(nl->system().solution.get());
1062 PetscVector<Number> X_global(x, nl->comm());
1063
1064 // Set the dof maps
1065 the_pc.attach_dof_map(nl->system().get_dof_map());
1066 Jac.attach_dof_map(nl->system().get_dof_map());
1067
1068 // Use the system's update() to get a good local version of the
1069 // parallel solution. system.update() does change the Jacobian, so
1070 // there's no reason to swap PETSc's Jacobian into the system for
1071 // this step.
1072 X_global.swap(X_sys);
1073 nl->system().update();
1074 X_global.swap(X_sys);
1075
1076 // Enforce constraints (if any) exactly on the
1077 // current_local_solution. This is the solution vector that is
1078 // actually used in the computation of the Jacobian below, and is
1079 // not locked by debug-enabled PETSc the way that "x" is.
1081 nl->system().current_local_solution.get());
1082
1083 // Zero out the preconditioner before computing the Jacobian.
1084 the_pc.zero();
1085
1086 // if the user has provided both function pointers and objects only the pointer
1087 // will be used, so catch that as an error
1088 if (nl->nonlinearSolver()->jacobian && nl->nonlinearSolver()->jacobian_object)
1089 {
1090 std::ostringstream err;
1091 err << "ERROR: cannot specifiy both a function and object to compute the Jacobian!"
1092 << std::endl;
1093 mooseError(err.str());
1094 }
1095 if (nl->nonlinearSolver()->matvec && nl->nonlinearSolver()->residual_and_jacobian_object)
1096 {
1097 std::ostringstream err;
1098 err << "ERROR: cannot specifiy both a function and object to compute the combined Residual & "
1099 "Jacobian!"
1100 << std::endl;
1101 mooseError(err.str());
1102 }
1103 if (nl->nonlinearSolver()->jacobian != NULL)
1104 nl->nonlinearSolver()->jacobian(
1105 *(nl->system().current_local_solution.get()), the_pc, nl->nonlinearSolver()->system());
1106 else if (nl->nonlinearSolver()->jacobian_object != NULL)
1107 nl->nonlinearSolver()->jacobian_object->jacobian(
1108 *(nl->system().current_local_solution.get()), the_pc, nl->nonlinearSolver()->system());
1109 else if (nl->nonlinearSolver()->matvec != NULL)
1110 nl->nonlinearSolver()->matvec(*(nl->system().current_local_solution.get()),
1111 NULL,
1112 &the_pc,
1113 nl->nonlinearSolver()->system());
1114 else if (nl->nonlinearSolver()->residual_and_jacobian_object != NULL)
1115 nl->nonlinearSolver()->residual_and_jacobian_object->residual_and_jacobian(
1116 *(nl->system().current_local_solution.get()),
1117 NULL,
1118 &the_pc,
1119 nl->nonlinearSolver()->system());
1120 else
1121 {
1122 std::ostringstream err;
1123 err << "No suitable Jacobian routine or object";
1124 mooseError(err.str());
1125 }
1126 the_pc.close();
1127 Jac.close();
1128 PetscFunctionReturn(PETSC_SUCCESS);
1129}

Referenced by SNESJacobian_DMMoose().

◆ DMMooseRegisterAll()

PetscErrorCode DMMooseRegisterAll ( )

Definition at line 2180 of file PetscDMMoose.C.

2181{
2182 static PetscBool DMMooseRegisterAllCalled = PETSC_FALSE;
2183
2185 if (!DMMooseRegisterAllCalled)
2186 {
2187 LibmeshPetscCallQ(DMRegister(DMMOOSE, DMCreate_Moose));
2188 DMMooseRegisterAllCalled = PETSC_TRUE;
2189 }
2190 PetscFunctionReturn(PETSC_SUCCESS);
2191}
EXTERN_C_BEGIN PetscErrorCode DMCreate_Moose(DM dm)

Referenced by FieldSplitPreconditioner::setupDM(), and StaticCondensationFieldSplitPreconditioner::setupDM().

◆ DMMooseReset()

PetscErrorCode DMMooseReset ( DM  dm)

Definition at line 1612 of file PetscDMMoose.C.

1613{
1614 PetscBool ismoose;
1615 DM_Moose * dmm = (DM_Moose *)(dm->data);
1616
1618 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMMOOSE, &ismoose));
1619 if (!ismoose)
1620 PetscFunctionReturn(PETSC_SUCCESS);
1621 if (!dmm->_nl)
1622 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1623 LibmeshPetscCallQ(ISDestroy(&dmm->_embedding));
1624 for (auto & it : *(dmm->_splits))
1625 {
1626 DM_Moose::SplitInfo & split = it.second;
1627 LibmeshPetscCallQ(ISDestroy(&split._rembedding));
1628 if (split._dm)
1630 }
1631 dm->setupcalled = PETSC_FALSE;
1632 PetscFunctionReturn(PETSC_SUCCESS);
1633}
PetscErrorCode DMMooseReset(DM dm)
tbb::split split

Referenced by DMMooseReset(), and SNESUpdateDMMoose().

◆ DMMooseSetBlocks()

PetscErrorCode DMMooseSetBlocks ( DM  dm,
const std::set< std::string > &  blocks 
)

Definition at line 325 of file PetscDMMoose.C.

326{
327 DM_Moose * dmm = (DM_Moose *)dm->data;
328
331 if (dm->setupcalled)
332 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
333 if (dmm->_blocks)
334 delete dmm->_blocks;
335 dmm->_blocks = new std::set<std::string>(blocks);
336 PetscFunctionReturn(PETSC_SUCCESS);
337}

◆ DMMooseSetContacts()

PetscErrorCode DMMooseSetContacts ( DM  dm,
const std::vector< std::pair< std::string, std::string > > &  contacts,
const std::vector< PetscBool > &  displaced 
)

Definition at line 385 of file PetscDMMoose.C.

388{
389 DM_Moose * dmm = (DM_Moose *)dm->data;
390
393 if (dm->setupcalled)
394 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
395 if (contacts.size() != displaced.size())
396 LIBMESH_SETERRQ2(PETSC_COMM_SELF,
397 PETSC_ERR_ARG_SIZ,
398 "Nonmatching sizes of the contact and displaced arrays: %" LIBMESH_PETSCINT_FMT
399 " != %" LIBMESH_PETSCINT_FMT,
400 static_cast<PetscInt>(contacts.size()),
401 static_cast<PetscInt>(displaced.size()));
402 if (dmm->_contacts)
403 delete dmm->_contacts;
404 dmm->_contact_displaced->clear();
405 dmm->_contacts = new std::set<DM_Moose::ContactName>();
406 for (unsigned int i = 0; i < contacts.size(); ++i)
407 {
408 dmm->_contacts->insert(contacts[i]);
409 dmm->_contact_displaced->insert(std::make_pair(contacts[i], displaced[i]));
410 }
411 PetscFunctionReturn(PETSC_SUCCESS);
412}
contacts

◆ DMMooseSetDofMap()

PetscErrorCode DMMooseSetDofMap ( DM  dm,
const DofMapBase dof_map 
)

Definition at line 239 of file PetscDMMoose.C.

240{
243 if (dm->setupcalled)
244 SETERRQ(((PetscObject)dm)->comm,
246 "Cannot reset the degree of freedom map after DM has been set up.");
247 DM_Moose * dmm = (DM_Moose *)(dm->data);
248 dmm->_dof_map = &dof_map;
249 PetscFunctionReturn(PETSC_SUCCESS);
250}

Referenced by DMCreateMoose().

◆ DMMooseSetName()

PetscErrorCode DMMooseSetName ( DM  dm,
const std::string &  dm_name 
)

Definition at line 267 of file PetscDMMoose.C.

268{
271 if (dm->setupcalled)
272 SETERRQ(((PetscObject)dm)->comm,
274 "Cannot reset the MOOSE DM name after DM has been set up.");
275 DM_Moose * dmm = (DM_Moose *)(dm->data);
276 *dmm->_name = dm_name;
277 PetscFunctionReturn(PETSC_SUCCESS);
278}

Referenced by DMCreateMoose().

◆ DMMooseSetNonlinearSystem()

PetscErrorCode DMMooseSetNonlinearSystem ( DM  dm,
NonlinearSystemBase nl 
)

Definition at line 225 of file PetscDMMoose.C.

226{
229 if (dm->setupcalled)
230 SETERRQ(((PetscObject)dm)->comm,
232 "Cannot reset the NonlinearSystem after DM has been set up.");
233 DM_Moose * dmm = (DM_Moose *)(dm->data);
234 dmm->_nl = &nl;
235 PetscFunctionReturn(PETSC_SUCCESS);
236}

Referenced by DMCreateMoose().

◆ DMMooseSetParentDM()

PetscErrorCode DMMooseSetParentDM ( DM  dm,
DM_Moose parent 
)

Definition at line 281 of file PetscDMMoose.C.

282{
285 if (dm->setupcalled)
286 SETERRQ(((PetscObject)dm)->comm,
288 "Cannot reset the parent DM after the child DM has been set up.");
289
290 DM_Moose * dmm = (DM_Moose *)(dm->data);
291 dmm->_parent = parent;
292 PetscFunctionReturn(PETSC_SUCCESS);
293}

Referenced by DMCreateFieldDecomposition_Moose().

◆ DMMooseSetSides()

PetscErrorCode DMMooseSetSides ( DM  dm,
const std::set< std::string > &  sides 
)

Definition at line 340 of file PetscDMMoose.C.

341{
342 DM_Moose * dmm = (DM_Moose *)dm->data;
343
346 if (dm->setupcalled)
347 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
348 if (dmm->_sides)
349 delete dmm->_sides;
350 dmm->_sides = new std::set<std::string>(sides);
351 PetscFunctionReturn(PETSC_SUCCESS);
352}
char ** sides

◆ DMMooseSetSplitNames()

PetscErrorCode DMMooseSetSplitNames ( DM  dm,
const std::vector< std::string > &  split_names 
)

Definition at line 456 of file PetscDMMoose.C.

457{
460 DM_Moose * dmm = (DM_Moose *)(dm->data);
461
462 if (dmm->_splits)
463 {
464 for (auto & it : *(dmm->_splits))
465 {
466 LibmeshPetscCallQ(DMDestroy(&(it.second._dm)));
467 LibmeshPetscCallQ(ISDestroy(&(it.second._rembedding)));
468 }
469 delete dmm->_splits;
470 dmm->_splits = LIBMESH_PETSC_NULLPTR;
471 }
472 if (dmm->_splitlocs)
473 {
474 delete dmm->_splitlocs;
475 dmm->_splitlocs = LIBMESH_PETSC_NULLPTR;
476 }
477 dmm->_splits = new std::map<std::string, DM_Moose::SplitInfo>();
478 dmm->_splitlocs = new std::multimap<std::string, unsigned int>();
479 for (unsigned int i = 0; i < split_names.size(); ++i)
480 {
482 info._dm = LIBMESH_PETSC_NULLPTR;
483 info._rembedding = LIBMESH_PETSC_NULLPTR;
484 std::string name = split_names[i];
485 (*dmm->_splits)[name] = info;
486 dmm->_splitlocs->insert(std::make_pair(name, i));
487 }
488 PetscFunctionReturn(PETSC_SUCCESS);
489}
MPI_Info info
std::string name(const ElemQuality q)

Referenced by if().

◆ DMMooseSetSystem()

PetscErrorCode DMMooseSetSystem ( DM  dm,
const System system 
)

Definition at line 253 of file PetscDMMoose.C.

254{
257 if (dm->setupcalled)
258 SETERRQ(((PetscObject)dm)->comm,
260 "Cannot reset the degree of freedom map after DM has been set up.");
261 DM_Moose * dmm = (DM_Moose *)(dm->data);
262 dmm->_system = &system;
263 PetscFunctionReturn(PETSC_SUCCESS);
264}

Referenced by DMCreateMoose().

◆ DMMooseSetUnContacts()

PetscErrorCode DMMooseSetUnContacts ( DM  dm,
const std::vector< std::pair< std::string, std::string > > &  uncontacts,
const std::vector< PetscBool > &  displaced 
)

Definition at line 415 of file PetscDMMoose.C.

418{
419 DM_Moose * dmm = (DM_Moose *)dm->data;
420
423 if (dm->setupcalled)
424 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
425 if (uncontacts.size() != displaced.size())
426 LIBMESH_SETERRQ2(
427 PETSC_COMM_SELF,
428 PETSC_ERR_ARG_SIZ,
429 "Nonmatching sizes of the uncontact and displaced arrays: %" LIBMESH_PETSCINT_FMT
430 " != %" LIBMESH_PETSCINT_FMT,
431 static_cast<PetscInt>(uncontacts.size()),
432 static_cast<PetscInt>(displaced.size()));
433 if (dmm->_uncontacts)
434 delete dmm->_uncontacts;
435 dmm->_uncontact_displaced->clear();
436 dmm->_uncontacts = new std::set<DM_Moose::ContactName>();
437 for (unsigned int i = 0; i < uncontacts.size(); ++i)
438 {
439 dmm->_uncontacts->insert(uncontacts[i]);
440 dmm->_uncontact_displaced->insert(std::make_pair(uncontacts[i], displaced[i]));
441 }
442 PetscFunctionReturn(PETSC_SUCCESS);
443}
std::vector< DM_Moose::ContactName > uncontacts

◆ DMMooseSetUnSideByVar()

PetscErrorCode DMMooseSetUnSideByVar ( DM  dm,
const std::set< std::string > &  unside_by_var 
)

Definition at line 370 of file PetscDMMoose.C.

371{
372 DM_Moose * dmm = (DM_Moose *)dm->data;
373
376 if (dm->setupcalled)
377 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
378 if (dmm->_unside_by_var)
379 delete dmm->_unside_by_var;
380 dmm->_unside_by_var = new std::set<std::string>(unside_by_var);
381 PetscFunctionReturn(PETSC_SUCCESS);
382}

◆ DMMooseSetUnSides()

PetscErrorCode DMMooseSetUnSides ( DM  dm,
const std::set< std::string > &  unsides 
)

Definition at line 355 of file PetscDMMoose.C.

356{
357 DM_Moose * dmm = (DM_Moose *)dm->data;
358
361 if (dm->setupcalled)
362 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
363 if (dmm->_unsides)
364 delete dmm->_unsides;
365 dmm->_unsides = new std::set<std::string>(unsides);
366 PetscFunctionReturn(PETSC_SUCCESS);
367}

◆ DMMooseSetVariables()

PetscErrorCode DMMooseSetVariables ( DM  dm,
const std::set< std::string > &  vars 
)

Definition at line 296 of file PetscDMMoose.C.

297{
298 DM_Moose * dmm = (DM_Moose *)dm->data;
299
302 if (dm->setupcalled)
303 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
304 if (dmm->_vars)
305 delete dmm->_vars;
306 std::set<std::string> processed_vars;
307 for (const auto & var_name : vars)
308 {
309 const auto * const var =
310 dmm->_nl->hasVariable(var_name)
311 ? static_cast<MooseVariableBase *>(&dmm->_nl->getVariable(0, var_name))
312 : static_cast<MooseVariableBase *>(&dmm->_nl->getScalarVariable(0, var_name));
313 if (var->isArray())
314 for (const auto i : make_range(var->count()))
315 processed_vars.insert(var->arrayVariableComponent(i));
316 else
317 processed_vars.insert(var_name);
318 }
319
320 dmm->_vars = new std::set<std::string>(std::move(processed_vars));
321 PetscFunctionReturn(PETSC_SUCCESS);
322}
unsigned int count
Definition MortarUtils.C:53
char ** vars
Base variable class.
IntRange< T > make_range(T beg, T end)

◆ DMMooseValidityCheck()

PetscErrorCode DMMooseValidityCheck ( DM  dm)

Definition at line 132 of file PetscDMMoose.C.

133{
134 PetscBool ismoose;
135
137 PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
138 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMMOOSE, &ismoose));
139 if (!ismoose)
140 LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
141 PETSC_ERR_ARG_WRONG,
142 "Got DM of type %s, not of type %s",
143 ((PetscObject)dm)->type_name,
144 DMMOOSE);
145 PetscFunctionReturn(PETSC_SUCCESS);
146}

Referenced by DMCreateGlobalVector_Moose(), DMCreateMatrix_Moose(), DMMooseGetBlocks(), DMMooseGetContacts(), DMMooseGetMeshBlocks_Private(), DMMooseGetNonlinearSystem(), DMMooseGetSides(), DMMooseGetSplitNames(), DMMooseGetUnContacts(), DMMooseGetUnSides(), DMMooseGetVariables(), DMMooseSetBlocks(), DMMooseSetContacts(), DMMooseSetDofMap(), DMMooseSetName(), DMMooseSetNonlinearSystem(), DMMooseSetParentDM(), DMMooseSetSides(), DMMooseSetSplitNames(), DMMooseSetSystem(), DMMooseSetUnContacts(), DMMooseSetUnSideByVar(), DMMooseSetUnSides(), DMMooseSetVariables(), DMSetUp_Moose(), and DMSetUp_Moose_Pre().

◆ DMSetFromOptions_Moose() [1/2]

PetscErrorCode DMSetFromOptions_Moose ( DM  dm,
PetscOptionItems   
)

Referenced by DMCreate_Moose().

◆ DMSetFromOptions_Moose() [2/2]

PetscErrorCode PetscOptionItems *PetscErrorCode DMSetFromOptions_Moose ( PetscOptionItems *  ,
DM  dm 
)

◆ DMSetUp_Moose()

static PetscErrorCode DMSetUp_Moose ( DM  dm)
static

Definition at line 1636 of file PetscDMMoose.C.

1637{
1638 DM_Moose * dmm = (DM_Moose *)(dm->data);
1639
1642 if (!dmm->_nl)
1643 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1644 if (dmm->_print_embedding)
1645 {
1646 const char *name, *prefix;
1647 IS embedding;
1648
1649 LibmeshPetscCallQ(PetscObjectGetName((PetscObject)dm, &name));
1650 LibmeshPetscCallQ(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
1651 LibmeshPetscCallQ(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1652 "DM Moose with name %s and prefix %s\n",
1653 name,
1654 prefix));
1655 if (dmm->_all_vars && dmm->_all_blocks && dmm->_nosides && dmm->_nounsides &&
1656 dmm->_nocontacts && dmm->_nouncontacts)
1657 LibmeshPetscCallQ(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1658 "\thas a trivial embedding\n"));
1659 else
1660 {
1662 LibmeshPetscCallQ(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1663 "\thas embedding defined by IS:\n"));
1664 LibmeshPetscCallQ(ISView(embedding, PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm)));
1665 LibmeshPetscCallQ(ISDestroy(&embedding));
1666 }
1667 }
1668 /*
1669 Do not evaluate function, Jacobian or bounds for an embedded DM -- the subproblem might not have
1670 enough information for that.
1671 */
1672 if (dmm->_all_vars && dmm->_all_blocks && dmm->_nosides && dmm->_nounsides && dmm->_nocontacts &&
1673 dmm->_nouncontacts)
1674 {
1675 LibmeshPetscCallQ(DMSNESSetFunction(dm, SNESFunction_DMMoose, (void *)dm));
1676 LibmeshPetscCallQ(DMSNESSetJacobian(dm, SNESJacobian_DMMoose, (void *)dm));
1677 if (dmm->_nl->nonlinearSolver()->bounds || dmm->_nl->nonlinearSolver()->bounds_object)
1678 LibmeshPetscCallQ(DMSetVariableBounds(dm, DMVariableBounds_Moose));
1679 }
1680 PetscFunctionReturn(PETSC_SUCCESS);
1681}
static PetscErrorCode DMVariableBounds_Moose(DM dm, Vec xl, Vec xu)
static PetscErrorCode SNESJacobian_DMMoose(SNES, Vec x, Mat jac, Mat pc, void *ctx)
static PetscErrorCode SNESFunction_DMMoose(SNES, Vec x, Vec r, void *ctx)
bool _nocontacts
bool _nounsides
bool _nouncontacts
bool _nosides
bool _all_vars
bool _all_blocks

Referenced by DMCreate_Moose().

◆ DMSetUp_Moose_Pre()

static PetscErrorCode DMSetUp_Moose_Pre ( DM  dm)
static

Definition at line 1357 of file PetscDMMoose.C.

1358{
1359 DM_Moose * dmm = (DM_Moose *)(dm->data);
1360
1363 if (!dmm->_nl)
1364 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1365
1366 /* Set up variables, blocks and sides. */
1367 const auto & dofmap = *dmm->_dof_map;
1368 /* libMesh mesh */
1369 const MeshBase & mesh = dmm->_system->get_mesh();
1370
1371 // Do sides
1372 dmm->_nosides = PETSC_TRUE;
1373 dmm->_side_ids->clear();
1374 dmm->_side_names->clear();
1375 if (dmm->_sides)
1376 {
1377 dmm->_nosides = PETSC_FALSE;
1378 for (const auto & name : *(dmm->_sides))
1379 {
1380 boundary_id_type id = dmm->_nl->mesh().getBoundaryID(name);
1381 dmm->_side_names->insert(std::make_pair(id, name));
1382 dmm->_side_ids->insert(std::make_pair(name, id));
1383 }
1384 delete dmm->_sides;
1385 dmm->_sides = LIBMESH_PETSC_NULLPTR;
1386 }
1387
1388 // Do unsides
1389 dmm->_nounsides = PETSC_TRUE;
1390 dmm->_unside_ids->clear();
1391 dmm->_unside_names->clear();
1392 if (dmm->_unsides)
1393 {
1394 dmm->_nounsides = PETSC_FALSE;
1395 for (const auto & name : *(dmm->_unsides))
1396 {
1397 boundary_id_type id = dmm->_nl->mesh().getBoundaryID(name);
1398 dmm->_unside_names->insert(std::make_pair(id, name));
1399 dmm->_unside_ids->insert(std::make_pair(name, id));
1400 }
1401 delete dmm->_unsides;
1402 dmm->_unsides = LIBMESH_PETSC_NULLPTR;
1403 }
1404
1405 // Do unside by var
1406 dmm->_nounside_by_var = PETSC_TRUE;
1407 dmm->_unside_by_var_set->clear();
1408 if (dmm->_unside_by_var)
1409 {
1410 dmm->_nounside_by_var = PETSC_FALSE;
1411 for (const auto & name : *(dmm->_unside_by_var))
1412 {
1413 const auto colon_pos = name.find(":");
1414 auto unside_name = name.substr(0, colon_pos);
1415 auto var_name = name.substr(colon_pos + 1);
1416 boundary_id_type id = dmm->_nl->mesh().getBoundaryID(unside_name);
1417 bool var_found = false;
1418 for (unsigned int v = 0; v < dofmap.n_variables(); ++v)
1419 {
1420 const auto & vname = dofmap.variable(v).name();
1421 if (vname == var_name)
1422 {
1423 dmm->_unside_by_var_set->insert(std::make_pair(id, v));
1424 var_found = true;
1425 break;
1426 }
1427 }
1428 if (!var_found)
1429 mooseError("No variable named '", var_name, "' found");
1430 }
1431 delete dmm->_unside_by_var;
1432 dmm->_unside_by_var = LIBMESH_PETSC_NULLPTR;
1433 }
1434
1435 dmm->_nocontacts = PETSC_TRUE;
1436
1437 if (dmm->_contacts)
1438 {
1439 dmm->_nocontacts = PETSC_FALSE;
1440 for (const auto & cpair : *(dmm->_contacts))
1441 {
1442 try
1443 {
1444 if ((*dmm->_contact_displaced)[cpair])
1445 dmm->_nl->feProblem().getDisplacedProblem()->geomSearchData().getPenetrationLocator(
1446 cpair.first, cpair.second);
1447 else
1448 dmm->_nl->feProblem().geomSearchData().getPenetrationLocator(cpair.first, cpair.second);
1449 }
1450 catch (...)
1451 {
1452 std::ostringstream err;
1453 err << "Problem retrieving contact for PenetrationLocator with primary " << cpair.first
1454 << " and secondary " << cpair.second;
1455 mooseError(err.str());
1456 }
1457 BoundaryID primary_id = dmm->_nl->mesh().getBoundaryID(cpair.first);
1458 BoundaryID secondary_id = dmm->_nl->mesh().getBoundaryID(cpair.second);
1459 DM_Moose::ContactID cid(primary_id, secondary_id);
1460 dmm->_contact_names->insert(std::make_pair(cid, cpair));
1461 }
1462 }
1463
1464 dmm->_nouncontacts = PETSC_TRUE;
1465 if (dmm->_uncontacts)
1466 {
1467 dmm->_nouncontacts = PETSC_FALSE;
1468 for (const auto & cpair : *(dmm->_uncontacts))
1469 {
1470 try
1471 {
1472 if ((*dmm->_uncontact_displaced)[cpair])
1473 dmm->_nl->feProblem().getDisplacedProblem()->geomSearchData().getPenetrationLocator(
1474 cpair.first, cpair.second);
1475 else
1476 dmm->_nl->feProblem().geomSearchData().getPenetrationLocator(cpair.first, cpair.second);
1477 }
1478 catch (...)
1479 {
1480 std::ostringstream err;
1481 err << "Problem retrieving uncontact for PenetrationLocator with primary " << cpair.first
1482 << " and secondary " << cpair.second;
1483 mooseError(err.str());
1484 }
1485 BoundaryID primary_id = dmm->_nl->mesh().getBoundaryID(cpair.first);
1486 BoundaryID secondary_id = dmm->_nl->mesh().getBoundaryID(cpair.second);
1487 DM_Moose::ContactID cid(primary_id, secondary_id);
1488 dmm->_uncontact_names->insert(std::make_pair(cid, cpair));
1489 }
1490 }
1491
1492 dmm->_var_ids->clear();
1493 dmm->_var_names->clear();
1494 // FIXME: would be nice to invert this nested loop structure so we could iterate over the
1495 // potentially smaller dmm->vars,
1496 // but checking against dofmap.variable would still require a linear search, hence, no win. Would
1497 // be nice to endow dofmap.variable
1498 // with a fast search capability.
1499 for (unsigned int v = 0; v < dofmap.n_variables(); ++v)
1500 {
1501 std::string vname = dofmap.variable(v).name();
1502 if (dmm->_vars && dmm->_vars->size() && dmm->_vars->find(vname) == dmm->_vars->end())
1503 continue;
1504 dmm->_var_ids->insert(std::pair<std::string, unsigned int>(vname, v));
1505 dmm->_var_names->insert(std::pair<unsigned int, std::string>(v, vname));
1506 }
1507 if (dmm->_var_ids->size() == dofmap.n_variables())
1508 dmm->_all_vars = PETSC_TRUE;
1509 else
1510 dmm->_all_vars = PETSC_FALSE;
1511 if (dmm->_vars)
1512 {
1513 delete dmm->_vars;
1514 dmm->_vars = LIBMESH_PETSC_NULLPTR;
1515 }
1516
1517 dmm->_block_ids->clear();
1518 dmm->_block_names->clear();
1519 std::set<subdomain_id_type> blocks;
1521 if (blocks.empty())
1522 SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "No mesh blocks found.");
1523
1524 for (const auto & bid : blocks)
1525 {
1526 std::string bname = mesh.subdomain_name(bid);
1527 if (!bname.length())
1528 {
1529 // Block names are currently implemented for Exodus meshes
1530 // only, so we might have to make up our own block names and
1531 // maintain our own mapping of block ids to names.
1532 std::ostringstream ss;
1533 ss << bid;
1534 bname = ss.str();
1535 }
1536 if (dmm->_nosides && dmm->_nocontacts)
1537 {
1538 // If no sides and no contacts have been specified, by default (null or empty dmm->blocks) all
1539 // blocks are included in the split Thus, skip this block only if it is explicitly excluded
1540 // from a nonempty dmm->blocks.
1541 if (dmm->_blocks && dmm->_blocks->size() &&
1542 (dmm->_blocks->find(bname) ==
1543 dmm->_blocks->end() && // We should allow users to use subdomain IDs
1544 dmm->_blocks->find(std::to_string(bid)) == dmm->_blocks->end()))
1545 continue;
1546 }
1547 else
1548 {
1549 // If sides or contacts have been specified, only the explicitly-specified blocks (those in
1550 // dmm->blocks, if it's non-null) are in the split. Thus, include this block only if it is
1551 // explicitly specified in a nonempty dmm->blocks. Equivalently, skip this block if
1552 // dmm->blocks is dmm->blocks is null or empty or excludes this block.
1553 if (!dmm->_blocks || !dmm->_blocks->size() ||
1554 (dmm->_blocks->find(bname) ==
1555 dmm->_blocks->end() // We should allow users to use subdomain IDs
1556 && dmm->_blocks->find(std::to_string(bid)) == dmm->_blocks->end()))
1557 continue;
1558 }
1559 dmm->_block_ids->insert(std::make_pair(bname, bid));
1560 dmm->_block_names->insert(std::make_pair(bid, bname));
1561 }
1562
1563 if (dmm->_block_ids->size() == blocks.size())
1564 dmm->_all_blocks = PETSC_TRUE;
1565 else
1566 dmm->_all_blocks = PETSC_FALSE;
1567 if (dmm->_blocks)
1568 {
1569 delete dmm->_blocks;
1570 dmm->_blocks = LIBMESH_PETSC_NULLPTR;
1571 }
1572
1573 std::string name = dmm->_system->name();
1574 name += "_vars";
1575 for (const auto & vit : *(dmm->_var_names))
1576 name += "_" + vit.second;
1577
1578 name += "_blocks";
1579
1580 for (const auto & bit : *(dmm->_block_names))
1581 name += "_" + bit.second;
1582
1583 if (dmm->_side_names && dmm->_side_names->size())
1584 {
1585 name += "_sides";
1586 for (const auto & sit : *(dmm->_side_names))
1587 name += "_" + sit.second;
1588 }
1589 if (dmm->_unside_names && dmm->_unside_names->size())
1590 {
1591 name += "_unsides";
1592 for (const auto & sit : *(dmm->_unside_names))
1593 name += "_" + sit.second;
1594 }
1595 if (dmm->_contact_names && dmm->_contact_names->size())
1596 {
1597 name += "_contacts";
1598 for (const auto & cit : *(dmm->_contact_names))
1599 name += "_primary_" + cit.second.first + "_secondary_" + cit.second.second;
1600 }
1601 if (dmm->_uncontact_names && dmm->_uncontact_names->size())
1602 {
1603 name += "_uncontacts";
1604 for (const auto & cit : *(dmm->_uncontact_names))
1605 name += "_primary_" + cit.second.first + "_secondary_" + cit.second.second;
1606 }
1607 LibmeshPetscCallQ(PetscObjectSetName((PetscObject)dm, name.c_str()));
1608 PetscFunctionReturn(PETSC_SUCCESS);
1609}
static PetscErrorCode DMMooseGetMeshBlocks_Private(DM dm, std::set< subdomain_id_type > &blocks)
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
virtual GeometricSearchData & geomSearchData() override
PenetrationLocator & getPenetrationLocator(const BoundaryName &primary, const BoundaryName &secondary, libMesh::Order order=libMesh::FIRST)
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
Definition MooseMesh.C:1681
FEProblemBase & feProblem()
Definition SystemBase.h:104
MooseMesh & mesh()
Definition SystemBase.h:100
std::string & subdomain_name(subdomain_id_type id)
const std::string & name() const
int8_t boundary_id_type
bool _nounside_by_var
std::pair< BoundaryID, BoundaryID > ContactID

◆ DMVariableBounds_Moose()

static PetscErrorCode DMVariableBounds_Moose ( DM  dm,
Vec  xl,
Vec  xu 
)
static

Definition at line 1142 of file PetscDMMoose.C.

1143{
1144 NonlinearSystemBase * nl = NULL;
1145
1148
1149 PetscVector<Number> XL(xl, nl->comm());
1150 PetscVector<Number> XU(xu, nl->comm());
1151
1152 LibmeshPetscCallQ(VecSet(xl, PETSC_NINFINITY));
1153 LibmeshPetscCallQ(VecSet(xu, PETSC_INFINITY));
1154 if (nl->nonlinearSolver()->bounds != NULL)
1155 nl->nonlinearSolver()->bounds(XL, XU, nl->nonlinearSolver()->system());
1156 else if (nl->nonlinearSolver()->bounds_object != NULL)
1157 nl->nonlinearSolver()->bounds_object->bounds(XL, XU, nl->nonlinearSolver()->system());
1158 else
1159 SETERRQ(
1160 ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "No bounds calculation in this Moose object");
1161 PetscFunctionReturn(PETSC_SUCCESS);
1162}

Referenced by DMSetUp_Moose().

◆ DMView_Moose()

static PetscErrorCode DMView_Moose ( DM  dm,
PetscViewer  viewer 
)
static

Definition at line 1238 of file PetscDMMoose.C.

1239{
1240 PetscBool isascii;
1241 const char *name, *prefix;
1242 DM_Moose * dmm = (DM_Moose *)dm->data;
1243
1245 LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
1246 if (isascii)
1247 {
1248 LibmeshPetscCallQ(PetscObjectGetName((PetscObject)dm, &name));
1249 LibmeshPetscCallQ(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
1251 PetscViewerASCIIPrintf(viewer, "DM Moose with name %s and prefix %s\n", name, prefix));
1252 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "variables:"));
1253 for (const auto & vit : *(dmm->_var_ids))
1254 {
1255 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "(%s,%u) ", vit.first.c_str(), vit.second));
1256 }
1257 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
1258 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "blocks:"));
1259 for (const auto & bit : *(dmm->_block_ids))
1260 {
1261 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "(%s,%d) ", bit.first.c_str(), bit.second));
1262 }
1263 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
1264
1265 if (dmm->_side_ids->size())
1266 {
1267 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "sides:"));
1268 for (const auto & sit : *(dmm->_side_ids))
1269 {
1271 PetscViewerASCIIPrintf(viewer, "(%s,%d) ", sit.first.c_str(), sit.second));
1272 }
1273 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
1274 }
1275
1276 if (dmm->_unside_ids->size())
1277 {
1278 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "unsides:"));
1279 for (const auto & sit : *(dmm->_unside_ids))
1280 {
1282 PetscViewerASCIIPrintf(viewer, "(%s,%d) ", sit.first.c_str(), sit.second));
1283 }
1284 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
1285 }
1286
1287 if (dmm->_contact_names->size())
1288 {
1289 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "contacts:"));
1290 for (const auto & cit : *(dmm->_contact_names))
1291 {
1292 LibmeshPetscCallQ(PetscViewerASCIIPrintf(
1293 viewer, "(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str()));
1294 if ((*dmm->_contact_displaced)[cit.second])
1295 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "displaced) "));
1296 else
1297 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "undisplaced) "));
1298 }
1299 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
1300 }
1301
1302 if (dmm->_uncontact_names->size())
1303 {
1304 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "_uncontacts:"));
1305 for (const auto & cit : *(dmm->_uncontact_names))
1306 {
1307 LibmeshPetscCallQ(PetscViewerASCIIPrintf(
1308 viewer, "(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str()));
1309 if ((*dmm->_uncontact_displaced)[cit.second])
1310 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "displaced) "));
1311 else
1312 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "undisplaced) "));
1313 }
1314 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
1315 }
1316
1317 if (dmm->_splitlocs && dmm->_splitlocs->size())
1318 {
1319 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "Field decomposition:"));
1320 // FIX: decompositions might have different sizes and components on different ranks.
1321 for (const auto & dit : *(dmm->_splitlocs))
1322 {
1323 std::string dname = dit.first;
1324 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, " %s", dname.c_str()));
1325 }
1326 LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
1327 }
1328 }
1329 else
1330 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Non-ASCII viewers are not supported");
1331
1332 PetscFunctionReturn(PETSC_SUCCESS);
1333}

Referenced by DMCreate_Moose().

◆ for()

for ( )

Definition at line 1721 of file PetscDMMoose.C.

1722 {
1723 varset.insert(std::string(vars[i]));
1724 LibmeshPetscCallQ(PetscFree(vars[i]));
1725 }
std::set< std::string > varset

◆ if() [1/9]

if ( !dmm->  _nl)

◆ if() [2/9]

if ( blockset.  size())

◆ if() [3/9]

if ( contacts.  size())

◆ if() [4/9]

Definition at line 1801 of file PetscDMMoose.C.

1829 {
1830 {
1831 char * primary_secondary[2];
1832 PetscInt sz = 2;
1833 std::ostringstream oopt, ohelp;
1834 oopt << "-dm_moose_contact_" << i;
1835 ohelp << "Primary and secondary for contact " << i;
1836 LibmeshPetscCallQ(PetscOptionsStringArray(oopt.str().c_str(),
1837 ohelp.str().c_str(),
1838 "DMMooseSetContacts",
1839 primary_secondary,
1840 &sz,
1841 LIBMESH_PETSC_NULLPTR));
1842 if (sz != 2)
1843 LIBMESH_SETERRQ2(
1844 ((PetscObject)dm)->comm,
1845 PETSC_ERR_ARG_SIZ,
1846 "Expected 2 sideset IDs (primary & secondary) for contact %" LIBMESH_PETSCINT_FMT
1847 ", got %" LIBMESH_PETSCINT_FMT " instead",
1848 i,
1849 sz);
1850 contacts.push_back(DM_Moose::ContactName(std::string(primary_secondary[0]),
1851 std::string(primary_secondary[1])));
1852 LibmeshPetscCallQ(PetscFree(primary_secondary[0]));
1853 LibmeshPetscCallQ(PetscFree(primary_secondary[1]));
1854 }
1855 {
1856 PetscBool displaced = PETSC_FALSE;
1857 std::ostringstream oopt, ohelp;
1858 oopt << "-dm_moose_contact_" << i << "_displaced";
1859 ohelp << "Whether contact " << i << " is determined using displaced mesh or not";
1860 LibmeshPetscCallQ(PetscOptionsBool(oopt.str().c_str(),
1861 ohelp.str().c_str(),
1862 "DMMooseSetContacts",
1863 PETSC_FALSE,
1864 &displaced,
1865 LIBMESH_PETSC_NULLPTR));
1866 contact_displaced.push_back(displaced);
1867 }
1868 }
contact_displaced
std::pair< std::string, std::string > ContactName

◆ if() [5/9]

if ( LIBMESH_SETERRQ2(  nuncontacts,
maxcontacts   
)

Definition at line 1900 of file PetscDMMoose.C.

1908 {
1909 {
1910 char * primary_secondary[2];
1911 PetscInt sz = 2;
1912 std::ostringstream oopt, ohelp;
1913 oopt << "-dm_moose_uncontact_" << i;
1914 ohelp << "Primary and secondary for uncontact " << i;
1915 LibmeshPetscCallQ(PetscOptionsStringArray(oopt.str().c_str(),
1916 ohelp.str().c_str(),
1917 "DMMooseSetUnContacts",
1918 primary_secondary,
1919 &sz,
1920 LIBMESH_PETSC_NULLPTR));
1921 if (sz != 2)
1922 LIBMESH_SETERRQ2(
1923 ((PetscObject)dm)->comm,
1924 PETSC_ERR_ARG_SIZ,
1925 "Expected 2 sideset IDs (primary & secondary) for uncontact %" LIBMESH_PETSCINT_FMT
1926 ", got %" LIBMESH_PETSCINT_FMT " instead",
1927 i,
1928 sz);
1929 uncontacts.push_back(DM_Moose::ContactName(std::string(primary_secondary[0]),
1930 std::string(primary_secondary[1])));
1931 LibmeshPetscCallQ(PetscFree(primary_secondary[0]));
1932 LibmeshPetscCallQ(PetscFree(primary_secondary[1]));
1933 }
1934 {
1935 PetscBool displaced = PETSC_FALSE;
1936 std::ostringstream oopt, ohelp;
1937 oopt << "-dm_moose_uncontact_" << i << "_displaced";
1938 ohelp << "Whether uncontact " << i << " is determined using displaced mesh or not";
1939 LibmeshPetscCallQ(PetscOptionsBool(oopt.str().c_str(),
1940 ohelp.str().c_str(),
1941 "DMMooseSetUnContact",
1942 PETSC_FALSE,
1943 &displaced,
1944 LIBMESH_PETSC_NULLPTR));
1945 uncontact_displaced.push_back(displaced);
1946 }
1947 }
std::vector< PetscBool > uncontact_displaced

◆ if() [6/9]

if ( nsplits  )

Definition at line 1959 of file PetscDMMoose.C.

1960 {
1961 PetscInt nnsplits = nsplits;
1962 std::vector<std::string> split_names;
1963 char ** splitnames;
1964 LibmeshPetscCallQ(PetscMalloc(nsplits * sizeof(char *), &splitnames));
1965 LibmeshPetscCallQ(PetscOptionsStringArray("-dm_moose_fieldsplit_names",
1966 "Names of fieldsplits defined by the DM",
1967 "DMMooseSetSplitNames",
1968 splitnames,
1969 &nnsplits,
1970 LIBMESH_PETSC_NULLPTR));
1971 if (!nnsplits)
1972 {
1973 for (PetscInt i = 0; i < nsplits; ++i)
1974 {
1975 std::ostringstream s;
1976 s << i;
1977 split_names.push_back(s.str());
1978 }
1979 }
1980 else if (nsplits != nnsplits)
1981 LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
1982 PETSC_ERR_ARG_SIZ,
1983 "Expected %" LIBMESH_PETSCINT_FMT
1984 " fieldsplit names, got %" LIBMESH_PETSCINT_FMT " instead",
1985 nsplits,
1986 nnsplits);
1987 else
1988 {
1989 for (PetscInt i = 0; i < nsplits; ++i)
1990 {
1991 split_names.push_back(std::string(splitnames[i]));
1992 LibmeshPetscCallQ(PetscFree(splitnames[i]));
1993 }
1994 }
1995 LibmeshPetscCallQ(PetscFree(splitnames));
1997 }
PetscErrorCode DMMooseSetSplitNames(DM dm, const std::vector< std::string > &split_names)
PetscInt nsplits

◆ if() [7/9]

if ( sideset.  size())

◆ if() [8/9]

if ( uncontacts.  size())

◆ if() [9/9]

if ( varset.  size())

◆ LibmeshPetscCallQ() [1/18]

LibmeshPetscCallQ ( DMMooseGetMeshBlocks_Private(dm, meshblocks )

◆ LibmeshPetscCallQ() [2/18]

LibmeshPetscCallQ ( DMMooseValidityCheck(dm )

◆ LibmeshPetscCallQ() [3/18]

LibmeshPetscCallQ ( DMSetUp_Moose_Pre(dm )

◆ LibmeshPetscCallQ() [4/18]

LibmeshPetscCallQ ( PetscFree(blocks )

◆ LibmeshPetscCallQ() [5/18]

LibmeshPetscCallQ ( PetscFree(sides )

◆ LibmeshPetscCallQ() [6/18]

LibmeshPetscCallQ ( PetscFree(vars )

◆ LibmeshPetscCallQ() [7/18]

LibmeshPetscCallQ ( PetscMalloc(maxblocks *sizeof(char *), &blocks )

◆ LibmeshPetscCallQ() [8/18]

LibmeshPetscCallQ ( PetscMalloc(maxsides *maxvars *sizeof(char *), &sides )

◆ LibmeshPetscCallQ() [9/18]

LibmeshPetscCallQ ( PetscMalloc(maxvars *sizeof(char *), &vars )

◆ LibmeshPetscCallQ() [10/18]

LibmeshPetscCallQ ( PetscOptionsBegin(((PetscObject) dm) ->comm,((PetscObject) dm) ->prefix, "DMMoose options", "DM")  )

◆ LibmeshPetscCallQ() [11/18]

LibmeshPetscCallQ ( PetscOptionsBool("-dm_moose_print_embedding", "Print IS embedding DM's dofs", "DMMoose", dmm->_print_embedding, &dmm->_print_embedding, LIBMESH_PETSC_NULLPTR)  )

◆ LibmeshPetscCallQ() [12/18]

LibmeshPetscCallQ ( PetscOptionsInt("-dm_moose_nfieldsplits", fdhelp, "DMMooseSetSplitNames", nsplits, &nsplits, NULL)  )

◆ LibmeshPetscCallQ() [13/18]

LibmeshPetscCallQ ( PetscOptionsInt(opt.c_str(), help.c_str(), "DMMooseSetUnContacts", nuncontacts, &nuncontacts, LIBMESH_PETSC_NULLPTR)  )

◆ LibmeshPetscCallQ() [14/18]

LibmeshPetscCallQ ( PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetBlocks", blocks, &nblocks, LIBMESH_PETSC_NULLPTR)  )

◆ LibmeshPetscCallQ() [15/18]

LibmeshPetscCallQ ( PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetSides", sides, &nsides, LIBMESH_PETSC_NULLPTR)  )

◆ LibmeshPetscCallQ() [16/18]

LibmeshPetscCallQ ( PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetUnSideByVar", sides, &nsides, LIBMESH_PETSC_NULLPTR)  )

◆ LibmeshPetscCallQ() [17/18]

LibmeshPetscCallQ ( PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetUnSides", sides, &nsides, LIBMESH_PETSC_NULLPTR)  )

◆ LibmeshPetscCallQ() [18/18]

LibmeshPetscCallQ ( PetscOptionsStringArray(opt.c_str(), help.c_str(), "DMMooseSetVars", vars, &nvars, LIBMESH_PETSC_NULLPTR)  )

◆ PetscFunctionReturn()

PetscFunctionReturn ( PETSC_SUCCESS  )

◆ PetscOptionsBegin()

PetscOptionsBegin ( ((PetscObject) dm) ->  comm,
((PetscObject) dm) ->  prefix,
"DMMoose options"  ,
"DM"   
)

◆ PetscOptionsEnd()

PetscOptionsEnd ( )

◆ SNESFunction_DMMoose()

static PetscErrorCode SNESFunction_DMMoose ( SNES  ,
Vec  x,
Vec  r,
void *  ctx 
)
static

Definition at line 1042 of file PetscDMMoose.C.

1043{
1044 DM dm = (DM)ctx;
1045
1048 PetscFunctionReturn(PETSC_SUCCESS);
1049}
static PetscErrorCode DMMooseFunction(DM dm, Vec x, Vec r)
void * ctx

Referenced by DMSetUp_Moose().

◆ SNESJacobian_DMMoose()

static PetscErrorCode SNESJacobian_DMMoose ( SNES  ,
Vec  x,
Mat  jac,
Mat  pc,
void *  ctx 
)
static

Definition at line 1132 of file PetscDMMoose.C.

1133{
1134 DM dm = (DM)ctx;
1135
1137 LibmeshPetscCallQ(DMMooseJacobian(dm, x, jac, pc));
1138 PetscFunctionReturn(PETSC_SUCCESS);
1139}
static PetscErrorCode DMMooseJacobian(DM dm, Vec x, Mat jac, Mat pc)

Referenced by DMSetUp_Moose().

◆ SNESUpdateDMMoose()

PetscErrorCode SNESUpdateDMMoose ( SNES  snes,
PetscInt  iteration 
)

Definition at line 2141 of file PetscDMMoose.C.

2142{
2143 /* This is called any time the structure of the problem changes in a way that affects the Jacobian
2144 sparsity pattern.
2145 For example, this may happen when NodeFaceConstraints change Jacobian's sparsity pattern based
2146 on newly-detected Penetration.
2147 In that case certain preconditioners (e.g., PCASM) will not work, unless we tell them that the
2148 sparsity pattern has changed.
2149 For now we are rebuilding the whole KSP, when necessary.
2150 */
2151 DM dm;
2152 KSP ksp;
2153 const char * prefix;
2154 MPI_Comm comm;
2155 PC pc;
2156
2158 if (iteration)
2159 {
2160 /* TODO: limit this only to situations when displaced (un)contact splits are present, as is
2161 * DisplacedProblem(). */
2162 LibmeshPetscCallQ(SNESGetDM(snes, &dm));
2164 LibmeshPetscCallQ(DMSetUp(dm));
2165 LibmeshPetscCallQ(SNESGetKSP(snes, &ksp));
2166 /* Should we rebuild the whole KSP? */
2167 LibmeshPetscCallQ(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
2168 LibmeshPetscCallQ(PetscObjectGetComm((PetscObject)ksp, &comm));
2169 LibmeshPetscCallQ(PCCreate(comm, &pc));
2170 LibmeshPetscCallQ(PCSetDM(pc, dm));
2171 LibmeshPetscCallQ(PCSetOptionsPrefix(pc, prefix));
2172 LibmeshPetscCallQ(PCSetFromOptions(pc));
2173 LibmeshPetscCallQ(KSPSetPC(ksp, pc));
2174 LibmeshPetscCallQ(PCDestroy(&pc));
2175 }
2176 PetscFunctionReturn(PETSC_SUCCESS);
2177}

Variable Documentation

◆ _include_all_contact_nodes

oopt<< "-dm_moose_includeAllContactNodes"; ohelp << "Whether to include all nodes on the contact surfaces into the subsolver"; LibmeshPetscCallQ(PetscOptionsBool(oopt.str().c_str(), ohelp.str().c_str(), "", PETSC_FALSE, &is_include_all_nodes, LIBMESH_PETSC_NULLPTR)); dmm-> _include_all_contact_nodes = is_include_all_nodes

Definition at line 1882 of file PetscDMMoose.C.

◆ blocks

char** blocks

Definition at line 1733 of file PetscDMMoose.C.

Referenced by Moose::MFEM::CoefficientMap< T, Tpw >::addPiecewiseBlocks(), SystemBase::addVariable(), FEProblemBase::checkProblemIntegrity(), FEProblemBase::computeJacobianBlock(), NonlinearSystemBase::computeJacobianBlocks(), NonlinearSystemBase::computeJacobianBlocks(), FEProblemBase::computeJacobianBlocks(), EigenProblem::computeJacobianBlocks(), Moose::MFEM::CoefficientManager::declareMatrixProperty(), Moose::MFEM::CoefficientManager::declareMatrixProperty(), Moose::MFEM::CoefficientManager::declareMatrixProperty(), Moose::MFEM::CoefficientManager::declareScalarProperty(), Moose::MFEM::CoefficientManager::declareScalarProperty(), Moose::MFEM::CoefficientManager::declareScalarProperty(), Moose::MFEM::CoefficientManager::declareVectorProperty(), Moose::MFEM::CoefficientManager::declareVectorProperty(), Moose::MFEM::CoefficientManager::declareVectorProperty(), DMMooseGetMeshBlocks_Private(), DMMooseSetBlocks(), DMSetUp_Moose_Pre(), DumpObjectsProblem::dumpVariableHelper(), MultiAppUserObjectTransfer::execute(), ExtraIDIntegralReporter::ExtraIDIntegralReporter(), DiracKernelInfo::findPoint(), RenumberBySubdomainGenerator::generate(), SubdomainPerElementGenerator::generate(), MaterialPropertyInterface::getBlockMaterialProperty(), MooseMesh::getBlocksMaxDimension(), MaterialPropertyInterface::getKokkosBlockMaterialProperty(), SubProblem::getMaterialPropertyBlockNames(), SubProblem::getMaterialPropertyBlocks(), AddVariableAction::getSubdomainIDs(), MooseObjectWarehouseBase< T >::hasObjectsForVariableAndBlocks(), MultiAppGeneralFieldTransfer::inBlocks(), MultiAppGeneralFieldKDTreeTransferBase::inBlocks(), MultiAppGeneralFieldTransfer::inBlocks(), BlockRestrictionDebugOutput::printBlockRestrictionGroups(), MooseMesh::setCoordSystem(), FEProblemBase::setCoordSystem(), MooseMesh::setGeneralAxisymmetricCoordAxes(), PhysicsBasedPreconditioner::setup(), BreakMeshByBlockGenerator::syncConnectedBlocks(), and GlobalParamsAction::validParams().

◆ blockset

blockset

Definition at line 1735 of file PetscDMMoose.C.

◆ contact_displaced

contact_displaced

Definition at line 1870 of file PetscDMMoose.C.

◆ contacts

contacts

Definition at line 1870 of file PetscDMMoose.C.

Referenced by DMMooseSetContacts().

◆ displaced_problem

std::shared_ptr<DisplacedProblem> displaced_problem = dmm->_nl->feProblem().getDisplacedProblem()

◆ dm

PetscErrorCode PetscOptionItems *PetscErrorCode DM dm

◆ DM_Moose

No Moose system set for DM_Moose

Definition at line 1701 of file PetscDMMoose.C.

◆ fdhelp

const char* fdhelp
Initial value:
= "Number of named fieldsplits defined by the DM.\n\
\tNames of fieldsplits are defined by -dm_moose_fieldsplit_names <splitname1> <splitname2> ...\n\
\tEach split can be configured with its own variables, blocks and sides, as any DMMoose"

Definition at line 1954 of file PetscDMMoose.C.

◆ help

help = "Variables in DMMoose"

◆ is_include_all_nodes

PetscBool is_include_all_nodes
Initial value:
{
std::ostringstream oopt, ohelp

Definition at line 1873 of file PetscDMMoose.C.

◆ maxblocks

PetscInt maxblocks = meshblocks.size()

Definition at line 1732 of file PetscDMMoose.C.

◆ maxcontacts

PetscInt maxcontacts = dmm->_nl->feProblem().geomSearchData()._penetration_locators.size()

Definition at line 1799 of file PetscDMMoose.C.

◆ maxsides

PetscInt maxsides = dmm->_system->get_mesh().get_boundary_info().get_global_boundary_ids().size()

Definition at line 1749 of file PetscDMMoose.C.

◆ maxvars

PetscInt maxvars = dmm->_dof_map->n_variables()

Definition at line 1712 of file PetscDMMoose.C.

◆ meshblocks

std::set<subdomain_id_type> meshblocks

Definition at line 1730 of file PetscDMMoose.C.

◆ nblocks

PetscInt nblocks = maxblocks

Definition at line 1736 of file PetscDMMoose.C.

◆ nsides

nsides = maxsides

Definition at line 1752 of file PetscDMMoose.C.

◆ nsplits

PetscInt nsplits = 0

Definition at line 1951 of file PetscDMMoose.C.

Referenced by if().

◆ nuncontacts

PetscInt nuncontacts = 0

Definition at line 1886 of file PetscDMMoose.C.

◆ nvars

PetscInt nvars = maxvars

Definition at line 1715 of file PetscDMMoose.C.

◆ opt

opt = "-dm_moose_vars"

Definition at line 1711 of file PetscDMMoose.C.

Referenced by Moose::findSimilar(), and BoundaryDeletionGenerator::validParams().

◆ PETSC_ERR_ARG_WRONGSTATE

PETSC_ERR_ARG_WRONGSTATE

◆ PetscFunctionBegin

PetscFunctionBegin

Definition at line 1698 of file PetscDMMoose.C.

Referenced by DMCreate_Moose(), DMCreateDomainDecomposition_Moose(), DMCreateFieldDecomposition_Moose(), DMCreateGlobalVector_Moose(), DMCreateMatrix_Moose(), DMCreateMoose(), DMDestroy_Moose(), DMMooseFunction(), DMMooseGetBlocks(), DMMooseGetContacts(), DMMooseGetEmbedding_Private(), DMMooseGetMeshBlocks_Private(), DMMooseGetNonlinearSystem(), DMMooseGetSides(), DMMooseGetSplitNames(), DMMooseGetUnContacts(), DMMooseGetUnSides(), DMMooseGetVariables(), DMMooseJacobian(), DMMooseRegisterAll(), DMMooseReset(), DMMooseSetBlocks(), DMMooseSetContacts(), DMMooseSetDofMap(), DMMooseSetName(), DMMooseSetNonlinearSystem(), DMMooseSetParentDM(), DMMooseSetSides(), DMMooseSetSplitNames(), DMMooseSetSystem(), DMMooseSetUnContacts(), DMMooseSetUnSideByVar(), DMMooseSetUnSides(), DMMooseSetVariables(), DMMooseValidityCheck(), DMSetUp_Moose(), DMSetUp_Moose_Pre(), DMVariableBounds_Moose(), DMView_Moose(), Moose::SlepcSupport::mooseEPSFormMatrices(), Moose::SlepcSupport::mooseMatMult_Eigen(), Moose::SlepcSupport::mooseMatMult_NonEigen(), Moose::SlepcSupport::mooseSlepcEigenFormFunctionA(), Moose::SlepcSupport::mooseSlepcEigenFormFunctionAB(), Moose::SlepcSupport::mooseSlepcEigenFormFunctionB(), Moose::SlepcSupport::mooseSlepcEigenFormFunctionMFFD(), Moose::SlepcSupport::mooseSlepcEigenFormJacobianA(), Moose::SlepcSupport::mooseSlepcEigenFormJacobianB(), Moose::SlepcSupport::mooseSlepcEigenFormNorm(), Moose::SlepcSupport::mooseSlepcEPSGetSNES(), Moose::SlepcSupport::mooseSlepcEPSMonitor(), Moose::SlepcSupport::mooseSlepcEPSSNESKSPSetPCSide(), Moose::SlepcSupport::mooseSlepcEPSSNESSetCustomizePC(), Moose::SlepcSupport::mooseSlepcEPSSNESSetUpOptionPrefix(), Moose::SlepcSupport::mooseSlepcStoppingTest(), Moose::SlepcSupport::PCApply_MoosePC(), Moose::SlepcSupport::PCCreate_MoosePC(), Moose::SlepcSupport::PCDestroy_MoosePC(), Moose::SlepcSupport::PCSetUp_MoosePC(), Moose::SlepcSupport::PCView_MoosePC(), Moose::PetscSupport::petscLinearConverged(), Moose::PetscSupport::petscNonlinearConverged(), Moose::PetscSupport::petscSetupOutput(), Moose::SlepcSupport::registerPCToPETSc(), SNESFunction_DMMoose(), SNESJacobian_DMMoose(), and SNESUpdateDMMoose().

◆ sides

char** sides

◆ sideset

sideset

◆ uncontact_displaced

uncontact_displaced

Definition at line 1885 of file PetscDMMoose.C.

◆ uncontacts

uncontacts

Definition at line 1884 of file PetscDMMoose.C.

Referenced by DMMooseSetUnContacts().

◆ vars

char** vars

Definition at line 1713 of file PetscDMMoose.C.

Referenced by AddFunctionAction::act(), VariableWarehouse::addBoundaryVars(), Assembly::addJacobianOffDiagScalar(), MooseVariableDependencyInterface::addMooseVariableDependency(), Assembly::addResidual(), Assembly::addResidualLower(), Assembly::addResidualNeighbor(), Assembly::addResidualScalar(), AllLocalDofIndicesThread::AllLocalDofIndicesThread(), DerivativeParsedMaterialHelperTempl< is_ad >::assembleDerivatives(), Assembly::cacheResidual(), Assembly::cacheResidualLower(), Assembly::cacheResidualNeighbor(), NonlinearSystemBase::checkKernelCoverage(), ComputeFullJacobianThread::computeOnBoundary(), ComputeFullJacobianThread::computeOnElement(), Coupleable::Coupleable(), DMMooseSetVariables(), ADFParser::Eval(), MultiAppPostprocessorInterpolationTransfer::execute(), for(), FEProblemBase::getFunction(), SystemBase::getMinQuadratureOrder(), AuxiliarySystem::getMinQuadratureOrder(), TransientBase::getTimeIntegratorNames(), AddPeriodicBCAction::getVariables(), Coupleable::getVarsHelper(), InputParameters::getVecMooseType(), Assembly::init(), SolutionAux::initialSetup(), SolutionScalarAux::initialSetup(), Axisymmetric2D3DSolutionFunction::initialSetup(), Assembly::initNonlocalCoupling(), Moose::isSectionActive(), SystemBase::prepare(), SystemBase::prepareFace(), Assembly::prepareLowerD(), SystemBase::prepareLowerD(), Assembly::prepareNeighbor(), SystemBase::prepareNeighbor(), Assembly::prepareOffDiagScalar(), Assembly::prepareResidual(), Assembly::prepareScalar(), ProjectedStatefulMaterialStorageAction::processProperty(), InputParameters::rangeCheck(), SystemBase::reinitElem(), SystemBase::reinitElemFace(), SystemBase::reinitLowerD(), SystemBase::reinitNeighbor(), SystemBase::reinitNeighborFace(), SystemBase::reinitNode(), SystemBase::reinitNodeFace(), SystemBase::reinitNodes(), SystemBase::reinitNodesNeighbor(), SystemBase::reinitScalars(), ScalarCoupleable::ScalarCoupleable(), FixedPointSolve::setMultiAppTransformedVariables(), FEProblemBase::setNonlocalCouplingMatrix(), Assembly::setResidual(), Assembly::setResidualNeighbor(), SingleMatrixPreconditioner::SingleMatrixPreconditioner(), VariableCondensationPreconditioner::VariableCondensationPreconditioner(), and BadActiveWalker::walk().

◆ varset

varset

Definition at line 1714 of file PetscDMMoose.C.

Referenced by for().