libMesh
Loading...
Searching...
No Matches
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.

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}
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
static PetscErrorCode DMCreateGlobalVector_libMesh(DM dm, Vec *x)
static PetscErrorCode DMView_libMesh(DM dm, PetscViewer viewer)
static PetscErrorCode DMSetUp_libMesh(DM dm)
static PetscErrorCode DMCreateMatrix_libMesh(DM dm, Mat *A)
static PetscErrorCode DMDestroy_libMesh(DM dm)
PetscErrorCode DMlibMeshGetSystem_libMesh(DM dm, NonlinearImplicitSystem *&sys)
PetscErrorCode DMlibMeshSetSystem_libMesh(DM dm, NonlinearImplicitSystem &sys)
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)
unsigned int decomposition_type
std::vector< std::set< unsigned int > > * decomposition
std::map< std::string, unsigned int > * varids
std::map< unsigned int, std::string > * blocknames
std::map< std::string, unsigned int > * blockids
std::map< unsigned int, std::string > * varnames

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.

◆ 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.

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 first_dof(const processor_id_type proc) const
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition dof_map.C:2201
This is the base class from which all geometric element types are derived.
Definition elem.h:96
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
const DofMap & get_dof_map() const
Definition system.h:2417
const MeshBase & get_mesh() const
Definition system.h:2401
static const Real b
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:153
dof_id_type numeric_index_type
Definition id_types.h:99
PetscErrorCode DMlibMeshSetUpName_Private(DM dm)
unsigned int embedding_type
NonlinearImplicitSystem * sys
The definition of the const_element_iterator struct.
Definition mesh_base.h:2556

References b, 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().

◆ 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.

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
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.

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().

◆ DMCreateGlobalVector_libMesh()

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

Definition at line 762 of file petscdmlibmeshimpl.C.

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}
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
This class provides a nice interface to PETSc's Vec object.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
const Elem & get(const ElemType type_in)

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

Referenced by DMCreate_libMesh().

◆ DMCreateMatrix_libMesh()

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

Definition at line 808 of file petscdmlibmeshimpl.C.

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}
SparseMatrix< Number > * matrix
The system matrix.
This class provides a nice interface to the PETSc C-based data structures for parallel,...

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

Referenced by DMCreate_libMesh().

◆ DMDestroy_libMesh()

static PetscErrorCode DMDestroy_libMesh ( DM  dm)
static

Definition at line 926 of file petscdmlibmeshimpl.C.

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}

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().

◆ DMlibMeshCreateDomainDecompositionDM()

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

Definition at line 537 of file petscdmlibmeshimpl.C.

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}

References b, 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.

◆ DMlibMeshCreateFieldDecompositionDM()

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

Definition at line 482 of file petscdmlibmeshimpl.C.

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}

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.

◆ DMlibMeshFunction()

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

Definition at line 599 of file petscdmlibmeshimpl.C.

600{
601 PetscFunctionBegin;
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}
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:2518
NumericVector< Number > * rhs
The system matrix.
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
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:1667
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition system.C:498
libmesh_assert(ctx)
PETSC_EXTERN PetscErrorCode DMlibMeshGetSystem(DM, libMesh::NonlinearImplicitSystem *&)

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, and libMesh::System::update().

Referenced by SNESFunction_DMlibMesh().

◆ DMlibMeshGetBlocks()

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

Definition at line 168 of file petscdmlibmeshimpl.C.

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}

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

◆ DMlibMeshGetSystem_libMesh()

PetscErrorCode DMlibMeshGetSystem_libMesh ( DM  dm,
NonlinearImplicitSystem *&  sys 
)

Definition at line 153 of file petscdmlibmeshimpl.C.

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}

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

Referenced by DMCreate_libMesh().

◆ DMlibMeshGetVariables()

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

Definition at line 196 of file petscdmlibmeshimpl.C.

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}

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

◆ DMlibMeshGetVec_Private()

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

Definition at line 80 of file petscdmlibmeshimpl.C.

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

References libMesh::PetscFunctionReturn().

◆ DMlibMeshJacobian()

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

Definition at line 665 of file petscdmlibmeshimpl.C.

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}
void swap(PetscMatrixBase< T > &)
Swaps the internal data pointers of two PetscMatrices, no actual values are swapped.
static PetscMatrixBase< T > * get_context(Mat mat, const TIMPI::Communicator &comm)
virtual void close() override
Calls the SparseMatrix'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.
virtual void zero()=0
Set all entries to 0.

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().

◆ DMlibMeshSetSystem_libMesh()

PetscErrorCode DMlibMeshSetSystem_libMesh ( DM  dm,
NonlinearImplicitSystem sys 
)

Definition at line 93 of file petscdmlibmeshimpl.C.

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}
void set_union(T &data, const unsigned int root_id) const
const Variable & variable(const unsigned int c) const override
Definition dof_map.h:2358
This is the MeshBase class.
Definition mesh_base.h:81
std::string & subdomain_name(subdomain_id_type id)
Definition mesh_base.C:1887
const std::string & name() const
Definition variable.h:122
MeshBase & mesh
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:176

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().

◆ DMlibMeshSetUpName_Private()

PetscErrorCode DMlibMeshSetUpName_Private ( DM  dm)

Definition at line 224 of file petscdmlibmeshimpl.C.

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.

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

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

◆ DMSetUp_libMesh()

static PetscErrorCode DMSetUp_libMesh ( DM  dm)
static

Definition at line 888 of file petscdmlibmeshimpl.C.

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)

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().

◆ DMVariableBounds_libMesh()

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

Definition at line 737 of file petscdmlibmeshimpl.C.

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}

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

Referenced by DMSetUp_libMesh().

◆ DMView_libMesh()

static PetscErrorCode DMView_libMesh ( DM  dm,
PetscViewer  viewer 
)
static

Definition at line 830 of file petscdmlibmeshimpl.C.

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}

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

Referenced by DMCreate_libMesh().

◆ SNESFunction_DMlibMesh()

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

Definition at line 654 of file petscdmlibmeshimpl.C.

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

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

Referenced by DMSetUp_libMesh().

◆ SNESJacobian_DMlibMesh()

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

Definition at line 727 of file petscdmlibmeshimpl.C.

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

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

Referenced by DMSetUp_libMesh().