libMesh
Classes | Functions
petscdmlibmeshimpl.C File Reference

Go to the source code of this file.

Classes

struct  DM_libMesh
 
struct  DMVec_libMesh
 
struct  token
 

Functions

PetscErrorCode DMlibMeshGetVec_Private (DM, const char *, Vec *)
 
PetscErrorCode DMlibMeshSetUpName_Private (DM dm)
 
PetscErrorCode DMlibMeshSetSystem_libMesh (DM dm, NonlinearImplicitSystem &sys)
 
PetscErrorCode DMlibMeshGetSystem_libMesh (DM dm, NonlinearImplicitSystem *&sys)
 
PetscErrorCode DMlibMeshGetBlocks (DM dm, PetscInt *n, char ***blocknames)
 
PetscErrorCode DMlibMeshGetVariables (DM dm, PetscInt *n, char ***varnames)
 
static PetscErrorCode DMCreateFieldDecomposition_libMesh (DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
 
static PetscErrorCode DMCreateDomainDecomposition_libMesh (DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
 
PetscErrorCode DMlibMeshCreateFieldDecompositionDM (DM dm, PetscInt dnumber, PetscInt *dsizes, char ***dvarlists, DM *ddm)
 
PetscErrorCode DMlibMeshCreateDomainDecompositionDM (DM dm, PetscInt dnumber, PetscInt *dsizes, char ***dblocklists, DM *ddm)
 
static PetscErrorCode DMlibMeshFunction (DM dm, Vec x, Vec r)
 
static PetscErrorCode SNESFunction_DMlibMesh (SNES, Vec x, Vec r, void *ctx)
 
static PetscErrorCode DMlibMeshJacobian (DM dm, Vec x, Mat jac, Mat pc)
 
static PetscErrorCode SNESJacobian_DMlibMesh (SNES, Vec x, Mat jac, Mat pc, void *ctx)
 
static PetscErrorCode DMVariableBounds_libMesh (DM dm, Vec xl, Vec xu)
 
static PetscErrorCode DMCreateGlobalVector_libMesh (DM dm, Vec *x)
 
static PetscErrorCode DMCreateMatrix_libMesh (DM dm, Mat *A)
 
static PetscErrorCode DMView_libMesh (DM dm, PetscViewer viewer)
 
static PetscErrorCode DMSetUp_libMesh (DM dm)
 
static PetscErrorCode DMDestroy_libMesh (DM dm)
 
PetscErrorCode DMCreate_libMesh (DM dm)
 

Function Documentation

◆ DMCreate_libMesh()

PetscErrorCode DMCreate_libMesh ( DM  dm)

Definition at line 944 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMCreateDomainDecomposition_libMesh(), DMCreateFieldDecomposition_libMesh(), DMCreateGlobalVector_libMesh(), DMCreateMatrix_libMesh(), DMDestroy_libMesh(), DMlibMeshGetSystem_libMesh(), DMlibMeshSetSystem_libMesh(), DMSetUp_libMesh(), DMView_libMesh(), libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), DM_libMesh::varids, and DM_libMesh::varnames.

945 {
946  DM_libMesh * dlm;
947 
948  PetscFunctionBegin;
949  PetscValidHeaderSpecific(dm,DM_CLASSID,1);
950  LibmeshPetscCallQ(PetscNew(&dlm));
951  dm->data = dlm;
952 
953  /* DMlibMesh impl */
954  dlm->varids = new(std::map<std::string, unsigned int>);
955  dlm->blockids = new(std::map<std::string, unsigned int>);
956  dlm->varnames = new(std::map<unsigned int, std::string>);
957  dlm->blocknames = new(std::map<unsigned int, std::string>);
958  dlm->decomposition = LIBMESH_PETSC_NULLPTR;
959  dlm->decomposition_type = DMLIBMESH_NO_DECOMPOSITION;
960 
961  /* DM API */
962  dm->ops->createglobalvector = DMCreateGlobalVector_libMesh;
963  dm->ops->createlocalvector = 0; // DMCreateLocalVector_libMesh;
964  dm->ops->getcoloring = 0; // DMGetColoring_libMesh;
965  dm->ops->creatematrix = DMCreateMatrix_libMesh;
966  dm->ops->createinterpolation= 0; // DMCreateInterpolation_libMesh;
967 
968  dm->ops->refine = 0; // DMRefine_libMesh;
969  dm->ops->coarsen = 0; // DMCoarsen_libMesh;
970 
971  // * dm->ops->getinjection was renamed to dm->ops->createinjection in PETSc 5a84ad338 (5 Jul 2019)
972  // * dm->ops-getaggregates was removed in PETSc 97779f9a (5 Jul 2019)
973  // * Both changes were merged into PETSc master in 94aad3ce (7 Jul 2019).
974 #if PETSC_VERSION_LESS_THAN(3,12,0)
975  dm->ops->getinjection = 0; // DMGetInjection_libMesh;
976  dm->ops->getaggregates = 0; // DMGetAggregates_libMesh;
977 #else
978  dm->ops->createinjection = 0;
979 #endif
980 
981 
982  dm->ops->createfielddecomposition = DMCreateFieldDecomposition_libMesh;
983  dm->ops->createdomaindecomposition = DMCreateDomainDecomposition_libMesh;
984 
985  dm->ops->destroy = DMDestroy_libMesh;
986  dm->ops->view = DMView_libMesh;
987  dm->ops->setfromoptions = 0; // DMSetFromOptions_libMesh;
988  dm->ops->setup = DMSetUp_libMesh;
989 
990  /* DMlibMesh API */
991  LibmeshPetscCallQ(PetscObjectComposeFunction((PetscObject)dm,"DMlibMeshSetSystem_C",DMlibMeshSetSystem_libMesh));
992  LibmeshPetscCallQ(PetscObjectComposeFunction((PetscObject)dm,"DMlibMeshGetSystem_C",DMlibMeshGetSystem_libMesh));
993 
994  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
995 }
static PetscErrorCode DMCreateDomainDecomposition_libMesh(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
static PetscErrorCode DMCreateGlobalVector_libMesh(DM dm, Vec *x)
std::map< std::string, unsigned int > * blockids
PetscErrorCode DMlibMeshSetSystem_libMesh(DM dm, NonlinearImplicitSystem &sys)
std::map< std::string, unsigned int > * varids
static PetscErrorCode DMCreateMatrix_libMesh(DM dm, Mat *A)
static PetscErrorCode DMCreateFieldDecomposition_libMesh(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
std::vector< std::set< unsigned int > > * decomposition
static PetscErrorCode DMSetUp_libMesh(DM dm)
PetscErrorCode DMlibMeshGetSystem_libMesh(DM dm, NonlinearImplicitSystem *&sys)
std::map< unsigned int, std::string > * varnames
std::map< unsigned int, std::string > * blocknames
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
static PetscErrorCode DMView_libMesh(DM dm, PetscViewer viewer)
unsigned int decomposition_type
static PetscErrorCode DMDestroy_libMesh(DM dm)

◆ DMCreateDomainDecomposition_libMesh()

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

Definition at line 378 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMlibMeshSetUpName_Private(), libMesh::DofMap::dof_indices(), DM_libMesh::embedding, DM_libMesh::embedding_type, libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::first_dof(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::index_range(), libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreate_libMesh().

379 {
380  PetscFunctionBegin;
381  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
382  NonlinearImplicitSystem * sys = dlm->sys;
383  IS emb;
384  if (dlm->decomposition_type != DMLIBMESH_DOMAIN_DECOMPOSITION) PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
385  *len = cast_int<unsigned int>(dlm->decomposition->size());
386  if (namelist) {LibmeshPetscCallQ(PetscMalloc(*len*sizeof(char *), namelist));}
387  if (innerislist) {LibmeshPetscCallQ(PetscMalloc(*len*sizeof(IS), innerislist));}
388  if (outerislist) *outerislist = LIBMESH_PETSC_NULLPTR; /* FIX: allow mesh-based overlap. */
389  if (dmlist) {LibmeshPetscCallQ(PetscMalloc(*len*sizeof(DM), dmlist));}
390  for (auto d : index_range(*dlm->decomposition)) {
391  std::set<numeric_index_type> dindices;
392  std::string dname;
393  std::map<std::string, unsigned int> dblockids;
394  std::map<unsigned int,std::string> dblocknames;
395  unsigned int dbcount = 0;
396  for (const auto & b : (*dlm->decomposition)[d]) {
397  std::string bname = (*dlm->blocknames)[b];
398  dblockids.insert(std::pair<std::string, unsigned int>(bname,b));
399  dblocknames.insert(std::pair<unsigned int,std::string>(b,bname));
400  if (!dbcount) dname = bname;
401  else dname += "_" + bname;
402  ++dbcount;
403  if (!innerislist) continue;
404  const subdomain_id_type b_sbd_id = cast_int<subdomain_id_type>(b);
405  MeshBase::const_element_iterator el = sys->get_mesh().active_local_subdomain_elements_begin(b_sbd_id);
406  const MeshBase::const_element_iterator end_el = sys->get_mesh().active_local_subdomain_elements_end(b_sbd_id);
407  for ( ; el != end_el; ++el) {
408  const Elem * elem = *el;
409  std::vector<numeric_index_type> evindices;
410  // Iterate only over this DM's variables.
411  for (const auto & pr : *(dlm->varids)) {
412  // Get the degree of freedom indices for the given variable off the current element.
413  sys->get_dof_map().dof_indices(elem, evindices, pr.second);
414  for (const auto & dof : evindices) {
415  if (dof >= sys->get_dof_map().first_dof() && dof < sys->get_dof_map().end_dof()) // might want to use variable_first/last_local_dof instead
416  dindices.insert(dof);
417  }
418  }
419  }
420  }
421  if (namelist) {
422  LibmeshPetscCallQ(PetscStrallocpy(dname.c_str(),(*namelist)+d));
423  }
424  if (innerislist) {
425  PetscInt * darray;
426  IS dis;
427  LibmeshPetscCallQ(PetscMalloc(sizeof(PetscInt)*dindices.size(), &darray));
428  numeric_index_type i = 0;
429  for (const auto & id : dindices) {
430  darray[i] = id;
431  ++i;
432  }
433  LibmeshPetscCallQ(ISCreateGeneral(((PetscObject)dm)->comm,
434  cast_int<PetscInt>(dindices.size()),
435  darray, PETSC_OWN_POINTER, &dis));
436  if (dlm->embedding) {
437  /* Create a relative embedding into the parent's index space. */
438  LibmeshPetscCallQ(ISEmbed(dis,dlm->embedding, PETSC_TRUE, &emb));
439  PetscInt elen, dlen;
440  LibmeshPetscCallQ(ISGetLocalSize(emb, &elen));
441  LibmeshPetscCallQ(ISGetLocalSize(dis, &dlen));
442  if (elen != dlen) LIBMESH_SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Failed to embed field %zu" , d);
443  LibmeshPetscCallQ(ISDestroy(&dis));
444  dis = emb;
445  }
446  else {
447  emb = dis;
448  }
449  if (innerislist) {
450  LibmeshPetscCallQ(PetscObjectReference((PetscObject)dis));
451  (*innerislist)[d] = dis;
452  }
453  LibmeshPetscCallQ(ISDestroy(&dis));
454  }
455  if (dmlist) {
456  DM ddm;
457  LibmeshPetscCallQ(DMCreate(((PetscObject)dm)->comm, &ddm));
458  LibmeshPetscCallQ(DMSetType(ddm, DMLIBMESH));
459  DM_libMesh * ddlm = (DM_libMesh *)(ddm->data);
460  ddlm->sys = dlm->sys;
461  /* copy over the varids and varnames */
462  *ddlm->varids = *dlm->varids;
463  *ddlm->varnames = *dlm->varnames;
464  /* set the blocks from the d-th part of the decomposition. */
465  *ddlm->blockids = dblockids;
466  *ddlm->blocknames = dblocknames;
467  LibmeshPetscCallQ(PetscObjectReference((PetscObject)emb));
468  ddlm->embedding = emb;
469  ddlm->embedding_type = DMLIBMESH_DOMAIN_EMBEDDING;
470 
472  LibmeshPetscCallQ(DMSetFromOptions(ddm));
473  (*dmlist)[d] = ddm;
474  }
475  }
476  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
477 }
dof_id_type end_dof(const processor_id_type proc) const
Definition: dof_map_base.h:191
NonlinearImplicitSystem * sys
PetscErrorCode DMlibMeshSetUpName_Private(DM dm)
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2164
The definition of the const_element_iterator struct.
Definition: mesh_base.h:2216
unsigned int embedding_type
std::map< std::string, unsigned int > * blockids
std::map< std::string, unsigned int > * varids
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const MeshBase & get_mesh() const
Definition: system.h:2358
std::vector< std::set< unsigned int > > * decomposition
dof_id_type numeric_index_type
Definition: id_types.h:99
std::map< unsigned int, std::string > * varnames
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
std::map< unsigned int, std::string > * blocknames
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
dof_id_type first_dof(const processor_id_type proc) const
Definition: dof_map_base.h:185
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
const DofMap & get_dof_map() const
Definition: system.h:2374
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
unsigned int decomposition_type

◆ DMCreateFieldDecomposition_libMesh()

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

Definition at line 278 of file petscdmlibmeshimpl.C.

References libMesh::as_range(), DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMlibMeshSetUpName_Private(), libMesh::DofMap::dof_indices(), DM_libMesh::embedding, DM_libMesh::embedding_type, libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::first_dof(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::index_range(), libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreate_libMesh().

279 {
280  PetscFunctionBegin;
281  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
282  NonlinearImplicitSystem * sys = dlm->sys;
283  IS emb;
284  if (dlm->decomposition_type != DMLIBMESH_FIELD_DECOMPOSITION) PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
285 
286  *len = cast_int<unsigned int>(dlm->decomposition->size());
287  if (namelist) {LibmeshPetscCallQ(PetscMalloc(*len*sizeof(char *), namelist));}
288  if (islist) {LibmeshPetscCallQ(PetscMalloc(*len*sizeof(IS), islist));}
289  if (dmlist) {LibmeshPetscCallQ(PetscMalloc(*len*sizeof(DM), dmlist));}
290  DofMap & dofmap = dlm->sys->get_dof_map();
291  for (auto d : index_range(*dlm->decomposition)) {
292  std::set<numeric_index_type> dindices;
293  std::string dname;
294  std::map<std::string, unsigned int> dvarids;
295  std::map<unsigned int, std::string> dvarnames;
296  unsigned int dvcount = 0;
297  for (const auto & v : (*dlm->decomposition)[d]) {
298  std::string vname = (*dlm->varnames)[v];
299  dvarids.insert(std::pair<std::string, unsigned int>(vname,v));
300  dvarnames.insert(std::pair<unsigned int,std::string>(v,vname));
301  if (!dvcount) dname = vname;
302  else dname += "_" + vname;
303  ++dvcount;
304  if (!islist) continue;
305  // Iterate only over this DM's blocks.
306  for (const auto & pr : *(dlm->blockids)) {
307  const subdomain_id_type sbd_id = cast_int<subdomain_id_type>(pr.second);
308  for (const auto & elem :
309  as_range(sys->get_mesh().active_local_subdomain_elements_begin(sbd_id),
310  sys->get_mesh().active_local_subdomain_elements_end(sbd_id))) {
311  //unsigned int e_subdomain = elem->subdomain_id();
312  std::vector<numeric_index_type> evindices;
313  // Get the degree of freedom indices for the given variable off the current element.
314  dofmap.dof_indices(elem, evindices, v);
315  for (numeric_index_type dof : evindices) {
316  if (dof >= dofmap.first_dof() && dof < dofmap.end_dof()) // might want to use variable_first/last_local_dof instead
317  dindices.insert(dof);
318  }
319  }
320  }
321  }
322  if (namelist) {
323  LibmeshPetscCallQ(PetscStrallocpy(dname.c_str(),(*namelist)+d));
324  }
325  if (islist) {
326  IS dis;
327  PetscInt * darray;
328  LibmeshPetscCallQ(PetscMalloc(sizeof(PetscInt)*dindices.size(), &darray));
329  numeric_index_type i = 0;
330  for (const auto & id : dindices) {
331  darray[i] = id;
332  ++i;
333  }
334  LibmeshPetscCallQ(ISCreateGeneral(((PetscObject)dm)->comm,
335  cast_int<PetscInt>(dindices.size()),
336  darray, PETSC_OWN_POINTER, &dis));
337  if (dlm->embedding) {
338  /* Create a relative embedding into the parent's index space. */
339  LibmeshPetscCallQ(ISEmbed(dis,dlm->embedding, PETSC_TRUE, &emb));
340  PetscInt elen, dlen;
341  LibmeshPetscCallQ(ISGetLocalSize(emb, &elen));
342  LibmeshPetscCallQ(ISGetLocalSize(dis, &dlen));
343  if (elen != dlen) LIBMESH_SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Failed to embed subdomain %zu", d);
344  LibmeshPetscCallQ(ISDestroy(&dis));
345  dis = emb;
346  }
347  else {
348  emb = dis;
349  }
350  (*islist)[d] = dis;
351  }
352  if (dmlist) {
353  DM ddm;
354  LibmeshPetscCallQ(DMCreate(((PetscObject)dm)->comm, &ddm));
355  LibmeshPetscCallQ(DMSetType(ddm, DMLIBMESH));
356  DM_libMesh * ddlm = (DM_libMesh *)(ddm->data);
357  ddlm->sys = dlm->sys;
358  /* copy over the block ids and names */
359  *ddlm->blockids = *dlm->blockids;
360  *ddlm->blocknames = *dlm->blocknames;
361  /* set the vars from the d-th part of the decomposition. */
362  *ddlm->varids = dvarids;
363  *ddlm->varnames = dvarnames;
364  LibmeshPetscCallQ(PetscObjectReference((PetscObject)emb));
365  ddlm->embedding = emb;
366  ddlm->embedding_type = DMLIBMESH_FIELD_EMBEDDING;
367 
369  LibmeshPetscCallQ(DMSetFromOptions(ddm));
370  (*dmlist)[d] = ddm;
371  }
372  }
373  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
374 }
dof_id_type end_dof(const processor_id_type proc) const
Definition: dof_map_base.h:191
NonlinearImplicitSystem * sys
PetscErrorCode DMlibMeshSetUpName_Private(DM dm)
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2164
unsigned int embedding_type
std::map< std::string, unsigned int > * blockids
std::map< std::string, unsigned int > * varids
const MeshBase & get_mesh() const
Definition: system.h:2358
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
std::vector< std::set< unsigned int > > * decomposition
dof_id_type numeric_index_type
Definition: id_types.h:99
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
std::map< unsigned int, std::string > * varnames
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
std::map< unsigned int, std::string > * blocknames
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
dof_id_type first_dof(const processor_id_type proc) const
Definition: dof_map_base.h:185
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
const DofMap & get_dof_map() const
Definition: system.h:2374
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
unsigned int decomposition_type

◆ DMCreateGlobalVector_libMesh()

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

Definition at line 762 of file petscdmlibmeshimpl.C.

References DM_libMesh::embedding, libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), libMesh::System::solution, DM_libMesh::sys, and libMesh::PetscVector< T >::vec().

Referenced by DMCreate_libMesh().

763 {
764  PetscFunctionBegin;
765  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
766  PetscBool eq;
767 
768  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH, &eq));
769 
770  if (!eq)
771  LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
772 
773  if (!dlm->sys)
774  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No libMesh system set for DM_libMesh");
775 
776  NumericVector<Number> * nv = (dlm->sys->solution).get();
777  PetscVector<Number> * pv = dynamic_cast<PetscVector<Number> *>(nv);
778  Vec v = pv->vec();
779  /* Unfortunately, currently this does not produce a ghosted vector, so nonlinear subproblem solves aren't going to be easily available.
780  Should work fine for getting vectors out for linear subproblem solvers. */
781  if (dlm->embedding) {
782  PetscInt n;
783  LibmeshPetscCallQ(VecCreate(((PetscObject)v)->comm, x));
784  LibmeshPetscCallQ(ISGetLocalSize(dlm->embedding, &n));
785  LibmeshPetscCallQ(VecSetSizes(*x,n,PETSC_DETERMINE));
786  LibmeshPetscCallQ(VecSetType(*x,((PetscObject)v)->type_name));
787  LibmeshPetscCallQ(VecSetFromOptions(*x));
788  LibmeshPetscCallQ(VecSetUp(*x));
789  }
790  else {
791  LibmeshPetscCallQ(VecDuplicate(v,x));
792  }
793 
794 #if PETSC_VERSION_LESS_THAN(3,13,0)
795  LibmeshPetscCallQ(PetscObjectCompose((PetscObject)*x,"DM",(PetscObject)dm));
796 #else
797  LibmeshPetscCallQ(VecSetDM(*x, dm));
798 #endif
799 
800  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
801 }
NonlinearImplicitSystem * sys
This class provides a nice interface to PETSc&#39;s Vec object.
Definition: petsc_vector.h:73
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1593
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMCreateMatrix_libMesh()

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

Definition at line 808 of file petscdmlibmeshimpl.C.

References libMesh::LibmeshPetscCallQ(), libMesh::ImplicitSystem::matrix, libMesh::PetscFunctionReturn(), and DM_libMesh::sys.

Referenced by DMCreate_libMesh().

809 {
810  PetscFunctionBegin;
811  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
812  PetscBool eq;
813 
814  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH, &eq));
815 
816  if (!eq)
817  LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
818 
819  if (!dlm->sys)
820  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No libMesh system set for DM_libMesh");
821 
822  *A = (dynamic_cast<PetscMatrixBase<Number> *>(dlm->sys->matrix))->mat();
823  LibmeshPetscCallQ(PetscObjectReference((PetscObject)(*A)));
824  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
825 }
NonlinearImplicitSystem * sys
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
SparseMatrix< Number > * matrix
The system matrix.
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMDestroy_libMesh()

