www.mooseframework.org
Classes | Functions
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 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(PetscOptionItems *
 
PetscErrorCode DM dm PetscErrorCode DMSetFromOptions_Moose (PetscOptions *, DM dm)
 
static PetscErrorCode DMDestroy_Moose (DM dm)
 
PetscErrorCode DMCreateMoose (MPI_Comm comm, NonlinearSystemBase &nl, const std::string &dm_name, DM *dm)
 Create a MOOSE DM. More...
 
EXTERN_C_BEGIN PetscErrorCode DMCreate_Moose (DM dm)
 
PetscErrorCode SNESUpdateDMMoose (SNES snes, PetscInt iteration)
 
PetscErrorCode DMMooseRegisterAll ()
 

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 37 of file PetscDMMoose.C.

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

38 {
39  if (libMesh::cast_int<libMesh::numeric_index_type>(split_size) !=
40  libMesh::cast_int<libMesh::numeric_index_type>(size_expected_by_parent))
41  mooseError("Split '",
42  split_name,
43  "' has size ",
44  libMesh::cast_int<libMesh::numeric_index_type>(split_size),
45  " but the parent split expected size ",
46  libMesh::cast_int<libMesh::numeric_index_type>(size_expected_by_parent),
47  ". Make sure that you have non-overlapping complete sets for variables and "
48  "blocks as well as consistency in sides/unsides, contacts/uncontacts, etc.");
49 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284

◆ DMCreate_Moose()

EXTERN_C_BEGIN PetscErrorCode DMCreate_Moose ( DM  dm)

Definition at line 2316 of file PetscDMMoose.C.

Referenced by DMMooseRegisterAll().

2317 {
2318  PetscErrorCode ierr;
2319  DM_Moose * dmm;
2320 
2321  PetscFunctionBegin;
2322  PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2323 #if PETSC_RELEASE_LESS_THAN(3, 18, 0)
2324  ierr = PetscNewLog(dm, &dmm);
2325  CHKERRQ(ierr);
2326 #else // PetscNewLog was deprecated
2327  ierr = PetscNew(&dmm);
2328  CHKERRQ(ierr);
2329 #endif
2330  dm->data = dmm;
2331 
2332  dmm->_name = new (std::string);
2333  dmm->_var_ids = new (std::map<std::string, unsigned int>);
2334  dmm->_block_ids = new (std::map<std::string, subdomain_id_type>);
2335  dmm->_var_names = new (std::map<unsigned int, std::string>);
2336  dmm->_block_names = new (std::map<unsigned int, std::string>);
2337  dmm->_side_ids = new (std::map<std::string, BoundaryID>);
2338  dmm->_side_names = new (std::map<BoundaryID, std::string>);
2339  dmm->_unside_ids = new (std::map<std::string, BoundaryID>);
2340  dmm->_unside_names = new (std::map<BoundaryID, std::string>);
2341  dmm->_unside_by_var_set = new (std::set<std::pair<BoundaryID, unsigned int>>);
2342  dmm->_contact_names = new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2343  dmm->_uncontact_names = new (std::map<DM_Moose::ContactID, DM_Moose::ContactName>);
2344  dmm->_contact_displaced = new (std::map<DM_Moose::ContactName, PetscBool>);
2345  dmm->_uncontact_displaced = new (std::map<DM_Moose::ContactName, PetscBool>);
2346 
2347  dmm->_splits = new (std::map<std::string, DM_Moose::SplitInfo>);
2348 
2349  dmm->_print_embedding = PETSC_FALSE;
2350 
2351  dm->ops->createglobalvector = DMCreateGlobalVector_Moose;
2352  dm->ops->createlocalvector = 0; // DMCreateLocalVector_Moose;
2353  dm->ops->getcoloring = 0; // DMGetColoring_Moose;
2354  dm->ops->creatematrix = DMCreateMatrix_Moose;
2355  dm->ops->createinterpolation = 0; // DMCreateInterpolation_Moose;
2356 
2357  dm->ops->refine = 0; // DMRefine_Moose;
2358  dm->ops->coarsen = 0; // DMCoarsen_Moose;
2359 #if PETSC_RELEASE_LESS_THAN(3, 12, 0)
2360  dm->ops->getinjection = 0; // DMGetInjection_Moose;
2361  dm->ops->getaggregates = 0; // DMGetAggregates_Moose;
2362 #else
2363  dm->ops->createinjection = 0;
2364 #endif
2365 
2366  dm->ops->createfielddecomposition = DMCreateFieldDecomposition_Moose;
2367  dm->ops->createdomaindecomposition = DMCreateDomainDecomposition_Moose;
2368 
2369  dm->ops->destroy = DMDestroy_Moose;
2370  dm->ops->view = DMView_Moose;
2371  dm->ops->setfromoptions = DMSetFromOptions_Moose;
2372  dm->ops->setup = DMSetUp_Moose;
2373  PetscFunctionReturn(0);
2374 }
static PetscErrorCode DMSetUp_Moose(DM dm)
std::set< std::pair< BoundaryID, unsigned int > > * _unside_by_var_set
Definition: PetscDMMoose.C:70
std::map< BoundaryID, std::string > * _side_names
Definition: PetscDMMoose.C:64
std::map< ContactName, PetscBool > * _contact_displaced
Definition: PetscDMMoose.C:80
std::map< std::string, BoundaryID > * _side_ids
Definition: PetscDMMoose.C:65
std::string * _name
The name of this DM.
Definition: PetscDMMoose.C:101
std::map< ContactName, PetscBool > * _uncontact_displaced
Definition: PetscDMMoose.C:81
ierr
std::map< std::string, unsigned int > * _var_ids
Definition: PetscDMMoose.C:56
std::map< unsigned int, std::string > * _var_names
Definition: PetscDMMoose.C:57
static PetscErrorCode DMView_Moose(DM dm, PetscViewer viewer)
std::map< ContactID, ContactName > * _uncontact_names
Definition: PetscDMMoose.C:79
std::map< std::string, SplitInfo > * _splits
Definition: PetscDMMoose.C:95
static PetscErrorCode DMCreateFieldDecomposition_Moose(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
Definition: PetscDMMoose.C:877
std::map< std::string, BoundaryID > * _unside_ids
Definition: PetscDMMoose.C:67
CHKERRQ(ierr)
PetscBool _print_embedding
Definition: PetscDMMoose.C:98
PetscErrorCode DMSetFromOptions_Moose(DM dm, PetscOptionItems *) PetscErrorCode DMSetFromOptions_Moose(PetscOptionItems *
std::map< std::string, subdomain_id_type > * _block_ids
Definition: PetscDMMoose.C:60
static PetscErrorCode DMCreateGlobalVector_Moose(DM dm, Vec *x)
std::map< ContactID, ContactName > * _contact_names
Definition: PetscDMMoose.C:77
static PetscErrorCode DMDestroy_Moose(DM dm)
static PetscErrorCode DMCreateDomainDecomposition_Moose(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
static PetscErrorCode DMCreateMatrix_Moose(DM dm, Mat *A)
std::map< BoundaryID, std::string > * _unside_names
Definition: PetscDMMoose.C:68
std::map< unsigned int, std::string > * _block_names
Definition: PetscDMMoose.C:61

◆ DMCreateDomainDecomposition_Moose()

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

Definition at line 1021 of file PetscDMMoose.C.

Referenced by DMCreate_Moose().

1023 {
1024  PetscErrorCode ierr;
1025 
1026  PetscFunctionBegin;
1027  /* Use DMCreateFieldDecomposition_Moose() to obtain everything but outerislist, which is currently
1028  * LIBMESH_PETSC_NULLPTR. */
1029  if (outerislist)
1030  *outerislist = LIBMESH_PETSC_NULLPTR; /* FIX: allow mesh-based overlap. */
1031  ierr = DMCreateFieldDecomposition_Moose(dm, len, namelist, innerislist, dmlist);
1032  CHKERRQ(ierr);
1033  PetscFunctionReturn(0);
1034 }
ierr
static PetscErrorCode DMCreateFieldDecomposition_Moose(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
Definition: PetscDMMoose.C:877
CHKERRQ(ierr)

◆ DMCreateFieldDecomposition_Moose()

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

Definition at line 877 of file PetscDMMoose.C.

Referenced by DMCreate_Moose(), and DMCreateDomainDecomposition_Moose().

879 {
880  PetscErrorCode ierr;
881  DM_Moose * dmm = (DM_Moose *)(dm->data);
882 
883  PetscFunctionBegin;
884 
885  PetscInt split_size_sum = 0;
886 
887  /* Only called after DMSetUp(). */
888  if (!dmm->_splitlocs)
889  PetscFunctionReturn(0);
890  *len = dmm->_splitlocs->size();
891  if (namelist)
892  {
893  ierr = PetscMalloc(*len * sizeof(char *), namelist);
894  CHKERRQ(ierr);
895  }
896  if (islist)
897  {
898  ierr = PetscMalloc(*len * sizeof(IS), islist);
899  CHKERRQ(ierr);
900  }
901  if (dmlist)
902  {
903  ierr = PetscMalloc(*len * sizeof(DM), dmlist);
904  CHKERRQ(ierr);
905  }
906  for (const auto & dit : *(dmm->_splitlocs))
907  {
908  unsigned int d = dit.second;
909  std::string dname = dit.first;
910  DM_Moose::SplitInfo & dinfo = (*dmm->_splits)[dname];
911  if (!dinfo._dm)
912  {
913  ierr = DMCreateMoose(((PetscObject)dm)->comm, *dmm->_nl, dname, &dinfo._dm);
914  CHKERRQ(ierr);
915  ierr = PetscObjectSetOptionsPrefix((PetscObject)dinfo._dm, ((PetscObject)dm)->prefix);
916  CHKERRQ(ierr);
917  std::string suffix = std::string("fieldsplit_") + dname + "_";
918  ierr = PetscObjectAppendOptionsPrefix((PetscObject)dinfo._dm, suffix.c_str());
919  CHKERRQ(ierr);
920  ierr = DMMooseSetParentDM(dinfo._dm, dmm);
921  CHKERRQ(ierr);
922  }
923  ierr = DMSetFromOptions(dinfo._dm);
924  CHKERRQ(ierr);
925  ierr = DMSetUp(dinfo._dm);
926  CHKERRQ(ierr);
927  if (namelist)
928  {
929  ierr = PetscStrallocpy(dname.c_str(), (*namelist) + d);
930  CHKERRQ(ierr);
931  }
932  if (islist)
933  {
934  if (!dinfo._rembedding)
935  {
936  IS dembedding, lembedding;
937  ierr = DMMooseGetEmbedding_Private(dinfo._dm, &dembedding);
938  CHKERRQ(ierr);
939  if (dmm->_embedding)
940  {
941  // Create a relative embedding into the parent's index space.
942  ierr = ISEmbed(dembedding, dmm->_embedding, PETSC_TRUE, &lembedding);
943  CHKERRQ(ierr);
944  const PetscInt * lindices;
945  PetscInt len, dlen, llen, *rindices, off, i;
946  ierr = ISGetLocalSize(dembedding, &dlen);
947  CHKERRQ(ierr);
948  ierr = ISGetLocalSize(lembedding, &llen);
949  CHKERRQ(ierr);
950  if (llen != dlen)
951  LIBMESH_SETERRQ1(
952  ((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Failed to embed split %u", d);
953  ierr = ISDestroy(&dembedding);
954  CHKERRQ(ierr);
955  // Convert local embedding to global (but still relative) embedding
956  ierr = PetscMalloc(llen * sizeof(PetscInt), &rindices);
957  CHKERRQ(ierr);
958  ierr = ISGetIndices(lembedding, &lindices);
959  CHKERRQ(ierr);
960  ierr = PetscMemcpy(rindices, lindices, llen * sizeof(PetscInt));
961  CHKERRQ(ierr);
962  ierr = ISDestroy(&lembedding);
963  CHKERRQ(ierr);
964  // We could get the index offset from a corresponding global vector, but subDMs don't yet
965  // have global vectors
966  ierr = ISGetLocalSize(dmm->_embedding, &len);
967  CHKERRQ(ierr);
968 
969  ierr = MPI_Scan(&len,
970  &off,
971  1,
972 #ifdef PETSC_USE_64BIT_INDICES
973  MPI_LONG_LONG_INT,
974 #else
975  MPI_INT,
976 #endif
977  MPI_SUM,
978  ((PetscObject)dm)->comm);
979  CHKERRQ(ierr);
980 
981  off -= len;
982  for (i = 0; i < llen; ++i)
983  rindices[i] += off;
984  ierr = ISCreateGeneral(
985  ((PetscObject)dm)->comm, llen, rindices, PETSC_OWN_POINTER, &(dinfo._rembedding));
986  CHKERRQ(ierr);
987  }
988  else
989  {
990  dinfo._rembedding = dembedding;
991  }
992  }
993  ierr = PetscObjectReference((PetscObject)(dinfo._rembedding));
994  CHKERRQ(ierr);
995  (*islist)[d] = dinfo._rembedding;
996  PetscInt is_size;
997  ISGetLocalSize(dinfo._rembedding, &is_size);
998  split_size_sum += is_size;
999  }
1000  if (dmlist)
1001  {
1002  ierr = PetscObjectReference((PetscObject)dinfo._dm);
1003  CHKERRQ(ierr);
1004  (*dmlist)[d] = dinfo._dm;
1005  }
1006  }
1007 
1008  mooseAssert(islist, "What does it even mean if this is NULL?");
1009 
1010  if (dmm->_parent)
1011  dmm->_parent->checkChildSize(dm, split_size_sum, *dmm->_name);
1012  else
1013  checkSize(*dmm->_name,
1014  split_size_sum,
1015  dmm->_nl->nonlinearSolver()->system().get_system_matrix().local_m());
1016 
1017  PetscFunctionReturn(0);
1018 }
virtual NonlinearSolver< Number > * nonlinearSolver()=0
DM_Moose * _parent
Definition: PetscDMMoose.C:54
std::string * _name
The name of this DM.
Definition: PetscDMMoose.C:101
void checkSize(const std::string &split_name, const I1 split_size, const I2 size_expected_by_parent)
Definition: PetscDMMoose.C:37
ierr
const sys_type & system() const
PetscErrorCode DMMooseSetParentDM(DM dm, DM_Moose *parent)
Definition: PetscDMMoose.C:275
IS _embedding
Definition: PetscDMMoose.C:97
std::map< std::string, SplitInfo > * _splits
Definition: PetscDMMoose.C:95
static PetscErrorCode DMMooseGetEmbedding_Private(DM dm, IS *embedding)
Definition: PetscDMMoose.C:534
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMCreateMoose(MPI_Comm comm, NonlinearSystemBase &nl, const std::string &dm_name, DM *dm)
Create a MOOSE DM.
void checkChildSize(DM child, PetscInt child_size, const std::string &child_name)
Check whether the size of the child matches the size we expect.
Definition: PetscDMMoose.C:110
std::multimap< std::string, unsigned int > * _splitlocs
Definition: PetscDMMoose.C:89

◆ DMCreateGlobalVector_Moose()

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

Definition at line 1242 of file PetscDMMoose.C.

Referenced by DMCreate_Moose().

1243 {
1244  PetscErrorCode ierr;
1245  DM_Moose * dmm = (DM_Moose *)(dm->data);
1246 
1247  PetscFunctionBegin;
1248  ierr = DMMooseValidityCheck(dm);
1249  CHKERRQ(ierr);
1250  if (!dmm->_nl)
1251  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1252 
1253  NumericVector<Number> * nv = (dmm->_nl->system().solution).get();
1254  PetscVector<Number> * pv = dynamic_cast<PetscVector<Number> *>(nv);
1255  Vec v = pv->vec();
1256  /* Unfortunately, currently this does not produce a ghosted vector, so nonlinear subproblem solves
1257  aren't going to be easily available.
1258  Should work fine for getting vectors out for linear subproblem solvers. */
1259  if (dmm->_embedding)
1260  {
1261  PetscInt n;
1262  ierr = VecCreate(((PetscObject)v)->comm, x);
1263  CHKERRQ(ierr);
1264  ierr = ISGetLocalSize(dmm->_embedding, &n);
1265  CHKERRQ(ierr);
1266  ierr = VecSetSizes(*x, n, PETSC_DETERMINE);
1267  CHKERRQ(ierr);
1268  ierr = VecSetType(*x, ((PetscObject)v)->type_name);
1269  CHKERRQ(ierr);
1270  ierr = VecSetFromOptions(*x);
1271  CHKERRQ(ierr);
1272  ierr = VecSetUp(*x);
1273  CHKERRQ(ierr);
1274  }
1275  else
1276  {
1277  ierr = VecDuplicate(v, x);
1278  CHKERRQ(ierr);
1279  }
1280 
1281 #if PETSC_RELEASE_LESS_THAN(3, 13, 0)
1282  ierr = PetscObjectCompose((PetscObject)*x, "DM", (PetscObject)dm);
1283  CHKERRQ(ierr);
1284 #else
1285  ierr = VecSetDM(*x, dm);
1286  CHKERRQ(ierr);
1287 #endif
1288  PetscFunctionReturn(0);
1289 }
ierr
IS _embedding
Definition: PetscDMMoose.C:97
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
virtual System & system() override
Get the reference to the libMesh system.

◆ DMCreateMatrix_Moose()

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

Definition at line 1292 of file PetscDMMoose.C.

Referenced by DMCreate_Moose().

1293 {
1294  PetscErrorCode ierr;
1295  DM_Moose * dmm = (DM_Moose *)(dm->data);
1296  MatType type;
1297 
1298  PetscFunctionBegin;
1299  ierr = DMMooseValidityCheck(dm);
1300  CHKERRQ(ierr);
1301  if (!dmm->_nl)
1302  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1303  ierr = DMGetMatType(dm, &type);
1304  CHKERRQ(ierr);
1305 
1306  /*
1307  The simplest thing for now: compute the sparsity_pattern using dof_map and init the matrix using
1308  that info.
1309  TODO: compute sparsity restricted to this DM's blocks, variables and sides.
1310  Even fancier: compute the sparsity of the coupling of a contact secondary to the contact primary.
1311  In any event, here we are in control of the matrix type and structure.
1312  */
1313  DofMap & dof_map = dmm->_nl->system().get_dof_map();
1314  PetscInt M, N, m, n;
1315  MPI_Comm comm;
1316  M = dof_map.n_dofs();
1317  N = M;
1318  m = static_cast<PetscInt>(dof_map.n_dofs_on_processor(dmm->_nl->system().processor_id()));
1319  n = m;
1320  ierr = PetscObjectGetComm((PetscObject)dm, &comm);
1321  CHKERRQ(ierr);
1322  ierr = MatCreate(comm, A);
1323  CHKERRQ(ierr);
1324  ierr = MatSetSizes(*A, m, n, M, N);
1325  CHKERRQ(ierr);
1326  ierr = MatSetType(*A, type);
1327  CHKERRQ(ierr);
1328  /* Set preallocation for the basic sparse matrix types (applies only if *A has the right type. */
1329  /* For now we ignore blocksize issues, since BAIJ doesn't play well with field decomposition by
1330  * variable. */
1331  const std::vector<numeric_index_type> & n_nz = dof_map.get_n_nz();
1332  const std::vector<numeric_index_type> & n_oz = dof_map.get_n_oz();
1333  ierr = MatSeqAIJSetPreallocation(*A, 0, (PetscInt *)(n_nz.empty() ? NULL : &n_nz[0]));
1334  CHKERRQ(ierr);
1335  ierr = MatMPIAIJSetPreallocation(*A,
1336  0,
1337  (PetscInt *)(n_nz.empty() ? NULL : &n_nz[0]),
1338  0,
1339  (PetscInt *)(n_oz.empty() ? NULL : &n_oz[0]));
1340  CHKERRQ(ierr);
1341  /* TODO: set the prefix for *A and MatSetFromOptions(*A)? Might override the type and other
1342  * settings made here. */
1343  ierr = MatSetUp(*A);
1344  CHKERRQ(ierr);
1345  PetscFunctionReturn(0);
1346 }
ierr
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
virtual System & system() override
Get the reference to the libMesh system.

◆ DMCreateMoose()

PetscErrorCode DMCreateMoose ( MPI_Comm  comm,
NonlinearSystemBase nl,
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
dm_nameA name to associate with the DM
dmA pointer to the PETSc DM

Definition at line 2298 of file PetscDMMoose.C.

Referenced by DMCreateFieldDecomposition_Moose(), and Moose::PetscSupport::petscSetupDM().

2299 {
2300  PetscErrorCode ierr;
2301 
2302  PetscFunctionBegin;
2303  ierr = DMCreate(comm, dm);
2304  CHKERRQ(ierr);
2305  ierr = DMSetType(*dm, DMMOOSE);
2306  CHKERRQ(ierr);
2307  ierr = DMMooseSetNonlinearSystem(*dm, nl);
2308  CHKERRQ(ierr);
2309  ierr = DMMooseSetName(*dm, dm_name);
2310  CHKERRQ(ierr);
2311  PetscFunctionReturn(0);
2312 }
PetscErrorCode DMMooseSetNonlinearSystem(DM dm, NonlinearSystemBase &nl)
Definition: PetscDMMoose.C:241
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseSetName(DM dm, const std::string &dm_name)
Definition: PetscDMMoose.C:258

◆ DMDestroy_Moose()

static PetscErrorCode DMDestroy_Moose ( DM  dm)
static

Definition at line 2243 of file PetscDMMoose.C.

Referenced by DMCreate_Moose().

2244 {
2245  DM_Moose * dmm = (DM_Moose *)(dm->data);
2246  PetscErrorCode ierr;
2247 
2248  PetscFunctionBegin;
2249  delete dmm->_name;
2250  if (dmm->_vars)
2251  delete dmm->_vars;
2252  delete dmm->_var_ids;
2253  delete dmm->_var_names;
2254  if (dmm->_blocks)
2255  delete dmm->_blocks;
2256  delete dmm->_block_ids;
2257  delete dmm->_block_names;
2258  if (dmm->_sides)
2259  delete dmm->_sides;
2260  delete dmm->_side_ids;
2261  delete dmm->_side_names;
2262  if (dmm->_unsides)
2263  delete dmm->_unsides;
2264  delete dmm->_unside_ids;
2265  delete dmm->_unside_names;
2266  if (dmm->_unside_by_var)
2267  delete dmm->_unside_by_var;
2268  delete dmm->_unside_by_var_set;
2269  if (dmm->_contacts)
2270  delete dmm->_contacts;
2271  delete dmm->_contact_names;
2272  delete dmm->_contact_displaced;
2273  if (dmm->_uncontacts)
2274  delete dmm->_uncontacts;
2275  delete dmm->_uncontact_names;
2276  delete dmm->_uncontact_displaced;
2277  if (dmm->_splits)
2278  {
2279  for (auto & sit : *(dmm->_splits))
2280  {
2281  ierr = DMDestroy(&(sit.second._dm));
2282  CHKERRQ(ierr);
2283  ierr = ISDestroy(&(sit.second._rembedding));
2284  CHKERRQ(ierr);
2285  }
2286  delete dmm->_splits;
2287  }
2288  if (dmm->_splitlocs)
2289  delete dmm->_splitlocs;
2290  ierr = ISDestroy(&dmm->_embedding);
2291  CHKERRQ(ierr);
2292  ierr = PetscFree(dm->data);
2293  CHKERRQ(ierr);
2294  PetscFunctionReturn(0);
2295 }
std::set< ContactName > * _uncontacts
Definition: PetscDMMoose.C:78
std::set< std::pair< BoundaryID, unsigned int > > * _unside_by_var_set
Definition: PetscDMMoose.C:70
std::map< BoundaryID, std::string > * _side_names
Definition: PetscDMMoose.C:64
std::map< ContactName, PetscBool > * _contact_displaced
Definition: PetscDMMoose.C:80
std::map< std::string, BoundaryID > * _side_ids
Definition: PetscDMMoose.C:65
std::string * _name
The name of this DM.
Definition: PetscDMMoose.C:101
std::map< ContactName, PetscBool > * _uncontact_displaced
Definition: PetscDMMoose.C:81
ierr
std::set< std::string > * _sides
Definition: PetscDMMoose.C:63
std::map< std::string, unsigned int > * _var_ids
Definition: PetscDMMoose.C:56
std::map< unsigned int, std::string > * _var_names
Definition: PetscDMMoose.C:57
std::map< ContactID, ContactName > * _uncontact_names
Definition: PetscDMMoose.C:79
std::set< ContactName > * _contacts
Definition: PetscDMMoose.C:76
IS _embedding
Definition: PetscDMMoose.C:97
std::set< std::string > * _unside_by_var
Definition: PetscDMMoose.C:69
std::map< std::string, SplitInfo > * _splits
Definition: PetscDMMoose.C:95
std::set< std::string > * _unsides
Definition: PetscDMMoose.C:66
std::set< std::string > * _vars
Definition: PetscDMMoose.C:55
std::map< std::string, BoundaryID > * _unside_ids
Definition: PetscDMMoose.C:67
CHKERRQ(ierr)
std::map< std::string, subdomain_id_type > * _block_ids
Definition: PetscDMMoose.C:60
std::set< std::string > * _blocks
Definition: PetscDMMoose.C:59
std::map< ContactID, ContactName > * _contact_names
Definition: PetscDMMoose.C:77
std::multimap< std::string, unsigned int > * _splitlocs
Definition: PetscDMMoose.C:89
std::map< BoundaryID, std::string > * _unside_names
Definition: PetscDMMoose.C:68
std::map< unsigned int, std::string > * _block_names
Definition: PetscDMMoose.C:61

◆ DMMooseFunction()

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

Definition at line 1037 of file PetscDMMoose.C.

Referenced by SNESFunction_DMMoose().

1038 {
1039  PetscErrorCode ierr;
1040 
1041  PetscFunctionBegin;
1042  libmesh_assert(x);
1043  libmesh_assert(r);
1044 
1045  NonlinearSystemBase * nl = NULL;
1046  ierr = DMMooseGetNonlinearSystem(dm, nl);
1047  CHKERRQ(ierr);
1048  PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(nl->system().solution.get());
1049  PetscVector<Number> X_global(x, nl->comm()), R(r, nl->comm());
1050 
1051  // Use the system's update() to get a good local version of the
1052  // parallel solution. system.update() does change the residual vector,
1053  // so there's no reason to swap PETSc's residual into the system for
1054  // this step.
1055  X_global.swap(X_sys);
1056  nl->system().update();
1057  X_global.swap(X_sys);
1058 
1059  // Enforce constraints (if any) exactly on the
1060  // current_local_solution. This is the solution vector that is
1061  // actually used in the computation of the residual below, and is
1062  // not locked by debug-enabled PETSc the way that "x" is.
1063  nl->system().get_dof_map().enforce_constraints_exactly(nl->system(),
1064  nl->system().current_local_solution.get());
1065 
1066  // Zero the residual vector before assembling
1067  R.zero();
1068 
1069  // if the user has provided both function pointers and objects only the pointer
1070  // will be used, so catch that as an error
1072  {
1073  std::ostringstream err;
1074  err << "ERROR: cannot specifiy both a function and object to compute the Residual!"
1075  << std::endl;
1076  mooseError(err.str());
1077  }
1079  {
1080  std::ostringstream err;
1081  err << "ERROR: cannot specifiy both a function and object to compute the combined Residual & "
1082  "Jacobian!"
1083  << std::endl;
1084  mooseError(err.str());
1085  }
1086  if (nl->nonlinearSolver()->residual != NULL)
1087  nl->nonlinearSolver()->residual(
1088  *(nl->system().current_local_solution.get()), R, nl->nonlinearSolver()->system());
1089  else if (nl->nonlinearSolver()->residual_object != NULL)
1090  nl->nonlinearSolver()->residual_object->residual(
1091  *(nl->system().current_local_solution.get()), R, nl->nonlinearSolver()->system());
1092  else if (nl->nonlinearSolver()->matvec != NULL)
1093  nl->nonlinearSolver()->matvec(
1094  *(nl->system().current_local_solution.get()), &R, NULL, nl->nonlinearSolver()->system());
1095  else if (nl->nonlinearSolver()->residual_and_jacobian_object != NULL)
1096  nl->nonlinearSolver()->residual_and_jacobian_object->residual_and_jacobian(
1097  *(nl->system().current_local_solution.get()), &R, NULL, nl->nonlinearSolver()->system());
1098  else
1099  {
1100  std::ostringstream err;
1101  err << "No suitable residual computation routine found";
1102  mooseError(err.str());
1103  }
1104  R.close();
1105  PetscFunctionReturn(0);
1106 }
OStreamProxy err
void(* residual)(const NumericVector< Number > &X, NumericVector< Number > &R, sys_type &S)
NonlinearImplicitSystem::ComputeResidualandJacobian * residual_and_jacobian_object
virtual NonlinearSolver< Number > * nonlinearSolver()=0
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
PetscErrorCode DMMooseGetNonlinearSystem(DM dm, NonlinearSystemBase *&nl)
Definition: PetscDMMoose.C:457
const Parallel::Communicator & comm() const
NonlinearImplicitSystem::ComputeResidual * residual_object
ierr
Nonlinear system to be solved.
const sys_type & system() const
libmesh_assert(ctx)
CHKERRQ(ierr)
virtual System & system() override
Get the reference to the libMesh system.
void(* matvec)(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)

◆ DMMooseGetBlocks()

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

Definition at line 213 of file PetscDMMoose.C.

214 {
215  PetscErrorCode ierr;
216 
217  PetscFunctionBegin;
219  CHKERRQ(ierr);
220  DM_Moose * dmm = (DM_Moose *)dm->data;
221  for (const auto & it : *(dmm->_block_ids))
222  block_names.push_back(it.first);
223  PetscFunctionReturn(0);
224 }
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
std::map< std::string, subdomain_id_type > * _block_ids
Definition: PetscDMMoose.C:60

◆ DMMooseGetContacts()

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

Definition at line 147 of file PetscDMMoose.C.

150 {
151  PetscErrorCode ierr;
152 
153  PetscFunctionBegin;
155  CHKERRQ(ierr);
156  DM_Moose * dmm = (DM_Moose *)dm->data;
157  for (const auto & it : *(dmm->_contact_names))
158  {
159  contact_names.push_back(it.second);
160  displaced.push_back((*dmm->_contact_displaced)[it.second]);
161  }
162  PetscFunctionReturn(0);
163 }
std::map< ContactName, PetscBool > * _contact_displaced
Definition: PetscDMMoose.C:80
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
std::map< ContactID, ContactName > * _contact_names
Definition: PetscDMMoose.C:77

◆ DMMooseGetEmbedding_Private()

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

Definition at line 534 of file PetscDMMoose.C.

Referenced by DMCreateFieldDecomposition_Moose(), and DMSetUp_Moose().

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

◆ DMMooseGetMeshBlocks_Private()

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

Definition at line 1482 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose(), and DMSetUp_Moose_Pre().

1483 {
1484  PetscErrorCode ierr;
1485  DM_Moose * dmm = (DM_Moose *)(dm->data);
1486 
1487  PetscFunctionBegin;
1488  ierr = DMMooseValidityCheck(dm);
1489  CHKERRQ(ierr);
1490  if (!dmm->_nl)
1491  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1492 
1493  const MeshBase & mesh = dmm->_nl->system().get_mesh();
1494  /* The following effectively is a verbatim copy of MeshBase::n_subdomains(). */
1495  // This requires an inspection on every processor
1496  libmesh_parallel_only(mesh.comm());
1497  for (const auto & elem : mesh.active_element_ptr_range())
1498  blocks.insert(elem->subdomain_id());
1499  // Some subdomains may only live on other processors
1500  mesh.comm().set_union(blocks);
1501  PetscFunctionReturn(0);
1502 }
MeshBase & mesh
ierr
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
virtual System & system() override
Get the reference to the libMesh system.

◆ DMMooseGetNonlinearSystem()

PetscErrorCode DMMooseGetNonlinearSystem ( DM  dm,
NonlinearSystemBase *&  nl 
)

Definition at line 457 of file PetscDMMoose.C.

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

458 {
459  PetscErrorCode ierr;
460 
461  PetscFunctionBegin;
463  CHKERRQ(ierr);
464  DM_Moose * dmm = (DM_Moose *)(dm->data);
465  nl = dmm->_nl;
466  PetscFunctionReturn(0);
467 }
ierr
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseGetSides()

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

Definition at line 185 of file PetscDMMoose.C.

186 {
187  PetscErrorCode ierr;
188 
189  PetscFunctionBegin;
191  CHKERRQ(ierr);
192  DM_Moose * dmm = (DM_Moose *)dm->data;
193  for (const auto & it : *(dmm->_side_ids))
194  side_names.push_back(it.first);
195  PetscFunctionReturn(0);
196 }
std::map< std::string, BoundaryID > * _side_ids
Definition: PetscDMMoose.C:65
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseGetSplitNames()

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

Definition at line 511 of file PetscDMMoose.C.

512 {
513  PetscErrorCode ierr;
514 
515  PetscFunctionBegin;
517  CHKERRQ(ierr);
518  DM_Moose * dmm = (DM_Moose *)(dm->data);
519  if (!dm->setupcalled)
520  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM not set up");
521  split_names.clear();
522  split_names.reserve(dmm->_splitlocs->size());
523  if (dmm->_splitlocs && dmm->_splitlocs->size())
524  for (const auto & lit : *(dmm->_splitlocs))
525  {
526  std::string sname = lit.first;
527  unsigned int sloc = lit.second;
528  split_names[sloc] = sname;
529  }
530  PetscFunctionReturn(0);
531 }
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
std::multimap< std::string, unsigned int > * _splitlocs
Definition: PetscDMMoose.C:89

◆ DMMooseGetUnContacts()

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

Definition at line 166 of file PetscDMMoose.C.

169 {
170  PetscErrorCode ierr;
171 
172  PetscFunctionBegin;
174  CHKERRQ(ierr);
175  DM_Moose * dmm = (DM_Moose *)dm->data;
176  for (const auto & it : *(dmm->_uncontact_names))
177  {
178  uncontact_names.push_back(it.second);
179  displaced.push_back((*dmm->_uncontact_displaced)[it.second]);
180  }
181  PetscFunctionReturn(0);
182 }
std::map< ContactName, PetscBool > * _uncontact_displaced
Definition: PetscDMMoose.C:81
ierr
std::map< ContactID, ContactName > * _uncontact_names
Definition: PetscDMMoose.C:79
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseGetUnSides()

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

Definition at line 199 of file PetscDMMoose.C.

200 {
201  PetscErrorCode ierr;
202 
203  PetscFunctionBegin;
205  CHKERRQ(ierr);
206  DM_Moose * dmm = (DM_Moose *)dm->data;
207  for (const auto & it : *(dmm->_unside_ids))
208  side_names.push_back(it.first);
209  PetscFunctionReturn(0);
210 }
ierr
std::map< std::string, BoundaryID > * _unside_ids
Definition: PetscDMMoose.C:67
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseGetVariables()

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

Definition at line 227 of file PetscDMMoose.C.

228 {
229  PetscErrorCode ierr;
230 
231  PetscFunctionBegin;
233  CHKERRQ(ierr);
234  DM_Moose * dmm = (DM_Moose *)(dm->data);
235  for (const auto & it : *(dmm->_var_ids))
236  var_names.push_back(it.first);
237  PetscFunctionReturn(0);
238 }
ierr
std::map< std::string, unsigned int > * _var_ids
Definition: PetscDMMoose.C:56
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseJacobian()

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

Definition at line 1121 of file PetscDMMoose.C.

Referenced by SNESJacobian_DMMoose().

1122 {
1123  PetscErrorCode ierr;
1124  NonlinearSystemBase * nl = NULL;
1125 
1126  PetscFunctionBegin;
1127  ierr = DMMooseGetNonlinearSystem(dm, nl);
1128  CHKERRQ(ierr);
1129 
1130  PetscMatrix<Number> the_pc(pc, nl->comm());
1131  PetscMatrix<Number> Jac(jac, nl->comm());
1132  PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(nl->system().solution.get());
1133  PetscVector<Number> X_global(x, nl->comm());
1134 
1135  // Set the dof maps
1136  the_pc.attach_dof_map(nl->system().get_dof_map());
1137  Jac.attach_dof_map(nl->system().get_dof_map());
1138 
1139  // Use the system's update() to get a good local version of the
1140  // parallel solution. system.update() does change the Jacobian, so
1141  // there's no reason to swap PETSc's Jacobian into the system for
1142  // this step.
1143  X_global.swap(X_sys);
1144  nl->system().update();
1145  X_global.swap(X_sys);
1146 
1147  // Enforce constraints (if any) exactly on the
1148  // current_local_solution. This is the solution vector that is
1149  // actually used in the computation of the Jacobian below, and is
1150  // not locked by debug-enabled PETSc the way that "x" is.
1151  nl->system().get_dof_map().enforce_constraints_exactly(nl->system(),
1152  nl->system().current_local_solution.get());
1153 
1154  // Zero out the preconditioner before computing the Jacobian.
1155  the_pc.zero();
1156 
1157  // if the user has provided both function pointers and objects only the pointer
1158  // will be used, so catch that as an error
1160  {
1161  std::ostringstream err;
1162  err << "ERROR: cannot specifiy both a function and object to compute the Jacobian!"
1163  << std::endl;
1164  mooseError(err.str());
1165  }
1167  {
1168  std::ostringstream err;
1169  err << "ERROR: cannot specifiy both a function and object to compute the combined Residual & "
1170  "Jacobian!"
1171  << std::endl;
1172  mooseError(err.str());
1173  }
1174  if (nl->nonlinearSolver()->jacobian != NULL)
1175  nl->nonlinearSolver()->jacobian(
1176  *(nl->system().current_local_solution.get()), the_pc, nl->nonlinearSolver()->system());
1177  else if (nl->nonlinearSolver()->jacobian_object != NULL)
1178  nl->nonlinearSolver()->jacobian_object->jacobian(
1179  *(nl->system().current_local_solution.get()), the_pc, nl->nonlinearSolver()->system());
1180  else if (nl->nonlinearSolver()->matvec != NULL)
1181  nl->nonlinearSolver()->matvec(*(nl->system().current_local_solution.get()),
1182  NULL,
1183  &the_pc,
1184  nl->nonlinearSolver()->system());
1185  else if (nl->nonlinearSolver()->residual_and_jacobian_object != NULL)
1186  nl->nonlinearSolver()->residual_and_jacobian_object->residual_and_jacobian(
1187  *(nl->system().current_local_solution.get()),
1188  NULL,
1189  &the_pc,
1190  nl->nonlinearSolver()->system());
1191  else
1192  {
1193  std::ostringstream err;
1194  err << "No suitable Jacobian routine or object";
1195  mooseError(err.str());
1196  }
1197  the_pc.close();
1198  Jac.close();
1199  PetscFunctionReturn(0);
1200 }
OStreamProxy err
NonlinearImplicitSystem::ComputeResidualandJacobian * residual_and_jacobian_object
virtual NonlinearSolver< Number > * nonlinearSolver()=0
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
PetscErrorCode DMMooseGetNonlinearSystem(DM dm, NonlinearSystemBase *&nl)
Definition: PetscDMMoose.C:457
const Parallel::Communicator & comm() const
void(* jacobian)(const NumericVector< Number > &X, SparseMatrix< Number > &J, sys_type &S)
ierr
Nonlinear system to be solved.
const sys_type & system() const
NonlinearImplicitSystem::ComputeJacobian * jacobian_object
CHKERRQ(ierr)
virtual System & system() override
Get the reference to the libMesh system.
void(* matvec)(const NumericVector< Number > &X, NumericVector< Number > *R, SparseMatrix< Number > *J, sys_type &S)

◆ DMMooseRegisterAll()

PetscErrorCode DMMooseRegisterAll ( )

Definition at line 2432 of file PetscDMMoose.C.

Referenced by Moose::PetscSupport::petscSetupDM().

2433 {
2434  static PetscBool DMMooseRegisterAllCalled = PETSC_FALSE;
2435  PetscErrorCode ierr;
2436 
2437  PetscFunctionBegin;
2438  if (!DMMooseRegisterAllCalled)
2439  {
2440  ierr = DMRegister(DMMOOSE, DMCreate_Moose);
2441  CHKERRQ(ierr);
2442  DMMooseRegisterAllCalled = PETSC_TRUE;
2443  }
2444  PetscFunctionReturn(0);
2445 }
ierr
EXTERN_C_BEGIN PetscErrorCode DMCreate_Moose(DM dm)
CHKERRQ(ierr)

◆ DMMooseReset()

PetscErrorCode DMMooseReset ( DM  dm)

Definition at line 1764 of file PetscDMMoose.C.

Referenced by SNESUpdateDMMoose().

1765 {
1766  PetscErrorCode ierr;
1767  PetscBool ismoose;
1768  DM_Moose * dmm = (DM_Moose *)(dm->data);
1769 
1770  PetscFunctionBegin;
1771  ierr = PetscObjectTypeCompare((PetscObject)dm, DMMOOSE, &ismoose);
1772  CHKERRQ(ierr);
1773  if (!ismoose)
1774  PetscFunctionReturn(0);
1775  if (!dmm->_nl)
1776  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1777  ierr = ISDestroy(&dmm->_embedding);
1778  CHKERRQ(ierr);
1779  for (auto & it : *(dmm->_splits))
1780  {
1781  DM_Moose::SplitInfo & split = it.second;
1782  ierr = ISDestroy(&split._rembedding);
1783  CHKERRQ(ierr);
1784  if (split._dm)
1785  {
1786  ierr = DMMooseReset(split._dm);
1787  CHKERRQ(ierr);
1788  }
1789  }
1790  dm->setupcalled = PETSC_FALSE;
1791  PetscFunctionReturn(0);
1792 }
PetscErrorCode DMMooseReset(DM dm)
ierr
IS _embedding
Definition: PetscDMMoose.C:97
std::map< std::string, SplitInfo > * _splits
Definition: PetscDMMoose.C:95
tbb::split split
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53

◆ DMMooseSetBlocks()

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

Definition at line 324 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

325 {
326  PetscErrorCode ierr;
327  DM_Moose * dmm = (DM_Moose *)dm->data;
328 
329  PetscFunctionBegin;
330  ierr = DMMooseValidityCheck(dm);
331  CHKERRQ(ierr);
332  if (dm->setupcalled)
333  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
334  if (dmm->_blocks)
335  delete dmm->_blocks;
336  dmm->_blocks = new std::set<std::string>(blocks);
337  PetscFunctionReturn(0);
338 }
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
std::set< std::string > * _blocks
Definition: PetscDMMoose.C:59

◆ DMMooseSetContacts()

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

Definition at line 392 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

395 {
396  PetscErrorCode ierr;
397  DM_Moose * dmm = (DM_Moose *)dm->data;
398 
399  PetscFunctionBegin;
400  ierr = DMMooseValidityCheck(dm);
401  CHKERRQ(ierr);
402  if (dm->setupcalled)
403  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
404  if (contacts.size() != displaced.size())
405  LIBMESH_SETERRQ2(PETSC_COMM_SELF,
406  PETSC_ERR_ARG_SIZ,
407  "Nonmatching sizes of the contact and displaced arrays: %" LIBMESH_PETSCINT_FMT
408  " != %" LIBMESH_PETSCINT_FMT,
409  static_cast<PetscInt>(contacts.size()),
410  static_cast<PetscInt>(displaced.size()));
411  if (dmm->_contacts)
412  delete dmm->_contacts;
413  dmm->_contact_displaced->clear();
414  dmm->_contacts = new std::set<DM_Moose::ContactName>();
415  for (unsigned int i = 0; i < contacts.size(); ++i)
416  {
417  dmm->_contacts->insert(contacts[i]);
418  dmm->_contact_displaced->insert(std::make_pair(contacts[i], displaced[i]));
419  }
420  PetscFunctionReturn(0);
421 }
std::map< ContactName, PetscBool > * _contact_displaced
Definition: PetscDMMoose.C:80
ierr
std::set< ContactName > * _contacts
Definition: PetscDMMoose.C:76
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetName()

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

Definition at line 258 of file PetscDMMoose.C.

Referenced by DMCreateMoose().

259 {
260  PetscErrorCode ierr;
261 
262  PetscFunctionBegin;
264  CHKERRQ(ierr);
265  if (dm->setupcalled)
266  SETERRQ(((PetscObject)dm)->comm,
267  PETSC_ERR_ARG_WRONGSTATE,
268  "Cannot reset the MOOSE DM name after DM has been set up.");
269  DM_Moose * dmm = (DM_Moose *)(dm->data);
270  *dmm->_name = dm_name;
271  PetscFunctionReturn(0);
272 }
std::string * _name
The name of this DM.
Definition: PetscDMMoose.C:101
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetNonlinearSystem()

PetscErrorCode DMMooseSetNonlinearSystem ( DM  dm,
NonlinearSystemBase nl 
)

Definition at line 241 of file PetscDMMoose.C.

Referenced by DMCreateMoose().

242 {
243  PetscErrorCode ierr;
244 
245  PetscFunctionBegin;
247  CHKERRQ(ierr);
248  if (dm->setupcalled)
249  SETERRQ(((PetscObject)dm)->comm,
250  PETSC_ERR_ARG_WRONGSTATE,
251  "Cannot reset the NonlinearSystem after DM has been set up.");
252  DM_Moose * dmm = (DM_Moose *)(dm->data);
253  dmm->_nl = &nl;
254  PetscFunctionReturn(0);
255 }
ierr
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetParentDM()

PetscErrorCode DMMooseSetParentDM ( DM  dm,
DM_Moose parent 
)

Definition at line 275 of file PetscDMMoose.C.

Referenced by DMCreateFieldDecomposition_Moose().

276 {
277  PetscErrorCode ierr;
278 
279  PetscFunctionBegin;
281  CHKERRQ(ierr);
282  if (dm->setupcalled)
283  SETERRQ(((PetscObject)dm)->comm,
284  PETSC_ERR_ARG_WRONGSTATE,
285  "Cannot reset the parent DM after the child DM has been set up.");
286 
287  DM_Moose * dmm = (DM_Moose *)(dm->data);
288  dmm->_parent = parent;
289  PetscFunctionReturn(0);
290 }
DM_Moose * _parent
Definition: PetscDMMoose.C:54
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetSides()

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

Definition at line 341 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

342 {
343  PetscErrorCode ierr;
344  DM_Moose * dmm = (DM_Moose *)dm->data;
345 
346  PetscFunctionBegin;
347  ierr = DMMooseValidityCheck(dm);
348  CHKERRQ(ierr);
349  if (dm->setupcalled)
350  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
351  if (dmm->_sides)
352  delete dmm->_sides;
353  dmm->_sides = new std::set<std::string>(sides);
354  PetscFunctionReturn(0);
355 }
ierr
std::set< std::string > * _sides
Definition: PetscDMMoose.C:63
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetSplitNames()

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

Definition at line 470 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

471 {
472  PetscErrorCode ierr;
473 
474  PetscFunctionBegin;
476  CHKERRQ(ierr);
477  DM_Moose * dmm = (DM_Moose *)(dm->data);
478 
479  if (dmm->_splits)
480  {
481  for (auto & it : *(dmm->_splits))
482  {
483  ierr = DMDestroy(&(it.second._dm));
484  CHKERRQ(ierr);
485  ierr = ISDestroy(&(it.second._rembedding));
486  CHKERRQ(ierr);
487  }
488  delete dmm->_splits;
489  dmm->_splits = LIBMESH_PETSC_NULLPTR;
490  }
491  if (dmm->_splitlocs)
492  {
493  delete dmm->_splitlocs;
494  dmm->_splitlocs = LIBMESH_PETSC_NULLPTR;
495  }
496  dmm->_splits = new std::map<std::string, DM_Moose::SplitInfo>();
497  dmm->_splitlocs = new std::multimap<std::string, unsigned int>();
498  for (unsigned int i = 0; i < split_names.size(); ++i)
499  {
501  info._dm = LIBMESH_PETSC_NULLPTR;
502  info._rembedding = LIBMESH_PETSC_NULLPTR;
503  std::string name = split_names[i];
504  (*dmm->_splits)[name] = info;
505  dmm->_splitlocs->insert(std::make_pair(name, i));
506  }
507  PetscFunctionReturn(0);
508 }
std::string name(const ElemQuality q)
MPI_Info info
ierr
std::map< std::string, SplitInfo > * _splits
Definition: PetscDMMoose.C:95
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
std::multimap< std::string, unsigned int > * _splitlocs
Definition: PetscDMMoose.C:89

◆ DMMooseSetUnContacts()

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

Definition at line 424 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

427 {
428  PetscErrorCode ierr;
429  DM_Moose * dmm = (DM_Moose *)dm->data;
430 
431  PetscFunctionBegin;
432  ierr = DMMooseValidityCheck(dm);
433  CHKERRQ(ierr);
434  if (dm->setupcalled)
435  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
436  if (uncontacts.size() != displaced.size())
437  LIBMESH_SETERRQ2(
438  PETSC_COMM_SELF,
439  PETSC_ERR_ARG_SIZ,
440  "Nonmatching sizes of the uncontact and displaced arrays: %" LIBMESH_PETSCINT_FMT
441  " != %" LIBMESH_PETSCINT_FMT,
442  static_cast<PetscInt>(uncontacts.size()),
443  static_cast<PetscInt>(displaced.size()));
444  if (dmm->_uncontacts)
445  delete dmm->_uncontacts;
446  dmm->_uncontact_displaced->clear();
447  dmm->_uncontacts = new std::set<DM_Moose::ContactName>();
448  for (unsigned int i = 0; i < uncontacts.size(); ++i)
449  {
450  dmm->_uncontacts->insert(uncontacts[i]);
451  dmm->_uncontact_displaced->insert(std::make_pair(uncontacts[i], displaced[i]));
452  }
453  PetscFunctionReturn(0);
454 }
std::set< ContactName > * _uncontacts
Definition: PetscDMMoose.C:78
std::map< ContactName, PetscBool > * _uncontact_displaced
Definition: PetscDMMoose.C:81
ierr
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetUnSideByVar()

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

Definition at line 375 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

376 {
377  PetscErrorCode ierr;
378  DM_Moose * dmm = (DM_Moose *)dm->data;
379 
380  PetscFunctionBegin;
381  ierr = DMMooseValidityCheck(dm);
382  CHKERRQ(ierr);
383  if (dm->setupcalled)
384  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
385  if (dmm->_unside_by_var)
386  delete dmm->_unside_by_var;
387  dmm->_unside_by_var = new std::set<std::string>(unside_by_var);
388  PetscFunctionReturn(0);
389 }
ierr
std::set< std::string > * _unside_by_var
Definition: PetscDMMoose.C:69
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetUnSides()

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

Definition at line 358 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

359 {
360  PetscErrorCode ierr;
361  DM_Moose * dmm = (DM_Moose *)dm->data;
362 
363  PetscFunctionBegin;
364  ierr = DMMooseValidityCheck(dm);
365  CHKERRQ(ierr);
366  if (dm->setupcalled)
367  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
368  if (dmm->_unsides)
369  delete dmm->_unsides;
370  dmm->_unsides = new std::set<std::string>(unsides);
371  PetscFunctionReturn(0);
372 }
ierr
std::set< std::string > * _unsides
Definition: PetscDMMoose.C:66
CHKERRQ(ierr)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128

◆ DMMooseSetVariables()

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

Definition at line 293 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

294 {
295  PetscErrorCode ierr;
296  DM_Moose * dmm = (DM_Moose *)dm->data;
297 
298  PetscFunctionBegin;
299  ierr = DMMooseValidityCheck(dm);
300  CHKERRQ(ierr);
301  if (dm->setupcalled)
302  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for an already setup DM");
303  if (dmm->_vars)
304  delete dmm->_vars;
305  std::set<std::string> processed_vars;
306  for (const auto & var_name : vars)
307  {
308  const auto * const var =
309  dmm->_nl->hasVariable(var_name)
310  ? static_cast<MooseVariableBase *>(&dmm->_nl->getVariable(0, var_name))
311  : static_cast<MooseVariableBase *>(&dmm->_nl->getScalarVariable(0, var_name));
312  if (var->isArray())
313  for (const auto i : make_range(var->count()))
314  processed_vars.insert(SubProblem::arrayVariableComponent(var_name, i));
315  else
316  processed_vars.insert(var_name);
317  }
318 
319  dmm->_vars = new std::set<std::string>(std::move(processed_vars));
320  PetscFunctionReturn(0);
321 }
ierr
virtual bool hasVariable(const std::string &var_name) const
Query a system for a variable.
Definition: SystemBase.C:800
std::set< std::string > * _vars
Definition: PetscDMMoose.C:55
virtual MooseVariableScalar & getScalarVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a scalar variable with specified number.
Definition: SystemBase.C:134
static std::string arrayVariableComponent(const std::string &var_name, unsigned int i)
Returns the variable name of a component of an array variable.
Definition: SubProblem.h:261
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
IntRange< T > make_range(T beg, T end)
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
Definition: SystemBase.C:79

◆ DMMooseValidityCheck()

PetscErrorCode DMMooseValidityCheck ( DM  dm)

Definition at line 128 of file PetscDMMoose.C.

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

129 {
130  PetscErrorCode ierr;
131  PetscBool ismoose;
132 
133  PetscFunctionBegin;
134  PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
135  ierr = PetscObjectTypeCompare((PetscObject)dm, DMMOOSE, &ismoose);
136  CHKERRQ(ierr);
137  if (!ismoose)
138  LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
139  PETSC_ERR_ARG_WRONG,
140  "Got DM of type %s, not of type %s",
141  ((PetscObject)dm)->type_name,
142  DMMOOSE);
143  PetscFunctionReturn(0);
144 }
ierr
CHKERRQ(ierr)

◆ DMSetFromOptions_Moose() [1/2]

PetscErrorCode DMSetFromOptions_Moose ( DM  dm,
PetscOptionItems *   
)

Referenced by DMCreate_Moose().

◆ DMSetFromOptions_Moose() [2/2]

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

Definition at line 1865 of file PetscDMMoose.C.

1867 {
1868  PetscErrorCode ierr;
1869  DM_Moose * dmm = (DM_Moose *)dm->data;
1870 
1871  PetscFunctionBegin;
1872  ierr = DMMooseValidityCheck(dm);
1873  CHKERRQ(ierr);
1874  if (!dmm->_nl)
1875  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1876 // PETSc changed macro definitions in 3.18; the former correct usage
1877 // is now a compiler error and the new usage is now a compiler
1878 // warning.
1879 #if !PETSC_VERSION_LESS_THAN(3, 18, 0)
1880  PetscOptionsBegin(((PetscObject)dm)->comm, ((PetscObject)dm)->prefix, "DMMoose options", "DM");
1881 #else
1882  ierr = PetscOptionsBegin(
1883  ((PetscObject)dm)->comm, ((PetscObject)dm)->prefix, "DMMoose options", "DM");
1884 #endif
1885  std::string opt, help;
1886  PetscInt maxvars = dmm->_nl->system().get_dof_map().n_variables();
1887  char ** vars;
1888  std::set<std::string> varset;
1889  PetscInt nvars = maxvars;
1890  ierr = PetscMalloc(maxvars * sizeof(char *), &vars);
1891  CHKERRQ(ierr);
1892  opt = "-dm_moose_vars";
1893  help = "Variables in DMMoose";
1894  ierr = PetscOptionsStringArray(
1895  opt.c_str(), help.c_str(), "DMMooseSetVars", vars, &nvars, LIBMESH_PETSC_NULLPTR);
1896  CHKERRQ(ierr);
1897  for (PetscInt i = 0; i < nvars; ++i)
1898  {
1899  varset.insert(std::string(vars[i]));
1900  ierr = PetscFree(vars[i]);
1901  CHKERRQ(ierr);
1902  }
1903  ierr = PetscFree(vars);
1904  CHKERRQ(ierr);
1905  if (varset.size())
1906  {
1907  ierr = DMMooseSetVariables(dm, varset);
1908  CHKERRQ(ierr);
1909  }
1910  //
1911  std::set<subdomain_id_type> meshblocks;
1912  ierr = DMMooseGetMeshBlocks_Private(dm, meshblocks);
1913  CHKERRQ(ierr);
1914  PetscInt maxblocks = meshblocks.size();
1915  char ** blocks;
1916  ierr = PetscMalloc(maxblocks * sizeof(char *), &blocks);
1917  CHKERRQ(ierr);
1918  std::set<std::string> blockset;
1919  PetscInt nblocks = maxblocks;
1920  opt = "-dm_moose_blocks";
1921  help = "Blocks in DMMoose";
1922  ierr = PetscOptionsStringArray(
1923  opt.c_str(), help.c_str(), "DMMooseSetBlocks", blocks, &nblocks, LIBMESH_PETSC_NULLPTR);
1924  CHKERRQ(ierr);
1925  for (PetscInt i = 0; i < nblocks; ++i)
1926  {
1927  blockset.insert(std::string(blocks[i]));
1928  ierr = PetscFree(blocks[i]);
1929  CHKERRQ(ierr);
1930  }
1931  ierr = PetscFree(blocks);
1932  CHKERRQ(ierr);
1933  if (blockset.size())
1934  {
1935  ierr = DMMooseSetBlocks(dm, blockset);
1936  CHKERRQ(ierr);
1937  }
1938  PetscInt maxsides =
1939  dmm->_nl->system().get_mesh().get_boundary_info().get_global_boundary_ids().size();
1940  char ** sides;
1941  ierr = PetscMalloc(maxsides * maxvars * sizeof(char *), &sides);
1942  CHKERRQ(ierr);
1943  PetscInt nsides = maxsides;
1944  std::set<std::string> sideset;
1945 
1946  // Do sides
1947  opt = "-dm_moose_sides";
1948  help = "Sides to include in DMMoose";
1949  ierr = PetscOptionsStringArray(
1950  opt.c_str(), help.c_str(), "DMMooseSetSides", sides, &nsides, LIBMESH_PETSC_NULLPTR);
1951  CHKERRQ(ierr);
1952  for (PetscInt i = 0; i < nsides; ++i)
1953  {
1954  sideset.insert(std::string(sides[i]));
1955  ierr = PetscFree(sides[i]);
1956  CHKERRQ(ierr);
1957  }
1958  if (sideset.size())
1959  {
1960  ierr = DMMooseSetSides(dm, sideset);
1961  CHKERRQ(ierr);
1962  }
1963 
1964  // Do unsides
1965  opt = "-dm_moose_unsides";
1966  help = "Sides to exclude from DMMoose";
1967  nsides = maxsides;
1968  ierr = PetscOptionsStringArray(
1969  opt.c_str(), help.c_str(), "DMMooseSetUnSides", sides, &nsides, LIBMESH_PETSC_NULLPTR);
1970  CHKERRQ(ierr);
1971  sideset.clear();
1972  for (PetscInt i = 0; i < nsides; ++i)
1973  {
1974  sideset.insert(std::string(sides[i]));
1975  ierr = PetscFree(sides[i]);
1976  CHKERRQ(ierr);
1977  }
1978  if (sideset.size())
1979  {
1980  ierr = DMMooseSetUnSides(dm, sideset);
1981  CHKERRQ(ierr);
1982  }
1983 
1984  // Do unsides by var
1985  opt = "-dm_moose_unside_by_var";
1986  help = "Sides to exclude from DMMoose on a by-var basis";
1987  nsides = maxsides * maxvars;
1988  ierr = PetscOptionsStringArray(
1989  opt.c_str(), help.c_str(), "DMMooseSetUnSideByVar", sides, &nsides, LIBMESH_PETSC_NULLPTR);
1990  CHKERRQ(ierr);
1991  sideset.clear();
1992  for (PetscInt i = 0; i < nsides; ++i)
1993  {
1994  sideset.insert(std::string(sides[i]));
1995  ierr = PetscFree(sides[i]);
1996  CHKERRQ(ierr);
1997  }
1998  if (sideset.size())
1999  {
2000  ierr = DMMooseSetUnSideByVar(dm, sideset);
2001  CHKERRQ(ierr);
2002  }
2003 
2004  ierr = PetscFree(sides);
2005  CHKERRQ(ierr);
2006  PetscInt maxcontacts = dmm->_nl->_fe_problem.geomSearchData()._penetration_locators.size();
2007  std::shared_ptr<DisplacedProblem> displaced_problem = dmm->_nl->_fe_problem.getDisplacedProblem();
2008  if (displaced_problem)
2009  maxcontacts = PetscMax(
2010  maxcontacts, (PetscInt)displaced_problem->geomSearchData()._penetration_locators.size());
2011 
2012  std::vector<DM_Moose::ContactName> contacts;
2013  std::vector<PetscBool> contact_displaced;
2014  PetscInt ncontacts = 0;
2015  opt = "-dm_moose_ncontacts";
2016  help =
2017  "Number of contacts to include in DMMoose. For each <n> < "
2018  "dm_moose_contacts\n\t-dm_moose_contact_<n> is a comma-separated <primary>,<secondary> pair "
2019  "defining the contact surfaces"
2020  "\t-dm_moose_contact_<n>_displaced <bool> determines whether the contact is defined on "
2021  "the displaced mesh or not";
2022  ierr = PetscOptionsInt(opt.c_str(),
2023  help.c_str(),
2024  "DMMooseSetContacts",
2025  ncontacts,
2026  &ncontacts,
2027  LIBMESH_PETSC_NULLPTR);
2028  CHKERRQ(ierr);
2029  if (ncontacts > maxcontacts)
2030  LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
2031  PETSC_ERR_ARG_SIZ,
2032  "Number of requested contacts %" LIBMESH_PETSCINT_FMT
2033  " exceeds the maximum number of contacts %" LIBMESH_PETSCINT_FMT,
2034  ncontacts,
2035  maxcontacts);
2036  for (PetscInt i = 0; i < ncontacts; ++i)
2037  {
2038  {
2039  char * primary_secondary[2];
2040  PetscInt sz = 2;
2041  std::ostringstream oopt, ohelp;
2042  oopt << "-dm_moose_contact_" << i;
2043  ohelp << "Primary and secondary for contact " << i;
2044  ierr = PetscOptionsStringArray(oopt.str().c_str(),
2045  ohelp.str().c_str(),
2046  "DMMooseSetContacts",
2047  primary_secondary,
2048  &sz,
2049  LIBMESH_PETSC_NULLPTR);
2050  CHKERRQ(ierr);
2051  if (sz != 2)
2052  LIBMESH_SETERRQ2(
2053  ((PetscObject)dm)->comm,
2054  PETSC_ERR_ARG_SIZ,
2055  "Expected 2 sideset IDs (primary & secondary) for contact %" LIBMESH_PETSCINT_FMT
2056  ", got %" LIBMESH_PETSCINT_FMT " instead",
2057  i,
2058  sz);
2059  contacts.push_back(DM_Moose::ContactName(std::string(primary_secondary[0]),
2060  std::string(primary_secondary[1])));
2061  ierr = PetscFree(primary_secondary[0]);
2062  CHKERRQ(ierr);
2063  ierr = PetscFree(primary_secondary[1]);
2064  CHKERRQ(ierr);
2065  }
2066  {
2067  PetscBool displaced = PETSC_FALSE;
2068  std::ostringstream oopt, ohelp;
2069  oopt << "-dm_moose_contact_" << i << "_displaced";
2070  ohelp << "Whether contact " << i << " is determined using displaced mesh or not";
2071  ierr = PetscOptionsBool(oopt.str().c_str(),
2072  ohelp.str().c_str(),
2073  "DMMooseSetContacts",
2074  PETSC_FALSE,
2075  &displaced,
2076  LIBMESH_PETSC_NULLPTR);
2077  CHKERRQ(ierr);
2078  contact_displaced.push_back(displaced);
2079  }
2080  }
2081  if (contacts.size())
2082  {
2083  ierr = DMMooseSetContacts(dm, contacts, contact_displaced);
2084  CHKERRQ(ierr);
2085  }
2086  {
2087  std::ostringstream oopt, ohelp;
2088  PetscBool is_include_all_nodes;
2089  oopt << "-dm_moose_includeAllContactNodes";
2090  ohelp << "Whether to include all nodes on the contact surfaces into the subsolver";
2091  ierr = PetscOptionsBool(oopt.str().c_str(),
2092  ohelp.str().c_str(),
2093  "",
2094  PETSC_FALSE,
2095  &is_include_all_nodes,
2096  LIBMESH_PETSC_NULLPTR);
2097  CHKERRQ(ierr);
2098  dmm->_include_all_contact_nodes = is_include_all_nodes;
2099  }
2100  std::vector<DM_Moose::ContactName> uncontacts;
2101  std::vector<PetscBool> uncontact_displaced;
2102  PetscInt nuncontacts = 0;
2103  opt = "-dm_moose_nuncontacts";
2104  help =
2105  "Number of contacts to exclude from DMMoose. For each <n> < "
2106  "dm_moose_contacts\n\t-dm_moose_contact_<n> is a comma-separated <primary>,<secondary> pair "
2107  "defining the contact surfaces"
2108  "\t-dm_moose_contact_<n>_displaced <bool> determines whether the contact is defined on "
2109  "the displaced mesh or not";
2110  ierr = PetscOptionsInt(opt.c_str(),
2111  help.c_str(),
2112  "DMMooseSetUnContacts",
2113  nuncontacts,
2114  &nuncontacts,
2115  LIBMESH_PETSC_NULLPTR);
2116  CHKERRQ(ierr);
2117  if (nuncontacts > maxcontacts)
2118  LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
2119  PETSC_ERR_ARG_SIZ,
2120  "Number of requested uncontacts %" LIBMESH_PETSCINT_FMT
2121  " exceeds the maximum number of contacts %" LIBMESH_PETSCINT_FMT,
2122  nuncontacts,
2123  maxcontacts);
2124  for (PetscInt i = 0; i < nuncontacts; ++i)
2125  {
2126  {
2127  char * primary_secondary[2];
2128  PetscInt sz = 2;
2129  std::ostringstream oopt, ohelp;
2130  oopt << "-dm_moose_uncontact_" << i;
2131  ohelp << "Primary and secondary for uncontact " << i;
2132  ierr = PetscOptionsStringArray(oopt.str().c_str(),
2133  ohelp.str().c_str(),
2134  "DMMooseSetUnContacts",
2135  primary_secondary,
2136  &sz,
2137  LIBMESH_PETSC_NULLPTR);
2138  CHKERRQ(ierr);
2139  if (sz != 2)
2140  LIBMESH_SETERRQ2(
2141  ((PetscObject)dm)->comm,
2142  PETSC_ERR_ARG_SIZ,
2143  "Expected 2 sideset IDs (primary & secondary) for uncontact %" LIBMESH_PETSCINT_FMT
2144  ", got %" LIBMESH_PETSCINT_FMT " instead",
2145  i,
2146  sz);
2147  uncontacts.push_back(DM_Moose::ContactName(std::string(primary_secondary[0]),
2148  std::string(primary_secondary[1])));
2149  ierr = PetscFree(primary_secondary[0]);
2150  CHKERRQ(ierr);
2151  ierr = PetscFree(primary_secondary[1]);
2152  CHKERRQ(ierr);
2153  }
2154  {
2155  PetscBool displaced = PETSC_FALSE;
2156  std::ostringstream oopt, ohelp;
2157  oopt << "-dm_moose_uncontact_" << i << "_displaced";
2158  ohelp << "Whether uncontact " << i << " is determined using displaced mesh or not";
2159  ierr = PetscOptionsBool(oopt.str().c_str(),
2160  ohelp.str().c_str(),
2161  "DMMooseSetUnContact",
2162  PETSC_FALSE,
2163  &displaced,
2164  LIBMESH_PETSC_NULLPTR);
2165  CHKERRQ(ierr);
2166  uncontact_displaced.push_back(displaced);
2167  }
2168  }
2169  if (uncontacts.size())
2170  {
2171  ierr = DMMooseSetUnContacts(dm, uncontacts, uncontact_displaced);
2172  CHKERRQ(ierr);
2173  }
2174 
2175  PetscInt nsplits = 0;
2176  /* Insert the usage of -dm_moose_fieldsplit_names into this help message, since the following
2177  * if-clause might never fire, if -help is requested. */
2178  const char * fdhelp = "Number of named fieldsplits defined by the DM.\n\
2179  \tNames of fieldsplits are defined by -dm_moose_fieldsplit_names <splitname1> <splitname2> ...\n\
2180  \tEach split can be configured with its own variables, blocks and sides, as any DMMoose";
2181  ierr = PetscOptionsInt(
2182  "-dm_moose_nfieldsplits", fdhelp, "DMMooseSetSplitNames", nsplits, &nsplits, NULL);
2183  CHKERRQ(ierr);
2184  if (nsplits)
2185  {
2186  PetscInt nnsplits = nsplits;
2187  std::vector<std::string> split_names;
2188  char ** splitnames;
2189  ierr = PetscMalloc(nsplits * sizeof(char *), &splitnames);
2190  CHKERRQ(ierr);
2191  ierr = PetscOptionsStringArray("-dm_moose_fieldsplit_names",
2192  "Names of fieldsplits defined by the DM",
2193  "DMMooseSetSplitNames",
2194  splitnames,
2195  &nnsplits,
2196  LIBMESH_PETSC_NULLPTR);
2197  CHKERRQ(ierr);
2198  if (!nnsplits)
2199  {
2200  for (PetscInt i = 0; i < nsplits; ++i)
2201  {
2202  std::ostringstream s;
2203  s << i;
2204  split_names.push_back(s.str());
2205  }
2206  }
2207  else if (nsplits != nnsplits)
2208  LIBMESH_SETERRQ2(((PetscObject)dm)->comm,
2209  PETSC_ERR_ARG_SIZ,
2210  "Expected %" LIBMESH_PETSCINT_FMT
2211  " fieldsplit names, got %" LIBMESH_PETSCINT_FMT " instead",
2212  nsplits,
2213  nnsplits);
2214  else
2215  {
2216  for (PetscInt i = 0; i < nsplits; ++i)
2217  {
2218  split_names.push_back(std::string(splitnames[i]));
2219  ierr = PetscFree(splitnames[i]);
2220  CHKERRQ(ierr);
2221  }
2222  }
2223  ierr = PetscFree(splitnames);
2224  CHKERRQ(ierr);
2225  ierr = DMMooseSetSplitNames(dm, split_names);
2226  CHKERRQ(ierr);
2227  }
2228  ierr = PetscOptionsBool("-dm_moose_print_embedding",
2229  "Print IS embedding DM's dofs",
2230  "DMMoose",
2231  dmm->_print_embedding,
2232  &dmm->_print_embedding,
2233  LIBMESH_PETSC_NULLPTR);
2234  CHKERRQ(ierr);
2235  PetscOptionsEnd();
2236  ierr = DMSetUp_Moose_Pre(dm);
2237  CHKERRQ(ierr); /* Need some preliminary set up because, strangely enough, DMView() is called in
2238  DMSetFromOptions(). */
2239  PetscFunctionReturn(0);
2240 }
std::map< std::pair< BoundaryID, BoundaryID >, PenetrationLocator * > _penetration_locators
PetscErrorCode DMMooseSetContacts(DM dm, const std::vector< std::pair< std::string, std::string >> &contacts, const std::vector< PetscBool > &displaced)
Definition: PetscDMMoose.C:392
PetscErrorCode DMMooseSetVariables(DM dm, const std::set< std::string > &vars)
Definition: PetscDMMoose.C:293
PetscErrorCode DMMooseSetUnContacts(DM dm, const std::vector< std::pair< std::string, std::string >> &uncontacts, const std::vector< PetscBool > &displaced)
Definition: PetscDMMoose.C:424
bool _include_all_contact_nodes
Definition: PetscDMMoose.C:84
static PetscErrorCode DMMooseGetMeshBlocks_Private(DM dm, std::set< subdomain_id_type > &blocks)
ierr
static PetscErrorCode DMSetUp_Moose_Pre(DM dm)
virtual GeometricSearchData & geomSearchData() override
FEProblemBase & _fe_problem
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
CHKERRQ(ierr)
PetscBool _print_embedding
Definition: PetscDMMoose.C:98
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
virtual System & system() override
Get the reference to the libMesh system.
PetscErrorCode DMMooseSetSides(DM dm, const std::set< std::string > &sides)
Definition: PetscDMMoose.C:341
PetscErrorCode DMMooseSetUnSideByVar(DM dm, const std::set< std::string > &unside_by_var)
Definition: PetscDMMoose.C:375
PetscErrorCode DMMooseSetBlocks(DM dm, const std::set< std::string > &blocks)
Definition: PetscDMMoose.C:324
std::pair< std::string, std::string > ContactName
Definition: PetscDMMoose.C:74
PetscErrorCode DMMooseSetSplitNames(DM dm, const std::vector< std::string > &split_names)
Definition: PetscDMMoose.C:470
PetscErrorCode DMMooseSetUnSides(DM dm, const std::set< std::string > &unsides)
Definition: PetscDMMoose.C:358

◆ DMSetUp_Moose()

static PetscErrorCode DMSetUp_Moose ( DM  dm)
static

Definition at line 1795 of file PetscDMMoose.C.

Referenced by DMCreate_Moose().

1796 {
1797  PetscErrorCode ierr;
1798  DM_Moose * dmm = (DM_Moose *)(dm->data);
1799 
1800  PetscFunctionBegin;
1801  ierr = DMMooseValidityCheck(dm);
1802  CHKERRQ(ierr);
1803  if (!dmm->_nl)
1804  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1805  if (dmm->_print_embedding)
1806  {
1807  const char *name, *prefix;
1808  IS embedding;
1809 
1810  ierr = PetscObjectGetName((PetscObject)dm, &name);
1811  CHKERRQ(ierr);
1812  ierr = PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix);
1813  CHKERRQ(ierr);
1814  ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1815  "DM Moose with name %s and prefix %s\n",
1816  name,
1817  prefix);
1818  CHKERRQ(ierr);
1819  if (dmm->_all_vars && dmm->_all_blocks && dmm->_nosides && dmm->_nounsides &&
1820  dmm->_nocontacts && dmm->_nouncontacts)
1821  {
1822  ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1823  "\thas a trivial embedding\n");
1824  CHKERRQ(ierr);
1825  }
1826  else
1827  {
1828  ierr = DMMooseGetEmbedding_Private(dm, &embedding);
1829  CHKERRQ(ierr);
1830  ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm),
1831  "\thas embedding defined by IS:\n");
1832  CHKERRQ(ierr);
1833  ierr = ISView(embedding, PETSC_VIEWER_STDOUT_(((PetscObject)dm)->comm));
1834  CHKERRQ(ierr);
1835  ierr = ISDestroy(&embedding);
1836  CHKERRQ(ierr);
1837  }
1838  }
1839  /*
1840  Do not evaluate function, Jacobian or bounds for an embedded DM -- the subproblem might not have
1841  enough information for that.
1842  */
1843  if (dmm->_all_vars && dmm->_all_blocks && dmm->_nosides && dmm->_nounsides && dmm->_nocontacts &&
1844  dmm->_nouncontacts)
1845  {
1846  ierr = DMSNESSetFunction(dm, SNESFunction_DMMoose, (void *)dm);
1847  CHKERRQ(ierr);
1848  ierr = DMSNESSetJacobian(dm, SNESJacobian_DMMoose, (void *)dm);
1849  CHKERRQ(ierr);
1850  if (dmm->_nl->nonlinearSolver()->bounds || dmm->_nl->nonlinearSolver()->bounds_object)
1851  ierr = DMSetVariableBounds(dm, DMVariableBounds_Moose);
1852  CHKERRQ(ierr);
1853  }
1854  PetscFunctionReturn(0);
1855 }
std::string name(const ElemQuality q)
bool _all_vars
Definition: PetscDMMoose.C:58
virtual NonlinearSolver< Number > * nonlinearSolver()=0
bool _nounsides
Definition: PetscDMMoose.C:72
bool _nouncontacts
Definition: PetscDMMoose.C:83
ierr
bool _nocontacts
Definition: PetscDMMoose.C:82
static PetscErrorCode DMVariableBounds_Moose(DM dm, Vec xl, Vec xu)
static PetscErrorCode SNESJacobian_DMMoose(SNES, Vec x, Mat jac, Mat pc, void *ctx)
NonlinearImplicitSystem::ComputeBounds * bounds_object
bool _all_blocks
Definition: PetscDMMoose.C:62
static PetscErrorCode DMMooseGetEmbedding_Private(DM dm, IS *embedding)
Definition: PetscDMMoose.C:534
CHKERRQ(ierr)
PetscBool _print_embedding
Definition: PetscDMMoose.C:98
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
static PetscErrorCode SNESFunction_DMMoose(SNES, Vec x, Vec r, void *ctx)
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
void(* bounds)(NumericVector< Number > &XL, NumericVector< Number > &XU, sys_type &S)
bool _nosides
Definition: PetscDMMoose.C:71

◆ DMSetUp_Moose_Pre()

static PetscErrorCode DMSetUp_Moose_Pre ( DM  dm)
static

Definition at line 1505 of file PetscDMMoose.C.

Referenced by DMSetFromOptions_Moose().

1506 {
1507  PetscErrorCode ierr;
1508  DM_Moose * dmm = (DM_Moose *)(dm->data);
1509 
1510  PetscFunctionBegin;
1511  ierr = DMMooseValidityCheck(dm);
1512  CHKERRQ(ierr);
1513  if (!dmm->_nl)
1514  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No Moose system set for DM_Moose");
1515 
1516  /* Set up variables, blocks and sides. */
1517  DofMap & dofmap = dmm->_nl->system().get_dof_map();
1518  /* libMesh mesh */
1519  const MeshBase & mesh = dmm->_nl->system().get_mesh();
1520 
1521  // Do sides
1522  dmm->_nosides = PETSC_TRUE;
1523  dmm->_side_ids->clear();
1524  dmm->_side_names->clear();
1525  if (dmm->_sides)
1526  {
1527  dmm->_nosides = PETSC_FALSE;
1528  for (const auto & name : *(dmm->_sides))
1529  {
1530  boundary_id_type id = dmm->_nl->mesh().getBoundaryID(name);
1531  dmm->_side_names->insert(std::make_pair(id, name));
1532  dmm->_side_ids->insert(std::make_pair(name, id));
1533  }
1534  delete dmm->_sides;
1535  dmm->_sides = LIBMESH_PETSC_NULLPTR;
1536  }
1537 
1538  // Do unsides
1539  dmm->_nounsides = PETSC_TRUE;
1540  dmm->_unside_ids->clear();
1541  dmm->_unside_names->clear();
1542  if (dmm->_unsides)
1543  {
1544  dmm->_nounsides = PETSC_FALSE;
1545  for (const auto & name : *(dmm->_unsides))
1546  {
1547  boundary_id_type id = dmm->_nl->mesh().getBoundaryID(name);
1548  dmm->_unside_names->insert(std::make_pair(id, name));
1549  dmm->_unside_ids->insert(std::make_pair(name, id));
1550  }
1551  delete dmm->_unsides;
1552  dmm->_unsides = LIBMESH_PETSC_NULLPTR;
1553  }
1554 
1555  // Do unside by var
1556  dmm->_nounside_by_var = PETSC_TRUE;
1557  dmm->_unside_by_var_set->clear();
1558  if (dmm->_unside_by_var)
1559  {
1560  dmm->_nounside_by_var = PETSC_FALSE;
1561  for (const auto & name : *(dmm->_unside_by_var))
1562  {
1563  const auto colon_pos = name.find(":");
1564  auto unside_name = name.substr(0, colon_pos);
1565  auto var_name = name.substr(colon_pos + 1);
1566  boundary_id_type id = dmm->_nl->mesh().getBoundaryID(unside_name);
1567  bool var_found = false;
1568  for (unsigned int v = 0; v < dofmap.n_variables(); ++v)
1569  {
1570  const auto & vname = dofmap.variable(v).name();
1571  if (vname == var_name)
1572  {
1573  dmm->_unside_by_var_set->insert(std::make_pair(id, v));
1574  var_found = true;
1575  break;
1576  }
1577  }
1578  if (!var_found)
1579  mooseError("No variable named '", var_name, "' found");
1580  }
1581  delete dmm->_unside_by_var;
1582  dmm->_unside_by_var = LIBMESH_PETSC_NULLPTR;
1583  }
1584 
1585  dmm->_nocontacts = PETSC_TRUE;
1586 
1587  if (dmm->_contacts)
1588  {
1589  dmm->_nocontacts = PETSC_FALSE;
1590  for (const auto & cpair : *(dmm->_contacts))
1591  {
1592  try
1593  {
1594  if ((*dmm->_contact_displaced)[cpair])
1595  dmm->_nl->_fe_problem.getDisplacedProblem()->geomSearchData().getPenetrationLocator(
1596  cpair.first, cpair.second);
1597  else
1598  dmm->_nl->_fe_problem.geomSearchData().getPenetrationLocator(cpair.first, cpair.second);
1599  }
1600  catch (...)
1601  {
1602  std::ostringstream err;
1603  err << "Problem retrieving contact for PenetrationLocator with primary " << cpair.first
1604  << " and secondary " << cpair.second;
1605  mooseError(err.str());
1606  }
1607  BoundaryID primary_id = dmm->_nl->mesh().getBoundaryID(cpair.first);
1608  BoundaryID secondary_id = dmm->_nl->mesh().getBoundaryID(cpair.second);
1609  DM_Moose::ContactID cid(primary_id, secondary_id);
1610  dmm->_contact_names->insert(std::make_pair(cid, cpair));
1611  }
1612  }
1613 
1614  dmm->_nouncontacts = PETSC_TRUE;
1615  if (dmm->_uncontacts)
1616  {
1617  dmm->_nouncontacts = PETSC_FALSE;
1618  for (const auto & cpair : *(dmm->_uncontacts))
1619  {
1620  try
1621  {
1622  if ((*dmm->_uncontact_displaced)[cpair])
1623  dmm->_nl->_fe_problem.getDisplacedProblem()->geomSearchData().getPenetrationLocator(
1624  cpair.first, cpair.second);
1625  else
1626  dmm->_nl->_fe_problem.geomSearchData().getPenetrationLocator(cpair.first, cpair.second);
1627  }
1628  catch (...)
1629  {
1630  std::ostringstream err;
1631  err << "Problem retrieving uncontact for PenetrationLocator with primary " << cpair.first
1632  << " and secondary " << cpair.second;
1633  mooseError(err.str());
1634  }
1635  BoundaryID primary_id = dmm->_nl->mesh().getBoundaryID(cpair.first);
1636  BoundaryID secondary_id = dmm->_nl->mesh().getBoundaryID(cpair.second);
1637  DM_Moose::ContactID cid(primary_id, secondary_id);
1638  dmm->_uncontact_names->insert(std::make_pair(cid, cpair));
1639  }
1640  }
1641 
1642  dmm->_var_ids->clear();
1643  dmm->_var_names->clear();
1644  // FIXME: would be nice to invert this nested loop structure so we could iterate over the
1645  // potentially smaller dmm->vars,
1646  // but checking against dofmap.variable would still require a linear search, hence, no win. Would
1647  // be nice to endow dofmap.variable
1648  // with a fast search capability.
1649  for (unsigned int v = 0; v < dofmap.n_variables(); ++v)
1650  {
1651  std::string vname = dofmap.variable(v).name();
1652  if (dmm->_vars && dmm->_vars->size() && dmm->_vars->find(vname) == dmm->_vars->end())
1653  continue;
1654  dmm->_var_ids->insert(std::pair<std::string, unsigned int>(vname, v));
1655  dmm->_var_names->insert(std::pair<unsigned int, std::string>(v, vname));
1656  }
1657  if (dmm->_var_ids->size() == dofmap.n_variables())
1658  dmm->_all_vars = PETSC_TRUE;
1659  else
1660  dmm->_all_vars = PETSC_FALSE;
1661  if (dmm->_vars)
1662  {
1663  delete dmm->_vars;
1664  dmm->_vars = LIBMESH_PETSC_NULLPTR;
1665  }
1666 
1667  dmm->_block_ids->clear();
1668  dmm->_block_names->clear();
1669  std::set<subdomain_id_type> blocks;
1670  ierr = DMMooseGetMeshBlocks_Private(dm, blocks);
1671  CHKERRQ(ierr);
1672  if (blocks.empty())
1673  SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "No mesh blocks found.");
1674 
1675  for (const auto & bid : blocks)
1676  {
1677  std::string bname = mesh.subdomain_name(bid);
1678  if (!bname.length())
1679  {
1680  // Block names are currently implemented for Exodus II meshes
1681  // only, so we might have to make up our own block names and
1682  // maintain our own mapping of block ids to names.
1683  std::ostringstream ss;
1684  ss << bid;
1685  bname = ss.str();
1686  }
1687  if (dmm->_nosides && dmm->_nocontacts)
1688  {
1689  // If no sides and no contacts have been specified, by default (null or empty dmm->blocks) all
1690  // blocks are included in the split Thus, skip this block only if it is explicitly excluded
1691  // from a nonempty dmm->blocks.
1692  if (dmm->_blocks && dmm->_blocks->size() &&
1693  (dmm->_blocks->find(bname) ==
1694  dmm->_blocks->end() && // We should allow users to use subdomain IDs
1695  dmm->_blocks->find(std::to_string(bid)) == dmm->_blocks->end()))
1696  continue;
1697  }
1698  else
1699  {
1700  // If sides or contacts have been specified, only the explicitly-specified blocks (those in
1701  // dmm->blocks, if it's non-null) are in the split. Thus, include this block only if it is
1702  // explicitly specified in a nonempty dmm->blocks. Equivalently, skip this block if
1703  // dmm->blocks is dmm->blocks is null or empty or excludes this block.
1704  if (!dmm->_blocks || !dmm->_blocks->size() ||
1705  (dmm->_blocks->find(bname) ==
1706  dmm->_blocks->end() // We should allow users to use subdomain IDs
1707  && dmm->_blocks->find(std::to_string(bid)) == dmm->_blocks->end()))
1708  continue;
1709  }
1710  dmm->_block_ids->insert(std::make_pair(bname, bid));
1711  dmm->_block_names->insert(std::make_pair(bid, bname));
1712  }
1713 
1714  if (dmm->_block_ids->size() == blocks.size())
1715  dmm->_all_blocks = PETSC_TRUE;
1716  else
1717  dmm->_all_blocks = PETSC_FALSE;
1718  if (dmm->_blocks)
1719  {
1720  delete dmm->_blocks;
1721  dmm->_blocks = LIBMESH_PETSC_NULLPTR;
1722  }
1723 
1724  std::string name = dmm->_nl->system().name();
1725  name += "_vars";
1726  for (const auto & vit : *(dmm->_var_names))
1727  name += "_" + vit.second;
1728 
1729  name += "_blocks";
1730 
1731  for (const auto & bit : *(dmm->_block_names))
1732  name += "_" + bit.second;
1733 
1734  if (dmm->_side_names && dmm->_side_names->size())
1735  {
1736  name += "_sides";
1737  for (const auto & sit : *(dmm->_side_names))
1738  name += "_" + sit.second;
1739  }
1740  if (dmm->_unside_names && dmm->_unside_names->size())
1741  {
1742  name += "_unsides";
1743  for (const auto & sit : *(dmm->_unside_names))
1744  name += "_" + sit.second;
1745  }
1746  if (dmm->_contact_names && dmm->_contact_names->size())
1747  {
1748  name += "_contacts";
1749  for (const auto & cit : *(dmm->_contact_names))
1750  name += "_primary_" + cit.second.first + "_secondary_" + cit.second.second;
1751  }
1752  if (dmm->_uncontact_names && dmm->_uncontact_names->size())
1753  {
1754  name += "_uncontacts";
1755  for (const auto & cit : *(dmm->_uncontact_names))
1756  name += "_primary_" + cit.second.first + "_secondary_" + cit.second.second;
1757  }
1758  ierr = PetscObjectSetName((PetscObject)dm, name.c_str());
1759  CHKERRQ(ierr);
1760  PetscFunctionReturn(0);
1761 }
std::string name(const ElemQuality q)
OStreamProxy err
std::set< ContactName > * _uncontacts
Definition: PetscDMMoose.C:78
bool _all_vars
Definition: PetscDMMoose.C:58
std::set< std::pair< BoundaryID, unsigned int > > * _unside_by_var_set
Definition: PetscDMMoose.C:70
std::map< BoundaryID, std::string > * _side_names
Definition: PetscDMMoose.C:64
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
std::map< ContactName, PetscBool > * _contact_displaced
Definition: PetscDMMoose.C:80
bool _nounsides
Definition: PetscDMMoose.C:72
bool _nouncontacts
Definition: PetscDMMoose.C:83
std::map< std::string, BoundaryID > * _side_ids
Definition: PetscDMMoose.C:65
if(subdm)
MeshBase & mesh
static PetscErrorCode DMMooseGetMeshBlocks_Private(DM dm, std::set< subdomain_id_type > &blocks)
std::map< ContactName, PetscBool > * _uncontact_displaced
Definition: PetscDMMoose.C:81
ierr
std::set< std::string > * _sides
Definition: PetscDMMoose.C:63
virtual GeometricSearchData & geomSearchData() override
bool _nocontacts
Definition: PetscDMMoose.C:82
std::map< std::string, unsigned int > * _var_ids
Definition: PetscDMMoose.C:56
std::map< unsigned int, std::string > * _var_names
Definition: PetscDMMoose.C:57
PenetrationLocator & getPenetrationLocator(const BoundaryName &primary, const BoundaryName &secondary, Order order=FIRST)
FEProblemBase & _fe_problem
int8_t boundary_id_type
std::map< ContactID, ContactName > * _uncontact_names
Definition: PetscDMMoose.C:79
boundary_id_type BoundaryID
std::set< ContactName > * _contacts
Definition: PetscDMMoose.C:76
std::set< std::string > * _unside_by_var
Definition: PetscDMMoose.C:69
bool _all_blocks
Definition: PetscDMMoose.C:62
std::pair< BoundaryID, BoundaryID > ContactID
Definition: PetscDMMoose.C:75
std::set< std::string > * _unsides
Definition: PetscDMMoose.C:66
std::set< std::string > * _vars
Definition: PetscDMMoose.C:55
std::map< std::string, BoundaryID > * _unside_ids
Definition: PetscDMMoose.C:67
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
CHKERRQ(ierr)
NonlinearSystemBase * _nl
Definition: PetscDMMoose.C:53
PetscErrorCode DMMooseValidityCheck(DM dm)
Definition: PetscDMMoose.C:128
virtual System & system() override
Get the reference to the libMesh system.
virtual MooseMesh & mesh()
Definition: SystemBase.h:96
std::map< std::string, subdomain_id_type > * _block_ids
Definition: PetscDMMoose.C:60
std::set< std::string > * _blocks
Definition: PetscDMMoose.C:59
std::map< ContactID, ContactName > * _contact_names
Definition: PetscDMMoose.C:77
bool _nosides
Definition: PetscDMMoose.C:71
bool _nounside_by_var
Definition: PetscDMMoose.C:73
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
Definition: MooseMesh.C:1474
std::map< BoundaryID, std::string > * _unside_names
Definition: PetscDMMoose.C:68
std::map< unsigned int, std::string > * _block_names
Definition: PetscDMMoose.C:61

◆ DMVariableBounds_Moose()

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

Definition at line 1215 of file PetscDMMoose.C.

Referenced by DMSetUp_Moose().

1216 {
1217  PetscErrorCode ierr;
1218  NonlinearSystemBase * nl = NULL;
1219 
1220  PetscFunctionBegin;
1221  ierr = DMMooseGetNonlinearSystem(dm, nl);
1222  CHKERRQ(ierr);
1223 
1224  PetscVector<Number> XL(xl, nl->comm());
1225  PetscVector<Number> XU(xu, nl->comm());
1226 
1227  ierr = VecSet(xl, PETSC_NINFINITY);
1228  CHKERRQ(ierr);
1229  ierr = VecSet(xu, PETSC_INFINITY);
1230  CHKERRQ(ierr);
1231  if (nl->nonlinearSolver()->bounds != NULL)
1232  nl->nonlinearSolver()->bounds(XL, XU, nl->nonlinearSolver()->system());
1233  else if (nl->nonlinearSolver()->bounds_object != NULL)
1234  nl->nonlinearSolver()->bounds_object->bounds(XL, XU, nl->nonlinearSolver()->system());
1235  else
1236  SETERRQ(
1237  ((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "No bounds calculation in this Moose object");
1238  PetscFunctionReturn(0);
1239 }
virtual NonlinearSolver< Number > * nonlinearSolver()=0
PetscErrorCode DMMooseGetNonlinearSystem(DM dm, NonlinearSystemBase *&nl)
Definition: PetscDMMoose.C:457
const Parallel::Communicator & comm() const
ierr
Nonlinear system to be solved.
const sys_type & system() const
NonlinearImplicitSystem::ComputeBounds * bounds_object
CHKERRQ(ierr)
void(* bounds)(NumericVector< Number > &XL, NumericVector< Number > &XU, sys_type &S)

◆ DMView_Moose()

static PetscErrorCode DMView_Moose ( DM  dm,
PetscViewer  viewer 
)
static

Definition at line 1349 of file PetscDMMoose.C.

Referenced by DMCreate_Moose().

1350 {
1351  PetscErrorCode ierr;
1352  PetscBool isascii;
1353  const char *name, *prefix;
1354  DM_Moose * dmm = (DM_Moose *)dm->data;
1355 
1356  PetscFunctionBegin;
1357  ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);
1358  CHKERRQ(ierr);
1359  if (isascii)
1360  {
1361  ierr = PetscObjectGetName((PetscObject)dm, &name);
1362  CHKERRQ(ierr);
1363  ierr = PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix);
1364  CHKERRQ(ierr);
1365  ierr = PetscViewerASCIIPrintf(viewer, "DM Moose with name %s and prefix %s\n", name, prefix);
1366  CHKERRQ(ierr);
1367  ierr = PetscViewerASCIIPrintf(viewer, "variables:");
1368  CHKERRQ(ierr);
1369  for (const auto & vit : *(dmm->_var_ids))
1370  {
1371  ierr = PetscViewerASCIIPrintf(viewer, "(%s,%u) ", vit.first.c_str(), vit.second);
1372  CHKERRQ(ierr);
1373  }
1374  ierr = PetscViewerASCIIPrintf(viewer, "\n");
1375  CHKERRQ(ierr);
1376  ierr = PetscViewerASCIIPrintf(viewer, "blocks:");
1377  CHKERRQ(ierr);
1378  for (const auto & bit : *(dmm->_block_ids))
1379  {
1380  ierr = PetscViewerASCIIPrintf(viewer, "(%s,%d) ", bit.first.c_str(), bit.second);
1381  CHKERRQ(ierr);
1382  }
1383  ierr = PetscViewerASCIIPrintf(viewer, "\n");
1384  CHKERRQ(ierr);
1385 
1386  if (dmm->_side_ids->size())
1387  {
1388  ierr = PetscViewerASCIIPrintf(viewer, "sides:");
1389  CHKERRQ(ierr);
1390  for (const auto & sit : *(dmm->_side_ids))
1391  {
1392  ierr = PetscViewerASCIIPrintf(viewer, "(%s,%d) ", sit.first.c_str(), sit.second);
1393  CHKERRQ(ierr);
1394  }
1395  ierr = PetscViewerASCIIPrintf(viewer, "\n");
1396  CHKERRQ(ierr);
1397  }
1398 
1399  if (dmm->_unside_ids->size())
1400  {
1401  ierr = PetscViewerASCIIPrintf(viewer, "unsides:");
1402  CHKERRQ(ierr);
1403  for (const auto & sit : *(dmm->_unside_ids))
1404  {
1405  ierr = PetscViewerASCIIPrintf(viewer, "(%s,%d) ", sit.first.c_str(), sit.second);
1406  CHKERRQ(ierr);
1407  }
1408  ierr = PetscViewerASCIIPrintf(viewer, "\n");
1409  CHKERRQ(ierr);
1410  }
1411 
1412  if (dmm->_contact_names->size())
1413  {
1414  ierr = PetscViewerASCIIPrintf(viewer, "contacts:");
1415  CHKERRQ(ierr);
1416  for (const auto & cit : *(dmm->_contact_names))
1417  {
1418  ierr = PetscViewerASCIIPrintf(
1419  viewer, "(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str());
1420  CHKERRQ(ierr);
1421  if ((*dmm->_contact_displaced)[cit.second])
1422  {
1423  ierr = PetscViewerASCIIPrintf(viewer, "displaced) ");
1424  CHKERRQ(ierr);
1425  }
1426  else
1427  {
1428  ierr = PetscViewerASCIIPrintf(viewer, "undisplaced) ");
1429  CHKERRQ(ierr);
1430  }
1431  }
1432  ierr = PetscViewerASCIIPrintf(viewer, "\n");
1433  CHKERRQ(ierr);
1434  }
1435 
1436  if (dmm->_uncontact_names->size())
1437  {
1438  ierr = PetscViewerASCIIPrintf(viewer, "_uncontacts:");
1439  CHKERRQ(ierr);
1440  for (const auto & cit : *(dmm->_uncontact_names))
1441  {
1442  ierr = PetscViewerASCIIPrintf(
1443  viewer, "(%s,%s,", cit.second.first.c_str(), cit.second.second.c_str());
1444  CHKERRQ(ierr);
1445  if ((*dmm->_uncontact_displaced)[cit.second])
1446  {
1447  ierr = PetscViewerASCIIPrintf(viewer, "displaced) ");
1448  CHKERRQ(ierr);
1449  }
1450  else
1451  {
1452  ierr = PetscViewerASCIIPrintf(viewer, "undisplaced) ");
1453  CHKERRQ(ierr);
1454  }
1455  }
1456  ierr = PetscViewerASCIIPrintf(viewer, "\n");
1457  CHKERRQ(ierr);
1458  }
1459 
1460  if (dmm->_splitlocs && dmm->_splitlocs->size())
1461  {
1462  ierr = PetscViewerASCIIPrintf(viewer, "Field decomposition:");
1463  CHKERRQ(ierr);
1464  // FIX: decompositions might have different sizes and components on different ranks.
1465  for (const auto & dit : *(dmm->_splitlocs))
1466  {
1467  std::string dname = dit.first;
1468  ierr = PetscViewerASCIIPrintf(viewer, " %s", dname.c_str());
1469  CHKERRQ(ierr);
1470  }
1471  ierr = PetscViewerASCIIPrintf(viewer, "\n");
1472  CHKERRQ(ierr);
1473  }
1474  }
1475  else
1476  SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Non-ASCII viewers are not supported");
1477 
1478  PetscFunctionReturn(0);
1479 }
std::string name(const ElemQuality q)
std::map< ContactName, PetscBool > * _contact_displaced
Definition: PetscDMMoose.C:80
std::map< std::string, BoundaryID > * _side_ids
Definition: PetscDMMoose.C:65
std::map< ContactName, PetscBool > * _uncontact_displaced
Definition: PetscDMMoose.C:81
ierr
std::map< std::string, unsigned int > * _var_ids
Definition: PetscDMMoose.C:56
std::map< ContactID, ContactName > * _uncontact_names
Definition: PetscDMMoose.C:79
std::map< std::string, BoundaryID > * _unside_ids
Definition: PetscDMMoose.C:67
CHKERRQ(ierr)
std::map< std::string, subdomain_id_type > * _block_ids
Definition: PetscDMMoose.C:60
std::map< ContactID, ContactName > * _contact_names
Definition: PetscDMMoose.C:77
std::multimap< std::string, unsigned int > * _splitlocs
Definition: PetscDMMoose.C:89

◆ SNESFunction_DMMoose()

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

Definition at line 1109 of file PetscDMMoose.C.

Referenced by DMSetUp_Moose().

1110 {
1111  DM dm = (DM)ctx;
1112  PetscErrorCode ierr;
1113 
1114  PetscFunctionBegin;
1115  ierr = DMMooseFunction(dm, x, r);
1116  CHKERRQ(ierr);
1117  PetscFunctionReturn(0);
1118 }
ierr
CHKERRQ(ierr)
static PetscErrorCode DMMooseFunction(DM dm, Vec x, Vec r)

◆ SNESJacobian_DMMoose()

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

Definition at line 1203 of file PetscDMMoose.C.

Referenced by DMSetUp_Moose().

1204 {
1205  DM dm = (DM)ctx;
1206  PetscErrorCode ierr;
1207 
1208  PetscFunctionBegin;
1209  ierr = DMMooseJacobian(dm, x, jac, pc);
1210  CHKERRQ(ierr);
1211  PetscFunctionReturn(0);
1212 }
ierr
static PetscErrorCode DMMooseJacobian(DM dm, Vec x, Mat jac, Mat pc)
CHKERRQ(ierr)

◆ SNESUpdateDMMoose()

PetscErrorCode SNESUpdateDMMoose ( SNES  snes,
PetscInt  iteration 
)

Definition at line 2380 of file PetscDMMoose.C.

2381 {
2382  /* This is called any time the structure of the problem changes in a way that affects the Jacobian
2383  sparsity pattern.
2384  For example, this may happen when NodeFaceConstraints change Jacobian's sparsity pattern based
2385  on newly-detected Penetration.
2386  In that case certain preconditioners (e.g., PCASM) will not work, unless we tell them that the
2387  sparsity pattern has changed.
2388  For now we are rebuilding the whole KSP, when necessary.
2389  */
2390  PetscErrorCode ierr;
2391  DM dm;
2392  KSP ksp;
2393  const char * prefix;
2394  MPI_Comm comm;
2395  PC pc;
2396 
2397  PetscFunctionBegin;
2398  if (iteration)
2399  {
2400  /* TODO: limit this only to situations when displaced (un)contact splits are present, as is
2401  * DisplacedProblem(). */
2402  ierr = SNESGetDM(snes, &dm);
2403  CHKERRQ(ierr);
2404  ierr = DMMooseReset(dm);
2405  CHKERRQ(ierr);
2406  ierr = DMSetUp(dm);
2407  CHKERRQ(ierr);
2408  ierr = SNESGetKSP(snes, &ksp);
2409  CHKERRQ(ierr);
2410  /* Should we rebuild the whole KSP? */
2411  ierr = PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
2412  CHKERRQ(ierr);
2413  ierr = PetscObjectGetComm((PetscObject)ksp, &comm);
2414  CHKERRQ(ierr);
2415  ierr = PCCreate(comm, &pc);
2416  CHKERRQ(ierr);
2417  ierr = PCSetDM(pc, dm);
2418  CHKERRQ(ierr);
2419  ierr = PCSetOptionsPrefix(pc, prefix);
2420  CHKERRQ(ierr);
2421  ierr = PCSetFromOptions(pc);
2422  CHKERRQ(ierr);
2423  ierr = KSPSetPC(ksp, pc);
2424  CHKERRQ(ierr);
2425  ierr = PCDestroy(&pc);
2426  CHKERRQ(ierr);
2427  }
2428  PetscFunctionReturn(0);
2429 }
PetscErrorCode DMMooseReset(DM dm)
ierr
CHKERRQ(ierr)