static PetscErrorCode DMDestroy_libMesh ( DM  dm)
static

Definition at line 926 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::embedding, libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreate_libMesh().

927 {
928  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
929  PetscFunctionBegin;
930  delete dlm->varids;
931  delete dlm->varnames;
932  delete dlm->blockids;
933  delete dlm->blocknames;
934  delete dlm->decomposition;
935  LibmeshPetscCallQ(ISDestroy(&dlm->embedding));
936  LibmeshPetscCallQ(PetscFree(dm->data));
937 
938  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
939 }
std::map< std::string, unsigned int > * blockids
std::map< std::string, unsigned int > * varids
std::vector< std::set< unsigned int > > * decomposition
std::map< unsigned int, std::string > * varnames
std::map< unsigned int, std::string > * blocknames
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMlibMeshCreateDomainDecompositionDM()

PetscErrorCode DMlibMeshCreateDomainDecompositionDM ( DM  dm,
PetscInt  dnumber,
PetscInt *  dsizes,
char ***  dblocklists,
DM *  ddm 
)

Definition at line 537 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMlibMeshSetUpName_Private(), libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

538 {
539  PetscBool islibmesh;
540  PetscFunctionBegin;
541  PetscValidHeaderSpecific(dm,DM_CLASSID,1);
542  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh));
543  if (!islibmesh) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
544  if (dnumber < 0) LIBMESH_SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative number %" LIBMESH_PETSCINT_FMT " of decomposition parts", dnumber);
545 #if PETSC_RELEASE_GREATER_EQUALS(3,20,0)
546  PetscAssertPointer(ddm,5);
547 #else
548  PetscValidPointer(ddm,5);
549 #endif
550  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
551  LibmeshPetscCallQ(DMCreate(((PetscObject)dm)->comm, ddm));
552  LibmeshPetscCallQ(DMSetType(*ddm, DMLIBMESH));
553  DM_libMesh * ddlm = (DM_libMesh *)((*ddm)->data);
554  ddlm->sys = dlm->sys;
555  ddlm->varids = dlm->varids;
556  ddlm->varnames = dlm->varnames;
557  ddlm->blockids = dlm->blockids;
558  ddlm->blocknames = dlm->blocknames;
559  ddlm->decomposition = new(std::vector<std::set<unsigned int>>);
560  ddlm->decomposition_type = DMLIBMESH_DOMAIN_DECOMPOSITION;
561  if (dnumber) {
562  for (PetscInt d = 0; d < dnumber; ++d) {
563  if (dsizes[d] < 0) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative size %" LIBMESH_PETSCINT_FMT " of decomposition part %" LIBMESH_PETSCINT_FMT, dsizes[d],d);
564  ddlm->decomposition->push_back(std::set<unsigned int>());
565  for (PetscInt b = 0; b < dsizes[d]; ++b) {
566  std::string bname(dblocklists[d][b]);
567  std::map<std::string, unsigned int>::const_iterator bit = dlm->blockids->find(bname);
568  if (bit == dlm->blockids->end())
569  LIBMESH_SETERRQ3(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Block %" LIBMESH_PETSCINT_FMT " on the %" LIBMESH_PETSCINT_FMT "-th list with name %s is not owned by this DM", b, d, dblocklists[d][b]);
570  unsigned int bid = bit->second;
571  (*ddlm->decomposition)[d].insert(bid);
572  }
573  }
574  }
575  else { // Empty splits indicate default: split all blocks with one per split.
576  PetscInt d = 0;
577  for (const auto & pr : (*ddlm->blockids)) {
578  ddlm->decomposition->push_back(std::set<unsigned int>());
579  unsigned int bid = pr.second;
580  (*ddlm->decomposition)[d].insert(bid);
581  ++d;
582  }
583  }
585  LibmeshPetscCallQ(DMSetFromOptions(*ddm));
586  LibmeshPetscCallQ(DMSetUp(*ddm));
587  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
588 }
NonlinearImplicitSystem * sys
PetscErrorCode DMlibMeshSetUpName_Private(DM dm)
std::map< std::string, unsigned int > * blockids
std::map< std::string, unsigned int > * varids
std::vector< std::set< unsigned int > > * decomposition
std::map< unsigned int, std::string > * varnames
std::map< unsigned int, std::string > * blocknames
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
unsigned int decomposition_type

◆ DMlibMeshCreateFieldDecompositionDM()

PetscErrorCode DMlibMeshCreateFieldDecompositionDM ( DM  dm,
PetscInt  dnumber,
PetscInt *  dsizes,
char ***  dvarlists,
DM *  ddm 
)

Definition at line 482 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DMlibMeshSetUpName_Private(), libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), DM_libMesh::sys, DM_libMesh::varids, and DM_libMesh::varnames.

483 {
484  PetscBool islibmesh;
485  PetscFunctionBegin;
486  PetscValidHeaderSpecific(dm,DM_CLASSID,1);
487  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh));
488  if (!islibmesh) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
489  if (dnumber < 0) LIBMESH_SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative number %" LIBMESH_PETSCINT_FMT " of decomposition parts", dnumber);
490 #if PETSC_RELEASE_GREATER_EQUALS(3,20,0)
491  PetscAssertPointer(ddm,5);
492 #else
493  PetscValidPointer(ddm,5);
494 #endif
495  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
496  LibmeshPetscCallQ(DMCreate(((PetscObject)dm)->comm, ddm));
497  LibmeshPetscCallQ(DMSetType(*ddm, DMLIBMESH));
498  DM_libMesh * ddlm = (DM_libMesh *)((*ddm)->data);
499  ddlm->sys = dlm->sys;
500  ddlm->varids = dlm->varids;
501  ddlm->varnames = dlm->varnames;
502  ddlm->blockids = dlm->blockids;
503  ddlm->blocknames = dlm->blocknames;
504  ddlm->decomposition = new(std::vector<std::set<unsigned int>>);
505  ddlm->decomposition_type = DMLIBMESH_FIELD_DECOMPOSITION;
506  if (dnumber) {
507  for (PetscInt d = 0; d < dnumber; ++d) {
508  if (dsizes[d] < 0) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Negative size %" LIBMESH_PETSCINT_FMT " of decomposition part %" LIBMESH_PETSCINT_FMT, dsizes[d],d);
509  ddlm->decomposition->push_back(std::set<unsigned int>());
510  for (PetscInt v = 0; v < dsizes[d]; ++v) {
511  std::string vname(dvarlists[d][v]);
512  std::map<std::string, unsigned int>::const_iterator vit = dlm->varids->find(vname);
513  if (vit == dlm->varids->end())
514  LIBMESH_SETERRQ3(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Variable %" LIBMESH_PETSCINT_FMT " on the %" LIBMESH_PETSCINT_FMT "-th list with name %s is not owned by this DM", v, d, dvarlists[d][v]);
515  unsigned int vid = vit->second;
516  (*ddlm->decomposition)[d].insert(vid);
517  }
518  }
519  }
520  else { // Empty splits indicate default: split all variables with one per split.
521  PetscInt d = 0;
522  for (const auto & pr : (*ddlm->varids)) {
523  ddlm->decomposition->push_back(std::set<unsigned int>());
524  unsigned int vid = pr.second;
525  (*ddlm->decomposition)[d].insert(vid);
526  ++d;
527  }
528  }
530  LibmeshPetscCallQ(DMSetFromOptions(*ddm));
531  LibmeshPetscCallQ(DMSetUp(*ddm));
532  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
533 }
NonlinearImplicitSystem * sys
PetscErrorCode DMlibMeshSetUpName_Private(DM dm)
std::map< std::string, unsigned int > * blockids
std::map< std::string, unsigned int > * varids
std::vector< std::set< unsigned int > > * decomposition
std::map< unsigned int, std::string > * varnames
std::map< unsigned int, std::string > * blocknames
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
unsigned int decomposition_type

◆ DMlibMeshFunction()

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

Definition at line 599 of file petscdmlibmeshimpl.C.

References libMesh::ParallelObject::comm(), libMesh::System::current_local_solution, DMlibMeshGetSystem(), libMesh::DofMap::enforce_constraints_exactly(), libMesh::System::get_dof_map(), libMesh::libmesh_assert(), libMesh::LibmeshPetscCallQ(), libMesh::NonlinearImplicitSystem::nonlinear_solver, libMesh::PetscFunctionReturn(), libMesh::ExplicitSystem::rhs, libMesh::System::solution, libMesh::PetscVector< T >::swap(), and libMesh::System::update().

Referenced by SNESFunction_DMlibMesh().

600 {
601  PetscFunctionBegin;
602  libmesh_assert(x);
603  libmesh_assert(r);
604 
607  NonlinearImplicitSystem & sys = *_sys;
608  PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(sys.solution.get());
609  PetscVector<Number> & R_sys = *cast_ptr<PetscVector<Number> *>(sys.rhs);
610  PetscVector<Number> X_global(x, _sys->comm()), R(r, _sys->comm());
611 
612  // Use the systems update() to get a good local version of the parallel solution
613  X_global.swap(X_sys);
614  R.swap(R_sys);
615 
617  _sys->update();
618 
619  // Swap back
620  X_global.swap(X_sys);
621  R.swap(R_sys);
622  R.zero();
623 
624  // if the user has provided both function pointers and objects only the pointer
625  // will be used, so catch that as an error
626  libmesh_error_msg_if(_sys->nonlinear_solver->residual && _sys->nonlinear_solver->residual_object,
627  "ERROR: cannot specify both a function and object to compute the Residual!");
628 
629  libmesh_error_msg_if(_sys->nonlinear_solver->matvec && _sys->nonlinear_solver->residual_and_jacobian_object,
630  "ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
631 
632  if (_sys->nonlinear_solver->residual != nullptr)
633  _sys->nonlinear_solver->residual(*(_sys->current_local_solution.get()), R, *_sys);
634 
635  else if (_sys->nonlinear_solver->residual_object != nullptr)
636  _sys->nonlinear_solver->residual_object->residual(*(_sys->current_local_solution.get()), R, *_sys);
637 
638  else if (_sys->nonlinear_solver->matvec != nullptr)
639  _sys->nonlinear_solver->matvec(*(_sys->current_local_solution.get()), &R, nullptr, *_sys);
640 
641  else if (_sys->nonlinear_solver->residual_and_jacobian_object != nullptr)
642  _sys->nonlinear_solver->residual_and_jacobian_object->residual_and_jacobian(*(_sys->current_local_solution.get()), &R, nullptr, *_sys);
643 
644  else
645  libmesh_error_msg("Error! Unable to compute residual and/or Jacobian!");
646 
647  R.close();
648  X_global.close();
649  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
650 }
This class provides a nice interface to PETSc&#39;s Vec object.
Definition: petsc_vector.h:73
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system...
NumericVector< Number > * rhs
The system matrix.
const Parallel::Communicator & comm() const
PETSC_EXTERN PetscErrorCode DMlibMeshGetSystem(DM, libMesh::NonlinearImplicitSystem *&)
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1593
libmesh_assert(ctx)
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:510
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1605
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
const DofMap & get_dof_map() const
Definition: system.h:2374
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
Constrains the numeric vector v, which represents a solution defined on the mesh. ...
Definition: dof_map.h:2350

◆ DMlibMeshGetBlocks()

PetscErrorCode DMlibMeshGetBlocks ( DM  dm,
PetscInt *  n,
char ***  blocknames 
)

Definition at line 168 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, libMesh::LibmeshPetscCallQ(), and libMesh::PetscFunctionReturn().

169 {
170  PetscInt i;
171  PetscFunctionBegin;
172  PetscValidHeaderSpecific(dm,DM_CLASSID,1);
173  PetscBool islibmesh;
174  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh));
175  if (!islibmesh) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
176  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
177 #if PETSC_RELEASE_GREATER_EQUALS(3,20,0)
178  PetscAssertPointer(n,2);
179 #else
180  PetscValidPointer(n,2);
181 #endif
182  *n = cast_int<unsigned int>(dlm->blockids->size());
183  if (!blocknames) PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
184  LibmeshPetscCallQ(PetscMalloc(*n*sizeof(char *), blocknames));
185  i = 0;
186  for (const auto & pr : *(dlm->blockids))
187  {
188  LibmeshPetscCallQ(PetscStrallocpy(pr.first.c_str(), *blocknames+i));
189  ++i;
190  }
191  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
192 }
std::map< std::string, unsigned int > * blockids
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMlibMeshGetSystem_libMesh()

PetscErrorCode DMlibMeshGetSystem_libMesh ( DM  dm,
NonlinearImplicitSystem *&  sys 
)

Definition at line 153 of file petscdmlibmeshimpl.C.

References libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), and DM_libMesh::sys.

Referenced by DMCreate_libMesh().

154 {
155  PetscFunctionBegin;
156  PetscValidHeaderSpecific(dm,DM_CLASSID,1);
157  PetscBool islibmesh;
158  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh));
159  if (!islibmesh) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
160  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
161  sys = dlm->sys;
162  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
163 }
NonlinearImplicitSystem * sys
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMlibMeshGetVariables()

PetscErrorCode DMlibMeshGetVariables ( DM  dm,
PetscInt *  n,
char ***  varnames 
)

Definition at line 196 of file petscdmlibmeshimpl.C.

References libMesh::LibmeshPetscCallQ(), libMesh::PetscFunctionReturn(), and DM_libMesh::varids.

197 {
198  PetscFunctionBegin;
199  PetscValidHeaderSpecific(dm,DM_CLASSID,1);
200  PetscBool islibmesh;
201  PetscInt i;
202  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh));
203  if (!islibmesh) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
204  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
205 #if PETSC_RELEASE_GREATER_EQUALS(3,20,0)
206  PetscAssertPointer(n,2);
207 #else
208  PetscValidPointer(n,2);
209 #endif
210  *n = cast_int<unsigned int>(dlm->varids->size());
211  if (!varnames) PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
212  LibmeshPetscCallQ(PetscMalloc(*n*sizeof(char *), varnames));
213  i = 0;
214  for (const auto & pr : *(dlm->varids))
215  {
216  LibmeshPetscCallQ(PetscStrallocpy(pr.first.c_str(), *varnames+i));
217  ++i;
218  }
219  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
220 }
std::map< std::string, unsigned int > * varids
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMlibMeshGetVec_Private()

PetscErrorCode DMlibMeshGetVec_Private ( DM  ,
const char *  ,
Vec *   
)

Definition at line 80 of file petscdmlibmeshimpl.C.

References libMesh::PetscFunctionReturn().

81 {
82  PetscFunctionBegin;
83 
84  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
85 }
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMlibMeshJacobian()

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

Definition at line 665 of file petscdmlibmeshimpl.C.

References libMesh::SparseMatrix< T >::attach_dof_map(), libMesh::PetscMatrixBase< T >::close(), libMesh::ParallelObject::comm(), libMesh::System::current_local_solution, DMlibMeshGetSystem(), libMesh::DofMap::enforce_constraints_exactly(), libMesh::PetscMatrixBase< T >::get_context(), libMesh::System::get_dof_map(), libMesh::libmesh_assert(), libMesh::LibmeshPetscCallQ(), libMesh::ImplicitSystem::matrix, libMesh::NonlinearImplicitSystem::nonlinear_solver, libMesh::PetscFunctionReturn(), libMesh::System::solution, libMesh::PetscMatrixBase< T >::swap(), libMesh::System::update(), and libMesh::SparseMatrix< T >::zero().

Referenced by SNESJacobian_DMlibMesh().

666 {
667  PetscFunctionBegin;
670  NonlinearImplicitSystem & sys = *_sys;
671 
672  libmesh_assert(pc);
673  libmesh_assert(jac);
676  PetscVector<Number> & X_sys = *cast_ptr<PetscVector<Number> *>(sys.solution.get());
677  PetscMatrixBase<Number> & Jac_sys = *cast_ptr<PetscMatrixBase<Number> *>(sys.matrix);
678  PetscVector<Number> X_global(x, sys.comm());
679 
680  // Set the dof maps
681  the_pc.attach_dof_map(sys.get_dof_map());
682  Jac.attach_dof_map(sys.get_dof_map());
683 
684  // Use the systems update() to get a good local version of the parallel solution
685  X_global.swap(X_sys);
686  Jac.swap(Jac_sys);
687 
689  sys.update();
690 
691  X_global.swap(X_sys);
692  Jac.swap(Jac_sys);
693 
694  the_pc.zero();
695 
696  // if the user has provided both function pointers and objects only the pointer
697  // will be used, so catch that as an error
698  libmesh_error_msg_if(sys.nonlinear_solver->jacobian && sys.nonlinear_solver->jacobian_object,
699  "ERROR: cannot specify both a function and object to compute the Jacobian!");
700 
701  libmesh_error_msg_if(sys.nonlinear_solver->matvec && sys.nonlinear_solver->residual_and_jacobian_object,
702  "ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");
703 
704  if (sys.nonlinear_solver->jacobian != nullptr)
705  sys.nonlinear_solver->jacobian(*(sys.current_local_solution.get()), the_pc, sys);
706 
707  else if (sys.nonlinear_solver->jacobian_object != nullptr)
708  sys.nonlinear_solver->jacobian_object->jacobian(*(sys.current_local_solution.get()), the_pc, sys);
709 
710  else if (sys.nonlinear_solver->matvec != nullptr)
711  sys.nonlinear_solver->matvec(*(sys.current_local_solution.get()), nullptr, &the_pc, sys);
712 
713  else if (sys.nonlinear_solver->residual_and_jacobian_object != nullptr)
714  sys.nonlinear_solver->residual_and_jacobian_object->residual_and_jacobian(*(sys.current_local_solution.get()), nullptr, &the_pc, sys);
715 
716  else
717  libmesh_error_msg("Error! Unable to compute residual and/or Jacobian!");
718 
719  the_pc.close();
720  Jac.close();
721  X_global.close();
722  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
723 }
This class provides a nice interface to PETSc&#39;s Vec object.
Definition: petsc_vector.h:73
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system...
void swap(PetscMatrixBase< T > &)
Swaps the internal data pointers of two PetscMatrices, no actual values are swapped.
const Parallel::Communicator & comm() const
PETSC_EXTERN PetscErrorCode DMlibMeshGetSystem(DM, libMesh::NonlinearImplicitSystem *&)
virtual void zero()=0
Set all entries to 0.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1593
libmesh_assert(ctx)
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
virtual void close() override
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
Definition: sparse_matrix.C:72
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:510
SparseMatrix< Number > * matrix
The system matrix.
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1605
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
const DofMap & get_dof_map() const
Definition: system.h:2374
void enforce_constraints_exactly(const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
Constrains the numeric vector v, which represents a solution defined on the mesh. ...
Definition: dof_map.h:2350

◆ DMlibMeshSetSystem_libMesh()

PetscErrorCode DMlibMeshSetSystem_libMesh ( DM  dm,
NonlinearImplicitSystem sys 
)

Definition at line 93 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, DM_libMesh::blocknames, libMesh::ParallelObject::comm(), DMlibMeshSetUpName_Private(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::LibmeshPetscCallQ(), libMesh::make_range(), mesh, libMesh::DofMap::n_variables(), libMesh::Variable::name(), libMesh::PetscFunctionReturn(), libMesh::Parallel::Communicator::set_union(), libMesh::MeshBase::subdomain_name(), DM_libMesh::sys, libMesh::DofMap::variable(), DM_libMesh::varids, and DM_libMesh::varnames.

Referenced by DMCreate_libMesh().

94 {
95  const Parallel::Communicator & comm = sys.comm();
96 
97  PetscFunctionBegin;
98  PetscValidHeaderSpecific(dm,DM_CLASSID,1);
99  PetscBool islibmesh;
100  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH,&islibmesh));
101  if (!islibmesh) LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Got DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
102 
103  if (dm->setupcalled) SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot reset the libMesh system after DM has been set up.");
104  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
105  dlm->sys =&sys;
106  /* Initially populate the sets of active blockids and varids using all of the
107  existing blocks/variables (only variables are supported at the moment). */
108  DofMap & dofmap = dlm->sys->get_dof_map();
109  dlm->varids->clear();
110  dlm->varnames->clear();
111  for (auto v : make_range(dofmap.n_variables())) {
112  std::string vname = dofmap.variable(v).name();
113  dlm->varids->insert(std::pair<std::string,unsigned int>(vname,v));
114  dlm->varnames->insert(std::pair<unsigned int,std::string>(v,vname));
115  }
116  const MeshBase & mesh = dlm->sys->get_mesh();
117  dlm->blockids->clear();
118  dlm->blocknames->clear();
119  std::set<subdomain_id_type> blocks;
120  /* The following effectively is a verbatim copy of MeshBase::n_subdomains(). */
121  // This requires an inspection on every processor
122  libmesh_parallel_only(mesh.comm());
123  for (const auto & elem : mesh.active_element_ptr_range())
124  blocks.insert(elem->subdomain_id());
125  // Some subdomains may only live on other processors
126  comm.set_union(blocks);
127 
128  std::set<subdomain_id_type>::iterator bit = blocks.begin();
129  std::set<subdomain_id_type>::iterator bend = blocks.end();
130  if (bit == bend) SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "No mesh blocks found.");
131 
132  for (; bit != bend; ++bit) {
133  subdomain_id_type bid = *bit;
134  std::string bname = mesh.subdomain_name(bid);
135  if (!bname.length()) {
136  /* Block names are currently implemented for Exodus II meshes
137  only, so we might have to make up our own block names and
138  maintain our own mapping of block ids to names.
139  */
140  std::ostringstream ss;
141  ss << "dm" << bid;
142  bname = ss.str();
143  }
144  dlm->blockids->insert(std::pair<std::string,unsigned int>(bname,bid));
145  dlm->blocknames->insert(std::pair<unsigned int,std::string>(bid,bname));
146  }
148  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
149 }
NonlinearImplicitSystem * sys
PetscErrorCode DMlibMeshSetUpName_Private(DM dm)
std::map< std::string, unsigned int > * blockids
std::map< std::string, unsigned int > * varids
MeshBase & mesh
const Parallel::Communicator & comm() const
const MeshBase & get_mesh() const
Definition: system.h:2358
This is the MeshBase class.
Definition: mesh_base.h:75
const Variable & variable(const unsigned int c) const override
Definition: dof_map.h:2190
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
unsigned int n_variables() const override
Definition: dof_map.h:628
std::map< unsigned int, std::string > * varnames
std::map< unsigned int, std::string > * blocknames
std::string & subdomain_name(subdomain_id_type id)
Definition: mesh_base.C:1692
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
const std::string & name() const
Definition: variable.h:122
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
const DofMap & get_dof_map() const
Definition: system.h:2374
void set_union(T &data, const unsigned int root_id) const

◆ DMlibMeshSetUpName_Private()

PetscErrorCode DMlibMeshSetUpName_Private ( DM  dm)

Definition at line 224 of file petscdmlibmeshimpl.C.

References DM_libMesh::blocknames, DM_libMesh::decomposition, DM_libMesh::decomposition_type, DM_libMesh::embedding_type, libMesh::LibmeshPetscCallQ(), libMesh::Quality::name(), libMesh::System::name(), libMesh::PetscFunctionReturn(), DM_libMesh::sys, and DM_libMesh::varnames.

Referenced by DMCreateDomainDecomposition_libMesh(), DMCreateFieldDecomposition_libMesh(), DMlibMeshCreateDomainDecompositionDM(), DMlibMeshCreateFieldDecompositionDM(), and DMlibMeshSetSystem_libMesh().

225 {
226  DM_libMesh * dlm = (DM_libMesh *)dm->data;
227  PetscFunctionBegin;
228  std::string name = dlm->sys->name();
229  std::map<unsigned int, std::string> * dnames = LIBMESH_PETSC_NULLPTR,
230  * enames = LIBMESH_PETSC_NULLPTR;
231  if (dlm->decomposition_type == DMLIBMESH_FIELD_DECOMPOSITION) {
232  name += ":dec:var:";
233  dnames = dlm->varnames;
234  }
235  if (dlm->decomposition_type == DMLIBMESH_DOMAIN_DECOMPOSITION) {
236  name += ":dec:block:";
237  dnames = dlm->blocknames;
238  }
239  if (dnames) {
240  for (auto decomp : *dlm->decomposition) {
241  for (std::set<unsigned int>::iterator dit_begin = decomp.begin(),
242  dit = dit_begin,
243  dit_end = decomp.end();
244  dit != dit_end; ++dit) {
245  unsigned int id = *dit;
246  if (dit != dit_begin)
247  name += ",";
248  name += (*dnames)[id];
249  }
250  name += ";";
251  }
252  }
253  if (dlm->embedding_type == DMLIBMESH_FIELD_EMBEDDING) {
254  name += ":emb:var:";
255  enames = dlm->varnames;
256  }
257  if (dlm->embedding_type == DMLIBMESH_DOMAIN_EMBEDDING) {
258  name += ":emb:block:";
259  enames = dlm->blocknames;
260  }
261  if (enames) {
262  for (auto eit = enames->begin(),
263  eit_end = enames->end(); eit != eit_end; ++eit) {
264  std::string & ename = eit->second;
265  if (eit != enames->begin())
266  name += ",";
267  name += ename;
268  }
269  name += ";";
270  }
271  LibmeshPetscCallQ(PetscObjectSetName((PetscObject)dm, name.c_str()));
272  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
273 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
NonlinearImplicitSystem * sys
unsigned int embedding_type
std::vector< std::set< unsigned int > > * decomposition
std::map< unsigned int, std::string > * varnames
std::map< unsigned int, std::string > * blocknames
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
const std::string & name() const
Definition: system.h:2342
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
unsigned int decomposition_type

◆ DMSetUp_libMesh()

static PetscErrorCode DMSetUp_libMesh ( DM  dm)
static

Definition at line 888 of file petscdmlibmeshimpl.C.

References DMVariableBounds_libMesh(), DM_libMesh::embedding, libMesh::LibmeshPetscCallQ(), libMesh::NonlinearImplicitSystem::nonlinear_solver, libMesh::PetscFunctionReturn(), SNESFunction_DMlibMesh(), SNESJacobian_DMlibMesh(), and DM_libMesh::sys.

Referenced by DMCreate_libMesh().

889 {
890  PetscFunctionBegin;
891  DM_libMesh * dlm = (DM_libMesh *)(dm->data);
892  PetscBool eq;
893 
894  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)dm, DMLIBMESH, &eq));
895 
896  if (!eq)
897  LIBMESH_SETERRQ2(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "DM of type %s, not of type %s", ((PetscObject)dm)->type_name, DMLIBMESH);
898 
899  if (!dlm->sys)
900  SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "No libMesh system set for DM_libMesh");
901  /*
902  Do not evaluate function, Jacobian or bounds for an embedded DM -- the subproblem might not have enough information for that.
903  */
904  if (!dlm->embedding) {
905  LibmeshPetscCallQ(DMSNESSetFunction(dm, SNESFunction_DMlibMesh, (void *)dm));
906  LibmeshPetscCallQ(DMSNESSetJacobian(dm, SNESJacobian_DMlibMesh, (void *)dm));
907  if (dlm->sys->nonlinear_solver->bounds || dlm->sys->nonlinear_solver->bounds_object)
908  LibmeshPetscCallQ(DMSetVariableBounds(dm, DMVariableBounds_libMesh));
909  }
910  else {
911  /*
912  Fow now we don't implement even these, although a linear "Dirichlet" subproblem is well-defined.
913  Creating the submatrix, however, might require extracting the submatrix preallocation from an unassembled matrix.
914  */
915  dm->ops->createglobalvector = 0;
916  dm->ops->creatematrix = 0;
917  }
918  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
919 }
static PetscErrorCode SNESFunction_DMlibMesh(SNES, Vec x, Vec r, void *ctx)
static PetscErrorCode SNESJacobian_DMlibMesh(SNES, Vec x, Mat jac, Mat pc, void *ctx)
static PetscErrorCode DMVariableBounds_libMesh(DM dm, Vec xl, Vec xu)
NonlinearImplicitSystem * sys
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system...
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMVariableBounds_libMesh()

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

Definition at line 737 of file petscdmlibmeshimpl.C.

References libMesh::ParallelObject::comm(), DMlibMeshGetSystem(), libMesh::LibmeshPetscCallQ(), libMesh::NonlinearImplicitSystem::nonlinear_solver, and libMesh::PetscFunctionReturn().

Referenced by DMSetUp_libMesh().

738 {
741  NonlinearImplicitSystem & sys = *_sys;
742  PetscVector<Number> XL(xl, sys.comm());
743  PetscVector<Number> XU(xu, sys.comm());
744  PetscFunctionBegin;
745  // Workaround for nonstandard Q suffix warning with quad precision
746  const PetscReal petsc_inf = std::numeric_limits<PetscReal>::max() / 4;
747  LibmeshPetscCallQ(VecSet(xl, -petsc_inf));
748  LibmeshPetscCallQ(VecSet(xu, petsc_inf));
749  if (sys.nonlinear_solver->bounds != nullptr)
750  sys.nonlinear_solver->bounds(XL,XU,sys);
751  else if (sys.nonlinear_solver->bounds_object != nullptr)
752  sys.nonlinear_solver->bounds_object->bounds(XL,XU, sys);
753  else
754  SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "No bounds calculation in this libMesh object");
755 
756  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
757 }
This class provides a nice interface to PETSc&#39;s Vec object.
Definition: petsc_vector.h:73
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system...
const Parallel::Communicator & comm() const
PETSC_EXTERN PetscErrorCode DMlibMeshGetSystem(DM, libMesh::NonlinearImplicitSystem *&)
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ DMView_libMesh()

static PetscErrorCode DMView_libMesh ( DM  dm,
PetscViewer  viewer 
)
static

Definition at line 830 of file petscdmlibmeshimpl.C.

References DM_libMesh::blockids, DM_libMesh::decomposition, DM_libMesh::decomposition_type, libMesh::index_range(), libMesh::LibmeshPetscCallQ(), libMesh::Quality::name(), libMesh::PetscFunctionReturn(), and DM_libMesh::varids.

Referenced by DMCreate_libMesh().

831 {
832  PetscBool isascii;
833  const char * name, * prefix;
834  DM_libMesh * dlm = (DM_libMesh *)dm->data;
835  PetscFunctionBegin;
836  LibmeshPetscCallQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
837  if (isascii) {
838  LibmeshPetscCallQ(PetscObjectGetName((PetscObject)dm, &name));
839  LibmeshPetscCallQ(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
840  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "DM libMesh with name %s and prefix %s\n", name, prefix));
841  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "blocks:"));
842  std::map<std::string,unsigned int>::iterator bit = dlm->blockids->begin();
843  std::map<std::string,unsigned int>::const_iterator bend = dlm->blockids->end();
844  for (; bit != bend; ++bit) {
845  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "(%s,%d) ", bit->first.c_str(), bit->second));
846  }
847  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
848  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "variables:"));
849  std::map<std::string,unsigned int>::iterator vit = dlm->varids->begin();
850  std::map<std::string,unsigned int>::const_iterator vend = dlm->varids->end();
851  for (; vit != vend; ++vit) {
852  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "(%s,%d) ", vit->first.c_str(), vit->second));
853  }
854  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
855  if (dlm->decomposition_type == DMLIBMESH_NO_DECOMPOSITION) {
856  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "No decomposition\n"));
857  }
858  else {
859  if (dlm->decomposition_type == DMLIBMESH_FIELD_DECOMPOSITION) {
860  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "Field decomposition by variable: "));
861  }
862  else if (dlm->decomposition_type == DMLIBMESH_DOMAIN_DECOMPOSITION) {
863  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "Domain decomposition by block: "));
864  }
865  else LIBMESH_SETERRQ1(((PetscObject)dm)->comm, PETSC_ERR_PLIB, "Unexpected decomposition type: %d", dlm->decomposition_type);
866  /* FIX: decompositions might have different sizes and components on different ranks. */
867  for (auto d : index_range(*dlm->decomposition)) {
868  std::set<unsigned int>::iterator dbegin = (*dlm->decomposition)[d].begin();
869  std::set<unsigned int>::iterator dit = (*dlm->decomposition)[d].begin();
870  std::set<unsigned int>::iterator dend = (*dlm->decomposition)[d].end();
871  for (; dit != dend; ++dit) {
872  if (dit != dbegin) {
873  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, ","));
874  }
875  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "%u", *dit));
876  }
877  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, ";"));
878  }
879  LibmeshPetscCallQ(PetscViewerASCIIPrintf(viewer, "\n"));
880  }
881  }
882 
883  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
884 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
std::map< std::string, unsigned int > * blockids
std::map< std::string, unsigned int > * varids
std::vector< std::set< unsigned int > > * decomposition
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
unsigned int decomposition_type

◆ SNESFunction_DMlibMesh()

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

Definition at line 654 of file petscdmlibmeshimpl.C.

References libMesh::ctx, DMlibMeshFunction(), libMesh::LibmeshPetscCallQ(), and libMesh::PetscFunctionReturn().

Referenced by DMSetUp_libMesh().

655 {
656  DM dm = (DM)ctx;
657  PetscFunctionBegin;
659  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
660 }
static PetscErrorCode DMlibMeshFunction(DM dm, Vec x, Vec r)
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
void * ctx
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)

◆ SNESJacobian_DMlibMesh()

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

Definition at line 727 of file petscdmlibmeshimpl.C.

References libMesh::ctx, DMlibMeshJacobian(), libMesh::LibmeshPetscCallQ(), and libMesh::PetscFunctionReturn().

Referenced by DMSetUp_libMesh().

728 {
729  DM dm = (DM)ctx;
730  PetscFunctionBegin;
731  LibmeshPetscCallQ(DMlibMeshJacobian(dm,x,jac,pc));
732  PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
733 }
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
static PetscErrorCode DMlibMeshJacobian(DM dm, Vec x, Mat jac, Mat pc)
void * ctx
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)