1d0295fc0SJunchao Zhang #include <petscvec.h> 2af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 3c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 4e6f8dbb6SToby Isaac #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/ 53e922f36SToby Isaac #include <petscdmplex.h> 6d2b2dc1eSMatthew G. Knepley #include <petscdmceed.h> 7f19dbd58SToby Isaac #include <petscdmfield.h> 80c312b8eSJed Brown #include <petscsf.h> 92764a2aaSMatthew G. Knepley #include <petscds.h> 1047c6ae99SBarry Smith 11f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 12f918ec44SMatthew G. Knepley #include <petscfeceed.h> 13f918ec44SMatthew G. Knepley #endif 14f918ec44SMatthew G. Knepley 15732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 16d67d17b1SMatthew G. Knepley PetscClassId DMLABEL_CLASSID; 1742d0c57aSJames Wright PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction, DM_CreateInjection, DM_CreateMatrix, DM_CreateMassMatrix, DM_Load, DM_View, DM_AdaptInterpolator, DM_ProjectFunction; 1867a56275SMatthew G Knepley 19ea78f98cSLisandro Dalcin const char *const DMBoundaryTypes[] = {"NONE", "GHOSTED", "MIRROR", "PERIODIC", "TWIST", "DMBoundaryType", "DM_BOUNDARY_", NULL}; 20d1b3049bSMatthew G. Knepley const char *const DMBoundaryConditionTypes[] = {"INVALID", "ESSENTIAL", "NATURAL", "INVALID", "INVALID", "ESSENTIAL_FIELD", "NATURAL_FIELD", "INVALID", "INVALID", "ESSENTIAL_BD_FIELD", "NATURAL_RIEMANN", "DMBoundaryConditionType", "DM_BC_", NULL}; 210e762ea3SJed Brown const char *const DMBlockingTypes[] = {"TOPOLOGICAL_POINT", "FIELD_NODE", "DMBlockingType", "DM_BLOCKING_", NULL}; 22476787b7SMatthew G. Knepley const char *const DMPolytopeTypes[] = 23476787b7SMatthew G. Knepley {"vertex", "segment", "tensor_segment", "triangle", "quadrilateral", "tensor_quad", "tetrahedron", "hexahedron", "triangular_prism", "tensor_triangular_prism", "tensor_quadrilateral_prism", "pyramid", "FV_ghost_cell", "interior_ghost_cell", 24476787b7SMatthew G. Knepley "unknown", "unknown_cell", "unknown_face", "invalid", "DMPolytopeType", "DM_POLYTOPE_", NULL}; 252cbb9b06SVaclav Hapla const char *const DMCopyLabelsModes[] = {"replace", "keep", "fail", "DMCopyLabelsMode", "DM_COPY_LABELS_", NULL}; 2660c22052SBarry Smith 27a4121054SBarry Smith /*@ 28bb7acecfSBarry Smith DMCreate - Creates an empty `DM` object. `DM`s are the abstract objects in PETSc that mediate between meshes and discretizations and the 290b4b7b1cSBarry Smith algebraic solvers, time integrators, and optimization algorithms in PETSc. 30a4121054SBarry Smith 31d083f849SBarry Smith Collective 32a4121054SBarry Smith 33a4121054SBarry Smith Input Parameter: 34bb7acecfSBarry Smith . comm - The communicator for the `DM` object 35a4121054SBarry Smith 36a4121054SBarry Smith Output Parameter: 37bb7acecfSBarry Smith . dm - The `DM` object 38a4121054SBarry Smith 39a4121054SBarry Smith Level: beginner 40a4121054SBarry Smith 41bb7acecfSBarry Smith Notes: 42bb7acecfSBarry Smith See `DMType` for a brief summary of available `DM`. 43bb7acecfSBarry Smith 44bb7acecfSBarry Smith The type must then be set with `DMSetType()`. If you never call `DMSetType()` it will generate an 450b4b7b1cSBarry Smith error when you try to use the `dm`. 460b4b7b1cSBarry Smith 470b4b7b1cSBarry Smith `DM` is an orphan initialism or orphan acronym, the letters have no meaning and never did. 48bb7acecfSBarry Smith 491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetType()`, `DMType`, `DMDACreate()`, `DMDA`, `DMSLICED`, `DMCOMPOSITE`, `DMPLEX`, `DMMOAB`, `DMNETWORK` 50a4121054SBarry Smith @*/ 51d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreate(MPI_Comm comm, DM *dm) 52d71ae5a4SJacob Faibussowitsch { 53a4121054SBarry Smith DM v; 54e5e52638SMatthew G. Knepley PetscDS ds; 55a4121054SBarry Smith 56a4121054SBarry Smith PetscFunctionBegin; 574f572ea9SToby Isaac PetscAssertPointer(dm, 2); 58377f809aSBarry Smith 599566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 609566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView)); 6162e5d2d2SJDBetteridge ((PetscObject)v)->non_cyclic_references = &DMCountNonCyclicReferences; 6249be4549SMatthew G. Knepley v->setupcalled = PETSC_FALSE; 6349be4549SMatthew G. Knepley v->setfromoptionscalled = PETSC_FALSE; 640298fd71SBarry Smith v->ltogmap = NULL; 65a4ea9b21SRichard Tran Mills v->bind_below = 0; 661411c6eeSJed Brown v->bs = 1; 67171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 689566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sf)); 699566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sectionSF)); 70c58f1c22SToby Isaac v->labels = NULL; 7134aa8a36SMatthew G. Knepley v->adjacency[0] = PETSC_FALSE; 7234aa8a36SMatthew G. Knepley v->adjacency[1] = PETSC_TRUE; 73c58f1c22SToby Isaac v->depthLabel = NULL; 74ba2698f1SMatthew G. Knepley v->celltypeLabel = NULL; 751bb6d2a8SBarry Smith v->localSection = NULL; 761bb6d2a8SBarry Smith v->globalSection = NULL; 773b8ba7d1SJed Brown v->defaultConstraint.section = NULL; 783b8ba7d1SJed Brown v->defaultConstraint.mat = NULL; 7979769bd5SJed Brown v->defaultConstraint.bias = NULL; 806858538eSMatthew G. Knepley v->coordinates[0].dim = PETSC_DEFAULT; 816858538eSMatthew G. Knepley v->coordinates[1].dim = PETSC_DEFAULT; 826858538eSMatthew G. Knepley v->sparseLocalize = PETSC_TRUE; 8396173672SStefano Zampini v->dim = PETSC_DETERMINE; 84435a35e8SMatthew G Knepley { 85435a35e8SMatthew G Knepley PetscInt i; 86435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 870298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 88f9d4088aSMatthew G. Knepley v->nearnullspaceConstructors[i] = NULL; 89435a35e8SMatthew G Knepley } 90435a35e8SMatthew G Knepley } 919566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 9207218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(v, NULL, NULL, ds, NULL)); 939566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 949566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxCreate(&v->auxData)); 9514f150ffSMatthew G. Knepley v->dmBC = NULL; 96a8fb8f29SToby Isaac v->coarseMesh = NULL; 97f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 98cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 999566063dSJacob Faibussowitsch PetscCall(DMSetVecType(v, VECSTANDARD)); 1009566063dSJacob Faibussowitsch PetscCall(DMSetMatType(v, MATAIJ)); 1014a7a4c06SLawrence Mitchell 1021411c6eeSJed Brown *dm = v; 1033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 104a4121054SBarry Smith } 105a4121054SBarry Smith 10638221697SMatthew G. Knepley /*@ 107bb7acecfSBarry Smith DMClone - Creates a `DM` object with the same topology as the original. 10838221697SMatthew G. Knepley 109d083f849SBarry Smith Collective 11038221697SMatthew G. Knepley 11138221697SMatthew G. Knepley Input Parameter: 112bb7acecfSBarry Smith . dm - The original `DM` object 11338221697SMatthew G. Knepley 11438221697SMatthew G. Knepley Output Parameter: 115bb7acecfSBarry Smith . newdm - The new `DM` object 11638221697SMatthew G. Knepley 11738221697SMatthew G. Knepley Level: beginner 11838221697SMatthew G. Knepley 1191cb8cacdSPatrick Sanan Notes: 120bb7acecfSBarry Smith For some `DM` implementations this is a shallow clone, the result of which may share (reference counted) information with its parent. For example, 121bb7acecfSBarry Smith `DMClone()` applied to a `DMPLEX` object will result in a new `DMPLEX` that shares the topology with the original `DMPLEX`. It does not 122bb7acecfSBarry Smith share the `PetscSection` of the original `DM`. 1231bb6d2a8SBarry Smith 124bb7acecfSBarry Smith The clone is considered set up if the original has been set up. 12589706ed2SPatrick Sanan 126bb7acecfSBarry Smith Use `DMConvert()` for a general way to create new `DM` from a given `DM` 127bb7acecfSBarry Smith 12860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMSetType()`, `DMSetLocalSection()`, `DMSetGlobalSection()`, `DMPLEX`, `DMConvert()` 12938221697SMatthew G. Knepley @*/ 130d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClone(DM dm, DM *newdm) 131d71ae5a4SJacob Faibussowitsch { 13238221697SMatthew G. Knepley PetscSF sf; 13338221697SMatthew G. Knepley Vec coords; 13438221697SMatthew G. Knepley void *ctx; 135ec196627SMatthew G. Knepley MatOrderingType otype; 136ec196627SMatthew G. Knepley DMReorderDefaultFlag flg; 1376858538eSMatthew G. Knepley PetscInt dim, cdim, i; 13838221697SMatthew G. Knepley 13938221697SMatthew G. Knepley PetscFunctionBegin; 14038221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1414f572ea9SToby Isaac PetscAssertPointer(newdm, 2); 1429566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), newdm)); 1439566063dSJacob Faibussowitsch PetscCall(DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE, DM_COPY_LABELS_FAIL)); 144ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 145ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 146c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 147fc214432SJed Brown (*newdm)->prealloc_skip = dm->prealloc_skip; 1489566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->vectype)); 1499566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*newdm)->vectype)); 1509566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->mattype)); 1519566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*newdm)->mattype)); 1529566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1539566063dSJacob Faibussowitsch PetscCall(DMSetDimension(*newdm, dim)); 154dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, clone, newdm); 1553f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 1569566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm, &sf)); 1579566063dSJacob Faibussowitsch PetscCall(DMSetPointSF(*newdm, sf)); 1589566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dm, &ctx)); 1599566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(*newdm, ctx)); 160ec196627SMatthew G. Knepley PetscCall(DMReorderSectionGetDefault(dm, &flg)); 161ec196627SMatthew G. Knepley PetscCall(DMReorderSectionSetDefault(*newdm, flg)); 162ec196627SMatthew G. Knepley PetscCall(DMReorderSectionGetType(dm, &otype)); 163ec196627SMatthew G. Knepley PetscCall(DMReorderSectionSetType(*newdm, otype)); 1646858538eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 1656858538eSMatthew G. Knepley if (dm->coordinates[i].dm) { 166be4c1c3eSMatthew G. Knepley DM ncdm; 167be4c1c3eSMatthew G. Knepley PetscSection cs; 1685a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 169be4c1c3eSMatthew G. Knepley 1706858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm->coordinates[i].dm, &cs)); 1719566063dSJacob Faibussowitsch if (cs) PetscCall(PetscSectionGetChart(cs, NULL, &pEnd)); 172462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&pEnd, &pEndMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 1735a0206caSToby Isaac if (pEndMax >= 0) { 1746858538eSMatthew G. Knepley PetscCall(DMClone(dm->coordinates[i].dm, &ncdm)); 1756858538eSMatthew G. Knepley PetscCall(DMCopyDisc(dm->coordinates[i].dm, ncdm)); 1769566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(ncdm, cs)); 1775e50ca95SJames Wright if (dm->coordinates[i].dm->periodic.setup) { 1785e50ca95SJames Wright ncdm->periodic.setup = dm->coordinates[i].dm->periodic.setup; 1795e50ca95SJames Wright PetscCall(ncdm->periodic.setup(ncdm)); 1805e50ca95SJames Wright } 1816858538eSMatthew G. Knepley if (i) PetscCall(DMSetCellCoordinateDM(*newdm, ncdm)); 1826858538eSMatthew G. Knepley else PetscCall(DMSetCoordinateDM(*newdm, ncdm)); 1839566063dSJacob Faibussowitsch PetscCall(DMDestroy(&ncdm)); 184be4c1c3eSMatthew G. Knepley } 185be4c1c3eSMatthew G. Knepley } 1866858538eSMatthew G. Knepley } 1879566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 1889566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateDim(*newdm, cdim)); 1899566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coords)); 19038221697SMatthew G. Knepley if (coords) { 1919566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(*newdm, coords)); 19238221697SMatthew G. Knepley } else { 1939566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm, &coords)); 1949566063dSJacob Faibussowitsch if (coords) PetscCall(DMSetCoordinates(*newdm, coords)); 19538221697SMatthew G. Knepley } 1966858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coords)); 1976858538eSMatthew G. Knepley if (coords) { 1986858538eSMatthew G. Knepley PetscCall(DMSetCellCoordinatesLocal(*newdm, coords)); 1996858538eSMatthew G. Knepley } else { 2006858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinates(dm, &coords)); 2016858538eSMatthew G. Knepley if (coords) PetscCall(DMSetCellCoordinates(*newdm, coords)); 2026858538eSMatthew G. Knepley } 20390b157c4SStefano Zampini { 2044fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 2056858538eSMatthew G. Knepley 2064fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 2074fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*newdm, maxCell, Lstart, L)); 208c6b900c6SMatthew G. Knepley } 20934aa8a36SMatthew G. Knepley { 21034aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 21134aa8a36SMatthew G. Knepley 2129566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure)); 2139566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure)); 21434aa8a36SMatthew G. Knepley } 2153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21638221697SMatthew G. Knepley } 21738221697SMatthew G. Knepley 2185d83a8b1SBarry Smith /*@ 2195d83a8b1SBarry Smith DMSetVecType - Sets the type of vector to be created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 2209a42bb27SBarry Smith 22120f4b53cSBarry Smith Logically Collective 2229a42bb27SBarry Smith 223147403d9SBarry Smith Input Parameters: 22432546409SMatthew G. Knepley + dm - initial distributed array 225bb7acecfSBarry Smith - ctype - the vector type, for example `VECSTANDARD`, `VECCUDA`, or `VECVIENNACL` 2269a42bb27SBarry Smith 22720f4b53cSBarry Smith Options Database Key: 228147403d9SBarry Smith . -dm_vec_type ctype - the type of vector to create 2299a42bb27SBarry Smith 2309a42bb27SBarry Smith Level: intermediate 2319a42bb27SBarry Smith 23260225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMDestroy()`, `DMDAInterpolationType`, `VecType`, `DMGetVecType()`, `DMSetMatType()`, `DMGetMatType()`, 233bb7acecfSBarry Smith `VECSTANDARD`, `VECCUDA`, `VECVIENNACL`, `DMCreateLocalVector()`, `DMCreateGlobalVector()` 2349a42bb27SBarry Smith @*/ 23532546409SMatthew G. Knepley PetscErrorCode DMSetVecType(DM dm, VecType ctype) 236d71ae5a4SJacob Faibussowitsch { 23732546409SMatthew G. Knepley char *tmp; 23832546409SMatthew G. Knepley 2399a42bb27SBarry Smith PetscFunctionBegin; 24032546409SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 24132546409SMatthew G. Knepley PetscAssertPointer(ctype, 2); 24232546409SMatthew G. Knepley tmp = (char *)dm->vectype; 24332546409SMatthew G. Knepley PetscCall(PetscStrallocpy(ctype, (char **)&dm->vectype)); 24432546409SMatthew G. Knepley PetscCall(PetscFree(tmp)); 2453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2469a42bb27SBarry Smith } 2479a42bb27SBarry Smith 2485d83a8b1SBarry Smith /*@ 249bb7acecfSBarry Smith DMGetVecType - Gets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 250c0dedaeaSBarry Smith 25120f4b53cSBarry Smith Logically Collective 252c0dedaeaSBarry Smith 253c0dedaeaSBarry Smith Input Parameter: 254c0dedaeaSBarry Smith . da - initial distributed array 255c0dedaeaSBarry Smith 256c0dedaeaSBarry Smith Output Parameter: 257c0dedaeaSBarry Smith . ctype - the vector type 258c0dedaeaSBarry Smith 259c0dedaeaSBarry Smith Level: intermediate 260c0dedaeaSBarry Smith 26160225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMDestroy()`, `DMDAInterpolationType`, `VecType`, `DMSetMatType()`, `DMGetMatType()`, `DMSetVecType()` 262c0dedaeaSBarry Smith @*/ 263d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetVecType(DM da, VecType *ctype) 264d71ae5a4SJacob Faibussowitsch { 265c0dedaeaSBarry Smith PetscFunctionBegin; 266c0dedaeaSBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 267c0dedaeaSBarry Smith *ctype = da->vectype; 2683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 269c0dedaeaSBarry Smith } 270c0dedaeaSBarry Smith 2715f1ad066SMatthew G Knepley /*@ 272bb7acecfSBarry Smith VecGetDM - Gets the `DM` defining the data layout of the vector 2735f1ad066SMatthew G Knepley 27420f4b53cSBarry Smith Not Collective 2755f1ad066SMatthew G Knepley 2765f1ad066SMatthew G Knepley Input Parameter: 277bb7acecfSBarry Smith . v - The `Vec` 2785f1ad066SMatthew G Knepley 2795f1ad066SMatthew G Knepley Output Parameter: 280bb7acecfSBarry Smith . dm - The `DM` 2815f1ad066SMatthew G Knepley 2825f1ad066SMatthew G Knepley Level: intermediate 2835f1ad066SMatthew G Knepley 284bb7acecfSBarry Smith Note: 285bb7acecfSBarry Smith A `Vec` may not have a `DM` associated with it. 286bb7acecfSBarry Smith 2871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecSetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 2885f1ad066SMatthew G Knepley @*/ 289d71ae5a4SJacob Faibussowitsch PetscErrorCode VecGetDM(Vec v, DM *dm) 290d71ae5a4SJacob Faibussowitsch { 2915f1ad066SMatthew G Knepley PetscFunctionBegin; 2925f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 2934f572ea9SToby Isaac PetscAssertPointer(dm, 2); 2949566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)v, "__PETSc_dm", (PetscObject *)dm)); 2953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2965f1ad066SMatthew G Knepley } 2975f1ad066SMatthew G Knepley 2985f1ad066SMatthew G Knepley /*@ 299bb7acecfSBarry Smith VecSetDM - Sets the `DM` defining the data layout of the vector. 3005f1ad066SMatthew G Knepley 30120f4b53cSBarry Smith Not Collective 3025f1ad066SMatthew G Knepley 3035f1ad066SMatthew G Knepley Input Parameters: 304bb7acecfSBarry Smith + v - The `Vec` 305bb7acecfSBarry Smith - dm - The `DM` 3065f1ad066SMatthew G Knepley 30720f4b53cSBarry Smith Level: developer 30820f4b53cSBarry Smith 30973ff1848SBarry Smith Notes: 310bb7acecfSBarry Smith This is rarely used, generally one uses `DMGetLocalVector()` or `DMGetGlobalVector()` to create a vector associated with a given `DM` 311d9805387SMatthew G. Knepley 312bb7acecfSBarry Smith This is NOT the same as `DMCreateGlobalVector()` since it does not change the view methods or perform other customization, but merely sets the `DM` member. 313bb7acecfSBarry Smith 3141cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecGetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 3155f1ad066SMatthew G Knepley @*/ 316d71ae5a4SJacob Faibussowitsch PetscErrorCode VecSetDM(Vec v, DM dm) 317d71ae5a4SJacob Faibussowitsch { 3185f1ad066SMatthew G Knepley PetscFunctionBegin; 3195f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 320d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 3219566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)v, "__PETSc_dm", (PetscObject)dm)); 3223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3235f1ad066SMatthew G Knepley } 3245f1ad066SMatthew G Knepley 325cc4c1da9SBarry Smith /*@ 326bb7acecfSBarry Smith DMSetISColoringType - Sets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 3278f1509bcSBarry Smith 32820f4b53cSBarry Smith Logically Collective 3298f1509bcSBarry Smith 3308f1509bcSBarry Smith Input Parameters: 331bb7acecfSBarry Smith + dm - the `DM` context 3328f1509bcSBarry Smith - ctype - the matrix type 3338f1509bcSBarry Smith 33420f4b53cSBarry Smith Options Database Key: 3358f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3368f1509bcSBarry Smith 3378f1509bcSBarry Smith Level: intermediate 3388f1509bcSBarry Smith 3391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 340bb7acecfSBarry Smith `DMGetISColoringType()`, `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3418f1509bcSBarry Smith @*/ 342d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetISColoringType(DM dm, ISColoringType ctype) 343d71ae5a4SJacob Faibussowitsch { 3448f1509bcSBarry Smith PetscFunctionBegin; 3458f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3468f1509bcSBarry Smith dm->coloringtype = ctype; 3473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3488f1509bcSBarry Smith } 3498f1509bcSBarry Smith 350cc4c1da9SBarry Smith /*@ 351bb7acecfSBarry Smith DMGetISColoringType - Gets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 352521d9a4cSLisandro Dalcin 35320f4b53cSBarry Smith Logically Collective 354521d9a4cSLisandro Dalcin 355521d9a4cSLisandro Dalcin Input Parameter: 356bb7acecfSBarry Smith . dm - the `DM` context 3578f1509bcSBarry Smith 3588f1509bcSBarry Smith Output Parameter: 3598f1509bcSBarry Smith . ctype - the matrix type 3608f1509bcSBarry Smith 36120f4b53cSBarry Smith Options Database Key: 3628f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3638f1509bcSBarry Smith 3648f1509bcSBarry Smith Level: intermediate 3658f1509bcSBarry Smith 3661cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 36742747ad1SJacob Faibussowitsch `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3688f1509bcSBarry Smith @*/ 369d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetISColoringType(DM dm, ISColoringType *ctype) 370d71ae5a4SJacob Faibussowitsch { 3718f1509bcSBarry Smith PetscFunctionBegin; 3728f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3738f1509bcSBarry Smith *ctype = dm->coloringtype; 3743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3758f1509bcSBarry Smith } 3768f1509bcSBarry Smith 377cc4c1da9SBarry Smith /*@ 378bb7acecfSBarry Smith DMSetMatType - Sets the type of matrix created with `DMCreateMatrix()` 3798f1509bcSBarry Smith 38020f4b53cSBarry Smith Logically Collective 3818f1509bcSBarry Smith 3828f1509bcSBarry Smith Input Parameters: 383bb7acecfSBarry Smith + dm - the `DM` context 384bb7acecfSBarry Smith - ctype - the matrix type, for example `MATMPIAIJ` 385521d9a4cSLisandro Dalcin 38620f4b53cSBarry Smith Options Database Key: 387bb7acecfSBarry Smith . -dm_mat_type ctype - the type of the matrix to create, for example mpiaij 388521d9a4cSLisandro Dalcin 389521d9a4cSLisandro Dalcin Level: intermediate 390521d9a4cSLisandro Dalcin 39142747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `MatType`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMGetMatType()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()` 392521d9a4cSLisandro Dalcin @*/ 393d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatType(DM dm, MatType ctype) 394d71ae5a4SJacob Faibussowitsch { 39532546409SMatthew G. Knepley char *tmp; 39632546409SMatthew G. Knepley 397521d9a4cSLisandro Dalcin PetscFunctionBegin; 398521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39932546409SMatthew G. Knepley PetscAssertPointer(ctype, 2); 40032546409SMatthew G. Knepley tmp = (char *)dm->mattype; 4019566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype, (char **)&dm->mattype)); 40232546409SMatthew G. Knepley PetscCall(PetscFree(tmp)); 4033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 404521d9a4cSLisandro Dalcin } 405521d9a4cSLisandro Dalcin 406cc4c1da9SBarry Smith /*@ 40720f4b53cSBarry Smith DMGetMatType - Gets the type of matrix that would be created with `DMCreateMatrix()` 408c0dedaeaSBarry Smith 40920f4b53cSBarry Smith Logically Collective 410c0dedaeaSBarry Smith 411c0dedaeaSBarry Smith Input Parameter: 412bb7acecfSBarry Smith . dm - the `DM` context 413c0dedaeaSBarry Smith 414c0dedaeaSBarry Smith Output Parameter: 415c0dedaeaSBarry Smith . ctype - the matrix type 416c0dedaeaSBarry Smith 417c0dedaeaSBarry Smith Level: intermediate 418c0dedaeaSBarry Smith 41942747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMSetMatType()` 420c0dedaeaSBarry Smith @*/ 421d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetMatType(DM dm, MatType *ctype) 422d71ae5a4SJacob Faibussowitsch { 423c0dedaeaSBarry Smith PetscFunctionBegin; 424c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 425c0dedaeaSBarry Smith *ctype = dm->mattype; 4263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 427c0dedaeaSBarry Smith } 428c0dedaeaSBarry Smith 429c688c046SMatthew G Knepley /*@ 430bb7acecfSBarry Smith MatGetDM - Gets the `DM` defining the data layout of the matrix 431c688c046SMatthew G Knepley 43220f4b53cSBarry Smith Not Collective 433c688c046SMatthew G Knepley 434c688c046SMatthew G Knepley Input Parameter: 435bb7acecfSBarry Smith . A - The `Mat` 436c688c046SMatthew G Knepley 437c688c046SMatthew G Knepley Output Parameter: 438bb7acecfSBarry Smith . dm - The `DM` 439c688c046SMatthew G Knepley 440c688c046SMatthew G Knepley Level: intermediate 441c688c046SMatthew G Knepley 442bb7acecfSBarry Smith Note: 443bb7acecfSBarry Smith A matrix may not have a `DM` associated with it 444bb7acecfSBarry Smith 44573ff1848SBarry Smith Developer Note: 446bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with the `Mat` through a `PetscObjectCompose()` operation 4478f1509bcSBarry Smith 4481cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatSetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 449c688c046SMatthew G Knepley @*/ 450d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetDM(Mat A, DM *dm) 451d71ae5a4SJacob Faibussowitsch { 452c688c046SMatthew G Knepley PetscFunctionBegin; 453c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4544f572ea9SToby Isaac PetscAssertPointer(dm, 2); 4559566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_dm", (PetscObject *)dm)); 4563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 457c688c046SMatthew G Knepley } 458c688c046SMatthew G Knepley 459c688c046SMatthew G Knepley /*@ 460bb7acecfSBarry Smith MatSetDM - Sets the `DM` defining the data layout of the matrix 461c688c046SMatthew G Knepley 46220f4b53cSBarry Smith Not Collective 463c688c046SMatthew G Knepley 464c688c046SMatthew G Knepley Input Parameters: 46520f4b53cSBarry Smith + A - The `Mat` 46620f4b53cSBarry Smith - dm - The `DM` 467c688c046SMatthew G Knepley 468bb7acecfSBarry Smith Level: developer 469c688c046SMatthew G Knepley 470bb7acecfSBarry Smith Note: 471bb7acecfSBarry Smith This is rarely used in practice, rather `DMCreateMatrix()` is used to create a matrix associated with a particular `DM` 472bb7acecfSBarry Smith 47373ff1848SBarry Smith Developer Note: 474bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with 475bb7acecfSBarry Smith the `Mat` through a `PetscObjectCompose()` operation 4768f1509bcSBarry Smith 4771cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatGetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 478c688c046SMatthew G Knepley @*/ 479d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetDM(Mat A, DM dm) 480d71ae5a4SJacob Faibussowitsch { 481c688c046SMatthew G Knepley PetscFunctionBegin; 482c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4838865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 4849566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_dm", (PetscObject)dm)); 4853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 486c688c046SMatthew G Knepley } 487c688c046SMatthew G Knepley 488cc4c1da9SBarry Smith /*@ 489bb7acecfSBarry Smith DMSetOptionsPrefix - Sets the prefix prepended to all option names when searching through the options database 4909a42bb27SBarry Smith 49120f4b53cSBarry Smith Logically Collective 4929a42bb27SBarry Smith 493d8d19677SJose E. Roman Input Parameters: 49460225df5SJacob Faibussowitsch + dm - the `DM` context 495bb7acecfSBarry Smith - prefix - the prefix to prepend 4969a42bb27SBarry Smith 49720f4b53cSBarry Smith Level: advanced 49820f4b53cSBarry Smith 49920f4b53cSBarry Smith Note: 5009a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 5019a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 5029a42bb27SBarry Smith 5031cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscObjectSetOptionsPrefix()`, `DMSetFromOptions()` 5049a42bb27SBarry Smith @*/ 505d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOptionsPrefix(DM dm, const char prefix[]) 506d71ae5a4SJacob Faibussowitsch { 5079a42bb27SBarry Smith PetscFunctionBegin; 5089a42bb27SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5099566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm, prefix)); 5101baa6e33SBarry Smith if (dm->sf) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sf, prefix)); 5111baa6e33SBarry Smith if (dm->sectionSF) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF, prefix)); 5123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5139a42bb27SBarry Smith } 5149a42bb27SBarry Smith 515cc4c1da9SBarry Smith /*@ 516da81f932SPierre Jolivet DMAppendOptionsPrefix - Appends an additional string to an already existing prefix used for searching for 517bb7acecfSBarry Smith `DM` options in the options database. 51831697293SDave May 51920f4b53cSBarry Smith Logically Collective 52031697293SDave May 52131697293SDave May Input Parameters: 522bb7acecfSBarry Smith + dm - the `DM` context 523bb7acecfSBarry Smith - prefix - the string to append to the current prefix 52431697293SDave May 52520f4b53cSBarry Smith Level: advanced 52620f4b53cSBarry Smith 52720f4b53cSBarry Smith Note: 528bb7acecfSBarry Smith If the `DM` does not currently have an options prefix then this value is used alone as the prefix as if `DMSetOptionsPrefix()` had been called. 52931697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 53031697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 53131697293SDave May 5321cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetOptionsPrefix()`, `DMGetOptionsPrefix()`, `PetscObjectAppendOptionsPrefix()`, `DMSetFromOptions()` 53331697293SDave May @*/ 534d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAppendOptionsPrefix(DM dm, const char prefix[]) 535d71ae5a4SJacob Faibussowitsch { 53631697293SDave May PetscFunctionBegin; 53731697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5389566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)dm, prefix)); 5393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54031697293SDave May } 54131697293SDave May 542cc4c1da9SBarry Smith /*@ 54331697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 544bb7acecfSBarry Smith DM options in the options database. 54531697293SDave May 54631697293SDave May Not Collective 54731697293SDave May 5482fe279fdSBarry Smith Input Parameter: 549bb7acecfSBarry Smith . dm - the `DM` context 55031697293SDave May 5512fe279fdSBarry Smith Output Parameter: 55231697293SDave May . prefix - pointer to the prefix string used is returned 55331697293SDave May 55431697293SDave May Level: advanced 55531697293SDave May 5561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetOptionsPrefix()`, `DMAppendOptionsPrefix()`, `DMSetFromOptions()` 55731697293SDave May @*/ 558d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOptionsPrefix(DM dm, const char *prefix[]) 559d71ae5a4SJacob Faibussowitsch { 56031697293SDave May PetscFunctionBegin; 56131697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5629566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, prefix)); 5633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56431697293SDave May } 56531697293SDave May 56662e5d2d2SJDBetteridge static PetscErrorCode DMCountNonCyclicReferences_Internal(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 567d71ae5a4SJacob Faibussowitsch { 5686eb26441SStefano Zampini PetscInt refct = ((PetscObject)dm)->refct; 56988bdff64SToby Isaac 57088bdff64SToby Isaac PetscFunctionBegin; 571aab5bcd8SJed Brown *ncrefct = 0; 57288bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 57388bdff64SToby Isaac refct--; 57488bdff64SToby Isaac if (recurseCoarse) { 57588bdff64SToby Isaac PetscInt coarseCount; 57688bdff64SToby Isaac 57762e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE, &coarseCount)); 57888bdff64SToby Isaac refct += coarseCount; 57988bdff64SToby Isaac } 58088bdff64SToby Isaac } 58188bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 58288bdff64SToby Isaac refct--; 58388bdff64SToby Isaac if (recurseFine) { 58488bdff64SToby Isaac PetscInt fineCount; 58588bdff64SToby Isaac 58662e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->fineMesh, PETSC_FALSE, PETSC_TRUE, &fineCount)); 58788bdff64SToby Isaac refct += fineCount; 58888bdff64SToby Isaac } 58988bdff64SToby Isaac } 59088bdff64SToby Isaac *ncrefct = refct; 5913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 59288bdff64SToby Isaac } 59388bdff64SToby Isaac 59462e5d2d2SJDBetteridge /* Generic wrapper for DMCountNonCyclicReferences_Internal() */ 59562e5d2d2SJDBetteridge PetscErrorCode DMCountNonCyclicReferences(PetscObject dm, PetscInt *ncrefct) 59662e5d2d2SJDBetteridge { 59762e5d2d2SJDBetteridge PetscFunctionBegin; 59862e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal((DM)dm, PETSC_TRUE, PETSC_TRUE, ncrefct)); 5993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 60062e5d2d2SJDBetteridge } 60162e5d2d2SJDBetteridge 602d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 603d71ae5a4SJacob Faibussowitsch { 6045d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 605354557abSToby Isaac 606354557abSToby Isaac PetscFunctionBegin; 607354557abSToby Isaac /* destroy the labels */ 608354557abSToby Isaac while (next) { 609354557abSToby Isaac DMLabelLink tmp = next->next; 610354557abSToby Isaac 6115d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 612ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 6139566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 6149566063dSJacob Faibussowitsch PetscCall(PetscFree(next)); 615354557abSToby Isaac next = tmp; 616354557abSToby Isaac } 6175d80c0bfSVaclav Hapla dm->labels = NULL; 6183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 619354557abSToby Isaac } 620354557abSToby Isaac 62166976f2fSJacob Faibussowitsch static PetscErrorCode DMDestroyCoordinates_Private(DMCoordinates *c) 622d71ae5a4SJacob Faibussowitsch { 6236858538eSMatthew G. Knepley PetscFunctionBegin; 6246858538eSMatthew G. Knepley c->dim = PETSC_DEFAULT; 6256858538eSMatthew G. Knepley PetscCall(DMDestroy(&c->dm)); 6266858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->x)); 6276858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->xl)); 6286858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&c->field)); 6293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6306858538eSMatthew G. Knepley } 6316858538eSMatthew G. Knepley 6320764c050SBarry Smith /*@ 633bb7acecfSBarry Smith DMDestroy - Destroys a `DM`. 63447c6ae99SBarry Smith 63520f4b53cSBarry Smith Collective 63647c6ae99SBarry Smith 63747c6ae99SBarry Smith Input Parameter: 638bb7acecfSBarry Smith . dm - the `DM` object to destroy 63947c6ae99SBarry Smith 64047c6ae99SBarry Smith Level: developer 64147c6ae99SBarry Smith 6421cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMType`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 64347c6ae99SBarry Smith @*/ 644d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroy(DM *dm) 645d71ae5a4SJacob Faibussowitsch { 6466eb26441SStefano Zampini PetscInt cnt; 64747c6ae99SBarry Smith 64847c6ae99SBarry Smith PetscFunctionBegin; 6493ba16761SJacob Faibussowitsch if (!*dm) PetscFunctionReturn(PETSC_SUCCESS); 650f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*dm, DM_CLASSID, 1); 65187e657c6SBarry Smith 65288bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 65362e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(*dm, PETSC_TRUE, PETSC_TRUE, &cnt)); 654f4f49eeaSPierre Jolivet --((PetscObject)*dm)->refct; 6559371c9d4SSatish Balay if (--cnt > 0) { 6569371c9d4SSatish Balay *dm = NULL; 6573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6589371c9d4SSatish Balay } 659f4f49eeaSPierre Jolivet if (((PetscObject)*dm)->refct < 0) PetscFunctionReturn(PETSC_SUCCESS); 660f4f49eeaSPierre Jolivet ((PetscObject)*dm)->refct = 0; 6616eb26441SStefano Zampini 6629566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(*dm)); 6639566063dSJacob Faibussowitsch PetscCall(DMClearLocalVectors(*dm)); 664974ca4ecSStefano Zampini PetscCall(DMClearNamedGlobalVectors(*dm)); 665974ca4ecSStefano Zampini PetscCall(DMClearNamedLocalVectors(*dm)); 6662348bcf4SPeter Brune 667b17ce1afSJed Brown /* Destroy the list of hooks */ 668c833c3b5SJed Brown { 669c833c3b5SJed Brown DMCoarsenHookLink link, next; 670b17ce1afSJed Brown for (link = (*dm)->coarsenhook; link; link = next) { 671b17ce1afSJed Brown next = link->next; 6729566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 673b17ce1afSJed Brown } 6740298fd71SBarry Smith (*dm)->coarsenhook = NULL; 675c833c3b5SJed Brown } 676c833c3b5SJed Brown { 677c833c3b5SJed Brown DMRefineHookLink link, next; 678c833c3b5SJed Brown for (link = (*dm)->refinehook; link; link = next) { 679c833c3b5SJed Brown next = link->next; 6809566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 681c833c3b5SJed Brown } 6820298fd71SBarry Smith (*dm)->refinehook = NULL; 683c833c3b5SJed Brown } 684be081cd6SPeter Brune { 685be081cd6SPeter Brune DMSubDomainHookLink link, next; 686be081cd6SPeter Brune for (link = (*dm)->subdomainhook; link; link = next) { 687be081cd6SPeter Brune next = link->next; 6889566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 689be081cd6SPeter Brune } 6900298fd71SBarry Smith (*dm)->subdomainhook = NULL; 691be081cd6SPeter Brune } 692baf369e7SPeter Brune { 693baf369e7SPeter Brune DMGlobalToLocalHookLink link, next; 694baf369e7SPeter Brune for (link = (*dm)->gtolhook; link; link = next) { 695baf369e7SPeter Brune next = link->next; 6969566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 697baf369e7SPeter Brune } 6980298fd71SBarry Smith (*dm)->gtolhook = NULL; 699baf369e7SPeter Brune } 700d4d07f1eSToby Isaac { 701d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, next; 702d4d07f1eSToby Isaac for (link = (*dm)->ltoghook; link; link = next) { 703d4d07f1eSToby Isaac next = link->next; 7049566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 705d4d07f1eSToby Isaac } 706d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 707d4d07f1eSToby Isaac } 708aa1993deSMatthew G Knepley /* Destroy the work arrays */ 709aa1993deSMatthew G Knepley { 710aa1993deSMatthew G Knepley DMWorkLink link, next; 711835f2295SStefano Zampini PetscCheck(!(*dm)->workout, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Work array still checked out %p %p", (void *)(*dm)->workout, (*dm)->workout->mem); 712aa1993deSMatthew G Knepley for (link = (*dm)->workin; link; link = next) { 713aa1993deSMatthew G Knepley next = link->next; 7149566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 7159566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 716aa1993deSMatthew G Knepley } 7170298fd71SBarry Smith (*dm)->workin = NULL; 718aa1993deSMatthew G Knepley } 719c58f1c22SToby Isaac /* destroy the labels */ 7209566063dSJacob Faibussowitsch PetscCall(DMDestroyLabelLinkList_Internal(*dm)); 721f4cdcedcSVaclav Hapla /* destroy the fields */ 7229566063dSJacob Faibussowitsch PetscCall(DMClearFields(*dm)); 723f4cdcedcSVaclav Hapla /* destroy the boundaries */ 724e6f8dbb6SToby Isaac { 725e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 726e6f8dbb6SToby Isaac while (next) { 727e6f8dbb6SToby Isaac DMBoundary b = next; 728e6f8dbb6SToby Isaac 729e6f8dbb6SToby Isaac next = b->next; 7309566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 731e6f8dbb6SToby Isaac } 732e6f8dbb6SToby Isaac } 733b17ce1afSJed Brown 7349566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmksp)); 7359566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmsnes)); 7369566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmts)); 73752536dc3SBarry Smith 73848a46eb9SPierre Jolivet if ((*dm)->ctx && (*dm)->ctxdestroy) PetscCall((*(*dm)->ctxdestroy)(&(*dm)->ctx)); 7399566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&(*dm)->fd)); 7409566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap)); 7419566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->vectype)); 7429566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->mattype)); 74388ed4aceSMatthew G Knepley 7449566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->localSection)); 7459566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->globalSection)); 746adc21957SMatthew G. Knepley PetscCall(PetscFree((*dm)->reorderSectionType)); 7479566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&(*dm)->map)); 7489566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->defaultConstraint.section)); 7499566063dSJacob Faibussowitsch PetscCall(MatDestroy(&(*dm)->defaultConstraint.mat)); 7509566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sf)); 7519566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sectionSF)); 75248a46eb9SPierre Jolivet if ((*dm)->sfNatural) PetscCall(PetscSFDestroy(&(*dm)->sfNatural)); 7539566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)(*dm)->sfMigration)); 754e4d5475eSStefano Zampini PetscCall(DMClearAuxiliaryVec(*dm)); 7559566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&(*dm)->auxData)); 75648a46eb9SPierre Jolivet if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) PetscCall(DMSetFineDM((*dm)->coarseMesh, NULL)); 7576eb26441SStefano Zampini 7589566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->coarseMesh)); 75948a46eb9SPierre Jolivet if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) PetscCall(DMSetCoarseDM((*dm)->fineMesh, NULL)); 7609566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->fineMesh)); 7614fb89dddSMatthew G. Knepley PetscCall(PetscFree((*dm)->Lstart)); 7629566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->L)); 7639566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->maxCell)); 7646858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[0])); 7656858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[1])); 7669566063dSJacob Faibussowitsch if ((*dm)->transformDestroy) PetscCall((*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx)); 7679566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->transformDM)); 7689566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*dm)->transform)); 769ddedc8f6SJames Wright for (PetscInt i = 0; i < (*dm)->periodic.num_affines; i++) { 770ddedc8f6SJames Wright PetscCall(VecScatterDestroy(&(*dm)->periodic.affine_to_local[i])); 771ddedc8f6SJames Wright PetscCall(VecDestroy(&(*dm)->periodic.affine[i])); 772ddedc8f6SJames Wright } 773ddedc8f6SJames Wright if ((*dm)->periodic.num_affines > 0) PetscCall(PetscFree2((*dm)->periodic.affine_to_local, (*dm)->periodic.affine)); 7746636e97aSMatthew G Knepley 7759566063dSJacob Faibussowitsch PetscCall(DMClearDS(*dm)); 7769566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->dmBC)); 777e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 7789566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*dm)); 779732e2eb9SMatthew G Knepley 780213acdd3SPierre Jolivet PetscTryTypeMethod(*dm, destroy); 7819566063dSJacob Faibussowitsch PetscCall(DMMonitorCancel(*dm)); 782d2b2dc1eSMatthew G. Knepley PetscCall(DMCeedDestroy(&(*dm)->dmceed)); 783f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 7849566063dSJacob Faibussowitsch PetscCallCEED(CeedElemRestrictionDestroy(&(*dm)->ceedERestrict)); 7859566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*dm)->ceed)); 786f918ec44SMatthew G. Knepley #endif 787435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 7889566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(dm)); 7893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 79047c6ae99SBarry Smith } 79147c6ae99SBarry Smith 792d7bf68aeSBarry Smith /*@ 793bb7acecfSBarry Smith DMSetUp - sets up the data structures inside a `DM` object 794d7bf68aeSBarry Smith 79520f4b53cSBarry Smith Collective 796d7bf68aeSBarry Smith 797d7bf68aeSBarry Smith Input Parameter: 798bb7acecfSBarry Smith . dm - the `DM` object to setup 799d7bf68aeSBarry Smith 800bb7acecfSBarry Smith Level: intermediate 801d7bf68aeSBarry Smith 802bb7acecfSBarry Smith Note: 803bb7acecfSBarry Smith This is usually called after various parameter setting operations and `DMSetFromOptions()` are called on the `DM` 804bb7acecfSBarry Smith 8051cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 806d7bf68aeSBarry Smith @*/ 807d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUp(DM dm) 808d71ae5a4SJacob Faibussowitsch { 809d7bf68aeSBarry Smith PetscFunctionBegin; 810171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8113ba16761SJacob Faibussowitsch if (dm->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 812dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setup); 8138387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 8143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 815d7bf68aeSBarry Smith } 816d7bf68aeSBarry Smith 817d7bf68aeSBarry Smith /*@ 818bb7acecfSBarry Smith DMSetFromOptions - sets parameters in a `DM` from the options database 819d7bf68aeSBarry Smith 82020f4b53cSBarry Smith Collective 821d7bf68aeSBarry Smith 822d7bf68aeSBarry Smith Input Parameter: 823bb7acecfSBarry Smith . dm - the `DM` object to set options for 824d7bf68aeSBarry Smith 82520f4b53cSBarry Smith Options Database Keys: 826bb7acecfSBarry Smith + -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 827bb7acecfSBarry Smith . -dm_vec_type <type> - type of vector to create inside `DM` 828bb7acecfSBarry Smith . -dm_mat_type <type> - type of matrix to create inside `DM` 829a4ea9b21SRichard Tran Mills . -dm_is_coloring_type - <global or local> 83020f4b53cSBarry Smith . -dm_bind_below <n> - bind (force execution on CPU) for `Vec` and `Mat` objects with local size (number of vector entries or matrix rows) below n; currently only supported for `DMDA` 83122d6dc08SStefano Zampini . -dm_plex_option_phases <ph0_, ph1_, ...> - List of prefixes for option processing phases 83220f4b53cSBarry Smith . -dm_plex_filename <str> - File containing a mesh 8339318fe57SMatthew G. Knepley . -dm_plex_boundary_filename <str> - File containing a mesh boundary 834cd7e8a5eSksagiyam . -dm_plex_name <str> - Name of the mesh in the file 8355dca41c3SJed Brown . -dm_plex_shape <shape> - The domain shape, such as `BOX`, `SPHERE`, etc. 8369318fe57SMatthew G. Knepley . -dm_plex_cell <ct> - Cell shape 8379318fe57SMatthew G. Knepley . -dm_plex_reference_cell_domain <bool> - Use a reference cell domain 8389318fe57SMatthew G. Knepley . -dm_plex_dim <dim> - Set the topological dimension 839bb7acecfSBarry Smith . -dm_plex_simplex <bool> - `PETSC_TRUE` for simplex elements, `PETSC_FALSE` for tensor elements 840bb7acecfSBarry Smith . -dm_plex_interpolate <bool> - `PETSC_TRUE` turns on topological interpolation (creating edges and faces) 841b9da1bb3SMatthew G. Knepley . -dm_plex_orient <bool> - `PETSC_TRUE` turns on topological orientation (flipping edges and faces) 8429318fe57SMatthew G. Knepley . -dm_plex_scale <sc> - Scale factor for mesh coordinates 843be664eb1SMatthew G. Knepley . -dm_coord_remap <bool> - Map coordinates using a function 844ac9d17c7SMatthew G. Knepley . -dm_plex_coordinate_dim <dim> - Change the coordinate dimension of a mesh (usually given with cdm_ prefix) 845be664eb1SMatthew G. Knepley . -dm_coord_map <mapname> - Select a builtin coordinate map 846be664eb1SMatthew G. Knepley . -dm_coord_map_params <p0,p1,p2,...> - Set coordinate mapping parameters 8479318fe57SMatthew G. Knepley . -dm_plex_box_faces <m,n,p> - Number of faces along each dimension 8489318fe57SMatthew G. Knepley . -dm_plex_box_lower <x,y,z> - Specify lower-left-bottom coordinates for the box 8499318fe57SMatthew G. Knepley . -dm_plex_box_upper <x,y,z> - Specify upper-right-top coordinates for the box 850bb7acecfSBarry Smith . -dm_plex_box_bd <bx,by,bz> - Specify the `DMBoundaryType` for each direction 8519318fe57SMatthew G. Knepley . -dm_plex_sphere_radius <r> - The sphere radius 8529318fe57SMatthew G. Knepley . -dm_plex_ball_radius <r> - Radius of the ball 8539318fe57SMatthew G. Knepley . -dm_plex_cylinder_bd <bz> - Boundary type in the z direction 8549318fe57SMatthew G. Knepley . -dm_plex_cylinder_num_wedges <n> - Number of wedges around the cylinder 855bdf63967SMatthew G. Knepley . -dm_plex_reorder <order> - Reorder the mesh using the specified algorithm 8569318fe57SMatthew G. Knepley . -dm_refine_pre <n> - The number of refinements before distribution 8579318fe57SMatthew G. Knepley . -dm_refine_uniform_pre <bool> - Flag for uniform refinement before distribution 8589318fe57SMatthew G. Knepley . -dm_refine_volume_limit_pre <v> - The maximum cell volume after refinement before distribution 8599318fe57SMatthew G. Knepley . -dm_refine <n> - The number of refinements after distribution 860bdf63967SMatthew G. Knepley . -dm_extrude <l> - Activate extrusion and specify the number of layers to extrude 86161f058f9SMatthew G. Knepley . -dm_plex_save_transform <bool> - Save the `DMPlexTransform` that produced this mesh 862d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers 863d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding 864d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface 865d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction 866d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer 867909dfd52SMatthew G. Knepley . -dm_plex_create_fv_ghost_cells - Flag to create finite volume ghost cells on the boundary 868909dfd52SMatthew G. Knepley . -dm_plex_fv_ghost_cells_label <name> - Label name for ghost cells boundary 8699318fe57SMatthew G. Knepley . -dm_distribute <bool> - Flag to redistribute a mesh among processes 8709318fe57SMatthew G. Knepley . -dm_distribute_overlap <n> - The size of the overlap halo 8719318fe57SMatthew G. Knepley . -dm_plex_adj_cone <bool> - Set adjacency direction 87220f4b53cSBarry Smith . -dm_plex_adj_closure <bool> - Set adjacency size 873d2b2dc1eSMatthew G. Knepley . -dm_plex_use_ceed <bool> - Use LibCEED as the FEM backend 87420f4b53cSBarry Smith . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - `DMPlexCheckSymmetry()` 875bb7acecfSBarry Smith . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - `DMPlexCheckSkeleton()` 876bb7acecfSBarry Smith . -dm_plex_check_faces - Check that the faces of each cell give a vertex order this is consistent with what we expect from the cell type - `DMPlexCheckFaces()` 877bb7acecfSBarry Smith . -dm_plex_check_geometry - Check that cells have positive volume - `DMPlexCheckGeometry()` 878bb7acecfSBarry Smith . -dm_plex_check_pointsf - Check some necessary conditions for `PointSF` - `DMPlexCheckPointSF()` 879bb7acecfSBarry Smith . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - `DMPlexCheckInterfaceCones()` 880384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 881d7bf68aeSBarry Smith 88295eb5ee5SVaclav Hapla Level: intermediate 88395eb5ee5SVaclav Hapla 8848e704042SBarry Smith Note: 8858e704042SBarry Smith For some `DMType` such as `DMDA` this cannot be called after `DMSetUp()` has been called. 8868e704042SBarry Smith 8871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 888bb7acecfSBarry Smith `DMPlexCheckSymmetry()`, `DMPlexCheckSkeleton()`, `DMPlexCheckFaces()`, `DMPlexCheckGeometry()`, `DMPlexCheckPointSF()`, `DMPlexCheckInterfaceCones()`, 8898e704042SBarry Smith `DMSetOptionsPrefix()`, `DMType`, `DMPLEX`, `DMDA`, `DMSetUp()` 890d7bf68aeSBarry Smith @*/ 891d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFromOptions(DM dm) 892d71ae5a4SJacob Faibussowitsch { 8937781c08eSBarry Smith char typeName[256]; 894ca266f36SBarry Smith PetscBool flg; 895d7bf68aeSBarry Smith 896d7bf68aeSBarry Smith PetscFunctionBegin; 897171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89849be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 8999566063dSJacob Faibussowitsch if (dm->sf) PetscCall(PetscSFSetFromOptions(dm->sf)); 9009566063dSJacob Faibussowitsch if (dm->sectionSF) PetscCall(PetscSFSetFromOptions(dm->sectionSF)); 901dd4c3f67SMatthew G. Knepley if (dm->coordinates[0].dm) PetscCall(DMSetFromOptions(dm->coordinates[0].dm)); 902d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)dm); 9039566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-dm_preallocate_only", "only preallocate matrix, but do not set column indices", "DMSetMatrixPreallocateOnly", dm->prealloc_only, &dm->prealloc_only, NULL)); 9049566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_vec_type", "Vector type used for created vectors", "DMSetVecType", VecList, dm->vectype, typeName, 256, &flg)); 9051baa6e33SBarry Smith if (flg) PetscCall(DMSetVecType(dm, typeName)); 9069566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_mat_type", "Matrix type used for created matrices", "DMSetMatType", MatList, dm->mattype ? dm->mattype : typeName, typeName, sizeof(typeName), &flg)); 9071baa6e33SBarry Smith if (flg) PetscCall(DMSetMatType(dm, typeName)); 908863027abSJed Brown PetscCall(PetscOptionsEnum("-dm_blocking_type", "Topological point or field node blocking", "DMSetBlockingType", DMBlockingTypes, (PetscEnum)dm->blocking_type, (PetscEnum *)&dm->blocking_type, NULL)); 9099566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-dm_is_coloring_type", "Global or local coloring of Jacobian", "DMSetISColoringType", ISColoringTypes, (PetscEnum)dm->coloringtype, (PetscEnum *)&dm->coloringtype, NULL)); 9109566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-dm_bind_below", "Set the size threshold (in entries) below which the Vec is bound to the CPU", "VecBindToCPU", dm->bind_below, &dm->bind_below, &flg)); 911eb9d3e4dSMatthew G. Knepley PetscCall(PetscOptionsBool("-dm_ignore_perm_output", "Ignore the local section permutation on output", "DMGetOutputDM", dm->ignorePermOutput, &dm->ignorePermOutput, NULL)); 912dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setfromoptions, PetscOptionsObject); 913f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 914dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)dm, PetscOptionsObject)); 915d0609cedSBarry Smith PetscOptionsEnd(); 9163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 917d7bf68aeSBarry Smith } 918d7bf68aeSBarry Smith 919ffeef943SBarry Smith /*@ 920bb7acecfSBarry Smith DMViewFromOptions - View a `DM` in a particular way based on a request in the options database 921fe2efc57SMark 92220f4b53cSBarry Smith Collective 923fe2efc57SMark 924fe2efc57SMark Input Parameters: 925bb7acecfSBarry Smith + dm - the `DM` object 926ce78bad3SBarry Smith . obj - optional object that provides the prefix for the options database (if `NULL` then the prefix in `obj` is used) 92760225df5SJacob Faibussowitsch - name - option string that is used to activate viewing 928fe2efc57SMark 929fe2efc57SMark Level: intermediate 930bb7acecfSBarry Smith 931bb7acecfSBarry Smith Note: 932bb7acecfSBarry Smith See `PetscObjectViewFromOptions()` for a list of values that can be provided in the options database to determine how the `DM` is viewed 933bb7acecfSBarry Smith 93460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `PetscObjectViewFromOptions()`, `DMCreate()` 935fe2efc57SMark @*/ 936ce78bad3SBarry Smith PetscErrorCode DMViewFromOptions(DM dm, PeOp PetscObject obj, const char name[]) 937d71ae5a4SJacob Faibussowitsch { 938fe2efc57SMark PetscFunctionBegin; 939fe2efc57SMark PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9409566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)dm, obj, name)); 9413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 942fe2efc57SMark } 943fe2efc57SMark 944ffeef943SBarry Smith /*@ 945bb7acecfSBarry Smith DMView - Views a `DM`. Depending on the `PetscViewer` and its `PetscViewerFormat` it may print some ASCII information about the `DM` to the screen or a file or 946bb7acecfSBarry Smith save the `DM` in a binary file to be loaded later or create a visualization of the `DM` 94747c6ae99SBarry Smith 94820f4b53cSBarry Smith Collective 94947c6ae99SBarry Smith 950d8d19677SJose E. Roman Input Parameters: 951bb7acecfSBarry Smith + dm - the `DM` object to view 95247c6ae99SBarry Smith - v - the viewer 95347c6ae99SBarry Smith 954c8a418c4SMatthew G. Knepley Options Database Keys: 955c8a418c4SMatthew G. Knepley + -view_pyvista_warp <f> - Warps the mesh by the active scalar with factor f 956c8a418c4SMatthew G. Knepley - -view_pyvista_clip <xl,xu,yl,yu,zl,zu> - Defines the clipping box 957c8a418c4SMatthew G. Knepley 95820f4b53cSBarry Smith Level: beginner 95920f4b53cSBarry Smith 96049c89c76SBlaise Bourdin Notes: 96149c89c76SBlaise Bourdin 96249c89c76SBlaise Bourdin `PetscViewer` = `PETSCVIEWERHDF5` i.e. HDF5 format can be used with `PETSC_VIEWER_HDF5_PETSC` as the `PetscViewerFormat` to save multiple `DMPLEX` 963bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 964bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 965cd7e8a5eSksagiyam 96649c89c76SBlaise Bourdin `PetscViewer` = `PETSCVIEWEREXODUSII` i.e. ExodusII format assumes that element blocks (mapped to "Cell sets" labels) 96749c89c76SBlaise Bourdin consists of sequentially numbered cells. 96849c89c76SBlaise Bourdin 96949c89c76SBlaise Bourdin If `dm` has been distributed, only the part of the `DM` on MPI rank 0 (including "ghost" cells and vertices) will be written. 97049c89c76SBlaise Bourdin 971c8a418c4SMatthew G. Knepley Only TRI, TET, QUAD, and HEX cells are supported in ExodusII. 97249c89c76SBlaise Bourdin 97349c89c76SBlaise Bourdin `DMPLEX` only represents geometry while most post-processing software expect that a mesh also provides information on the discretization space. This function assumes that the file represents Lagrange finite elements of order 1 or 2. 97449c89c76SBlaise Bourdin The order of the mesh shall be set using `PetscViewerExodusIISetOrder()` 97549c89c76SBlaise Bourdin 976d7c1f440SPierre Jolivet Variable names can be set and queried using `PetscViewerExodusII[Set/Get][Nodal/Zonal]VariableNames[s]`. 97749c89c76SBlaise Bourdin 9781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewer`, `PetscViewerFormat`, `PetscViewerSetFormat()`, `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMLoad()`, `PetscObjectSetName()` 97947c6ae99SBarry Smith @*/ 980d71ae5a4SJacob Faibussowitsch PetscErrorCode DMView(DM dm, PetscViewer v) 981d71ae5a4SJacob Faibussowitsch { 98232c0f0efSBarry Smith PetscBool isbinary; 98376a8abe0SBarry Smith PetscMPIInt size; 98476a8abe0SBarry Smith PetscViewerFormat format; 98547c6ae99SBarry Smith 98647c6ae99SBarry Smith PetscFunctionBegin; 987171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 98848a46eb9SPierre Jolivet if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm), &v)); 989b1b135c8SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 99074903a4fSStefano Zampini /* Ideally, we would like to have this test on. 99174903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 99274903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 99374903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 99474903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 99574903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 99674903a4fSStefano Zampini in an error here */ 99774903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9989566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckWritable(v)); 999b1b135c8SBarry Smith 100042d0c57aSJames Wright PetscCall(PetscLogEventBegin(DM_View, v, 0, 0, 0)); 10019566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(v, &format)); 10029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 10033ba16761SJacob Faibussowitsch if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS); 10049566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)dm, v)); 10059566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERBINARY, &isbinary)); 100632c0f0efSBarry Smith if (isbinary) { 100755849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 100832c0f0efSBarry Smith char type[256]; 100932c0f0efSBarry Smith 10109566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, &classid, 1, PETSC_INT)); 1011c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(type, ((PetscObject)dm)->type_name, sizeof(type))); 10129566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, type, 256, PETSC_CHAR)); 101332c0f0efSBarry Smith } 1014dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, view, v); 101542d0c57aSJames Wright PetscCall(PetscLogEventEnd(DM_View, v, 0, 0, 0)); 10163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 101747c6ae99SBarry Smith } 101847c6ae99SBarry Smith 101947c6ae99SBarry Smith /*@ 1020bb7acecfSBarry Smith DMCreateGlobalVector - Creates a global vector from a `DM` object. A global vector is a parallel vector that has no duplicate values shared between MPI ranks, 1021bb7acecfSBarry Smith that is it has no ghost locations. 102247c6ae99SBarry Smith 102320f4b53cSBarry Smith Collective 102447c6ae99SBarry Smith 102547c6ae99SBarry Smith Input Parameter: 1026bb7acecfSBarry Smith . dm - the `DM` object 102747c6ae99SBarry Smith 102847c6ae99SBarry Smith Output Parameter: 102947c6ae99SBarry Smith . vec - the global vector 103047c6ae99SBarry Smith 1031073dac72SJed Brown Level: beginner 103247c6ae99SBarry Smith 10331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1034bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 103547c6ae99SBarry Smith @*/ 1036d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector(DM dm, Vec *vec) 1037d71ae5a4SJacob Faibussowitsch { 103847c6ae99SBarry Smith PetscFunctionBegin; 1039171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10404f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1041dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createglobalvector, vec); 104276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1043c6b011d8SStefano Zampini DM vdm; 1044c6b011d8SStefano Zampini 10459566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10467a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1047c6b011d8SStefano Zampini } 10483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 104947c6ae99SBarry Smith } 105047c6ae99SBarry Smith 105147c6ae99SBarry Smith /*@ 1052bb7acecfSBarry Smith DMCreateLocalVector - Creates a local vector from a `DM` object. 105347c6ae99SBarry Smith 105447c6ae99SBarry Smith Not Collective 105547c6ae99SBarry Smith 105647c6ae99SBarry Smith Input Parameter: 1057bb7acecfSBarry Smith . dm - the `DM` object 105847c6ae99SBarry Smith 105947c6ae99SBarry Smith Output Parameter: 106047c6ae99SBarry Smith . vec - the local vector 106147c6ae99SBarry Smith 1062073dac72SJed Brown Level: beginner 106347c6ae99SBarry Smith 106420f4b53cSBarry Smith Note: 1065bb7acecfSBarry Smith A local vector usually has ghost locations that contain values that are owned by different MPI ranks. A global vector has no ghost locations. 1066bb7acecfSBarry Smith 10671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateGlobalVector()`, `DMGetLocalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 1068bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 106947c6ae99SBarry Smith @*/ 1070d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector(DM dm, Vec *vec) 1071d71ae5a4SJacob Faibussowitsch { 107247c6ae99SBarry Smith PetscFunctionBegin; 1073171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10744f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1075dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalvector, vec); 107676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1077c6b011d8SStefano Zampini DM vdm; 1078c6b011d8SStefano Zampini 10799566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10807a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_LIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1081c6b011d8SStefano Zampini } 10823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 108347c6ae99SBarry Smith } 108447c6ae99SBarry Smith 10851411c6eeSJed Brown /*@ 1086bb7acecfSBarry Smith DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a `DM`. 10871411c6eeSJed Brown 108820f4b53cSBarry Smith Collective 10891411c6eeSJed Brown 10901411c6eeSJed Brown Input Parameter: 1091bb7acecfSBarry Smith . dm - the `DM` that provides the mapping 10921411c6eeSJed Brown 10931411c6eeSJed Brown Output Parameter: 10941411c6eeSJed Brown . ltog - the mapping 10951411c6eeSJed Brown 1096bb7acecfSBarry Smith Level: advanced 10971411c6eeSJed Brown 10981411c6eeSJed Brown Notes: 1099bb7acecfSBarry Smith The global to local mapping allows one to set values into the global vector or matrix using `VecSetValuesLocal()` and `MatSetValuesLocal()` 11001411c6eeSJed Brown 1101bb7acecfSBarry Smith Vectors obtained with `DMCreateGlobalVector()` and matrices obtained with `DMCreateMatrix()` already contain the global mapping so you do 1102bb7acecfSBarry Smith need to use this function with those objects. 1103bb7acecfSBarry Smith 1104bb7acecfSBarry Smith This mapping can then be used by `VecSetLocalToGlobalMapping()` or `MatSetLocalToGlobalMapping()`. 1105bb7acecfSBarry Smith 110660225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `VecSetLocalToGlobalMapping()`, `MatSetLocalToGlobalMapping()`, 1107bb7acecfSBarry Smith `DMCreateMatrix()` 11081411c6eeSJed Brown @*/ 1109d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalToGlobalMapping(DM dm, ISLocalToGlobalMapping *ltog) 1110d71ae5a4SJacob Faibussowitsch { 11110be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 11121411c6eeSJed Brown 11131411c6eeSJed Brown PetscFunctionBegin; 11141411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11154f572ea9SToby Isaac PetscAssertPointer(ltog, 2); 11161411c6eeSJed Brown if (!dm->ltogmap) { 111737d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 111837d0c07bSMatthew G Knepley 11199566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 112037d0c07bSMatthew G Knepley if (section) { 1121a974ec88SMatthew G. Knepley const PetscInt *cdofs; 112237d0c07bSMatthew G Knepley PetscInt *ltog; 1123ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 112437d0c07bSMatthew G Knepley 11259566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 11269566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 11279566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(section, &n)); 11289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, <og)); /* We want the local+overlap size */ 112937d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1130e6befd46SJed Brown PetscInt bdof, cdof, dof, off, c, cind; 113137d0c07bSMatthew G Knepley 113237d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 11339566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(section, p, &dof)); 11349566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(section, p, &cdof)); 11359566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(section, p, &cdofs)); 11369566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &off)); 11371a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 11381a7dc684SMatthew G. Knepley bdof = cdof && (dof - cdof) ? 1 : dof; 1139ad540459SPierre Jolivet if (dof) bs = bs < 0 ? bdof : PetscGCD(bs, bdof); 11405227eafbSStefano Zampini 1141e6befd46SJed Brown for (c = 0, cind = 0; c < dof; ++c, ++l) { 11425227eafbSStefano Zampini if (cind < cdof && c == cdofs[cind]) { 1143e6befd46SJed Brown ltog[l] = off < 0 ? off - c : -(off + c + 1); 1144e6befd46SJed Brown cind++; 1145e6befd46SJed Brown } else { 11465227eafbSStefano Zampini ltog[l] = (off < 0 ? -(off + 1) : off) + c - cind; 1147e6befd46SJed Brown } 114837d0c07bSMatthew G Knepley } 114937d0c07bSMatthew G Knepley } 1150bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 11511690c2aeSBarry Smith bsLocal[0] = bs < 0 ? PETSC_INT_MAX : bs; 11529371c9d4SSatish Balay bsLocal[1] = bs; 11539566063dSJacob Faibussowitsch PetscCall(PetscGlobalMinMaxInt(PetscObjectComm((PetscObject)dm), bsLocal, bsMinMax)); 11549371c9d4SSatish Balay if (bsMinMax[0] != bsMinMax[1]) { 11559371c9d4SSatish Balay bs = 1; 11569371c9d4SSatish Balay } else { 11579371c9d4SSatish Balay bs = bsMinMax[0]; 11589371c9d4SSatish Balay } 11597591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 11607591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1161ccf3bd66SMatthew G. Knepley if (bs > 1) { 1162ca469d19SJed Brown for (l = 0, k = 0; l < n; l += bs, ++k) { 1163ca469d19SJed Brown // Integer division of negative values truncates toward zero(!), not toward negative infinity 1164ca469d19SJed Brown ltog[k] = ltog[l] >= 0 ? ltog[l] / bs : -(-(ltog[l] + 1) / bs + 1); 1165ca469d19SJed Brown } 1166ccf3bd66SMatthew G. Knepley n /= bs; 1167ccf3bd66SMatthew G. Knepley } 11689566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap)); 1169dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, getlocaltoglobalmapping); 117037d0c07bSMatthew G Knepley } 11711411c6eeSJed Brown *ltog = dm->ltogmap; 11723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11731411c6eeSJed Brown } 11741411c6eeSJed Brown 11751411c6eeSJed Brown /*@ 1176bb7acecfSBarry Smith DMGetBlockSize - Gets the inherent block size associated with a `DM` 11771411c6eeSJed Brown 11781411c6eeSJed Brown Not Collective 11791411c6eeSJed Brown 11801411c6eeSJed Brown Input Parameter: 1181bb7acecfSBarry Smith . dm - the `DM` with block structure 11821411c6eeSJed Brown 11831411c6eeSJed Brown Output Parameter: 11841411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11851411c6eeSJed Brown 11861411c6eeSJed Brown Level: intermediate 11871411c6eeSJed Brown 118873ff1848SBarry Smith Notes: 1189bb7acecfSBarry Smith This might be the number of degrees of freedom at each grid point for a structured grid. 1190bb7acecfSBarry Smith 1191bb7acecfSBarry Smith Complex `DM` that represent multiphysics or staggered grids or mixed-methods do not generally have a single inherent block size, but 1192bb7acecfSBarry Smith rather different locations in the vectors may have a different block size. 1193bb7acecfSBarry Smith 11941cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISCreateBlock()`, `VecSetBlockSize()`, `MatSetBlockSize()`, `DMGetLocalToGlobalMapping()` 11951411c6eeSJed Brown @*/ 1196d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBlockSize(DM dm, PetscInt *bs) 1197d71ae5a4SJacob Faibussowitsch { 11981411c6eeSJed Brown PetscFunctionBegin; 11991411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12004f572ea9SToby Isaac PetscAssertPointer(bs, 2); 12017a8be351SBarry Smith PetscCheck(dm->bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM does not have enough information to provide a block size yet"); 12021411c6eeSJed Brown *bs = dm->bs; 12033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12041411c6eeSJed Brown } 12051411c6eeSJed Brown 1206ffeef943SBarry Smith /*@ 1207bb7acecfSBarry Smith DMCreateInterpolation - Gets the interpolation matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1208bb7acecfSBarry Smith `DMCreateGlobalVector()` on the coarse `DM` to similar vectors on the fine grid `DM`. 120947c6ae99SBarry Smith 121020f4b53cSBarry Smith Collective 121147c6ae99SBarry Smith 1212d8d19677SJose E. Roman Input Parameters: 1213bb7acecfSBarry Smith + dmc - the `DM` object 1214bb7acecfSBarry Smith - dmf - the second, finer `DM` object 121547c6ae99SBarry Smith 1216d8d19677SJose E. Roman Output Parameters: 121747c6ae99SBarry Smith + mat - the interpolation 1218b6971eaeSBarry Smith - vec - the scaling (optional, pass `NULL` if not needed), see `DMCreateInterpolationScale()` 121947c6ae99SBarry Smith 122047c6ae99SBarry Smith Level: developer 122147c6ae99SBarry Smith 122295452b02SPatrick Sanan Notes: 1223bb7acecfSBarry Smith For `DMDA` objects this only works for "uniform refinement", that is the refined mesh was obtained `DMRefine()` or the coarse mesh was obtained by 1224bb7acecfSBarry Smith DMCoarsen(). The coordinates set into the `DMDA` are completely ignored in computing the interpolation. 1225d52bd9f3SBarry Smith 1226bb7acecfSBarry Smith For `DMDA` objects you can use this interpolation (more precisely the interpolation from the `DMGetCoordinateDM()`) to interpolate the mesh coordinate 1227bb7acecfSBarry Smith vectors EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 122885afcc9aSBarry Smith 12291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolationScale()` 123047c6ae99SBarry Smith @*/ 1231d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolation(DM dmc, DM dmf, Mat *mat, Vec *vec) 1232d71ae5a4SJacob Faibussowitsch { 123347c6ae99SBarry Smith PetscFunctionBegin; 1234a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1235a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 12364f572ea9SToby Isaac PetscAssertPointer(mat, 3); 12379566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInterpolation, dmc, dmf, 0, 0)); 1238dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createinterpolation, dmf, mat, vec); 12399566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInterpolation, dmc, dmf, 0, 0)); 12403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 124147c6ae99SBarry Smith } 124247c6ae99SBarry Smith 12433ad4599aSBarry Smith /*@ 1244a4e35b19SJacob Faibussowitsch DMCreateInterpolationScale - Forms L = 1/(R*1) where 1 is the vector of all ones, and R is 1245a4e35b19SJacob Faibussowitsch the transpose of the interpolation between the `DM`. 12462ed6491fSPatrick Sanan 12472ed6491fSPatrick Sanan Input Parameters: 1248bb7acecfSBarry Smith + dac - `DM` that defines a coarse mesh 1249bb7acecfSBarry Smith . daf - `DM` that defines a fine mesh 12502ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 12512ed6491fSPatrick Sanan 12522ed6491fSPatrick Sanan Output Parameter: 12532ed6491fSPatrick Sanan . scale - the scaled vector 12542ed6491fSPatrick Sanan 1255bb7acecfSBarry Smith Level: advanced 12562ed6491fSPatrick Sanan 125773ff1848SBarry Smith Note: 1258a4e35b19SJacob Faibussowitsch xcoarse = diag(L)*R*xfine preserves scale and is thus suitable for state (versus residual) 1259a4e35b19SJacob Faibussowitsch restriction. In other words xcoarse is the coarse representation of xfine. 1260a4e35b19SJacob Faibussowitsch 126173ff1848SBarry Smith Developer Note: 1262bb7acecfSBarry Smith If the fine-scale `DMDA` has the -dm_bind_below option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 1263e9c74fd6SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 1264e9c74fd6SRichard Tran Mills 126560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `MatRestrict()`, `MatInterpolate()`, `DMCreateInterpolation()`, `DMCreateRestriction()`, `DMCreateGlobalVector()` 12662ed6491fSPatrick Sanan @*/ 1267d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolationScale(DM dac, DM daf, Mat mat, Vec *scale) 1268d71ae5a4SJacob Faibussowitsch { 12692ed6491fSPatrick Sanan Vec fine; 12702ed6491fSPatrick Sanan PetscScalar one = 1.0; 12719704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 1272e9c74fd6SRichard Tran Mills PetscBool bindingpropagates, isbound; 12739704db99SRichard Tran Mills #endif 12742ed6491fSPatrick Sanan 12752ed6491fSPatrick Sanan PetscFunctionBegin; 12769566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(daf, &fine)); 12779566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dac, scale)); 12789566063dSJacob Faibussowitsch PetscCall(VecSet(fine, one)); 12799704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 12809704db99SRichard Tran Mills /* If the 'fine' Vec is bound to the CPU, it makes sense to bind 'mat' as well. 12819704db99SRichard Tran Mills * Note that we only do this for the CUDA case, right now, but if we add support for MatMultTranspose() via ViennaCL, 12829704db99SRichard Tran Mills * we'll need to do it for that case, too.*/ 12839566063dSJacob Faibussowitsch PetscCall(VecGetBindingPropagates(fine, &bindingpropagates)); 1284e9c74fd6SRichard Tran Mills if (bindingpropagates) { 12859566063dSJacob Faibussowitsch PetscCall(MatSetBindingPropagates(mat, PETSC_TRUE)); 12869566063dSJacob Faibussowitsch PetscCall(VecBoundToCPU(fine, &isbound)); 12879566063dSJacob Faibussowitsch PetscCall(MatBindToCPU(mat, isbound)); 128883aa49f4SRichard Tran Mills } 12899704db99SRichard Tran Mills #endif 12909566063dSJacob Faibussowitsch PetscCall(MatRestrict(mat, fine, *scale)); 12919566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fine)); 12929566063dSJacob Faibussowitsch PetscCall(VecReciprocal(*scale)); 12933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12942ed6491fSPatrick Sanan } 12952ed6491fSPatrick Sanan 12962ed6491fSPatrick Sanan /*@ 1297bb7acecfSBarry Smith DMCreateRestriction - Gets restriction matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1298bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine `DM` to similar vectors on the coarse grid `DM`. 12993ad4599aSBarry Smith 130020f4b53cSBarry Smith Collective 13013ad4599aSBarry Smith 1302d8d19677SJose E. Roman Input Parameters: 1303bb7acecfSBarry Smith + dmc - the `DM` object 1304bb7acecfSBarry Smith - dmf - the second, finer `DM` object 13053ad4599aSBarry Smith 13063ad4599aSBarry Smith Output Parameter: 13073ad4599aSBarry Smith . mat - the restriction 13083ad4599aSBarry Smith 13093ad4599aSBarry Smith Level: developer 13103ad4599aSBarry Smith 1311bb7acecfSBarry Smith Note: 1312bb7acecfSBarry Smith This only works for `DMSTAG`. For many situations either the transpose of the operator obtained with `DMCreateInterpolation()` or that 1313bb7acecfSBarry Smith matrix multiplied by the vector obtained with `DMCreateInterpolationScale()` provides the desired object. 13143ad4599aSBarry Smith 13151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRestrict()`, `DMInterpolate()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateInterpolation()` 13163ad4599aSBarry Smith @*/ 1317d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateRestriction(DM dmc, DM dmf, Mat *mat) 1318d71ae5a4SJacob Faibussowitsch { 13193ad4599aSBarry Smith PetscFunctionBegin; 1320a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1321a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13224f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13239566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateRestriction, dmc, dmf, 0, 0)); 1324dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createrestriction, dmf, mat); 13259566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateRestriction, dmc, dmf, 0, 0)); 13263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13273ad4599aSBarry Smith } 13283ad4599aSBarry Smith 132947c6ae99SBarry Smith /*@ 1330a4e35b19SJacob Faibussowitsch DMCreateInjection - Gets injection matrix between two `DM` objects. 133147c6ae99SBarry Smith 133220f4b53cSBarry Smith Collective 133347c6ae99SBarry Smith 1334d8d19677SJose E. Roman Input Parameters: 1335bb7acecfSBarry Smith + dac - the `DM` object 1336bb7acecfSBarry Smith - daf - the second, finer `DM` object 133747c6ae99SBarry Smith 133847c6ae99SBarry Smith Output Parameter: 13396dbf9973SLawrence Mitchell . mat - the injection 134047c6ae99SBarry Smith 134147c6ae99SBarry Smith Level: developer 134247c6ae99SBarry Smith 1343a4e35b19SJacob Faibussowitsch Notes: 1344a4e35b19SJacob Faibussowitsch This is an operator that applied to a vector obtained with `DMCreateGlobalVector()` on the 1345a4e35b19SJacob Faibussowitsch fine grid maps the values to a vector on the vector on the coarse `DM` by simply selecting 1346a4e35b19SJacob Faibussowitsch the values on the coarse grid points. This compares to the operator obtained by 1347a4e35b19SJacob Faibussowitsch `DMCreateRestriction()` or the transpose of the operator obtained by 1348a4e35b19SJacob Faibussowitsch `DMCreateInterpolation()` that uses a "local weighted average" of the values around the 1349a4e35b19SJacob Faibussowitsch coarse grid point as the coarse grid value. 1350a4e35b19SJacob Faibussowitsch 1351bb7acecfSBarry Smith For `DMDA` objects this only works for "uniform refinement", that is the refined mesh was obtained `DMRefine()` or the coarse mesh was obtained by 1352bb7acecfSBarry Smith `DMCoarsen()`. The coordinates set into the `DMDA` are completely ignored in computing the injection. 135385afcc9aSBarry Smith 13541cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateInterpolation()`, 1355bb7acecfSBarry Smith `DMCreateRestriction()`, `MatRestrict()`, `MatInterpolate()` 135647c6ae99SBarry Smith @*/ 1357d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInjection(DM dac, DM daf, Mat *mat) 1358d71ae5a4SJacob Faibussowitsch { 135947c6ae99SBarry Smith PetscFunctionBegin; 1360a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac, DM_CLASSID, 1); 1361a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf, DM_CLASSID, 2); 13624f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13639566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInjection, dac, daf, 0, 0)); 1364dbbe0bcdSBarry Smith PetscUseTypeMethod(dac, createinjection, daf, mat); 13659566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInjection, dac, daf, 0, 0)); 13663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 136747c6ae99SBarry Smith } 136847c6ae99SBarry Smith 1369b412c318SBarry Smith /*@ 1370bb7acecfSBarry Smith DMCreateMassMatrix - Gets the mass matrix between two `DM` objects, M_ij = \int \phi_i \psi_j where the \phi are Galerkin basis functions for a 1371bb7acecfSBarry Smith a Galerkin finite element model on the `DM` 1372bd041c0cSMatthew G. Knepley 137320f4b53cSBarry Smith Collective 1374bd041c0cSMatthew G. Knepley 1375d8d19677SJose E. Roman Input Parameters: 1376bb7acecfSBarry Smith + dmc - the target `DM` object 13778c1c0954SStefano Zampini - dmf - the source `DM` object, can be `NULL` 1378bd041c0cSMatthew G. Knepley 1379bd041c0cSMatthew G. Knepley Output Parameter: 1380b4937a87SMatthew G. Knepley . mat - the mass matrix 1381bd041c0cSMatthew G. Knepley 1382bd041c0cSMatthew G. Knepley Level: developer 1383bd041c0cSMatthew G. Knepley 1384bb7acecfSBarry Smith Notes: 1385bb7acecfSBarry Smith For `DMPLEX` the finite element model for the `DM` must have been already provided. 1386bb7acecfSBarry Smith 13878c1c0954SStefano Zampini if `dmc` is `dmf` or `NULL`, then x^t M x is an approximation to the L2 norm of the vector x which is obtained by `DMCreateGlobalVector()` 1388bb7acecfSBarry Smith 138942747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrixLumped()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1390bd041c0cSMatthew G. Knepley @*/ 1391d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrix(DM dmc, DM dmf, Mat *mat) 1392d71ae5a4SJacob Faibussowitsch { 1393bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1394b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 13958c1c0954SStefano Zampini if (!dmf) dmf = dmc; 1396b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13974f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13988c1c0954SStefano Zampini PetscCall(PetscLogEventBegin(DM_CreateMassMatrix, dmc, dmf, 0, 0)); 1399dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createmassmatrix, dmf, mat); 14008c1c0954SStefano Zampini PetscCall(PetscLogEventEnd(DM_CreateMassMatrix, dmc, dmf, 0, 0)); 14013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1402b4937a87SMatthew G. Knepley } 1403b4937a87SMatthew G. Knepley 1404b4937a87SMatthew G. Knepley /*@ 1405bb7acecfSBarry Smith DMCreateMassMatrixLumped - Gets the lumped mass matrix for a given `DM` 1406b4937a87SMatthew G. Knepley 140720f4b53cSBarry Smith Collective 1408b4937a87SMatthew G. Knepley 1409b4937a87SMatthew G. Knepley Input Parameter: 1410bb7acecfSBarry Smith . dm - the `DM` object 1411b4937a87SMatthew G. Knepley 14127dcfde4dSJose E. Roman Output Parameters: 14138e9849d2SStefano Zampini + llm - the local lumped mass matrix, which is a diagonal matrix, represented as a vector 14148e9849d2SStefano Zampini - lm - the global lumped mass matrix, which is a diagonal matrix, represented as a vector 1415b4937a87SMatthew G. Knepley 1416b4937a87SMatthew G. Knepley Level: developer 1417b4937a87SMatthew G. Knepley 1418bb7acecfSBarry Smith Note: 1419bb7acecfSBarry Smith See `DMCreateMassMatrix()` for how to create the non-lumped version of the mass matrix. 1420bb7acecfSBarry Smith 142160225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrix()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1422b4937a87SMatthew G. Knepley @*/ 14238e9849d2SStefano Zampini PetscErrorCode DMCreateMassMatrixLumped(DM dm, Vec *llm, Vec *lm) 1424d71ae5a4SJacob Faibussowitsch { 1425b4937a87SMatthew G. Knepley PetscFunctionBegin; 1426b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14278e9849d2SStefano Zampini if (llm) PetscAssertPointer(llm, 2); 14288e9849d2SStefano Zampini if (lm) PetscAssertPointer(lm, 3); 14298e9849d2SStefano Zampini if (llm || lm) PetscUseTypeMethod(dm, createmassmatrixlumped, llm, lm); 14303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1431bd041c0cSMatthew G. Knepley } 1432bd041c0cSMatthew G. Knepley 1433bd041c0cSMatthew G. Knepley /*@ 1434bb7acecfSBarry Smith DMCreateColoring - Gets coloring of a graph associated with the `DM`. Often the graph represents the operator matrix associated with the discretization 1435bb7acecfSBarry Smith of a PDE on the `DM`. 143647c6ae99SBarry Smith 143720f4b53cSBarry Smith Collective 143847c6ae99SBarry Smith 1439d8d19677SJose E. Roman Input Parameters: 1440bb7acecfSBarry Smith + dm - the `DM` object 1441bb7acecfSBarry Smith - ctype - `IS_COLORING_LOCAL` or `IS_COLORING_GLOBAL` 144247c6ae99SBarry Smith 144347c6ae99SBarry Smith Output Parameter: 144447c6ae99SBarry Smith . coloring - the coloring 144547c6ae99SBarry Smith 14461bf8429eSBarry Smith Level: developer 14471bf8429eSBarry Smith 1448ec5066bdSBarry Smith Notes: 1449bb7acecfSBarry Smith Coloring of matrices can also be computed directly from the sparse matrix nonzero structure via the `MatColoring` object or from the mesh from which the 1450bb7acecfSBarry Smith matrix comes from (what this function provides). In general using the mesh produces a more optimal coloring (fewer colors). 1451ec5066bdSBarry Smith 1452bb7acecfSBarry Smith This produces a coloring with the distance of 2, see `MatSetColoringDistance()` which can be used for efficiently computing Jacobians with `MatFDColoringCreate()` 14531bf8429eSBarry Smith For `DMDA` in three dimensions with periodic boundary conditions the number of grid points in each dimension must be divisible by 2*stencil_width + 1, 14541bf8429eSBarry Smith otherwise an error will be generated. 1455ec5066bdSBarry Smith 14561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISColoring`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatType()`, `MatColoring`, `MatFDColoringCreate()` 1457aab9d709SJed Brown @*/ 1458d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateColoring(DM dm, ISColoringType ctype, ISColoring *coloring) 1459d71ae5a4SJacob Faibussowitsch { 146047c6ae99SBarry Smith PetscFunctionBegin; 1461171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14624f572ea9SToby Isaac PetscAssertPointer(coloring, 3); 1463dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getcoloring, ctype, coloring); 14643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 146547c6ae99SBarry Smith } 146647c6ae99SBarry Smith 1467b412c318SBarry Smith /*@ 1468bb7acecfSBarry Smith DMCreateMatrix - Gets an empty matrix for a `DM` that is most commonly used to store the Jacobian of a discrete PDE operator. 146947c6ae99SBarry Smith 147020f4b53cSBarry Smith Collective 147147c6ae99SBarry Smith 147247c6ae99SBarry Smith Input Parameter: 1473bb7acecfSBarry Smith . dm - the `DM` object 147447c6ae99SBarry Smith 147547c6ae99SBarry Smith Output Parameter: 147647c6ae99SBarry Smith . mat - the empty Jacobian 147747c6ae99SBarry Smith 147820f4b53cSBarry Smith Options Database Key: 1479bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 1480f27dd7c6SMatthew G. Knepley 148120f4b53cSBarry Smith Level: beginner 148220f4b53cSBarry Smith 148395452b02SPatrick Sanan Notes: 148495452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 148594013140SBarry Smith do not need to do it yourself. 148694013140SBarry Smith 148794013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 1488bb7acecfSBarry Smith the nonzero pattern call `DMSetMatrixPreallocateOnly()` 148994013140SBarry Smith 1490bb7acecfSBarry Smith For `DMDA`, when you call `MatView()` on this matrix it is displayed using the global natural ordering, NOT in the ordering used 149194013140SBarry Smith internally by PETSc. 149294013140SBarry Smith 1493bb7acecfSBarry Smith For `DMDA`, in general it is easiest to use `MatSetValuesStencil()` or `MatSetValuesLocal()` to put values into the matrix because 1494bb7acecfSBarry Smith `MatSetValues()` requires the indices for the global numbering for the `DMDA` which is complic`ated to compute 149594013140SBarry Smith 14961cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMSetMatType()`, `DMCreateMassMatrix()` 1497aab9d709SJed Brown @*/ 1498d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMatrix(DM dm, Mat *mat) 1499d71ae5a4SJacob Faibussowitsch { 150047c6ae99SBarry Smith PetscFunctionBegin; 1501171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 15024f572ea9SToby Isaac PetscAssertPointer(mat, 2); 15039566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 15049566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateMatrix, 0, 0, 0, 0)); 1505dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, creatematrix, mat); 150676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1507c6b011d8SStefano Zampini DM mdm; 1508c6b011d8SStefano Zampini 15099566063dSJacob Faibussowitsch PetscCall(MatGetDM(*mat, &mdm)); 15107a8be351SBarry Smith PetscCheck(mdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the matrix", ((PetscObject)dm)->type_name); 1511c6b011d8SStefano Zampini } 1512e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1513e5e52638SMatthew G. Knepley if (dm->Nf) { 1514e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1515649ef022SMatthew Knepley PetscInt Nf, f; 1516e571a35bSMatthew G. Knepley 15179566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1518649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1519649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 15209566063dSJacob Faibussowitsch PetscCall((*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace)); 15219566063dSJacob Faibussowitsch PetscCall(MatSetNullSpace(*mat, nullSpace)); 15229566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1523649ef022SMatthew Knepley break; 1524e571a35bSMatthew G. Knepley } 1525649ef022SMatthew Knepley } 1526649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1527649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 15289566063dSJacob Faibussowitsch PetscCall((*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace)); 15299566063dSJacob Faibussowitsch PetscCall(MatSetNearNullSpace(*mat, nullSpace)); 15309566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1531e571a35bSMatthew G. Knepley } 1532e571a35bSMatthew G. Knepley } 1533e571a35bSMatthew G. Knepley } 15349566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateMatrix, 0, 0, 0, 0)); 15353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 153647c6ae99SBarry Smith } 153747c6ae99SBarry Smith 1538732e2eb9SMatthew G Knepley /*@ 1539a4e35b19SJacob Faibussowitsch DMSetMatrixPreallocateSkip - When `DMCreateMatrix()` is called the matrix sizes and 1540a4e35b19SJacob Faibussowitsch `ISLocalToGlobalMapping` will be properly set, but the data structures to store values in the 1541a4e35b19SJacob Faibussowitsch matrices will not be preallocated. 1542aa0f6e3cSJed Brown 154320f4b53cSBarry Smith Logically Collective 1544aa0f6e3cSJed Brown 1545aa0f6e3cSJed Brown Input Parameters: 1546bb7acecfSBarry Smith + dm - the `DM` 1547bb7acecfSBarry Smith - skip - `PETSC_TRUE` to skip preallocation 1548aa0f6e3cSJed Brown 1549aa0f6e3cSJed Brown Level: developer 1550aa0f6e3cSJed Brown 155173ff1848SBarry Smith Note: 1552a4e35b19SJacob Faibussowitsch This is most useful to reduce initialization costs when `MatSetPreallocationCOO()` and 1553a4e35b19SJacob Faibussowitsch `MatSetValuesCOO()` will be used. 1554a4e35b19SJacob Faibussowitsch 15551cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateOnly()` 1556aa0f6e3cSJed Brown @*/ 1557d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateSkip(DM dm, PetscBool skip) 1558d71ae5a4SJacob Faibussowitsch { 1559aa0f6e3cSJed Brown PetscFunctionBegin; 1560aa0f6e3cSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1561aa0f6e3cSJed Brown dm->prealloc_skip = skip; 15623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1563aa0f6e3cSJed Brown } 1564aa0f6e3cSJed Brown 1565aa0f6e3cSJed Brown /*@ 1566bb7acecfSBarry Smith DMSetMatrixPreallocateOnly - When `DMCreateMatrix()` is called the matrix will be properly 1567732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1568732e2eb9SMatthew G Knepley 156920f4b53cSBarry Smith Logically Collective 1570732e2eb9SMatthew G Knepley 1571d8d19677SJose E. Roman Input Parameters: 1572bb7acecfSBarry Smith + dm - the `DM` 1573bb7acecfSBarry Smith - only - `PETSC_TRUE` if only want preallocation 1574732e2eb9SMatthew G Knepley 157520f4b53cSBarry Smith Options Database Key: 1576bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()`, `DMCreateMassMatrix()`, but do not fill it with zeros 1577f27dd7c6SMatthew G. Knepley 157820f4b53cSBarry Smith Level: developer 157920f4b53cSBarry Smith 15801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateSkip()` 1581732e2eb9SMatthew G Knepley @*/ 1582d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1583d71ae5a4SJacob Faibussowitsch { 1584732e2eb9SMatthew G Knepley PetscFunctionBegin; 1585732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1586732e2eb9SMatthew G Knepley dm->prealloc_only = only; 15873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1588732e2eb9SMatthew G Knepley } 1589732e2eb9SMatthew G Knepley 1590b06ff27eSHong Zhang /*@ 15910b4b7b1cSBarry Smith DMSetMatrixStructureOnly - When `DMCreateMatrix()` is called, the matrix nonzero structure will be created 1592bb7acecfSBarry Smith but the array for numerical values will not be allocated. 1593b06ff27eSHong Zhang 159420f4b53cSBarry Smith Logically Collective 1595b06ff27eSHong Zhang 1596d8d19677SJose E. Roman Input Parameters: 1597bb7acecfSBarry Smith + dm - the `DM` 15980b4b7b1cSBarry Smith - only - `PETSC_TRUE` if you only want matrix nonzero structure 1599b06ff27eSHong Zhang 1600b06ff27eSHong Zhang Level: developer 1601bb7acecfSBarry Smith 16021cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMSetMatrixPreallocateSkip()` 1603b06ff27eSHong Zhang @*/ 1604d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1605d71ae5a4SJacob Faibussowitsch { 1606b06ff27eSHong Zhang PetscFunctionBegin; 1607b06ff27eSHong Zhang PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1608b06ff27eSHong Zhang dm->structure_only = only; 16093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1610b06ff27eSHong Zhang } 1611b06ff27eSHong Zhang 1612863027abSJed Brown /*@ 1613863027abSJed Brown DMSetBlockingType - set the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1614863027abSJed Brown 161520f4b53cSBarry Smith Logically Collective 1616863027abSJed Brown 1617863027abSJed Brown Input Parameters: 1618863027abSJed Brown + dm - the `DM` 1619863027abSJed Brown - btype - block by topological point or field node 1620863027abSJed Brown 162120f4b53cSBarry Smith Options Database Key: 16220e762ea3SJed Brown . -dm_blocking_type [topological_point, field_node] - use topological point blocking or field node blocking 1623863027abSJed Brown 162420f4b53cSBarry Smith Level: advanced 162520f4b53cSBarry Smith 16261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1627863027abSJed Brown @*/ 1628863027abSJed Brown PetscErrorCode DMSetBlockingType(DM dm, DMBlockingType btype) 1629863027abSJed Brown { 1630863027abSJed Brown PetscFunctionBegin; 1631863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1632863027abSJed Brown dm->blocking_type = btype; 16333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1634863027abSJed Brown } 1635863027abSJed Brown 1636863027abSJed Brown /*@ 1637863027abSJed Brown DMGetBlockingType - get the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1638863027abSJed Brown 1639863027abSJed Brown Not Collective 1640863027abSJed Brown 16412fe279fdSBarry Smith Input Parameter: 1642863027abSJed Brown . dm - the `DM` 1643863027abSJed Brown 16442fe279fdSBarry Smith Output Parameter: 1645863027abSJed Brown . btype - block by topological point or field node 1646863027abSJed Brown 1647863027abSJed Brown Level: advanced 1648863027abSJed Brown 16491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1650863027abSJed Brown @*/ 1651863027abSJed Brown PetscErrorCode DMGetBlockingType(DM dm, DMBlockingType *btype) 1652863027abSJed Brown { 1653863027abSJed Brown PetscFunctionBegin; 1654863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16554f572ea9SToby Isaac PetscAssertPointer(btype, 2); 1656863027abSJed Brown *btype = dm->blocking_type; 16573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1658863027abSJed Brown } 1659863027abSJed Brown 1660a89ea682SMatthew G Knepley /*@C 1661bb7acecfSBarry Smith DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with `DMRestoreWorkArray()` 1662a89ea682SMatthew G Knepley 1663a89ea682SMatthew G Knepley Not Collective 1664a89ea682SMatthew G Knepley 1665a89ea682SMatthew G Knepley Input Parameters: 1666bb7acecfSBarry Smith + dm - the `DM` object 1667a5b23f4aSJose E. Roman . count - The minimum size 166820f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, or `MPIU_INT`) 1669a89ea682SMatthew G Knepley 1670a89ea682SMatthew G Knepley Output Parameter: 167160225df5SJacob Faibussowitsch . mem - the work array 1672a89ea682SMatthew G Knepley 1673a89ea682SMatthew G Knepley Level: developer 1674a89ea682SMatthew G Knepley 167573ff1848SBarry Smith Notes: 1676da81f932SPierre Jolivet A `DM` may stash the array between instantiations so using this routine may be more efficient than calling `PetscMalloc()` 1677bb7acecfSBarry Smith 1678bb7acecfSBarry Smith The array may contain nonzero values 1679bb7acecfSBarry Smith 16801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMRestoreWorkArray()`, `PetscMalloc()` 1681a89ea682SMatthew G Knepley @*/ 1682d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1683d71ae5a4SJacob Faibussowitsch { 1684aa1993deSMatthew G Knepley DMWorkLink link; 168569291d52SBarry Smith PetscMPIInt dsize; 1686a89ea682SMatthew G Knepley 1687a89ea682SMatthew G Knepley PetscFunctionBegin; 1688a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16894f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1690442f3b32SStefano Zampini if (!count) { 1691442f3b32SStefano Zampini *(void **)mem = NULL; 1692442f3b32SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 1693442f3b32SStefano Zampini } 1694aa1993deSMatthew G Knepley if (dm->workin) { 1695aa1993deSMatthew G Knepley link = dm->workin; 1696aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1697aa1993deSMatthew G Knepley } else { 16984dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&link)); 1699a89ea682SMatthew G Knepley } 1700b77fa653SStefano Zampini /* Avoid MPI_Type_size for most used datatypes 1701b77fa653SStefano Zampini Get size directly */ 1702b77fa653SStefano Zampini if (dtype == MPIU_INT) dsize = sizeof(PetscInt); 1703b77fa653SStefano Zampini else if (dtype == MPIU_REAL) dsize = sizeof(PetscReal); 1704b77fa653SStefano Zampini #if defined(PETSC_USE_64BIT_INDICES) 1705b77fa653SStefano Zampini else if (dtype == MPI_INT) dsize = sizeof(int); 1706b77fa653SStefano Zampini #endif 1707b77fa653SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1708b77fa653SStefano Zampini else if (dtype == MPIU_SCALAR) dsize = sizeof(PetscScalar); 1709b77fa653SStefano Zampini #endif 1710b77fa653SStefano Zampini else PetscCallMPI(MPI_Type_size(dtype, &dsize)); 1711b77fa653SStefano Zampini 17125056fcd2SBarry Smith if (((size_t)dsize * count) > link->bytes) { 17139566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 17149566063dSJacob Faibussowitsch PetscCall(PetscMalloc(dsize * count, &link->mem)); 1715854ce69bSBarry Smith link->bytes = dsize * count; 1716aa1993deSMatthew G Knepley } 1717aa1993deSMatthew G Knepley link->next = dm->workout; 1718aa1993deSMatthew G Knepley dm->workout = link; 1719aa1993deSMatthew G Knepley *(void **)mem = link->mem; 17203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1721a89ea682SMatthew G Knepley } 1722a89ea682SMatthew G Knepley 1723aa1993deSMatthew G Knepley /*@C 1724bb7acecfSBarry Smith DMRestoreWorkArray - Restores a work array obtained with `DMCreateWorkArray()` 1725aa1993deSMatthew G Knepley 1726aa1993deSMatthew G Knepley Not Collective 1727aa1993deSMatthew G Knepley 1728aa1993deSMatthew G Knepley Input Parameters: 1729bb7acecfSBarry Smith + dm - the `DM` object 1730a5b23f4aSJose E. Roman . count - The minimum size 173120f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_INT` 1732aa1993deSMatthew G Knepley 1733aa1993deSMatthew G Knepley Output Parameter: 173460225df5SJacob Faibussowitsch . mem - the work array 1735aa1993deSMatthew G Knepley 1736aa1993deSMatthew G Knepley Level: developer 1737aa1993deSMatthew G Knepley 173873ff1848SBarry Smith Developer Note: 1739bb7acecfSBarry Smith count and dtype are ignored, they are only needed for `DMGetWorkArray()` 1740147403d9SBarry Smith 17411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMGetWorkArray()` 1742aa1993deSMatthew G Knepley @*/ 1743d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1744d71ae5a4SJacob Faibussowitsch { 1745aa1993deSMatthew G Knepley DMWorkLink *p, link; 1746aa1993deSMatthew G Knepley 1747aa1993deSMatthew G Knepley PetscFunctionBegin; 17484f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1749a4e35b19SJacob Faibussowitsch (void)count; 1750a4e35b19SJacob Faibussowitsch (void)dtype; 1751442f3b32SStefano Zampini if (!*(void **)mem) PetscFunctionReturn(PETSC_SUCCESS); 1752aa1993deSMatthew G Knepley for (p = &dm->workout; (link = *p); p = &link->next) { 1753aa1993deSMatthew G Knepley if (link->mem == *(void **)mem) { 1754aa1993deSMatthew G Knepley *p = link->next; 1755aa1993deSMatthew G Knepley link->next = dm->workin; 1756aa1993deSMatthew G Knepley dm->workin = link; 17570298fd71SBarry Smith *(void **)mem = NULL; 17583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1759aa1993deSMatthew G Knepley } 1760aa1993deSMatthew G Knepley } 1761aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Array was not checked out"); 1762aa1993deSMatthew G Knepley } 1763e7c4fc90SDmitry Karpeev 17648cda7954SMatthew G. Knepley /*@C 1765bb7acecfSBarry Smith DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field, defined with `DMAddField()`, when function spaces 1766bb7acecfSBarry Smith are joined or split, such as in `DMCreateSubDM()` 17678cda7954SMatthew G. Knepley 176820f4b53cSBarry Smith Logically Collective; No Fortran Support 17698cda7954SMatthew G. Knepley 17708cda7954SMatthew G. Knepley Input Parameters: 1771bb7acecfSBarry Smith + dm - The `DM` 17728cda7954SMatthew G. Knepley . field - The field number for the nullspace 17738cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 17748cda7954SMatthew G. Knepley 177520f4b53cSBarry Smith Calling sequence of `nullsp`: 1776bb7acecfSBarry Smith + dm - The present `DM` 1777bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1778147403d9SBarry Smith . field - The field number in dm 1779147403d9SBarry Smith - nullSpace - The nullspace for the given field 17808cda7954SMatthew G. Knepley 178149762cbcSSatish Balay Level: intermediate 178249762cbcSSatish Balay 17831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1784147403d9SBarry Smith @*/ 1785a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1786d71ae5a4SJacob Faibussowitsch { 1787435a35e8SMatthew G Knepley PetscFunctionBegin; 1788435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17897a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1790435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 17913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1792435a35e8SMatthew G Knepley } 1793435a35e8SMatthew G Knepley 17948cda7954SMatthew G. Knepley /*@C 1795bb7acecfSBarry Smith DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, defined with `DMAddField()` 17968cda7954SMatthew G. Knepley 179720f4b53cSBarry Smith Not Collective; No Fortran Support 17988cda7954SMatthew G. Knepley 17998cda7954SMatthew G. Knepley Input Parameters: 1800bb7acecfSBarry Smith + dm - The `DM` 18018cda7954SMatthew G. Knepley - field - The field number for the nullspace 18028cda7954SMatthew G. Knepley 18038cda7954SMatthew G. Knepley Output Parameter: 18048cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 18058cda7954SMatthew G. Knepley 180620f4b53cSBarry Smith Calling sequence of `nullsp`: 1807147403d9SBarry Smith + dm - The present DM 1808147403d9SBarry Smith . origField - The field number given above, in the original DM 1809147403d9SBarry Smith . field - The field number in dm 1810147403d9SBarry Smith - nullSpace - The nullspace for the given field 18118cda7954SMatthew G. Knepley 181249762cbcSSatish Balay Level: intermediate 181349762cbcSSatish Balay 18141cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1815147403d9SBarry Smith @*/ 1816a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1817d71ae5a4SJacob Faibussowitsch { 18180a50eb56SMatthew G. Knepley PetscFunctionBegin; 18190a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18204f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 18217a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 18220a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 18233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18240a50eb56SMatthew G. Knepley } 18250a50eb56SMatthew G. Knepley 18268cda7954SMatthew G. Knepley /*@C 1827bb7acecfSBarry Smith DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 18288cda7954SMatthew G. Knepley 182920f4b53cSBarry Smith Logically Collective; No Fortran Support 18308cda7954SMatthew G. Knepley 18318cda7954SMatthew G. Knepley Input Parameters: 1832bb7acecfSBarry Smith + dm - The `DM` 18338cda7954SMatthew G. Knepley . field - The field number for the nullspace 18348cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 18358cda7954SMatthew G. Knepley 183620f4b53cSBarry Smith Calling sequence of `nullsp`: 1837bb7acecfSBarry Smith + dm - The present `DM` 1838bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1839147403d9SBarry Smith . field - The field number in dm 1840147403d9SBarry Smith - nullSpace - The nullspace for the given field 18418cda7954SMatthew G. Knepley 184249762cbcSSatish Balay Level: intermediate 184349762cbcSSatish Balay 18441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()`, 1845bb7acecfSBarry Smith `MatNullSpace` 1846147403d9SBarry Smith @*/ 1847a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1848d71ae5a4SJacob Faibussowitsch { 1849f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1850f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18517a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1852f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 18533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1854f9d4088aSMatthew G. Knepley } 1855f9d4088aSMatthew G. Knepley 18568cda7954SMatthew G. Knepley /*@C 1857bb7acecfSBarry Smith DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 18588cda7954SMatthew G. Knepley 185920f4b53cSBarry Smith Not Collective; No Fortran Support 18608cda7954SMatthew G. Knepley 18618cda7954SMatthew G. Knepley Input Parameters: 1862bb7acecfSBarry Smith + dm - The `DM` 18638cda7954SMatthew G. Knepley - field - The field number for the nullspace 18648cda7954SMatthew G. Knepley 18658cda7954SMatthew G. Knepley Output Parameter: 18668cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 18678cda7954SMatthew G. Knepley 186820f4b53cSBarry Smith Calling sequence of `nullsp`: 1869bb7acecfSBarry Smith + dm - The present `DM` 1870bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1871147403d9SBarry Smith . field - The field number in dm 1872147403d9SBarry Smith - nullSpace - The nullspace for the given field 18738cda7954SMatthew G. Knepley 187449762cbcSSatish Balay Level: intermediate 187549762cbcSSatish Balay 18761cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, 1877bb7acecfSBarry Smith `MatNullSpace`, `DMCreateSuperDM()` 1878147403d9SBarry Smith @*/ 1879a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1880d71ae5a4SJacob Faibussowitsch { 1881f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1882f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18834f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 18847a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1885f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 18863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1887f9d4088aSMatthew G. Knepley } 1888f9d4088aSMatthew G. Knepley 18894f3b5142SJed Brown /*@C 1890bb7acecfSBarry Smith DMCreateFieldIS - Creates a set of `IS` objects with the global indices of dofs for each field defined with `DMAddField()` 18914d343eeaSMatthew G Knepley 189220f4b53cSBarry Smith Not Collective; No Fortran Support 18934d343eeaSMatthew G Knepley 18944d343eeaSMatthew G Knepley Input Parameter: 1895bb7acecfSBarry Smith . dm - the `DM` object 18964d343eeaSMatthew G Knepley 18974d343eeaSMatthew G Knepley Output Parameters: 189820f4b53cSBarry Smith + numFields - The number of fields (or `NULL` if not requested) 1899ce78bad3SBarry Smith . fieldNames - The name of each field (or `NULL` if not requested) 190020f4b53cSBarry Smith - fields - The global indices for each field (or `NULL` if not requested) 19014d343eeaSMatthew G Knepley 19024d343eeaSMatthew G Knepley Level: intermediate 19034d343eeaSMatthew G Knepley 1904bb7acecfSBarry Smith Note: 190573ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `fieldNames` should be freed with 190673ff1848SBarry Smith `PetscFree()`, every entry of `fields` should be destroyed with `ISDestroy()`, and both arrays should be freed with 1907bb7acecfSBarry Smith `PetscFree()`. 190821c9b008SJed Brown 190973ff1848SBarry Smith Developer Note: 1910bb7acecfSBarry Smith It is not clear why both this function and `DMCreateFieldDecomposition()` exist. Having two seems redundant and confusing. This function should 1911bb7acecfSBarry Smith likely be removed. 1912bb7acecfSBarry Smith 19131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1914bb7acecfSBarry Smith `DMCreateFieldDecomposition()` 19154d343eeaSMatthew G Knepley @*/ 1916ce78bad3SBarry Smith PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS *fields[]) 1917d71ae5a4SJacob Faibussowitsch { 191837d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 19194d343eeaSMatthew G Knepley 19204d343eeaSMatthew G Knepley PetscFunctionBegin; 19214d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 192269ca1f37SDmitry Karpeev if (numFields) { 19234f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 192469ca1f37SDmitry Karpeev *numFields = 0; 192569ca1f37SDmitry Karpeev } 192637d0c07bSMatthew G Knepley if (fieldNames) { 19274f572ea9SToby Isaac PetscAssertPointer(fieldNames, 3); 19280298fd71SBarry Smith *fieldNames = NULL; 192969ca1f37SDmitry Karpeev } 193069ca1f37SDmitry Karpeev if (fields) { 19314f572ea9SToby Isaac PetscAssertPointer(fields, 4); 19320298fd71SBarry Smith *fields = NULL; 193369ca1f37SDmitry Karpeev } 19349566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 193537d0c07bSMatthew G Knepley if (section) { 19363a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 193737d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 193837d0c07bSMatthew G Knepley 19399566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 19409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nF)); 19419566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nF, &fieldSizes, nF, &fieldNc, nF, &fieldIndices)); 19429566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(sectionGlobal, &pStart, &pEnd)); 194337d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 194437d0c07bSMatthew G Knepley fieldSizes[f] = 0; 19459566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(section, f, &fieldNc[f])); 194637d0c07bSMatthew G Knepley } 194737d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 194837d0c07bSMatthew G Knepley PetscInt gdof; 194937d0c07bSMatthew G Knepley 19509566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 195137d0c07bSMatthew G Knepley if (gdof > 0) { 195237d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19533a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 195437d0c07bSMatthew G Knepley 19559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19569566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 19573a544194SStefano Zampini fpdof = fdof - fcdof; 19583a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 19593a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 19603a544194SStefano Zampini fieldNc[f] = 1; 19613a544194SStefano Zampini } 19623a544194SStefano Zampini fieldSizes[f] += fpdof; 196337d0c07bSMatthew G Knepley } 196437d0c07bSMatthew G Knepley } 196537d0c07bSMatthew G Knepley } 196637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fieldSizes[f], &fieldIndices[f])); 196837d0c07bSMatthew G Knepley fieldSizes[f] = 0; 196937d0c07bSMatthew G Knepley } 197037d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 197137d0c07bSMatthew G Knepley PetscInt gdof, goff; 197237d0c07bSMatthew G Knepley 19739566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 197437d0c07bSMatthew G Knepley if (gdof > 0) { 19759566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &goff)); 197637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 197737d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 197837d0c07bSMatthew G Knepley 19799566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 1981ad540459SPierre Jolivet for (fc = 0; fc < fdof - fcdof; ++fc, ++fieldSizes[f]) fieldIndices[f][fieldSizes[f]] = goff++; 198237d0c07bSMatthew G Knepley } 198337d0c07bSMatthew G Knepley } 198437d0c07bSMatthew G Knepley } 19858865f1eaSKarl Rupp if (numFields) *numFields = nF; 198637d0c07bSMatthew G Knepley if (fieldNames) { 19879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fieldNames)); 198837d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 198937d0c07bSMatthew G Knepley const char *fieldName; 199037d0c07bSMatthew G Knepley 19919566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 1992835f2295SStefano Zampini PetscCall(PetscStrallocpy(fieldName, &(*fieldNames)[f])); 199337d0c07bSMatthew G Knepley } 199437d0c07bSMatthew G Knepley } 199537d0c07bSMatthew G Knepley if (fields) { 19969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fields)); 199737d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19983a544194SStefano Zampini PetscInt bs, in[2], out[2]; 19993a544194SStefano Zampini 20009566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f])); 20013a544194SStefano Zampini in[0] = -fieldNc[f]; 20023a544194SStefano Zampini in[1] = fieldNc[f]; 2003462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 20043a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 20059566063dSJacob Faibussowitsch PetscCall(ISSetBlockSize((*fields)[f], bs)); 200637d0c07bSMatthew G Knepley } 200737d0c07bSMatthew G Knepley } 20089566063dSJacob Faibussowitsch PetscCall(PetscFree3(fieldSizes, fieldNc, fieldIndices)); 2009dbbe0bcdSBarry Smith } else PetscTryTypeMethod(dm, createfieldis, numFields, fieldNames, fields); 20103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20114d343eeaSMatthew G Knepley } 20124d343eeaSMatthew G Knepley 201316621825SDmitry Karpeev /*@C 2014bb7acecfSBarry Smith DMCreateFieldDecomposition - Returns a list of `IS` objects defining a decomposition of a problem into subproblems 2015a4e35b19SJacob Faibussowitsch corresponding to different fields. 2016e7c4fc90SDmitry Karpeev 201720f4b53cSBarry Smith Not Collective; No Fortran Support 2018e7c4fc90SDmitry Karpeev 2019e7c4fc90SDmitry Karpeev Input Parameter: 2020bb7acecfSBarry Smith . dm - the `DM` object 2021e7c4fc90SDmitry Karpeev 2022e7c4fc90SDmitry Karpeev Output Parameters: 202320f4b53cSBarry Smith + len - The number of fields (or `NULL` if not requested) 202420f4b53cSBarry Smith . namelist - The name for each field (or `NULL` if not requested) 202520f4b53cSBarry Smith . islist - The global indices for each field (or `NULL` if not requested) 202620f4b53cSBarry Smith - dmlist - The `DM`s for each field subproblem (or `NULL`, if not requested; if `NULL` is returned, no `DM`s are defined) 2027e7c4fc90SDmitry Karpeev 2028e7c4fc90SDmitry Karpeev Level: intermediate 2029e7c4fc90SDmitry Karpeev 2030a4e35b19SJacob Faibussowitsch Notes: 2031a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding field, defined by 2032a4e35b19SJacob Faibussowitsch `DMAddField()`. The optional list of `DM`s define the `DM` for each subproblem. 2033a4e35b19SJacob Faibussowitsch 2034a4e35b19SJacob Faibussowitsch The same as `DMCreateFieldIS()` but also returns a `DM` for each field. 2035a4e35b19SJacob Faibussowitsch 203673ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `namelist` should be freed with 203773ff1848SBarry Smith `PetscFree()`, every entry of `islist` should be destroyed with `ISDestroy()`, every entry of `dmlist` should be destroyed with `DMDestroy()`, 2038bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 2039e7c4fc90SDmitry Karpeev 20408d9ecca5SBarry Smith Fortran Notes: 20418d9ecca5SBarry Smith Use the declarations 20428d9ecca5SBarry Smith .vb 20438d9ecca5SBarry Smith character(80), pointer :: namelist(:) 20448d9ecca5SBarry Smith IS, pointer :: islist(:) 20458d9ecca5SBarry Smith DM, pointer :: dmlist(:) 20468d9ecca5SBarry Smith .ve 20478d9ecca5SBarry Smith 20488d9ecca5SBarry Smith `namelist` must be provided, `islist` may be `PETSC_NULL_IS_POINTER` and `dmlist` may be `PETSC_NULL_DM_POINTER` 20498d9ecca5SBarry Smith 20508d9ecca5SBarry Smith Use `DMDestroyFieldDecomposition()` to free the returned objects 20518d9ecca5SBarry Smith 205260225df5SJacob Faibussowitsch Developer Notes: 2053bb7acecfSBarry Smith It is not clear why this function and `DMCreateFieldIS()` exist. Having two seems redundant and confusing. 2054bb7acecfSBarry Smith 205573ff1848SBarry Smith Unlike `DMRefine()`, `DMCoarsen()`, and `DMCreateDomainDecomposition()` this provides no mechanism to provide hooks that are called after the 205673ff1848SBarry Smith decomposition is computed. 205773ff1848SBarry Smith 205873ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMCreateFieldIS()`, `DMCreateSubDM()`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()` 2059e7c4fc90SDmitry Karpeev @*/ 2060ce78bad3SBarry Smith PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS *islist[], DM *dmlist[]) 2061d71ae5a4SJacob Faibussowitsch { 2062e7c4fc90SDmitry Karpeev PetscFunctionBegin; 2063e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20648865f1eaSKarl Rupp if (len) { 20654f572ea9SToby Isaac PetscAssertPointer(len, 2); 20668865f1eaSKarl Rupp *len = 0; 20678865f1eaSKarl Rupp } 20688865f1eaSKarl Rupp if (namelist) { 20694f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 2070ea78f98cSLisandro Dalcin *namelist = NULL; 20718865f1eaSKarl Rupp } 20728865f1eaSKarl Rupp if (islist) { 20734f572ea9SToby Isaac PetscAssertPointer(islist, 4); 2074ea78f98cSLisandro Dalcin *islist = NULL; 20758865f1eaSKarl Rupp } 20768865f1eaSKarl Rupp if (dmlist) { 20774f572ea9SToby Isaac PetscAssertPointer(dmlist, 5); 2078ea78f98cSLisandro Dalcin *dmlist = NULL; 20798865f1eaSKarl Rupp } 2080f3f0edfdSDmitry Karpeev /* 2081f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2082f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2083f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2084f3f0edfdSDmitry Karpeev */ 20857a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 208616621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 2087435a35e8SMatthew G Knepley PetscSection section; 2088435a35e8SMatthew G Knepley PetscInt numFields, f; 2089435a35e8SMatthew G Knepley 20909566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 20919566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(section, &numFields)); 2092435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 2093f25d98f1SMatthew G. Knepley if (len) *len = numFields; 20949566063dSJacob Faibussowitsch if (namelist) PetscCall(PetscMalloc1(numFields, namelist)); 20959566063dSJacob Faibussowitsch if (islist) PetscCall(PetscMalloc1(numFields, islist)); 20969566063dSJacob Faibussowitsch if (dmlist) PetscCall(PetscMalloc1(numFields, dmlist)); 2097435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 2098435a35e8SMatthew G Knepley const char *fieldName; 2099435a35e8SMatthew G Knepley 21009566063dSJacob Faibussowitsch PetscCall(DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL)); 210103dc3394SMatthew G. Knepley if (namelist) { 21029566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 2103835f2295SStefano Zampini PetscCall(PetscStrallocpy(fieldName, &(*namelist)[f])); 2104435a35e8SMatthew G Knepley } 210503dc3394SMatthew G. Knepley } 2106435a35e8SMatthew G Knepley } else { 21079566063dSJacob Faibussowitsch PetscCall(DMCreateFieldIS(dm, len, namelist, islist)); 2108e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 21090298fd71SBarry Smith if (dmlist) *dmlist = NULL; 2110e7c4fc90SDmitry Karpeev } 2111dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, createfielddecomposition, len, namelist, islist, dmlist); 21123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 211316621825SDmitry Karpeev } 211416621825SDmitry Karpeev 21155d83a8b1SBarry Smith /*@ 211620f4b53cSBarry Smith DMCreateSubDM - Returns an `IS` and `DM` encapsulating a subproblem defined by the fields passed in. 211720f4b53cSBarry Smith The fields are defined by `DMCreateFieldIS()`. 2118435a35e8SMatthew G Knepley 2119435a35e8SMatthew G Knepley Not collective 2120435a35e8SMatthew G Knepley 2121435a35e8SMatthew G Knepley Input Parameters: 2122bb7acecfSBarry Smith + dm - The `DM` object 2123bb7acecfSBarry Smith . numFields - The number of fields to select 21242adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 2125435a35e8SMatthew G Knepley 2126435a35e8SMatthew G Knepley Output Parameters: 2127b6971eaeSBarry Smith + is - The global indices for all the degrees of freedom in the new sub `DM`, use `NULL` if not needed 2128b6971eaeSBarry Smith - subdm - The `DM` for the subproblem, use `NULL` if not needed 2129435a35e8SMatthew G Knepley 213020f4b53cSBarry Smith Level: intermediate 213120f4b53cSBarry Smith 2132bb7acecfSBarry Smith Note: 2133bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 21345d3b26e6SMatthew G. Knepley 213560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateFieldIS()`, `DMCreateFieldDecomposition()`, `DMAddField()`, `DMCreateSuperDM()`, `IS`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 2136435a35e8SMatthew G Knepley @*/ 2137d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2138d71ae5a4SJacob Faibussowitsch { 2139435a35e8SMatthew G Knepley PetscFunctionBegin; 2140435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21414f572ea9SToby Isaac PetscAssertPointer(fields, 3); 21424f572ea9SToby Isaac if (is) PetscAssertPointer(is, 4); 21434f572ea9SToby Isaac if (subdm) PetscAssertPointer(subdm, 5); 2144dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createsubdm, numFields, fields, is, subdm); 21453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2146435a35e8SMatthew G Knepley } 2147435a35e8SMatthew G Knepley 21482adcc780SMatthew G. Knepley /*@C 2149ce78bad3SBarry Smith DMCreateSuperDM - Returns an arrays of `IS` and a single `DM` encapsulating a superproblem defined by multiple `DM`s passed in. 21502adcc780SMatthew G. Knepley 21512adcc780SMatthew G. Knepley Not collective 21522adcc780SMatthew G. Knepley 2153d8d19677SJose E. Roman Input Parameters: 2154bb7acecfSBarry Smith + dms - The `DM` objects 2155bb7acecfSBarry Smith - n - The number of `DM`s 21562adcc780SMatthew G. Knepley 21572adcc780SMatthew G. Knepley Output Parameters: 2158ce78bad3SBarry Smith + is - The global indices for each of subproblem within the super `DM`, or `NULL`, its length is `n` 2159bb7acecfSBarry Smith - superdm - The `DM` for the superproblem 21602adcc780SMatthew G. Knepley 216120f4b53cSBarry Smith Level: intermediate 216220f4b53cSBarry Smith 2163bb7acecfSBarry Smith Note: 2164bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 21655d3b26e6SMatthew G. Knepley 216673ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateSubDM()`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()`, `DMCreateDomainDecomposition()` 21672adcc780SMatthew G. Knepley @*/ 21685d83a8b1SBarry Smith PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt n, IS *is[], DM *superdm) 2169d71ae5a4SJacob Faibussowitsch { 21702adcc780SMatthew G. Knepley PetscInt i; 21712adcc780SMatthew G. Knepley 21722adcc780SMatthew G. Knepley PetscFunctionBegin; 21734f572ea9SToby Isaac PetscAssertPointer(dms, 1); 2174ad540459SPierre Jolivet for (i = 0; i < n; ++i) PetscValidHeaderSpecific(dms[i], DM_CLASSID, 1); 21754f572ea9SToby Isaac if (is) PetscAssertPointer(is, 3); 21764f572ea9SToby Isaac PetscAssertPointer(superdm, 4); 2177bb7acecfSBarry Smith PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %" PetscInt_FMT, n); 2178bb7acecfSBarry Smith if (n) { 2179b9d85ea2SLisandro Dalcin DM dm = dms[0]; 218000045ab3SPierre Jolivet PetscCheck(dm->ops->createsuperdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No method createsuperdm for DM of type %s", ((PetscObject)dm)->type_name); 2181dbbe0bcdSBarry Smith PetscCall((*dm->ops->createsuperdm)(dms, n, is, superdm)); 21822adcc780SMatthew G. Knepley } 21833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21842adcc780SMatthew G. Knepley } 21852adcc780SMatthew G. Knepley 218616621825SDmitry Karpeev /*@C 2187a4e35b19SJacob Faibussowitsch DMCreateDomainDecomposition - Returns lists of `IS` objects defining a decomposition of a 2188a4e35b19SJacob Faibussowitsch problem into subproblems corresponding to restrictions to pairs of nested subdomains. 218916621825SDmitry Karpeev 219020f4b53cSBarry Smith Not Collective 219116621825SDmitry Karpeev 219216621825SDmitry Karpeev Input Parameter: 2193bb7acecfSBarry Smith . dm - the `DM` object 219416621825SDmitry Karpeev 219516621825SDmitry Karpeev Output Parameters: 2196ce78bad3SBarry Smith + n - The number of subproblems in the domain decomposition (or `NULL` if not requested), also the length of the four arrays below 219720f4b53cSBarry Smith . namelist - The name for each subdomain (or `NULL` if not requested) 219873ff1848SBarry Smith . innerislist - The global indices for each inner subdomain (or `NULL`, if not requested) 219973ff1848SBarry Smith . outerislist - The global indices for each outer subdomain (or `NULL`, if not requested) 220073ff1848SBarry Smith - dmlist - The `DM`s for each subdomain subproblem (or `NULL`, if not requested; if `NULL` is returned, no `DM`s are defined) 220116621825SDmitry Karpeev 220216621825SDmitry Karpeev Level: intermediate 220316621825SDmitry Karpeev 220473ff1848SBarry Smith Notes: 2205a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding subdomains with in the 2206a4e35b19SJacob Faibussowitsch dofs of the original `DM`. The inner subdomains conceptually define a nonoverlapping 2207a4e35b19SJacob Faibussowitsch covering, while outer subdomains can overlap. 2208a4e35b19SJacob Faibussowitsch 2209a4e35b19SJacob Faibussowitsch The optional list of `DM`s define a `DM` for each subproblem. 2210a4e35b19SJacob Faibussowitsch 221173ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `namelist` should be freed with 221273ff1848SBarry Smith `PetscFree()`, every entry of `innerislist` and `outerislist` should be destroyed with `ISDestroy()`, every entry of `dmlist` should be destroyed with `DMDestroy()`, 2213bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 221416621825SDmitry Karpeev 2215a4e35b19SJacob Faibussowitsch Developer Notes: 221620f4b53cSBarry Smith The `dmlist` is for the inner subdomains or the outer subdomains or all subdomains? 2217bb7acecfSBarry Smith 221873ff1848SBarry Smith The names are inconsistent, the hooks use `DMSubDomainHook` which is nothing like `DMCreateDomainDecomposition()` while `DMRefineHook` is used for `DMRefine()`. 221973ff1848SBarry Smith 222073ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateFieldDecomposition()`, `DMDestroy()`, `DMCreateDomainDecompositionScatters()`, `DMView()`, `DMCreateInterpolation()`, 222173ff1848SBarry Smith `DMSubDomainHookAdd()`, `DMSubDomainHookRemove()`,`DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()` 222216621825SDmitry Karpeev @*/ 2223ce78bad3SBarry Smith PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *n, char ***namelist, IS *innerislist[], IS *outerislist[], DM *dmlist[]) 2224d71ae5a4SJacob Faibussowitsch { 2225be081cd6SPeter Brune DMSubDomainHookLink link; 2226be081cd6SPeter Brune PetscInt i, l; 222716621825SDmitry Karpeev 222816621825SDmitry Karpeev PetscFunctionBegin; 222916621825SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22309371c9d4SSatish Balay if (n) { 22314f572ea9SToby Isaac PetscAssertPointer(n, 2); 22329371c9d4SSatish Balay *n = 0; 22339371c9d4SSatish Balay } 22349371c9d4SSatish Balay if (namelist) { 22354f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 22369371c9d4SSatish Balay *namelist = NULL; 22379371c9d4SSatish Balay } 22389371c9d4SSatish Balay if (innerislist) { 22394f572ea9SToby Isaac PetscAssertPointer(innerislist, 4); 22409371c9d4SSatish Balay *innerislist = NULL; 22419371c9d4SSatish Balay } 22429371c9d4SSatish Balay if (outerislist) { 22434f572ea9SToby Isaac PetscAssertPointer(outerislist, 5); 22449371c9d4SSatish Balay *outerislist = NULL; 22459371c9d4SSatish Balay } 22469371c9d4SSatish Balay if (dmlist) { 22474f572ea9SToby Isaac PetscAssertPointer(dmlist, 6); 22489371c9d4SSatish Balay *dmlist = NULL; 22499371c9d4SSatish Balay } 2250f3f0edfdSDmitry Karpeev /* 2251f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2252f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2253f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2254f3f0edfdSDmitry Karpeev */ 22557a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 225616621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 2257dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createdomaindecomposition, &l, namelist, innerislist, outerislist, dmlist); 225814a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 2259f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2260be081cd6SPeter Brune for (i = 0; i < l; i++) { 2261be081cd6SPeter Brune for (link = dm->subdomainhook; link; link = link->next) { 22629566063dSJacob Faibussowitsch if (link->ddhook) PetscCall((*link->ddhook)(dm, (*dmlist)[i], link->ctx)); 2263be081cd6SPeter Brune } 2264648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2265e7c4fc90SDmitry Karpeev } 226614a18fd3SPeter Brune } 2267bb7acecfSBarry Smith if (n) *n = l; 226814a18fd3SPeter Brune } 22693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2270e30e807fSPeter Brune } 2271e30e807fSPeter Brune 2272e30e807fSPeter Brune /*@C 227373ff1848SBarry Smith DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector for subdomains created with 227473ff1848SBarry Smith `DMCreateDomainDecomposition()` 2275e30e807fSPeter Brune 227620f4b53cSBarry Smith Not Collective 2277e30e807fSPeter Brune 2278e30e807fSPeter Brune Input Parameters: 2279bb7acecfSBarry Smith + dm - the `DM` object 228073ff1848SBarry Smith . n - the number of subdomains 2281e30e807fSPeter Brune - subdms - the local subdomains 2282e30e807fSPeter Brune 2283e30e807fSPeter Brune Output Parameters: 22846b867d5aSJose E. Roman + iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2285e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2286e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2287e30e807fSPeter Brune 228820f4b53cSBarry Smith Level: developer 228920f4b53cSBarry Smith 2290bb7acecfSBarry Smith Note: 2291bb7acecfSBarry Smith This is an alternative to the iis and ois arguments in `DMCreateDomainDecomposition()` that allow for the solution 2292e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2293e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2294e30e807fSPeter Brune solution and residual data. 2295e30e807fSPeter Brune 229673ff1848SBarry Smith Developer Note: 2297a4e35b19SJacob Faibussowitsch Can the subdms input be anything or are they exactly the `DM` obtained from 2298a4e35b19SJacob Faibussowitsch `DMCreateDomainDecomposition()`? 2299bb7acecfSBarry Smith 23001cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2301e30e807fSPeter Brune @*/ 23025d83a8b1SBarry Smith PetscErrorCode DMCreateDomainDecompositionScatters(DM dm, PetscInt n, DM *subdms, VecScatter *iscat[], VecScatter *oscat[], VecScatter *gscat[]) 2303d71ae5a4SJacob Faibussowitsch { 2304e30e807fSPeter Brune PetscFunctionBegin; 2305e30e807fSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 23064f572ea9SToby Isaac PetscAssertPointer(subdms, 3); 2307dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createddscatters, n, subdms, iscat, oscat, gscat); 23083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2309e7c4fc90SDmitry Karpeev } 2310e7c4fc90SDmitry Karpeev 231147c6ae99SBarry Smith /*@ 2312bb7acecfSBarry Smith DMRefine - Refines a `DM` object using a standard nonadaptive refinement of the underlying mesh 231347c6ae99SBarry Smith 231420f4b53cSBarry Smith Collective 231547c6ae99SBarry Smith 2316d8d19677SJose E. Roman Input Parameters: 2317bb7acecfSBarry Smith + dm - the `DM` object 2318bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 231947c6ae99SBarry Smith 232047c6ae99SBarry Smith Output Parameter: 232120f4b53cSBarry Smith . dmf - the refined `DM`, or `NULL` 2322ae0a1c52SMatthew G Knepley 232320f4b53cSBarry Smith Options Database Key: 2324412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2325412e9a14SMatthew G. Knepley 232647c6ae99SBarry Smith Level: developer 232747c6ae99SBarry Smith 232820f4b53cSBarry Smith Note: 232920f4b53cSBarry Smith If no refinement was done, the return value is `NULL` 233020f4b53cSBarry Smith 233173ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateDomainDecomposition()`, 233273ff1848SBarry Smith `DMRefineHookAdd()`, `DMRefineHookRemove()` 233347c6ae99SBarry Smith @*/ 2334d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine(DM dm, MPI_Comm comm, DM *dmf) 2335d71ae5a4SJacob Faibussowitsch { 2336c833c3b5SJed Brown DMRefineHookLink link; 233747c6ae99SBarry Smith 233847c6ae99SBarry Smith PetscFunctionBegin; 2339732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 23409566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Refine, dm, 0, 0, 0)); 2341dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refine, comm, dmf); 23424057135bSMatthew G Knepley if (*dmf) { 234343842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 23448865f1eaSKarl Rupp 23459566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmf)); 23468865f1eaSKarl Rupp 2347644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 23480598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2349656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 23508865f1eaSKarl Rupp 23519566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmf, dm->mattype)); 2352c833c3b5SJed Brown for (link = dm->refinehook; link; link = link->next) { 23531baa6e33SBarry Smith if (link->refinehook) PetscCall((*link->refinehook)(dm, *dmf, link->ctx)); 2354c833c3b5SJed Brown } 2355c833c3b5SJed Brown } 23569566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Refine, dm, 0, 0, 0)); 23573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2358c833c3b5SJed Brown } 2359c833c3b5SJed Brown 2360bb9467b5SJed Brown /*@C 2361c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2362c833c3b5SJed Brown 236320f4b53cSBarry Smith Logically Collective; No Fortran Support 2364c833c3b5SJed Brown 23654165533cSJose E. Roman Input Parameters: 2366bb7acecfSBarry Smith + coarse - `DM` on which to run a hook when interpolating to a finer level 2367bb7acecfSBarry Smith . refinehook - function to run when setting up the finer level 2368f826b5fcSPierre Jolivet . interphook - function to run to update data on finer levels (once per `SNESSolve()`) 236920f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2370c833c3b5SJed Brown 237120f4b53cSBarry Smith Calling sequence of `refinehook`: 2372bb7acecfSBarry Smith + coarse - coarse level `DM` 2373bb7acecfSBarry Smith . fine - fine level `DM` to interpolate problem to 2374c833c3b5SJed Brown - ctx - optional user-defined function context 2375c833c3b5SJed Brown 237620f4b53cSBarry Smith Calling sequence of `interphook`: 2377bb7acecfSBarry Smith + coarse - coarse level `DM` 2378c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2379bb7acecfSBarry Smith . fine - fine level `DM` to update 2380c833c3b5SJed Brown - ctx - optional user-defined function context 2381c833c3b5SJed Brown 2382c833c3b5SJed Brown Level: advanced 2383c833c3b5SJed Brown 2384c833c3b5SJed Brown Notes: 2385bb7acecfSBarry Smith This function is only needed if auxiliary data that is attached to the `DM`s via, for example, `PetscObjectCompose()`, needs to be 2386bb7acecfSBarry Smith passed to fine grids while grid sequencing. 2387bb7acecfSBarry Smith 2388bb7acecfSBarry Smith The actual interpolation is done when `DMInterpolate()` is called. 2389c833c3b5SJed Brown 2390c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2391c833c3b5SJed Brown 23921cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2393c833c3b5SJed Brown @*/ 2394a4e35b19SJacob Faibussowitsch PetscErrorCode DMRefineHookAdd(DM coarse, PetscErrorCode (*refinehook)(DM coarse, DM fine, void *ctx), PetscErrorCode (*interphook)(DM coarse, Mat interp, DM fine, void *ctx), void *ctx) 2395d71ae5a4SJacob Faibussowitsch { 2396c833c3b5SJed Brown DMRefineHookLink link, *p; 2397c833c3b5SJed Brown 2398c833c3b5SJed Brown PetscFunctionBegin; 2399c833c3b5SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 24003d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 24013ba16761SJacob Faibussowitsch if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 24023d8e3701SJed Brown } 24039566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2404c833c3b5SJed Brown link->refinehook = refinehook; 2405c833c3b5SJed Brown link->interphook = interphook; 2406c833c3b5SJed Brown link->ctx = ctx; 24070298fd71SBarry Smith link->next = NULL; 2408c833c3b5SJed Brown *p = link; 24093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2410c833c3b5SJed Brown } 2411c833c3b5SJed Brown 24123d8e3701SJed Brown /*@C 2413bb7acecfSBarry Smith DMRefineHookRemove - remove a callback from the list of hooks, that have been set with `DMRefineHookAdd()`, to be run when interpolating 2414bb7acecfSBarry Smith a nonlinear problem to a finer grid 24153d8e3701SJed Brown 241620f4b53cSBarry Smith Logically Collective; No Fortran Support 24173d8e3701SJed Brown 24184165533cSJose E. Roman Input Parameters: 2419bb7acecfSBarry Smith + coarse - the `DM` on which to run a hook when restricting to a coarser level 2420bb7acecfSBarry Smith . refinehook - function to run when setting up a finer level 2421bb7acecfSBarry Smith . interphook - function to run to update data on finer levels 242220f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 24233d8e3701SJed Brown 24243d8e3701SJed Brown Level: advanced 24253d8e3701SJed Brown 2426bb7acecfSBarry Smith Note: 24273d8e3701SJed Brown This function does nothing if the hook is not in the list. 24283d8e3701SJed Brown 24291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `DMCoarsenHookRemove()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 24303d8e3701SJed Brown @*/ 2431d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHookRemove(DM coarse, PetscErrorCode (*refinehook)(DM, DM, void *), PetscErrorCode (*interphook)(DM, Mat, DM, void *), void *ctx) 2432d71ae5a4SJacob Faibussowitsch { 24333d8e3701SJed Brown DMRefineHookLink link, *p; 24343d8e3701SJed Brown 24353d8e3701SJed Brown PetscFunctionBegin; 24363d8e3701SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 24373d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 24383d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 24393d8e3701SJed Brown link = *p; 24403d8e3701SJed Brown *p = link->next; 24419566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 24423d8e3701SJed Brown break; 24433d8e3701SJed Brown } 24443d8e3701SJed Brown } 24453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24463d8e3701SJed Brown } 24473d8e3701SJed Brown 2448c833c3b5SJed Brown /*@ 2449bb7acecfSBarry Smith DMInterpolate - interpolates user-defined problem data attached to a `DM` to a finer `DM` by running hooks registered by `DMRefineHookAdd()` 2450c833c3b5SJed Brown 2451c833c3b5SJed Brown Collective if any hooks are 2452c833c3b5SJed Brown 24534165533cSJose E. Roman Input Parameters: 2454bb7acecfSBarry Smith + coarse - coarser `DM` to use as a base 2455bb7acecfSBarry Smith . interp - interpolation matrix, apply using `MatInterpolate()` 2456bb7acecfSBarry Smith - fine - finer `DM` to update 2457c833c3b5SJed Brown 2458c833c3b5SJed Brown Level: developer 2459c833c3b5SJed Brown 246073ff1848SBarry Smith Developer Note: 2461bb7acecfSBarry Smith This routine is called `DMInterpolate()` while the hook is called `DMRefineHookAdd()`. It would be better to have an 2462bb7acecfSBarry Smith an API with consistent terminology. 2463bb7acecfSBarry Smith 24641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `MatInterpolate()` 2465c833c3b5SJed Brown @*/ 2466d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolate(DM coarse, Mat interp, DM fine) 2467d71ae5a4SJacob Faibussowitsch { 2468c833c3b5SJed Brown DMRefineHookLink link; 2469c833c3b5SJed Brown 2470c833c3b5SJed Brown PetscFunctionBegin; 2471c833c3b5SJed Brown for (link = fine->refinehook; link; link = link->next) { 24721baa6e33SBarry Smith if (link->interphook) PetscCall((*link->interphook)(coarse, interp, fine, link->ctx)); 24734057135bSMatthew G Knepley } 24743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 247547c6ae99SBarry Smith } 247647c6ae99SBarry Smith 2477eb3f98d2SBarry Smith /*@ 24781f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 24791f3379b2SToby Isaac 248020f4b53cSBarry Smith Collective 24811f3379b2SToby Isaac 24824165533cSJose E. Roman Input Parameters: 2483bb7acecfSBarry Smith + coarse - coarse `DM` 2484bb7acecfSBarry Smith . fine - fine `DM` 2485bb7acecfSBarry Smith . interp - (optional) the matrix computed by `DMCreateInterpolation()`. Implementations may not need this, but if it 2486bb7acecfSBarry Smith is available it can avoid some recomputation. If it is provided, `MatInterpolate()` will be used if 2487bb7acecfSBarry Smith the coarse `DM` does not have a specialized implementation. 24881f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 24891f3379b2SToby Isaac 24904165533cSJose E. Roman Output Parameter: 24911f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 24921f3379b2SToby Isaac 24931f3379b2SToby Isaac Level: developer 24941f3379b2SToby Isaac 2495bb7acecfSBarry Smith Note: 2496bb7acecfSBarry Smith This function exists because the interpolation of a solution vector between meshes is not always a linear 24971f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 24981f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 24991f3379b2SToby Isaac slope-limiting reconstruction. 25001f3379b2SToby Isaac 250173ff1848SBarry Smith Developer Note: 2502bb7acecfSBarry Smith This doesn't just interpolate "solutions" so its API name is questionable. 2503bb7acecfSBarry Smith 25041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMInterpolate()`, `DMCreateInterpolation()` 25051f3379b2SToby Isaac @*/ 2506d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 2507d71ae5a4SJacob Faibussowitsch { 25081f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM, DM, Mat, Vec, Vec) = NULL; 25091f3379b2SToby Isaac 25101f3379b2SToby Isaac PetscFunctionBegin; 25111f3379b2SToby Isaac PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 25121f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp, MAT_CLASSID, 3); 25131f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol, VEC_CLASSID, 4); 25141f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol, VEC_CLASSID, 5); 25151f3379b2SToby Isaac 25169566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)coarse, "DMInterpolateSolution_C", &interpsol)); 25171f3379b2SToby Isaac if (interpsol) { 25189566063dSJacob Faibussowitsch PetscCall((*interpsol)(coarse, fine, interp, coarseSol, fineSol)); 25191f3379b2SToby Isaac } else if (interp) { 25209566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, coarseSol, fineSol)); 252198921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 25223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25231f3379b2SToby Isaac } 25241f3379b2SToby Isaac 25251f3379b2SToby Isaac /*@ 2526bb7acecfSBarry Smith DMGetRefineLevel - Gets the number of refinements that have generated this `DM` from some initial `DM`. 2527eb3f98d2SBarry Smith 2528eb3f98d2SBarry Smith Not Collective 2529eb3f98d2SBarry Smith 2530eb3f98d2SBarry Smith Input Parameter: 2531bb7acecfSBarry Smith . dm - the `DM` object 2532eb3f98d2SBarry Smith 2533eb3f98d2SBarry Smith Output Parameter: 2534eb3f98d2SBarry Smith . level - number of refinements 2535eb3f98d2SBarry Smith 2536eb3f98d2SBarry Smith Level: developer 2537eb3f98d2SBarry Smith 2538bb7acecfSBarry Smith Note: 2539bb7acecfSBarry Smith This can be used, by example, to set the number of coarser levels associated with this `DM` for a multigrid solver. 2540bb7acecfSBarry Smith 25411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2542eb3f98d2SBarry Smith @*/ 2543d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRefineLevel(DM dm, PetscInt *level) 2544d71ae5a4SJacob Faibussowitsch { 2545eb3f98d2SBarry Smith PetscFunctionBegin; 2546eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2547eb3f98d2SBarry Smith *level = dm->levelup; 25483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2549eb3f98d2SBarry Smith } 2550eb3f98d2SBarry Smith 2551fef3a512SBarry Smith /*@ 2552bb7acecfSBarry Smith DMSetRefineLevel - Sets the number of refinements that have generated this `DM`. 2553fef3a512SBarry Smith 2554fef3a512SBarry Smith Not Collective 2555fef3a512SBarry Smith 2556d8d19677SJose E. Roman Input Parameters: 2557bb7acecfSBarry Smith + dm - the `DM` object 2558fef3a512SBarry Smith - level - number of refinements 2559fef3a512SBarry Smith 2560fef3a512SBarry Smith Level: advanced 2561fef3a512SBarry Smith 256295452b02SPatrick Sanan Notes: 2563bb7acecfSBarry Smith This value is used by `PCMG` to determine how many multigrid levels to use 2564fef3a512SBarry Smith 2565bb7acecfSBarry Smith The values are usually set automatically by the process that is causing the refinements of an initial `DM` by calling this routine. 2566bb7acecfSBarry Smith 25671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRefineLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2568fef3a512SBarry Smith @*/ 2569d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRefineLevel(DM dm, PetscInt level) 2570d71ae5a4SJacob Faibussowitsch { 2571fef3a512SBarry Smith PetscFunctionBegin; 2572fef3a512SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2573fef3a512SBarry Smith dm->levelup = level; 25743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2575fef3a512SBarry Smith } 2576fef3a512SBarry Smith 2577d410b0cfSMatthew G. Knepley /*@ 2578bb7acecfSBarry Smith DMExtrude - Extrude a `DM` object from a surface 2579d410b0cfSMatthew G. Knepley 258020f4b53cSBarry Smith Collective 2581d410b0cfSMatthew G. Knepley 2582f1a722f8SMatthew G. Knepley Input Parameters: 2583bb7acecfSBarry Smith + dm - the `DM` object 2584d410b0cfSMatthew G. Knepley - layers - the number of extruded cell layers 2585d410b0cfSMatthew G. Knepley 2586d410b0cfSMatthew G. Knepley Output Parameter: 258720f4b53cSBarry Smith . dme - the extruded `DM`, or `NULL` 2588d410b0cfSMatthew G. Knepley 2589d410b0cfSMatthew G. Knepley Level: developer 2590d410b0cfSMatthew G. Knepley 259120f4b53cSBarry Smith Note: 259220f4b53cSBarry Smith If no extrusion was done, the return value is `NULL` 259320f4b53cSBarry Smith 25941cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()` 2595d410b0cfSMatthew G. Knepley @*/ 2596d71ae5a4SJacob Faibussowitsch PetscErrorCode DMExtrude(DM dm, PetscInt layers, DM *dme) 2597d71ae5a4SJacob Faibussowitsch { 2598d410b0cfSMatthew G. Knepley PetscFunctionBegin; 2599d410b0cfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2600dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, extrude, layers, dme); 2601d410b0cfSMatthew G. Knepley if (*dme) { 2602d410b0cfSMatthew G. Knepley (*dme)->ops->creatematrix = dm->ops->creatematrix; 26039566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dme)); 2604d410b0cfSMatthew G. Knepley (*dme)->ctx = dm->ctx; 26059566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dme, dm->mattype)); 2606d410b0cfSMatthew G. Knepley } 26073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2608d410b0cfSMatthew G. Knepley } 2609d410b0cfSMatthew G. Knepley 2610d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2611d71ae5a4SJacob Faibussowitsch { 2612ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2613ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26144f572ea9SToby Isaac PetscAssertPointer(tdm, 2); 2615ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 26163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2617ca3d3a14SMatthew G. Knepley } 2618ca3d3a14SMatthew G. Knepley 2619d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2620d71ae5a4SJacob Faibussowitsch { 2621ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2622ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26234f572ea9SToby Isaac PetscAssertPointer(tv, 2); 2624ca3d3a14SMatthew G. Knepley *tv = dm->transform; 26253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2626ca3d3a14SMatthew G. Knepley } 2627ca3d3a14SMatthew G. Knepley 2628ca3d3a14SMatthew G. Knepley /*@ 2629bb7acecfSBarry Smith DMHasBasisTransform - Whether the `DM` employs a basis transformation from functions in global vectors to functions in local vectors 2630ca3d3a14SMatthew G. Knepley 2631ca3d3a14SMatthew G. Knepley Input Parameter: 263220f4b53cSBarry Smith . dm - The `DM` 2633ca3d3a14SMatthew G. Knepley 2634ca3d3a14SMatthew G. Knepley Output Parameter: 263520f4b53cSBarry Smith . flg - `PETSC_TRUE` if a basis transformation should be done 2636ca3d3a14SMatthew G. Knepley 2637ca3d3a14SMatthew G. Knepley Level: developer 2638ca3d3a14SMatthew G. Knepley 26391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPlexGlobalToLocalBasis()`, `DMPlexLocalToGlobalBasis()`, `DMPlexCreateBasisRotation()` 2640ca3d3a14SMatthew G. Knepley @*/ 2641d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2642d71ae5a4SJacob Faibussowitsch { 2643ca3d3a14SMatthew G. Knepley Vec tv; 2644ca3d3a14SMatthew G. Knepley 2645ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2646ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26474f572ea9SToby Isaac PetscAssertPointer(flg, 2); 26489566063dSJacob Faibussowitsch PetscCall(DMGetBasisTransformVec_Internal(dm, &tv)); 2649ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 26503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2651ca3d3a14SMatthew G. Knepley } 2652ca3d3a14SMatthew G. Knepley 2653d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2654d71ae5a4SJacob Faibussowitsch { 2655ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2656ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2657ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2658ca3d3a14SMatthew G. Knepley 2659ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 26609566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 26619566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 26629566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 26639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 26649566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->transformDM)); 26659566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm->transformDM, &ts)); 26669566063dSJacob Faibussowitsch PetscCall(PetscSectionSetNumFields(ts, Nf)); 26679566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(ts, pStart, pEnd)); 2668ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26699566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(s, f, &Nc)); 2670ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2671ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2672ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 26739566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &dof)); 2674ca3d3a14SMatthew G. Knepley if (!dof) continue; 26759566063dSJacob Faibussowitsch PetscCall(PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim))); 26769566063dSJacob Faibussowitsch PetscCall(PetscSectionAddDof(ts, p, PetscSqr(cdim))); 2677ca3d3a14SMatthew G. Knepley } 2678ca3d3a14SMatthew G. Knepley } 26799566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(ts)); 26809566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dm->transformDM, &dm->transform)); 26819566063dSJacob Faibussowitsch PetscCall(VecGetArray(dm->transform, &ta)); 2682ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2683ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26849566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(ts, p, f, &dof)); 2685ca3d3a14SMatthew G. Knepley if (dof) { 2686ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2687ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2688ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2689ca3d3a14SMatthew G. Knepley 2690ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 26919566063dSJacob Faibussowitsch PetscCall((*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx)); 26929566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *)&tva)); 26939566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tva, A, PetscSqr(cdim))); 2694ca3d3a14SMatthew G. Knepley } 2695ca3d3a14SMatthew G. Knepley } 2696ca3d3a14SMatthew G. Knepley } 26979566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(dm->transform, &ta)); 26983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2699ca3d3a14SMatthew G. Knepley } 2700ca3d3a14SMatthew G. Knepley 2701d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2702d71ae5a4SJacob Faibussowitsch { 2703ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2704ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2705ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2706ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2707ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2708ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2709ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 27109566063dSJacob Faibussowitsch if (newdm->transformSetUp) PetscCall(DMConstructBasisTransform_Internal(newdm)); 27113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2712ca3d3a14SMatthew G. Knepley } 2713ca3d3a14SMatthew G. Knepley 2714bb9467b5SJed Brown /*@C 2715bb7acecfSBarry Smith DMGlobalToLocalHookAdd - adds a callback to be run when `DMGlobalToLocal()` is called 2716baf369e7SPeter Brune 271720f4b53cSBarry Smith Logically Collective 2718baf369e7SPeter Brune 27194165533cSJose E. Roman Input Parameters: 2720bb7acecfSBarry Smith + dm - the `DM` 2721bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMGlobalToLocalBegin()` 2722bb7acecfSBarry Smith . endhook - function to run after `DMGlobalToLocalEnd()` has completed 272320f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2724baf369e7SPeter Brune 272520f4b53cSBarry Smith Calling sequence of `beginhook`: 2726a4e35b19SJacob Faibussowitsch + dm - global `DM` 2727baf369e7SPeter Brune . g - global vector 2728baf369e7SPeter Brune . mode - mode 2729baf369e7SPeter Brune . l - local vector 2730baf369e7SPeter Brune - ctx - optional user-defined function context 2731baf369e7SPeter Brune 273220f4b53cSBarry Smith Calling sequence of `endhook`: 2733a4e35b19SJacob Faibussowitsch + dm - global `DM` 2734a4e35b19SJacob Faibussowitsch . g - global vector 2735a4e35b19SJacob Faibussowitsch . mode - mode 2736a4e35b19SJacob Faibussowitsch . l - local vector 2737baf369e7SPeter Brune - ctx - optional user-defined function context 2738baf369e7SPeter Brune 2739baf369e7SPeter Brune Level: advanced 2740baf369e7SPeter Brune 2741bb7acecfSBarry Smith Note: 2742bb7acecfSBarry Smith The hook may be used to provide, for example, values that represent boundary conditions in the local vectors that do not exist on the global vector. 2743bb7acecfSBarry Smith 27441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocal()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2745baf369e7SPeter Brune @*/ 2746a4e35b19SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalHookAdd(DM dm, PetscErrorCode (*beginhook)(DM dm, Vec g, InsertMode mode, Vec l, void *ctx), PetscErrorCode (*endhook)(DM dm, Vec g, InsertMode mode, Vec l, void *ctx), void *ctx) 2747d71ae5a4SJacob Faibussowitsch { 2748baf369e7SPeter Brune DMGlobalToLocalHookLink link, *p; 2749baf369e7SPeter Brune 2750baf369e7SPeter Brune PetscFunctionBegin; 2751baf369e7SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2752baf369e7SPeter Brune for (p = &dm->gtolhook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 27539566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2754baf369e7SPeter Brune link->beginhook = beginhook; 2755baf369e7SPeter Brune link->endhook = endhook; 2756baf369e7SPeter Brune link->ctx = ctx; 27570298fd71SBarry Smith link->next = NULL; 2758baf369e7SPeter Brune *p = link; 27593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2760baf369e7SPeter Brune } 2761baf369e7SPeter Brune 2762d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 2763d71ae5a4SJacob Faibussowitsch { 27644c274da1SToby Isaac Mat cMat; 276579769bd5SJed Brown Vec cVec, cBias; 27664c274da1SToby Isaac PetscSection section, cSec; 27674c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 27684c274da1SToby Isaac 27694c274da1SToby Isaac PetscFunctionBegin; 2770a4e35b19SJacob Faibussowitsch (void)g; 2771a4e35b19SJacob Faibussowitsch (void)ctx; 27724c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 27739566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, &cBias)); 27744c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 27755db9a05bSToby Isaac PetscInt nRows; 27765db9a05bSToby Isaac 27779566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 27783ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 27799566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 27809566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 27819566063dSJacob Faibussowitsch PetscCall(MatMult(cMat, l, cVec)); 27829566063dSJacob Faibussowitsch if (cBias) PetscCall(VecAXPY(cVec, 1., cBias)); 27839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 27844c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 27859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 27864c274da1SToby Isaac if (dof) { 27874c274da1SToby Isaac PetscScalar *vals; 27889566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(cVec, cSec, p, &vals)); 27899566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(l, section, p, vals, INSERT_ALL_VALUES)); 27904c274da1SToby Isaac } 27914c274da1SToby Isaac } 27929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 27934c274da1SToby Isaac } 27943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27954c274da1SToby Isaac } 27964c274da1SToby Isaac 279747c6ae99SBarry Smith /*@ 279801729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 279901729b5cSPatrick Sanan 280020f4b53cSBarry Smith Neighbor-wise Collective 280101729b5cSPatrick Sanan 280201729b5cSPatrick Sanan Input Parameters: 2803bb7acecfSBarry Smith + dm - the `DM` object 280401729b5cSPatrick Sanan . g - the global vector 2805bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 280601729b5cSPatrick Sanan - l - the local vector 280701729b5cSPatrick Sanan 280820f4b53cSBarry Smith Level: beginner 280920f4b53cSBarry Smith 281001729b5cSPatrick Sanan Notes: 2811bb7acecfSBarry Smith The communication involved in this update can be overlapped with computation by instead using 2812bb7acecfSBarry Smith `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. 2813bb7acecfSBarry Smith 2814bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 281501729b5cSPatrick Sanan 28161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocalHookAdd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, 281760225df5SJacob Faibussowitsch `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, 2818bb7acecfSBarry Smith `DMGlobalToLocalBegin()` `DMGlobalToLocalEnd()` 281901729b5cSPatrick Sanan @*/ 2820d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocal(DM dm, Vec g, InsertMode mode, Vec l) 2821d71ae5a4SJacob Faibussowitsch { 282201729b5cSPatrick Sanan PetscFunctionBegin; 28239566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, g, mode, l)); 28249566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, g, mode, l)); 28253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 282601729b5cSPatrick Sanan } 282701729b5cSPatrick Sanan 282801729b5cSPatrick Sanan /*@ 282947c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 283047c6ae99SBarry Smith 283120f4b53cSBarry Smith Neighbor-wise Collective 283247c6ae99SBarry Smith 283347c6ae99SBarry Smith Input Parameters: 2834bb7acecfSBarry Smith + dm - the `DM` object 283547c6ae99SBarry Smith . g - the global vector 2836bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 283747c6ae99SBarry Smith - l - the local vector 283847c6ae99SBarry Smith 283901729b5cSPatrick Sanan Level: intermediate 284047c6ae99SBarry Smith 2841bb7acecfSBarry Smith Notes: 2842bb7acecfSBarry Smith The operation is completed with `DMGlobalToLocalEnd()` 2843bb7acecfSBarry Smith 2844bb7acecfSBarry Smith One can perform local computations between the `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to overlap communication and computation 2845bb7acecfSBarry Smith 2846bb7acecfSBarry Smith `DMGlobalToLocal()` is a short form of `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` 2847bb7acecfSBarry Smith 2848bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 2849bb7acecfSBarry Smith 285060225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 285147c6ae99SBarry Smith @*/ 2852d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 2853d71ae5a4SJacob Faibussowitsch { 28547128ae9fSMatthew G Knepley PetscSF sf; 2855baf369e7SPeter Brune DMGlobalToLocalHookLink link; 285647c6ae99SBarry Smith 285747c6ae99SBarry Smith PetscFunctionBegin; 2858171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2859baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 28601baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, g, mode, l, link->ctx)); 2861baf369e7SPeter Brune } 28629566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28637128ae9fSMatthew G Knepley if (sf) { 2864ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2865ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2866d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 28677128ae9fSMatthew G Knepley 28687a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28699566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28709566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28719566063dSJacob Faibussowitsch PetscCall(PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE)); 28729566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28739566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28747128ae9fSMatthew G Knepley } else { 2875fa1e479aSStefano Zampini PetscUseTypeMethod(dm, globaltolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 28767128ae9fSMatthew G Knepley } 28773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 287847c6ae99SBarry Smith } 287947c6ae99SBarry Smith 288047c6ae99SBarry Smith /*@ 288147c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 288247c6ae99SBarry Smith 288320f4b53cSBarry Smith Neighbor-wise Collective 288447c6ae99SBarry Smith 288547c6ae99SBarry Smith Input Parameters: 2886bb7acecfSBarry Smith + dm - the `DM` object 288747c6ae99SBarry Smith . g - the global vector 2888bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 288947c6ae99SBarry Smith - l - the local vector 289047c6ae99SBarry Smith 289101729b5cSPatrick Sanan Level: intermediate 289247c6ae99SBarry Smith 2893bb7acecfSBarry Smith Note: 2894bb7acecfSBarry Smith See `DMGlobalToLocalBegin()` for details. 2895bb7acecfSBarry Smith 289660225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 289747c6ae99SBarry Smith @*/ 2898d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 2899d71ae5a4SJacob Faibussowitsch { 29007128ae9fSMatthew G Knepley PetscSF sf; 2901ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2902ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2903ca3d3a14SMatthew G. Knepley PetscBool transform; 2904baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2905d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 290647c6ae99SBarry Smith 290747c6ae99SBarry Smith PetscFunctionBegin; 2908171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29099566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 29109566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 29117128ae9fSMatthew G Knepley if (sf) { 29127a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 29137128ae9fSMatthew G Knepley 29149566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 29159566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 29169566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray, MPI_REPLACE)); 29179566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 29189566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 29199566063dSJacob Faibussowitsch if (transform) PetscCall(DMPlexGlobalToLocalBasis(dm, l)); 29207128ae9fSMatthew G Knepley } else { 2921fa1e479aSStefano Zampini PetscUseTypeMethod(dm, globaltolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 29227128ae9fSMatthew G Knepley } 29239566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalHook_Constraints(dm, g, mode, l, NULL)); 2924baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 29259566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 2926baf369e7SPeter Brune } 29273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 292847c6ae99SBarry Smith } 292947c6ae99SBarry Smith 2930d4d07f1eSToby Isaac /*@C 2931d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2932d4d07f1eSToby Isaac 293320f4b53cSBarry Smith Logically Collective 2934d4d07f1eSToby Isaac 29354165533cSJose E. Roman Input Parameters: 2936bb7acecfSBarry Smith + dm - the `DM` 2937bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMLocalToGlobalBegin()` 2938bb7acecfSBarry Smith . endhook - function to run after `DMLocalToGlobalEnd()` has completed 293920f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2940d4d07f1eSToby Isaac 294120f4b53cSBarry Smith Calling sequence of `beginhook`: 2942a4e35b19SJacob Faibussowitsch + global - global `DM` 2943d4d07f1eSToby Isaac . l - local vector 2944d4d07f1eSToby Isaac . mode - mode 2945d4d07f1eSToby Isaac . g - global vector 2946d4d07f1eSToby Isaac - ctx - optional user-defined function context 2947d4d07f1eSToby Isaac 294820f4b53cSBarry Smith Calling sequence of `endhook`: 2949bb7acecfSBarry Smith + global - global `DM` 2950d4d07f1eSToby Isaac . l - local vector 2951d4d07f1eSToby Isaac . mode - mode 2952d4d07f1eSToby Isaac . g - global vector 2953d4d07f1eSToby Isaac - ctx - optional user-defined function context 2954d4d07f1eSToby Isaac 2955d4d07f1eSToby Isaac Level: advanced 2956d4d07f1eSToby Isaac 29571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMRefineHookAdd()`, `DMGlobalToLocalHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2958d4d07f1eSToby Isaac @*/ 2959a4e35b19SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalHookAdd(DM dm, PetscErrorCode (*beginhook)(DM global, Vec l, InsertMode mode, Vec g, void *ctx), PetscErrorCode (*endhook)(DM global, Vec l, InsertMode mode, Vec g, void *ctx), void *ctx) 2960d71ae5a4SJacob Faibussowitsch { 2961d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, *p; 2962d4d07f1eSToby Isaac 2963d4d07f1eSToby Isaac PetscFunctionBegin; 2964d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2965d4d07f1eSToby Isaac for (p = &dm->ltoghook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 29669566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2967d4d07f1eSToby Isaac link->beginhook = beginhook; 2968d4d07f1eSToby Isaac link->endhook = endhook; 2969d4d07f1eSToby Isaac link->ctx = ctx; 2970d4d07f1eSToby Isaac link->next = NULL; 2971d4d07f1eSToby Isaac *p = link; 29723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2973d4d07f1eSToby Isaac } 2974d4d07f1eSToby Isaac 2975d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 2976d71ae5a4SJacob Faibussowitsch { 29774c274da1SToby Isaac PetscFunctionBegin; 2978a4e35b19SJacob Faibussowitsch (void)g; 2979a4e35b19SJacob Faibussowitsch (void)ctx; 29804c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29812b6b7d09SToby Isaac if (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES) { 29822b6b7d09SToby Isaac Mat cMat; 29832b6b7d09SToby Isaac Vec cVec; 29845db9a05bSToby Isaac PetscInt nRows; 29852b6b7d09SToby Isaac PetscSection section, cSec; 29862b6b7d09SToby Isaac PetscInt pStart, pEnd, p, dof; 29872b6b7d09SToby Isaac 29882b6b7d09SToby Isaac PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, NULL)); 29892b6b7d09SToby Isaac if (!cMat) PetscFunctionReturn(PETSC_SUCCESS); 29905db9a05bSToby Isaac 29919566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 29923ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 29939566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 29949566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 29959566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 29964c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 29979566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 29984c274da1SToby Isaac if (dof) { 29994c274da1SToby Isaac PetscInt d; 30004c274da1SToby Isaac PetscScalar *vals; 30019566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(l, section, p, &vals)); 30029566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(cVec, cSec, p, vals, mode)); 30034c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 30044c274da1SToby Isaac * we just extracted */ 3005ad540459SPierre Jolivet for (d = 0; d < dof; d++) vals[d] = 0.; 30064c274da1SToby Isaac } 30074c274da1SToby Isaac } 30089566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd(cMat, cVec, l, l)); 30099566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 30104c274da1SToby Isaac } 30113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30124c274da1SToby Isaac } 301301729b5cSPatrick Sanan /*@ 301401729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 301501729b5cSPatrick Sanan 301620f4b53cSBarry Smith Neighbor-wise Collective 301701729b5cSPatrick Sanan 301801729b5cSPatrick Sanan Input Parameters: 3019bb7acecfSBarry Smith + dm - the `DM` object 302001729b5cSPatrick Sanan . l - the local vector 3021bb7acecfSBarry Smith . mode - if `INSERT_VALUES` then no parallel communication is used, if `ADD_VALUES` then all ghost points from the same base point accumulate into that base point. 302201729b5cSPatrick Sanan - g - the global vector 302301729b5cSPatrick Sanan 302420f4b53cSBarry Smith Level: beginner 302520f4b53cSBarry Smith 302601729b5cSPatrick Sanan Notes: 302701729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 3028bb7acecfSBarry Smith `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. 302901729b5cSPatrick Sanan 3030bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 3031bb7acecfSBarry Smith 3032bb7acecfSBarry Smith `INSERT_VALUES` is not supported for `DMDA`; in that case simply compute the values directly into a global vector instead of a local one. 3033bb7acecfSBarry Smith 3034bb7acecfSBarry Smith Use `DMLocalToGlobalHookAdd()` to add additional operations that are performed on the data during the update process 303501729b5cSPatrick Sanan 30361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalHookAdd()`, `DMGlobaToLocallHookAdd()` 303701729b5cSPatrick Sanan @*/ 3038d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobal(DM dm, Vec l, InsertMode mode, Vec g) 3039d71ae5a4SJacob Faibussowitsch { 304001729b5cSPatrick Sanan PetscFunctionBegin; 30419566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, l, mode, g)); 30429566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, l, mode, g)); 30433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 304401729b5cSPatrick Sanan } 30454c274da1SToby Isaac 304647c6ae99SBarry Smith /*@ 304701729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 30489a42bb27SBarry Smith 304920f4b53cSBarry Smith Neighbor-wise Collective 30509a42bb27SBarry Smith 30519a42bb27SBarry Smith Input Parameters: 3052bb7acecfSBarry Smith + dm - the `DM` object 3053f6813fd5SJed Brown . l - the local vector 3054aa624791SPierre Jolivet . mode - if `INSERT_VALUES` then no parallel communication is used, if `ADD_VALUES` then all ghost points from the same base point accumulate into that base point. 30551eb28f2eSBarry Smith - g - the global vector 30569a42bb27SBarry Smith 305720f4b53cSBarry Smith Level: intermediate 305820f4b53cSBarry Smith 305995452b02SPatrick Sanan Notes: 3060bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 3061bb7acecfSBarry Smith 3062bb7acecfSBarry Smith `INSERT_VALUES is` not supported for `DMDA`, in that case simply compute the values directly into a global vector instead of a local one. 3063bb7acecfSBarry Smith 3064bb7acecfSBarry Smith Use `DMLocalToGlobalEnd()` to complete the communication process. 3065bb7acecfSBarry Smith 3066bb7acecfSBarry Smith `DMLocalToGlobal()` is a short form of `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()` 3067bb7acecfSBarry Smith 3068bb7acecfSBarry Smith `DMLocalToGlobalHookAdd()` may be used to provide additional operations that are performed during the update process. 30699a42bb27SBarry Smith 30701cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()` 30719a42bb27SBarry Smith @*/ 3072d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBegin(DM dm, Vec l, InsertMode mode, Vec g) 3073d71ae5a4SJacob Faibussowitsch { 30747128ae9fSMatthew G Knepley PetscSF sf; 307584330215SMatthew G. Knepley PetscSection s, gs; 3076d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3077ca3d3a14SMatthew G. Knepley Vec tmpl; 3078ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3079ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3080fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 3081d0295fc0SJunchao Zhang PetscMemType lmtype = PETSC_MEMTYPE_HOST, gmtype = PETSC_MEMTYPE_HOST; 30829a42bb27SBarry Smith 30839a42bb27SBarry Smith PetscFunctionBegin; 3084171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3085d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 30861baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, l, mode, g, link->ctx)); 3087d4d07f1eSToby Isaac } 30889566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalHook_Constraints(dm, l, mode, g, NULL)); 30899566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 30909566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 30917128ae9fSMatthew G Knepley switch (mode) { 30927128ae9fSMatthew G Knepley case INSERT_VALUES: 30937128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 3094d71ae5a4SJacob Faibussowitsch case INSERT_BC_VALUES: 3095d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3096d71ae5a4SJacob Faibussowitsch break; 30977128ae9fSMatthew G Knepley case ADD_VALUES: 30987128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 3099d71ae5a4SJacob Faibussowitsch case ADD_BC_VALUES: 3100d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3101d71ae5a4SJacob Faibussowitsch break; 3102d71ae5a4SJacob Faibussowitsch default: 3103d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 31047128ae9fSMatthew G Knepley } 3105ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 31069566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3107ca3d3a14SMatthew G. Knepley if (transform) { 31089566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 31099566063dSJacob Faibussowitsch PetscCall(VecCopy(l, tmpl)); 31109566063dSJacob Faibussowitsch PetscCall(DMPlexLocalToGlobalBasis(dm, tmpl)); 31119566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3112fa88e482SJed Brown } else if (isInsert) { 31139566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(l, &lArray)); 3114fa88e482SJed Brown } else { 31159566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, &lmtype)); 3116fa88e482SJed Brown l_inplace = PETSC_TRUE; 3117ca3d3a14SMatthew G. Knepley } 3118fa88e482SJed Brown if (s && isInsert) { 31199566063dSJacob Faibussowitsch PetscCall(VecGetArray(g, &gArray)); 3120fa88e482SJed Brown } else { 31219566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, &gmtype)); 3122fa88e482SJed Brown g_inplace = PETSC_TRUE; 3123fa88e482SJed Brown } 3124ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 31259566063dSJacob Faibussowitsch PetscCall(PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM)); 312684330215SMatthew G. Knepley } else if (s && isInsert) { 312784330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 312884330215SMatthew G. Knepley 31299566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 31309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 31319566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g, &gStart, NULL)); 313284330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3133b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 313484330215SMatthew G. Knepley 31359566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 31369566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(gs, p, &gdof)); 31379566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 31389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(gs, p, &gcdof)); 31399566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(s, p, &off)); 31409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(gs, p, &goff)); 3141b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 314203442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 31437a8be351SBarry Smith PetscCheck(dof == gdof, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %" PetscInt_FMT " dof: %" PetscInt_FMT " gdof: %" PetscInt_FMT " cdof: %" PetscInt_FMT " gcdof: %" PetscInt_FMT, p, dof, gdof, cdof, gcdof); 3144b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 3145b3b16f48SMatthew G. Knepley if (!gcdof) { 314684330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff - gStart + d] = lArray[off + d]; 3147b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 3148b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 314984330215SMatthew G. Knepley const PetscInt *cdofs; 315084330215SMatthew G. Knepley PetscInt cind = 0; 315184330215SMatthew G. Knepley 31529566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(s, p, &cdofs)); 3153b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 31549371c9d4SSatish Balay if ((cind < cdof) && (d == cdofs[cind])) { 31559371c9d4SSatish Balay ++cind; 31569371c9d4SSatish Balay continue; 31579371c9d4SSatish Balay } 3158b3b16f48SMatthew G. Knepley gArray[goff - gStart + e++] = lArray[off + d]; 315984330215SMatthew G. Knepley } 31607a8be351SBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %" PetscInt_FMT " dof: %" PetscInt_FMT " gdof: %" PetscInt_FMT " cdof: %" PetscInt_FMT " gcdof: %" PetscInt_FMT, p, dof, gdof, cdof, gcdof); 316184330215SMatthew G. Knepley } 3162ca3d3a14SMatthew G. Knepley } 3163fa88e482SJed Brown if (g_inplace) { 31649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 3165fa88e482SJed Brown } else { 31669566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(g, &gArray)); 3167fa88e482SJed Brown } 3168ca3d3a14SMatthew G. Knepley if (transform) { 31699566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31709566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3171fa88e482SJed Brown } else if (l_inplace) { 31729566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3173ca3d3a14SMatthew G. Knepley } else { 31749566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(l, &lArray)); 3175ca3d3a14SMatthew G. Knepley } 31767128ae9fSMatthew G Knepley } else { 3177fa1e479aSStefano Zampini PetscUseTypeMethod(dm, localtoglobalbegin, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g); 31787128ae9fSMatthew G Knepley } 31793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31809a42bb27SBarry Smith } 31819a42bb27SBarry Smith 31829a42bb27SBarry Smith /*@ 31839a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 318447c6ae99SBarry Smith 318520f4b53cSBarry Smith Neighbor-wise Collective 318647c6ae99SBarry Smith 318747c6ae99SBarry Smith Input Parameters: 3188bb7acecfSBarry Smith + dm - the `DM` object 3189f6813fd5SJed Brown . l - the local vector 3190bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 3191f6813fd5SJed Brown - g - the global vector 319247c6ae99SBarry Smith 319301729b5cSPatrick Sanan Level: intermediate 319447c6ae99SBarry Smith 3195bb7acecfSBarry Smith Note: 3196bb7acecfSBarry Smith See `DMLocalToGlobalBegin()` for full details 3197bb7acecfSBarry Smith 319860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()` 319947c6ae99SBarry Smith @*/ 3200d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEnd(DM dm, Vec l, InsertMode mode, Vec g) 3201d71ae5a4SJacob Faibussowitsch { 32027128ae9fSMatthew G Knepley PetscSF sf; 320384330215SMatthew G. Knepley PetscSection s; 3204d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3205ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 320647c6ae99SBarry Smith 320747c6ae99SBarry Smith PetscFunctionBegin; 3208171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32099566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 32109566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 32117128ae9fSMatthew G Knepley switch (mode) { 32127128ae9fSMatthew G Knepley case INSERT_VALUES: 3213d71ae5a4SJacob Faibussowitsch case INSERT_ALL_VALUES: 3214d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3215d71ae5a4SJacob Faibussowitsch break; 32167128ae9fSMatthew G Knepley case ADD_VALUES: 3217d71ae5a4SJacob Faibussowitsch case ADD_ALL_VALUES: 3218d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3219d71ae5a4SJacob Faibussowitsch break; 3220d71ae5a4SJacob Faibussowitsch default: 3221d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 32227128ae9fSMatthew G Knepley } 322384330215SMatthew G. Knepley if (sf && !isInsert) { 3224ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3225ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3226ca3d3a14SMatthew G. Knepley Vec tmpl; 322784330215SMatthew G. Knepley 32289566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3229ca3d3a14SMatthew G. Knepley if (transform) { 32309566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 32319566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3232ca3d3a14SMatthew G. Knepley } else { 32339566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, NULL)); 3234ca3d3a14SMatthew G. Knepley } 32359566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, NULL)); 32369566063dSJacob Faibussowitsch PetscCall(PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM)); 3237ca3d3a14SMatthew G. Knepley if (transform) { 32389566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 32399566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3240ca3d3a14SMatthew G. Knepley } else { 32419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3242ca3d3a14SMatthew G. Knepley } 32439566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 324484330215SMatthew G. Knepley } else if (s && isInsert) { 32457128ae9fSMatthew G Knepley } else { 3246fa1e479aSStefano Zampini PetscUseTypeMethod(dm, localtoglobalend, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g); 32477128ae9fSMatthew G Knepley } 3248d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 32499566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 3250d4d07f1eSToby Isaac } 32513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 325247c6ae99SBarry Smith } 325347c6ae99SBarry Smith 3254f089877aSRichard Tran Mills /*@ 3255a4e35b19SJacob Faibussowitsch DMLocalToLocalBegin - Begins the process of mapping values from a local vector (that include 3256a4e35b19SJacob Faibussowitsch ghost points that contain irrelevant values) to another local vector where the ghost points 3257a4e35b19SJacob Faibussowitsch in the second are set correctly from values on other MPI ranks. 3258f089877aSRichard Tran Mills 325920f4b53cSBarry Smith Neighbor-wise Collective 3260f089877aSRichard Tran Mills 3261f089877aSRichard Tran Mills Input Parameters: 3262bb7acecfSBarry Smith + dm - the `DM` object 3263bc0a1609SRichard Tran Mills . g - the original local vector 3264bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3265f089877aSRichard Tran Mills 3266bc0a1609SRichard Tran Mills Output Parameter: 3267bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3268f089877aSRichard Tran Mills 3269f089877aSRichard Tran Mills Level: intermediate 3270f089877aSRichard Tran Mills 327173ff1848SBarry Smith Note: 3272a4e35b19SJacob Faibussowitsch Must be followed by `DMLocalToLocalEnd()`. 3273a4e35b19SJacob Faibussowitsch 327460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3275f089877aSRichard Tran Mills @*/ 3276d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 3277d71ae5a4SJacob Faibussowitsch { 3278f089877aSRichard Tran Mills PetscFunctionBegin; 3279f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32809f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 32819f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 32829f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 32833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3284f089877aSRichard Tran Mills } 3285f089877aSRichard Tran Mills 3286f089877aSRichard Tran Mills /*@ 3287bb7acecfSBarry Smith DMLocalToLocalEnd - Maps from a local vector to another local vector where the ghost 3288bb7acecfSBarry Smith points in the second are set correctly. Must be preceded by `DMLocalToLocalBegin()`. 3289f089877aSRichard Tran Mills 329020f4b53cSBarry Smith Neighbor-wise Collective 3291f089877aSRichard Tran Mills 3292f089877aSRichard Tran Mills Input Parameters: 329360225df5SJacob Faibussowitsch + dm - the `DM` object 3294bc0a1609SRichard Tran Mills . g - the original local vector 3295bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3296f089877aSRichard Tran Mills 3297bc0a1609SRichard Tran Mills Output Parameter: 3298bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3299f089877aSRichard Tran Mills 3300f089877aSRichard Tran Mills Level: intermediate 3301f089877aSRichard Tran Mills 330260225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3303f089877aSRichard Tran Mills @*/ 3304d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 3305d71ae5a4SJacob Faibussowitsch { 3306f089877aSRichard Tran Mills PetscFunctionBegin; 3307f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 33089f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 33099f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 33109f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 33113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3312f089877aSRichard Tran Mills } 3313f089877aSRichard Tran Mills 331447c6ae99SBarry Smith /*@ 3315bb7acecfSBarry Smith DMCoarsen - Coarsens a `DM` object using a standard, non-adaptive coarsening of the underlying mesh 331647c6ae99SBarry Smith 331720f4b53cSBarry Smith Collective 331847c6ae99SBarry Smith 3319d8d19677SJose E. Roman Input Parameters: 3320bb7acecfSBarry Smith + dm - the `DM` object 332120f4b53cSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 332247c6ae99SBarry Smith 332347c6ae99SBarry Smith Output Parameter: 3324bb7acecfSBarry Smith . dmc - the coarsened `DM` 332547c6ae99SBarry Smith 332647c6ae99SBarry Smith Level: developer 332747c6ae99SBarry Smith 332873ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateDomainDecomposition()`, 332973ff1848SBarry Smith `DMCoarsenHookAdd()`, `DMCoarsenHookRemove()` 333047c6ae99SBarry Smith @*/ 3331d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 3332d71ae5a4SJacob Faibussowitsch { 3333b17ce1afSJed Brown DMCoarsenHookLink link; 333447c6ae99SBarry Smith 333547c6ae99SBarry Smith PetscFunctionBegin; 3336171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 33379566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Coarsen, dm, 0, 0, 0)); 3338dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsen, comm, dmc); 3339b9d85ea2SLisandro Dalcin if (*dmc) { 3340a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 33419566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm, *dmc)); 334243842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 33439566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmc)); 3344644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 33450598a293SJed Brown (*dmc)->levelup = dm->levelup; 3346656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 33479566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmc, dm->mattype)); 3348b17ce1afSJed Brown for (link = dm->coarsenhook; link; link = link->next) { 33499566063dSJacob Faibussowitsch if (link->coarsenhook) PetscCall((*link->coarsenhook)(dm, *dmc, link->ctx)); 3350b17ce1afSJed Brown } 3351b9d85ea2SLisandro Dalcin } 33529566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Coarsen, dm, 0, 0, 0)); 33537a8be351SBarry Smith PetscCheck(*dmc, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 33543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3355b17ce1afSJed Brown } 3356b17ce1afSJed Brown 3357bb9467b5SJed Brown /*@C 3358b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3359b17ce1afSJed Brown 336020f4b53cSBarry Smith Logically Collective; No Fortran Support 3361b17ce1afSJed Brown 33624165533cSJose E. Roman Input Parameters: 3363bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3364b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3365bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels (called once per `SNESSolve()`) 336620f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3367b17ce1afSJed Brown 336820f4b53cSBarry Smith Calling sequence of `coarsenhook`: 3369bb7acecfSBarry Smith + fine - fine level `DM` 3370bb7acecfSBarry Smith . coarse - coarse level `DM` to restrict problem to 3371b17ce1afSJed Brown - ctx - optional user-defined function context 3372b17ce1afSJed Brown 337320f4b53cSBarry Smith Calling sequence of `restricthook`: 3374bb7acecfSBarry Smith + fine - fine level `DM` 3375bb7acecfSBarry Smith . mrestrict - matrix restricting a fine-level solution to the coarse grid, usually the transpose of the interpolation 3376c833c3b5SJed Brown . rscale - scaling vector for restriction 3377c833c3b5SJed Brown . inject - matrix restricting by injection 3378b17ce1afSJed Brown . coarse - coarse level DM to update 3379b17ce1afSJed Brown - ctx - optional user-defined function context 3380b17ce1afSJed Brown 3381b17ce1afSJed Brown Level: advanced 3382b17ce1afSJed Brown 3383b17ce1afSJed Brown Notes: 3384bb7acecfSBarry Smith This function is only needed if auxiliary data, attached to the `DM` with `PetscObjectCompose()`, needs to be set up or passed from the fine `DM` to the coarse `DM`. 3385b17ce1afSJed Brown 3386b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3387b17ce1afSJed Brown 3388b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3389bb7acecfSBarry Smith extract the finest level information from its context (instead of from the `SNES`). 3390b17ce1afSJed Brown 3391bb7acecfSBarry Smith The hooks are automatically called by `DMRestrict()` 3392bb7acecfSBarry Smith 33931cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3394b17ce1afSJed Brown @*/ 3395a4e35b19SJacob Faibussowitsch PetscErrorCode DMCoarsenHookAdd(DM fine, PetscErrorCode (*coarsenhook)(DM fine, DM coarse, void *ctx), PetscErrorCode (*restricthook)(DM fine, Mat mrestrict, Vec rscale, Mat inject, DM coarse, void *ctx), void *ctx) 3396d71ae5a4SJacob Faibussowitsch { 3397b17ce1afSJed Brown DMCoarsenHookLink link, *p; 3398b17ce1afSJed Brown 3399b17ce1afSJed Brown PetscFunctionBegin; 3400b17ce1afSJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 34011e3d8eccSJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 34023ba16761SJacob Faibussowitsch if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 34031e3d8eccSJed Brown } 34049566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3405b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3406b17ce1afSJed Brown link->restricthook = restricthook; 3407b17ce1afSJed Brown link->ctx = ctx; 34080298fd71SBarry Smith link->next = NULL; 3409b17ce1afSJed Brown *p = link; 34103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3411b17ce1afSJed Brown } 3412b17ce1afSJed Brown 3413dc822a44SJed Brown /*@C 3414bb7acecfSBarry Smith DMCoarsenHookRemove - remove a callback set with `DMCoarsenHookAdd()` 3415dc822a44SJed Brown 341620f4b53cSBarry Smith Logically Collective; No Fortran Support 3417dc822a44SJed Brown 34184165533cSJose E. Roman Input Parameters: 3419bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3420dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3421bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels 342220f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3423dc822a44SJed Brown 3424dc822a44SJed Brown Level: advanced 3425dc822a44SJed Brown 342673ff1848SBarry Smith Notes: 342773ff1848SBarry Smith This function does nothing if the `coarsenhook` is not in the list. 342873ff1848SBarry Smith 342973ff1848SBarry Smith See `DMCoarsenHookAdd()` for the calling sequence of `coarsenhook` and `restricthook` 3430dc822a44SJed Brown 34311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3432dc822a44SJed Brown @*/ 3433d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHookRemove(DM fine, PetscErrorCode (*coarsenhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, Mat, Vec, Mat, DM, void *), void *ctx) 3434d71ae5a4SJacob Faibussowitsch { 3435dc822a44SJed Brown DMCoarsenHookLink link, *p; 3436dc822a44SJed Brown 3437dc822a44SJed Brown PetscFunctionBegin; 3438dc822a44SJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 3439dc822a44SJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3440dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3441dc822a44SJed Brown link = *p; 3442dc822a44SJed Brown *p = link->next; 34439566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3444dc822a44SJed Brown break; 3445dc822a44SJed Brown } 3446dc822a44SJed Brown } 34473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3448dc822a44SJed Brown } 3449dc822a44SJed Brown 3450b17ce1afSJed Brown /*@ 3451bb7acecfSBarry Smith DMRestrict - restricts user-defined problem data to a coarser `DM` by running hooks registered by `DMCoarsenHookAdd()` 3452b17ce1afSJed Brown 3453b17ce1afSJed Brown Collective if any hooks are 3454b17ce1afSJed Brown 34554165533cSJose E. Roman Input Parameters: 3456bb7acecfSBarry Smith + fine - finer `DM` from which the data is obtained 3457bb7acecfSBarry Smith . restrct - restriction matrix, apply using `MatRestrict()`, usually the transpose of the interpolation 3458e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3459bb7acecfSBarry Smith . inject - injection matrix, also use `MatRestrict()` 346020f4b53cSBarry Smith - coarse - coarser `DM` to update 3461b17ce1afSJed Brown 3462b17ce1afSJed Brown Level: developer 3463b17ce1afSJed Brown 346473ff1848SBarry Smith Developer Note: 3465bb7acecfSBarry Smith Though this routine is called `DMRestrict()` the hooks are added with `DMCoarsenHookAdd()`, a consistent terminology would be better 3466bb7acecfSBarry Smith 34671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `MatRestrict()`, `DMInterpolate()`, `DMRefineHookAdd()` 3468b17ce1afSJed Brown @*/ 3469d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestrict(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse) 3470d71ae5a4SJacob Faibussowitsch { 3471b17ce1afSJed Brown DMCoarsenHookLink link; 3472b17ce1afSJed Brown 3473b17ce1afSJed Brown PetscFunctionBegin; 3474b17ce1afSJed Brown for (link = fine->coarsenhook; link; link = link->next) { 34751baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(fine, restrct, rscale, inject, coarse, link->ctx)); 3476b17ce1afSJed Brown } 34773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 347847c6ae99SBarry Smith } 347947c6ae99SBarry Smith 3480bb9467b5SJed Brown /*@C 348173ff1848SBarry Smith DMSubDomainHookAdd - adds a callback to be run when restricting a problem to subdomain `DM`s with `DMCreateDomainDecomposition()` 34825dbd56e3SPeter Brune 348320f4b53cSBarry Smith Logically Collective; No Fortran Support 34845dbd56e3SPeter Brune 34854165533cSJose E. Roman Input Parameters: 3486bb7acecfSBarry Smith + global - global `DM` 3487bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 34885dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 348920f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 34905dbd56e3SPeter Brune 349120f4b53cSBarry Smith Calling sequence of `ddhook`: 3492bb7acecfSBarry Smith + global - global `DM` 349373ff1848SBarry Smith . block - subdomain `DM` 3494ec4806b8SPeter Brune - ctx - optional user-defined function context 3495ec4806b8SPeter Brune 349620f4b53cSBarry Smith Calling sequence of `restricthook`: 3497bb7acecfSBarry Smith + global - global `DM` 349873ff1848SBarry Smith . out - scatter to the outer (with ghost and overlap points) sub vector 349973ff1848SBarry Smith . in - scatter to sub vector values only owned locally 350073ff1848SBarry Smith . block - subdomain `DM` 35015dbd56e3SPeter Brune - ctx - optional user-defined function context 35025dbd56e3SPeter Brune 35035dbd56e3SPeter Brune Level: advanced 35045dbd56e3SPeter Brune 35055dbd56e3SPeter Brune Notes: 350673ff1848SBarry Smith This function can be used if auxiliary data needs to be set up on subdomain `DM`s. 35075dbd56e3SPeter Brune 35085dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 35095dbd56e3SPeter Brune 35105dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3511bb7acecfSBarry Smith extract the global information from its context (instead of from the `SNES`). 35125dbd56e3SPeter Brune 351373ff1848SBarry Smith Developer Note: 351473ff1848SBarry Smith It is unclear what "block solve" means within the definition of `restricthook` 351573ff1848SBarry Smith 351673ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()`, `DMCreateDomainDecomposition()` 35175dbd56e3SPeter Brune @*/ 3518a4e35b19SJacob Faibussowitsch PetscErrorCode DMSubDomainHookAdd(DM global, PetscErrorCode (*ddhook)(DM global, DM block, void *ctx), PetscErrorCode (*restricthook)(DM global, VecScatter out, VecScatter in, DM block, void *ctx), void *ctx) 3519d71ae5a4SJacob Faibussowitsch { 3520be081cd6SPeter Brune DMSubDomainHookLink link, *p; 35215dbd56e3SPeter Brune 35225dbd56e3SPeter Brune PetscFunctionBegin; 35235dbd56e3SPeter Brune PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3524b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 35253ba16761SJacob Faibussowitsch if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 3526b3a6b972SJed Brown } 35279566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 35285dbd56e3SPeter Brune link->restricthook = restricthook; 3529be081cd6SPeter Brune link->ddhook = ddhook; 35305dbd56e3SPeter Brune link->ctx = ctx; 35310298fd71SBarry Smith link->next = NULL; 35325dbd56e3SPeter Brune *p = link; 35333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35345dbd56e3SPeter Brune } 35355dbd56e3SPeter Brune 3536b3a6b972SJed Brown /*@C 353773ff1848SBarry Smith DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to subdomain `DM`s with `DMCreateDomainDecomposition()` 3538b3a6b972SJed Brown 353920f4b53cSBarry Smith Logically Collective; No Fortran Support 3540b3a6b972SJed Brown 35414165533cSJose E. Roman Input Parameters: 3542bb7acecfSBarry Smith + global - global `DM` 3543bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 3544b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 354520f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3546b3a6b972SJed Brown 3547b3a6b972SJed Brown Level: advanced 3548b3a6b972SJed Brown 354973ff1848SBarry Smith Note: 355073ff1848SBarry Smith See `DMSubDomainHookAdd()` for the calling sequences of `ddhook` and `restricthook` 355173ff1848SBarry Smith 355273ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()`, 355373ff1848SBarry Smith `DMCreateDomainDecomposition()` 3554b3a6b972SJed Brown @*/ 3555d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookRemove(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3556d71ae5a4SJacob Faibussowitsch { 3557b3a6b972SJed Brown DMSubDomainHookLink link, *p; 3558b3a6b972SJed Brown 3559b3a6b972SJed Brown PetscFunctionBegin; 3560b3a6b972SJed Brown PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3561b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3562b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3563b3a6b972SJed Brown link = *p; 3564b3a6b972SJed Brown *p = link->next; 35659566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3566b3a6b972SJed Brown break; 3567b3a6b972SJed Brown } 3568b3a6b972SJed Brown } 35693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3570b3a6b972SJed Brown } 3571b3a6b972SJed Brown 35725dbd56e3SPeter Brune /*@ 357373ff1848SBarry Smith DMSubDomainRestrict - restricts user-defined problem data to a subdomain `DM` by running hooks registered by `DMSubDomainHookAdd()` 35745dbd56e3SPeter Brune 35755dbd56e3SPeter Brune Collective if any hooks are 35765dbd56e3SPeter Brune 35774165533cSJose E. Roman Input Parameters: 3578a4e35b19SJacob Faibussowitsch + global - The global `DM` to use as a base 3579a4e35b19SJacob Faibussowitsch . oscatter - The scatter from domain global vector filling subdomain global vector with overlap 3580a4e35b19SJacob Faibussowitsch . gscatter - The scatter from domain global vector filling subdomain local vector with ghosts 3581a4e35b19SJacob Faibussowitsch - subdm - The subdomain `DM` to update 35825dbd56e3SPeter Brune 35835dbd56e3SPeter Brune Level: developer 35845dbd56e3SPeter Brune 358573ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `MatRestrict()`, `DMCreateDomainDecomposition()` 35865dbd56e3SPeter Brune @*/ 3587d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainRestrict(DM global, VecScatter oscatter, VecScatter gscatter, DM subdm) 3588d71ae5a4SJacob Faibussowitsch { 3589be081cd6SPeter Brune DMSubDomainHookLink link; 35905dbd56e3SPeter Brune 35915dbd56e3SPeter Brune PetscFunctionBegin; 3592be081cd6SPeter Brune for (link = global->subdomainhook; link; link = link->next) { 35931baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(global, oscatter, gscatter, subdm, link->ctx)); 35945dbd56e3SPeter Brune } 35953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35965dbd56e3SPeter Brune } 35975dbd56e3SPeter Brune 35985fe1f584SPeter Brune /*@ 3599bb7acecfSBarry Smith DMGetCoarsenLevel - Gets the number of coarsenings that have generated this `DM`. 36005fe1f584SPeter Brune 36015fe1f584SPeter Brune Not Collective 36025fe1f584SPeter Brune 36035fe1f584SPeter Brune Input Parameter: 3604bb7acecfSBarry Smith . dm - the `DM` object 36055fe1f584SPeter Brune 36065fe1f584SPeter Brune Output Parameter: 36076a7d9d85SPeter Brune . level - number of coarsenings 36085fe1f584SPeter Brune 36095fe1f584SPeter Brune Level: developer 36105fe1f584SPeter Brune 36111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMSetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 36125fe1f584SPeter Brune @*/ 3613d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarsenLevel(DM dm, PetscInt *level) 3614d71ae5a4SJacob Faibussowitsch { 36155fe1f584SPeter Brune PetscFunctionBegin; 36165fe1f584SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36174f572ea9SToby Isaac PetscAssertPointer(level, 2); 36185fe1f584SPeter Brune *level = dm->leveldown; 36193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36205fe1f584SPeter Brune } 36215fe1f584SPeter Brune 36229a64c4a8SMatthew G. Knepley /*@ 3623bb7acecfSBarry Smith DMSetCoarsenLevel - Sets the number of coarsenings that have generated this `DM`. 36249a64c4a8SMatthew G. Knepley 362520f4b53cSBarry Smith Collective 36269a64c4a8SMatthew G. Knepley 36279a64c4a8SMatthew G. Knepley Input Parameters: 3628bb7acecfSBarry Smith + dm - the `DM` object 36299a64c4a8SMatthew G. Knepley - level - number of coarsenings 36309a64c4a8SMatthew G. Knepley 36319a64c4a8SMatthew G. Knepley Level: developer 36329a64c4a8SMatthew G. Knepley 3633bb7acecfSBarry Smith Note: 3634bb7acecfSBarry Smith This is rarely used directly, the information is automatically set when a `DM` is created with `DMCoarsen()` 3635bb7acecfSBarry Smith 363642747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 36379a64c4a8SMatthew G. Knepley @*/ 3638d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarsenLevel(DM dm, PetscInt level) 3639d71ae5a4SJacob Faibussowitsch { 36409a64c4a8SMatthew G. Knepley PetscFunctionBegin; 36419a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36429a64c4a8SMatthew G. Knepley dm->leveldown = level; 36433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36449a64c4a8SMatthew G. Knepley } 36459a64c4a8SMatthew G. Knepley 3646cc4c1da9SBarry Smith /*@ 3647bb7acecfSBarry Smith DMRefineHierarchy - Refines a `DM` object, all levels at once 364847c6ae99SBarry Smith 364920f4b53cSBarry Smith Collective 365047c6ae99SBarry Smith 3651d8d19677SJose E. Roman Input Parameters: 3652bb7acecfSBarry Smith + dm - the `DM` object 365347c6ae99SBarry Smith - nlevels - the number of levels of refinement 365447c6ae99SBarry Smith 365547c6ae99SBarry Smith Output Parameter: 3656bb7acecfSBarry Smith . dmf - the refined `DM` hierarchy 365747c6ae99SBarry Smith 365847c6ae99SBarry Smith Level: developer 365947c6ae99SBarry Smith 36601cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMCoarsenHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 366147c6ae99SBarry Smith @*/ 3662d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHierarchy(DM dm, PetscInt nlevels, DM dmf[]) 3663d71ae5a4SJacob Faibussowitsch { 366447c6ae99SBarry Smith PetscFunctionBegin; 3665171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36667a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36673ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 36684f572ea9SToby Isaac PetscAssertPointer(dmf, 3); 3669213acdd3SPierre Jolivet if (dm->ops->refine && !dm->ops->refinehierarchy) { 367047c6ae99SBarry Smith PetscInt i; 367147c6ae99SBarry Smith 36729566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0])); 367348a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i])); 3674213acdd3SPierre Jolivet } else PetscUseTypeMethod(dm, refinehierarchy, nlevels, dmf); 36753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 367647c6ae99SBarry Smith } 367747c6ae99SBarry Smith 3678cc4c1da9SBarry Smith /*@ 3679bb7acecfSBarry Smith DMCoarsenHierarchy - Coarsens a `DM` object, all levels at once 368047c6ae99SBarry Smith 368120f4b53cSBarry Smith Collective 368247c6ae99SBarry Smith 3683d8d19677SJose E. Roman Input Parameters: 3684bb7acecfSBarry Smith + dm - the `DM` object 368547c6ae99SBarry Smith - nlevels - the number of levels of coarsening 368647c6ae99SBarry Smith 368747c6ae99SBarry Smith Output Parameter: 3688bb7acecfSBarry Smith . dmc - the coarsened `DM` hierarchy 368947c6ae99SBarry Smith 369047c6ae99SBarry Smith Level: developer 369147c6ae99SBarry Smith 36921cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMRefineHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 369347c6ae99SBarry Smith @*/ 3694d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 3695d71ae5a4SJacob Faibussowitsch { 369647c6ae99SBarry Smith PetscFunctionBegin; 3697171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36987a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36993ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 37004f572ea9SToby Isaac PetscAssertPointer(dmc, 3); 3701213acdd3SPierre Jolivet if (dm->ops->coarsen && !dm->ops->coarsenhierarchy) { 370247c6ae99SBarry Smith PetscInt i; 370347c6ae99SBarry Smith 37049566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0])); 370548a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i])); 3706213acdd3SPierre Jolivet } else PetscUseTypeMethod(dm, coarsenhierarchy, nlevels, dmc); 37073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 370847c6ae99SBarry Smith } 370947c6ae99SBarry Smith 37101a266240SBarry Smith /*@C 3711bb7acecfSBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the `DM` is destroyed 37121a266240SBarry Smith 3713bb7acecfSBarry Smith Logically Collective if the function is collective 37141a266240SBarry Smith 37151a266240SBarry Smith Input Parameters: 3716bb7acecfSBarry Smith + dm - the `DM` object 371749abdd8aSBarry Smith - destroy - the destroy function, see `PetscCtxDestroyFn` for the calling sequence 37181a266240SBarry Smith 37191a266240SBarry Smith Level: intermediate 37201a266240SBarry Smith 372149abdd8aSBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, 372249abdd8aSBarry Smith `DMGetApplicationContext()`, `PetscCtxDestroyFn` 3723f07f9ceaSJed Brown @*/ 372449abdd8aSBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm, PetscCtxDestroyFn *destroy) 3725d71ae5a4SJacob Faibussowitsch { 37261a266240SBarry Smith PetscFunctionBegin; 3727171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37281a266240SBarry Smith dm->ctxdestroy = destroy; 37293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37301a266240SBarry Smith } 37311a266240SBarry Smith 3732b07ff414SBarry Smith /*@ 3733bb7acecfSBarry Smith DMSetApplicationContext - Set a user context into a `DM` object 373447c6ae99SBarry Smith 373547c6ae99SBarry Smith Not Collective 373647c6ae99SBarry Smith 373747c6ae99SBarry Smith Input Parameters: 3738bb7acecfSBarry Smith + dm - the `DM` object 373947c6ae99SBarry Smith - ctx - the user context 374047c6ae99SBarry Smith 374147c6ae99SBarry Smith Level: intermediate 374247c6ae99SBarry Smith 3743ce78bad3SBarry Smith Note: 374435cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3745e33b3f0fSStefano Zampini In a multilevel solver, the user context is shared by all the `DM` in the hierarchy; it is thus not advisable 3746e33b3f0fSStefano Zampini to store objects that represent discretized quantities inside the context. 3747bb7acecfSBarry Smith 3748ce78bad3SBarry Smith Fortran Note: 3749ce78bad3SBarry Smith This only works when `ctx` is a Fortran derived type (it cannot be a `PetscObject`), we recommend writing a Fortran interface definition for this 3750ce78bad3SBarry Smith function that tells the Fortran compiler the derived data type that is passed in as the `ctx` argument. See `DMGetApplicationContext()` for 3751ce78bad3SBarry Smith an example. 3752ce78bad3SBarry Smith 375360225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 375447c6ae99SBarry Smith @*/ 3755d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContext(DM dm, void *ctx) 3756d71ae5a4SJacob Faibussowitsch { 375747c6ae99SBarry Smith PetscFunctionBegin; 3758171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 375947c6ae99SBarry Smith dm->ctx = ctx; 37603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 376147c6ae99SBarry Smith } 376247c6ae99SBarry Smith 376347c6ae99SBarry Smith /*@ 3764ce78bad3SBarry Smith DMGetApplicationContext - Gets a user context from a `DM` object provided with `DMSetApplicationContext()` 376547c6ae99SBarry Smith 376647c6ae99SBarry Smith Not Collective 376747c6ae99SBarry Smith 376847c6ae99SBarry Smith Input Parameter: 3769bb7acecfSBarry Smith . dm - the `DM` object 377047c6ae99SBarry Smith 377147c6ae99SBarry Smith Output Parameter: 3772ce78bad3SBarry Smith . ctx - a pointer to the user context 377347c6ae99SBarry Smith 377447c6ae99SBarry Smith Level: intermediate 377547c6ae99SBarry Smith 3776bb7acecfSBarry Smith Note: 377735cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3778bb7acecfSBarry Smith 3779ce78bad3SBarry Smith Fortran Notes: 3780ce78bad3SBarry Smith This only works when the context is a Fortran derived type (it cannot be a `PetscObject`) and you **must** write a Fortran interface definition for this 3781ce78bad3SBarry Smith function that tells the Fortran compiler the derived data type that is returned as the `ctx` argument. For example, 3782ce78bad3SBarry Smith .vb 3783ce78bad3SBarry Smith Interface DMGetApplicationContext 3784ce78bad3SBarry Smith Subroutine DMGetApplicationContext(dm,ctx,ierr) 3785ce78bad3SBarry Smith #include <petsc/finclude/petscdm.h> 3786ce78bad3SBarry Smith use petscdm 3787ce78bad3SBarry Smith DM dm 3788ce78bad3SBarry Smith type(tUsertype), pointer :: ctx 3789ce78bad3SBarry Smith PetscErrorCode ierr 3790ce78bad3SBarry Smith End Subroutine 3791ce78bad3SBarry Smith End Interface DMGetApplicationContext 3792ce78bad3SBarry Smith .ve 3793ce78bad3SBarry Smith 3794bfe80ac4SPierre Jolivet The prototype for `ctx` must be 3795ce78bad3SBarry Smith .vb 3796ce78bad3SBarry Smith type(tUsertype), pointer :: ctx 3797ce78bad3SBarry Smith .ve 3798ce78bad3SBarry Smith 379942747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 380047c6ae99SBarry Smith @*/ 3801ce78bad3SBarry Smith PetscErrorCode DMGetApplicationContext(DM dm, PeCtx ctx) 3802d71ae5a4SJacob Faibussowitsch { 380347c6ae99SBarry Smith PetscFunctionBegin; 3804171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38051b2093e4SBarry Smith *(void **)ctx = dm->ctx; 38063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 380747c6ae99SBarry Smith } 380847c6ae99SBarry Smith 380908da532bSDmitry Karpeev /*@C 3810bb7acecfSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for `SNESVI`. 381108da532bSDmitry Karpeev 381220f4b53cSBarry Smith Logically Collective 381308da532bSDmitry Karpeev 3814d8d19677SJose E. Roman Input Parameters: 381508da532bSDmitry Karpeev + dm - the DM object 3816ce78bad3SBarry Smith - f - the function that computes variable bounds used by `SNESVI` (use `NULL` to cancel a previous function that was set) 381708da532bSDmitry Karpeev 381808da532bSDmitry Karpeev Level: intermediate 381908da532bSDmitry Karpeev 3820ce78bad3SBarry Smith Developer Note: 3821ce78bad3SBarry Smith Should be called `DMSetComputeVIBounds()` or something similar 3822ce78bad3SBarry Smith 38231cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()`, 3824db781477SPatrick Sanan `DMSetJacobian()` 382508da532bSDmitry Karpeev @*/ 3826d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVariableBounds(DM dm, PetscErrorCode (*f)(DM, Vec, Vec)) 3827d71ae5a4SJacob Faibussowitsch { 382808da532bSDmitry Karpeev PetscFunctionBegin; 38295a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 383008da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 38313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 383208da532bSDmitry Karpeev } 383308da532bSDmitry Karpeev 383408da532bSDmitry Karpeev /*@ 3835bb7acecfSBarry Smith DMHasVariableBounds - does the `DM` object have a variable bounds function? 383608da532bSDmitry Karpeev 383708da532bSDmitry Karpeev Not Collective 383808da532bSDmitry Karpeev 383908da532bSDmitry Karpeev Input Parameter: 3840bb7acecfSBarry Smith . dm - the `DM` object to destroy 384108da532bSDmitry Karpeev 384208da532bSDmitry Karpeev Output Parameter: 3843bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the variable bounds function exists 384408da532bSDmitry Karpeev 384508da532bSDmitry Karpeev Level: developer 384608da532bSDmitry Karpeev 38471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 384808da532bSDmitry Karpeev @*/ 3849d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasVariableBounds(DM dm, PetscBool *flg) 3850d71ae5a4SJacob Faibussowitsch { 385108da532bSDmitry Karpeev PetscFunctionBegin; 38525a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38534f572ea9SToby Isaac PetscAssertPointer(flg, 2); 385408da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 38553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 385608da532bSDmitry Karpeev } 385708da532bSDmitry Karpeev 3858cc4c1da9SBarry Smith /*@ 3859bb7acecfSBarry Smith DMComputeVariableBounds - compute variable bounds used by `SNESVI`. 386008da532bSDmitry Karpeev 386120f4b53cSBarry Smith Logically Collective 386208da532bSDmitry Karpeev 3863f899ff85SJose E. Roman Input Parameter: 3864bb7acecfSBarry Smith . dm - the `DM` object 386508da532bSDmitry Karpeev 386660225df5SJacob Faibussowitsch Output Parameters: 386708da532bSDmitry Karpeev + xl - lower bound 386808da532bSDmitry Karpeev - xu - upper bound 386908da532bSDmitry Karpeev 3870907376e6SBarry Smith Level: advanced 3871907376e6SBarry Smith 387220f4b53cSBarry Smith Note: 387395452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 387408da532bSDmitry Karpeev 38751cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 387608da532bSDmitry Karpeev @*/ 3877d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 3878d71ae5a4SJacob Faibussowitsch { 387908da532bSDmitry Karpeev PetscFunctionBegin; 38805a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 388108da532bSDmitry Karpeev PetscValidHeaderSpecific(xl, VEC_CLASSID, 2); 38825a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu, VEC_CLASSID, 3); 3883dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, computevariablebounds, xl, xu); 38843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 388508da532bSDmitry Karpeev } 388608da532bSDmitry Karpeev 3887b0ae01b7SPeter Brune /*@ 3888bb7acecfSBarry Smith DMHasColoring - does the `DM` object have a method of providing a coloring? 3889b0ae01b7SPeter Brune 3890b0ae01b7SPeter Brune Not Collective 3891b0ae01b7SPeter Brune 3892b0ae01b7SPeter Brune Input Parameter: 3893b0ae01b7SPeter Brune . dm - the DM object 3894b0ae01b7SPeter Brune 3895b0ae01b7SPeter Brune Output Parameter: 3896bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateColoring()`. 3897b0ae01b7SPeter Brune 3898b0ae01b7SPeter Brune Level: developer 3899b0ae01b7SPeter Brune 39001cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateColoring()` 3901b0ae01b7SPeter Brune @*/ 3902d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasColoring(DM dm, PetscBool *flg) 3903d71ae5a4SJacob Faibussowitsch { 3904b0ae01b7SPeter Brune PetscFunctionBegin; 39055a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39064f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3907b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 39083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3909b0ae01b7SPeter Brune } 3910b0ae01b7SPeter Brune 39113ad4599aSBarry Smith /*@ 3912bb7acecfSBarry Smith DMHasCreateRestriction - does the `DM` object have a method of providing a restriction? 39133ad4599aSBarry Smith 39143ad4599aSBarry Smith Not Collective 39153ad4599aSBarry Smith 39163ad4599aSBarry Smith Input Parameter: 3917bb7acecfSBarry Smith . dm - the `DM` object 39183ad4599aSBarry Smith 39193ad4599aSBarry Smith Output Parameter: 3920bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateRestriction()`. 39213ad4599aSBarry Smith 39223ad4599aSBarry Smith Level: developer 39233ad4599aSBarry Smith 39241cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateRestriction()`, `DMHasCreateInterpolation()`, `DMHasCreateInjection()` 39253ad4599aSBarry Smith @*/ 3926d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateRestriction(DM dm, PetscBool *flg) 3927d71ae5a4SJacob Faibussowitsch { 39283ad4599aSBarry Smith PetscFunctionBegin; 39295a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39304f572ea9SToby Isaac PetscAssertPointer(flg, 2); 39313ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 39323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39333ad4599aSBarry Smith } 39343ad4599aSBarry Smith 3935a7058e45SLawrence Mitchell /*@ 3936bb7acecfSBarry Smith DMHasCreateInjection - does the `DM` object have a method of providing an injection? 3937a7058e45SLawrence Mitchell 3938a7058e45SLawrence Mitchell Not Collective 3939a7058e45SLawrence Mitchell 3940a7058e45SLawrence Mitchell Input Parameter: 3941bb7acecfSBarry Smith . dm - the `DM` object 3942a7058e45SLawrence Mitchell 3943a7058e45SLawrence Mitchell Output Parameter: 3944bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateInjection()`. 3945a7058e45SLawrence Mitchell 3946a7058e45SLawrence Mitchell Level: developer 3947a7058e45SLawrence Mitchell 39481cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateInjection()`, `DMHasCreateRestriction()`, `DMHasCreateInterpolation()` 3949a7058e45SLawrence Mitchell @*/ 3950d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateInjection(DM dm, PetscBool *flg) 3951d71ae5a4SJacob Faibussowitsch { 3952a7058e45SLawrence Mitchell PetscFunctionBegin; 39535a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39544f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3955dbbe0bcdSBarry Smith if (dm->ops->hascreateinjection) PetscUseTypeMethod(dm, hascreateinjection, flg); 3956ad540459SPierre Jolivet else *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 39573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3958a7058e45SLawrence Mitchell } 3959a7058e45SLawrence Mitchell 39600298fd71SBarry Smith PetscFunctionList DMList = NULL; 3961264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3962264ace61SBarry Smith 3963cc4c1da9SBarry Smith /*@ 3964bb7acecfSBarry Smith DMSetType - Builds a `DM`, for a particular `DM` implementation. 3965264ace61SBarry Smith 396620f4b53cSBarry Smith Collective 3967264ace61SBarry Smith 3968264ace61SBarry Smith Input Parameters: 3969bb7acecfSBarry Smith + dm - The `DM` object 3970bb7acecfSBarry Smith - method - The name of the `DMType`, for example `DMDA`, `DMPLEX` 3971264ace61SBarry Smith 3972264ace61SBarry Smith Options Database Key: 3973bb7acecfSBarry Smith . -dm_type <type> - Sets the `DM` type; use -help for a list of available types 3974264ace61SBarry Smith 3975264ace61SBarry Smith Level: intermediate 3976264ace61SBarry Smith 3977bb7acecfSBarry Smith Note: 39780462cc06SPierre Jolivet Of the `DM` is constructed by directly calling a function to construct a particular `DM`, for example, `DMDACreate2d()` or `DMPlexCreateBoxMesh()` 3979bb7acecfSBarry Smith 39801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMGetType()`, `DMCreate()`, `DMDACreate2d()` 3981264ace61SBarry Smith @*/ 3982d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetType(DM dm, DMType method) 3983d71ae5a4SJacob Faibussowitsch { 3984264ace61SBarry Smith PetscErrorCode (*r)(DM); 3985264ace61SBarry Smith PetscBool match; 3986264ace61SBarry Smith 3987264ace61SBarry Smith PetscFunctionBegin; 3988264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, method, &match)); 39903ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 3991264ace61SBarry Smith 39929566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 39939566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(DMList, method, &r)); 39947a8be351SBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3995264ace61SBarry Smith 3996dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, destroy); 39979566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops, sizeof(*dm->ops))); 39989566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)dm, method)); 39999566063dSJacob Faibussowitsch PetscCall((*r)(dm)); 40003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4001264ace61SBarry Smith } 4002264ace61SBarry Smith 4003cc4c1da9SBarry Smith /*@ 4004bb7acecfSBarry Smith DMGetType - Gets the `DM` type name (as a string) from the `DM`. 4005264ace61SBarry Smith 4006264ace61SBarry Smith Not Collective 4007264ace61SBarry Smith 4008264ace61SBarry Smith Input Parameter: 4009bb7acecfSBarry Smith . dm - The `DM` 4010264ace61SBarry Smith 4011264ace61SBarry Smith Output Parameter: 4012bb7acecfSBarry Smith . type - The `DMType` name 4013264ace61SBarry Smith 4014264ace61SBarry Smith Level: intermediate 4015264ace61SBarry Smith 40161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMSetType()`, `DMCreate()` 4017264ace61SBarry Smith @*/ 4018d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetType(DM dm, DMType *type) 4019d71ae5a4SJacob Faibussowitsch { 4020264ace61SBarry Smith PetscFunctionBegin; 4021264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 40224f572ea9SToby Isaac PetscAssertPointer(type, 2); 40239566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 4024264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 40253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4026264ace61SBarry Smith } 4027264ace61SBarry Smith 40285d83a8b1SBarry Smith /*@ 4029bb7acecfSBarry Smith DMConvert - Converts a `DM` to another `DM`, either of the same or different type. 403067a56275SMatthew G Knepley 403120f4b53cSBarry Smith Collective 403267a56275SMatthew G Knepley 403367a56275SMatthew G Knepley Input Parameters: 4034bb7acecfSBarry Smith + dm - the `DM` 4035bb7acecfSBarry Smith - newtype - new `DM` type (use "same" for the same type) 403667a56275SMatthew G Knepley 403767a56275SMatthew G Knepley Output Parameter: 4038bb7acecfSBarry Smith . M - pointer to new `DM` 403967a56275SMatthew G Knepley 404020f4b53cSBarry Smith Level: intermediate 404120f4b53cSBarry Smith 404273ff1848SBarry Smith Note: 4043bb7acecfSBarry Smith Cannot be used to convert a sequential `DM` to a parallel or a parallel to sequential, 4044bb7acecfSBarry Smith the MPI communicator of the generated `DM` is always the same as the communicator 4045bb7acecfSBarry Smith of the input `DM`. 404667a56275SMatthew G Knepley 40471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetType()`, `DMCreate()`, `DMClone()` 404867a56275SMatthew G Knepley @*/ 4049d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 4050d71ae5a4SJacob Faibussowitsch { 405167a56275SMatthew G Knepley DM B; 405267a56275SMatthew G Knepley char convname[256]; 4053c067b6caSMatthew G. Knepley PetscBool sametype /*, issame */; 405467a56275SMatthew G Knepley 405567a56275SMatthew G Knepley PetscFunctionBegin; 405667a56275SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 405767a56275SMatthew G Knepley PetscValidType(dm, 1); 40584f572ea9SToby Isaac PetscAssertPointer(M, 3); 40599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, newtype, &sametype)); 40609566063dSJacob Faibussowitsch /* PetscCall(PetscStrcmp(newtype, "same", &issame)); */ 4061c067b6caSMatthew G. Knepley if (sametype) { 4062c067b6caSMatthew G. Knepley *M = dm; 40639566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 40643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4065c067b6caSMatthew G. Knepley } else { 40660298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM *) = NULL; 406767a56275SMatthew G Knepley 406867a56275SMatthew G Knepley /* 406967a56275SMatthew G Knepley Order of precedence: 407067a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 407167a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 407267a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 407367a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 407467a56275SMatthew G Knepley 5) Use a really basic converter. 407567a56275SMatthew G Knepley */ 407667a56275SMatthew G Knepley 407767a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 40789566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40799566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40809566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40819566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40829566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40839566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)dm, convname, &conv)); 408467a56275SMatthew G Knepley if (conv) goto foundconv; 408567a56275SMatthew G Knepley 408667a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 40879566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &B)); 40889566063dSJacob Faibussowitsch PetscCall(DMSetType(B, newtype)); 40899566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40909566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40919566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40929566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40939566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40949566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 409567a56275SMatthew G Knepley if (conv) { 40969566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 409767a56275SMatthew G Knepley goto foundconv; 409867a56275SMatthew G Knepley } 409967a56275SMatthew G Knepley 410067a56275SMatthew G Knepley #if 0 410167a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 410267a56275SMatthew G Knepley conv = B->ops->convertfrom; 41039566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 410467a56275SMatthew G Knepley if (conv) goto foundconv; 410567a56275SMatthew G Knepley 410667a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 410767a56275SMatthew G Knepley if (dm->ops->convert) { 410867a56275SMatthew G Knepley conv = dm->ops->convert; 410967a56275SMatthew G Knepley } 411067a56275SMatthew G Knepley if (conv) goto foundconv; 411167a56275SMatthew G Knepley #endif 411267a56275SMatthew G Knepley 411367a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 411498921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject)dm)->type_name, newtype); 411567a56275SMatthew G Knepley 411667a56275SMatthew G Knepley foundconv: 41179566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Convert, dm, 0, 0, 0)); 41189566063dSJacob Faibussowitsch PetscCall((*conv)(dm, newtype, M)); 411912fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 412090b157c4SStefano Zampini { 41214fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 41226858538eSMatthew G. Knepley 41234fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 41244fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*M, maxCell, Lstart, L)); 4125c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 41269566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->vectype)); 41279566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*M)->vectype)); 41289566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->mattype)); 41299566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*M)->mattype)); 413012fa691eSMatthew G. Knepley } 41319566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Convert, dm, 0, 0, 0)); 413267a56275SMatthew G Knepley } 41339566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 41343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 413567a56275SMatthew G Knepley } 4136264ace61SBarry Smith 4137264ace61SBarry Smith /*@C 4138bb7acecfSBarry Smith DMRegister - Adds a new `DM` type implementation 41391c84c290SBarry Smith 4140cc4c1da9SBarry Smith Not Collective, No Fortran Support 41411c84c290SBarry Smith 41421c84c290SBarry Smith Input Parameters: 414320f4b53cSBarry Smith + sname - The name of a new user-defined creation routine 414420f4b53cSBarry Smith - function - The creation routine itself 414520f4b53cSBarry Smith 414620f4b53cSBarry Smith Level: advanced 41471c84c290SBarry Smith 414873ff1848SBarry Smith Note: 414920f4b53cSBarry Smith `DMRegister()` may be called multiple times to add several user-defined `DM`s 41501c84c290SBarry Smith 415160225df5SJacob Faibussowitsch Example Usage: 41521c84c290SBarry Smith .vb 4153bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 41541c84c290SBarry Smith .ve 41551c84c290SBarry Smith 415620f4b53cSBarry Smith Then, your `DM` type can be chosen with the procedural interface via 41571c84c290SBarry Smith .vb 41581c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 41591c84c290SBarry Smith DMSetType(DM,"my_da"); 41601c84c290SBarry Smith .ve 41611c84c290SBarry Smith or at runtime via the option 41621c84c290SBarry Smith .vb 41631c84c290SBarry Smith -da_type my_da 41641c84c290SBarry Smith .ve 4165264ace61SBarry Smith 41661cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMSetType()`, `DMRegisterAll()`, `DMRegisterDestroy()` 4167264ace61SBarry Smith @*/ 4168d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRegister(const char sname[], PetscErrorCode (*function)(DM)) 4169d71ae5a4SJacob Faibussowitsch { 4170264ace61SBarry Smith PetscFunctionBegin; 41719566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 41729566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&DMList, sname, function)); 41733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4174264ace61SBarry Smith } 4175264ace61SBarry Smith 4176ffeef943SBarry Smith /*@ 4177bb7acecfSBarry Smith DMLoad - Loads a DM that has been stored in binary with `DMView()`. 4178b859378eSBarry Smith 417920f4b53cSBarry Smith Collective 4180b859378eSBarry Smith 4181b859378eSBarry Smith Input Parameters: 4182bb7acecfSBarry Smith + newdm - the newly loaded `DM`, this needs to have been created with `DMCreate()` or 4183bb7acecfSBarry Smith some related function before a call to `DMLoad()`. 4184bb7acecfSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or 4185bb7acecfSBarry Smith `PETSCVIEWERHDF5` file viewer, obtained from `PetscViewerHDF5Open()` 4186b859378eSBarry Smith 4187b859378eSBarry Smith Level: intermediate 4188b859378eSBarry Smith 4189b859378eSBarry Smith Notes: 419055849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4191b859378eSBarry Smith 4192bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` format, one can save multiple `DMPLEX` 4193bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 4194bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 4195cd7e8a5eSksagiyam 41961cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewerBinaryOpen()`, `DMView()`, `MatLoad()`, `VecLoad()` 4197b859378eSBarry Smith @*/ 4198d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4199d71ae5a4SJacob Faibussowitsch { 42009331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4201b859378eSBarry Smith 4202b859378eSBarry Smith PetscFunctionBegin; 4203b859378eSBarry Smith PetscValidHeaderSpecific(newdm, DM_CLASSID, 1); 4204b859378eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 42059566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckReadable(viewer)); 42069566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 42079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 42089566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Load, viewer, 0, 0, 0)); 42099331c7a4SMatthew G. Knepley if (isbinary) { 42109331c7a4SMatthew G. Knepley PetscInt classid; 42119331c7a4SMatthew G. Knepley char type[256]; 4212b859378eSBarry Smith 42139566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 4214835f2295SStefano Zampini PetscCheck(classid == DM_FILE_CLASSID, PetscObjectComm((PetscObject)newdm), PETSC_ERR_ARG_WRONG, "Not DM next in file, classid found %" PetscInt_FMT, classid); 42159566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 42169566063dSJacob Faibussowitsch PetscCall(DMSetType(newdm, type)); 4217dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 42189331c7a4SMatthew G. Knepley } else if (ishdf5) { 4219dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 42209331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 42219566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Load, viewer, 0, 0, 0)); 42223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4223b859378eSBarry Smith } 4224b859378eSBarry Smith 42254ee01570SBarry Smith /* FEM Support */ 42267da65231SMatthew G Knepley 42272ecf6ec3SMatthew G. Knepley PetscErrorCode DMPrintCellIndices(PetscInt c, const char name[], PetscInt len, const PetscInt x[]) 42282ecf6ec3SMatthew G. Knepley { 42292ecf6ec3SMatthew G. Knepley PetscInt f; 42302ecf6ec3SMatthew G. Knepley 42312ecf6ec3SMatthew G. Knepley PetscFunctionBegin; 42322ecf6ec3SMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 42332ecf6ec3SMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %" PetscInt_FMT " |\n", x[f])); 42342ecf6ec3SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 42352ecf6ec3SMatthew G. Knepley } 42362ecf6ec3SMatthew G. Knepley 4237d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4238d71ae5a4SJacob Faibussowitsch { 42391d47ebbbSSatish Balay PetscInt f; 42401b30c384SMatthew G Knepley 42417da65231SMatthew G Knepley PetscFunctionBegin; 424263a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 424348a46eb9SPierre Jolivet for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]))); 42443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42457da65231SMatthew G Knepley } 42467da65231SMatthew G Knepley 42475962854dSMatthew G. Knepley PetscErrorCode DMPrintCellVectorReal(PetscInt c, const char name[], PetscInt len, const PetscReal x[]) 42485962854dSMatthew G. Knepley { 42495962854dSMatthew G. Knepley PetscInt f; 42505962854dSMatthew G. Knepley 42515962854dSMatthew G. Knepley PetscFunctionBegin; 42525962854dSMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 42535962854dSMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)x[f])); 42545962854dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 42555962854dSMatthew G. Knepley } 42565962854dSMatthew G. Knepley 4257d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4258d71ae5a4SJacob Faibussowitsch { 42591b30c384SMatthew G Knepley PetscInt f, g; 42607da65231SMatthew G Knepley 42617da65231SMatthew G Knepley PetscFunctionBegin; 426263a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 42631d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 42649566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |")); 426548a46eb9SPierre Jolivet for (g = 0; g < cols; ++g) PetscCall(PetscPrintf(PETSC_COMM_SELF, " % 9.5g", (double)PetscRealPart(A[f * cols + g]))); 42669566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |\n")); 42677da65231SMatthew G Knepley } 42683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42697da65231SMatthew G Knepley } 4270e7c4fc90SDmitry Karpeev 4271d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4272d71ae5a4SJacob Faibussowitsch { 42730c5b8624SToby Isaac PetscInt localSize, bs; 42740c5b8624SToby Isaac PetscMPIInt size; 42750c5b8624SToby Isaac Vec x, xglob; 42760c5b8624SToby Isaac const PetscScalar *xarray; 4277e759306cSMatthew G. Knepley 4278e759306cSMatthew G. Knepley PetscFunctionBegin; 42799566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 42809566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &x)); 42819566063dSJacob Faibussowitsch PetscCall(VecCopy(X, x)); 428293ec0da9SPierre Jolivet PetscCall(VecFilter(x, tol)); 42839566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "%s:\n", name)); 42840c5b8624SToby Isaac if (size > 1) { 42859566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(x, &localSize)); 42869566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xarray)); 42879566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(x, &bs)); 42889566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm), bs, localSize, PETSC_DETERMINE, xarray, &xglob)); 42890c5b8624SToby Isaac } else { 42900c5b8624SToby Isaac xglob = x; 42910c5b8624SToby Isaac } 42929566063dSJacob Faibussowitsch PetscCall(VecView(xglob, PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)dm)))); 42930c5b8624SToby Isaac if (size > 1) { 42949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xglob)); 42959566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xarray)); 42960c5b8624SToby Isaac } 42979566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 42983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4299e759306cSMatthew G. Knepley } 4300e759306cSMatthew G. Knepley 430188ed4aceSMatthew G Knepley /*@ 4302bb7acecfSBarry Smith DMGetLocalSection - Get the `PetscSection` encoding the local data layout for the `DM`. 430388ed4aceSMatthew G Knepley 430488ed4aceSMatthew G Knepley Input Parameter: 4305bb7acecfSBarry Smith . dm - The `DM` 430688ed4aceSMatthew G Knepley 430788ed4aceSMatthew G Knepley Output Parameter: 4308bb7acecfSBarry Smith . section - The `PetscSection` 430988ed4aceSMatthew G Knepley 431020f4b53cSBarry Smith Options Database Key: 4311bb7acecfSBarry Smith . -dm_petscsection_view - View the section created by the `DM` 4312e5893cccSMatthew G. Knepley 431388ed4aceSMatthew G Knepley Level: intermediate 431488ed4aceSMatthew G Knepley 4315bb7acecfSBarry Smith Note: 4316bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 431788ed4aceSMatthew G Knepley 43181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetGlobalSection()` 431988ed4aceSMatthew G Knepley @*/ 4320d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 4321d71ae5a4SJacob Faibussowitsch { 432288ed4aceSMatthew G Knepley PetscFunctionBegin; 432388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 43244f572ea9SToby Isaac PetscAssertPointer(section, 2); 43251bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4326e5e52638SMatthew G. Knepley PetscInt d; 4327e5e52638SMatthew G. Knepley 432845480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 432945480ffeSMatthew G. Knepley PetscObject obj = (PetscObject)dm; 433045480ffeSMatthew G. Knepley PetscViewer viewer; 433145480ffeSMatthew G. Knepley PetscViewerFormat format; 433245480ffeSMatthew G. Knepley PetscBool flg; 433345480ffeSMatthew G. Knepley 4334648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg)); 43359566063dSJacob Faibussowitsch if (flg) PetscCall(PetscViewerPushFormat(viewer, format)); 433645480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 43379566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(dm->probs[d].ds)); 43389566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDSView(dm->probs[d].ds, viewer)); 433945480ffeSMatthew G. Knepley } 434045480ffeSMatthew G. Knepley if (flg) { 43419566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 43429566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 4343648c30bcSBarry Smith PetscCall(PetscViewerDestroy(&viewer)); 434445480ffeSMatthew G. Knepley } 434545480ffeSMatthew G. Knepley } 4346dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalsection); 43479566063dSJacob Faibussowitsch if (dm->localSection) PetscCall(PetscObjectViewFromOptions((PetscObject)dm->localSection, NULL, "-dm_petscsection_view")); 43482f0f8703SMatthew G. Knepley } 43491bb6d2a8SBarry Smith *section = dm->localSection; 43503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 435188ed4aceSMatthew G Knepley } 435288ed4aceSMatthew G Knepley 435388ed4aceSMatthew G Knepley /*@ 4354bb7acecfSBarry Smith DMSetLocalSection - Set the `PetscSection` encoding the local data layout for the `DM`. 435588ed4aceSMatthew G Knepley 435688ed4aceSMatthew G Knepley Input Parameters: 4357bb7acecfSBarry Smith + dm - The `DM` 4358bb7acecfSBarry Smith - section - The `PetscSection` 435988ed4aceSMatthew G Knepley 436088ed4aceSMatthew G Knepley Level: intermediate 436188ed4aceSMatthew G Knepley 4362bb7acecfSBarry Smith Note: 4363bb7acecfSBarry Smith Any existing Section will be destroyed 436488ed4aceSMatthew G Knepley 43651cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscSection`, `DMGetLocalSection()`, `DMSetGlobalSection()` 436688ed4aceSMatthew G Knepley @*/ 4367d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 4368d71ae5a4SJacob Faibussowitsch { 4369c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4370af122d2aSMatthew G Knepley PetscInt f; 437188ed4aceSMatthew G Knepley 437288ed4aceSMatthew G Knepley PetscFunctionBegin; 437388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4374b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 43759566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 43769566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->localSection)); 43771bb6d2a8SBarry Smith dm->localSection = section; 43789566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(dm->localSection, &numFields)); 4379af122d2aSMatthew G Knepley if (numFields) { 43809566063dSJacob Faibussowitsch PetscCall(DMSetNumFields(dm, numFields)); 4381af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43820f21e855SMatthew G. Knepley PetscObject disc; 4383af122d2aSMatthew G Knepley const char *name; 4384af122d2aSMatthew G Knepley 43859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(dm->localSection, f, &name)); 43869566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, &disc)); 43879566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName(disc, name)); 4388af122d2aSMatthew G Knepley } 4389af122d2aSMatthew G Knepley } 439050350c8eSStefano Zampini /* The global section and the SectionSF will be rebuilt 439150350c8eSStefano Zampini in the next call to DMGetGlobalSection() and DMGetSectionSF(). */ 43929566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 439350350c8eSStefano Zampini PetscCall(PetscSFDestroy(&dm->sectionSF)); 439452947b74SStefano Zampini PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 439550350c8eSStefano Zampini 439650350c8eSStefano Zampini /* Clear scratch vectors */ 439750350c8eSStefano Zampini PetscCall(DMClearGlobalVectors(dm)); 439850350c8eSStefano Zampini PetscCall(DMClearLocalVectors(dm)); 439950350c8eSStefano Zampini PetscCall(DMClearNamedGlobalVectors(dm)); 440050350c8eSStefano Zampini PetscCall(DMClearNamedLocalVectors(dm)); 44013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 440288ed4aceSMatthew G Knepley } 440388ed4aceSMatthew G Knepley 4404adc21957SMatthew G. Knepley /*@C 4405d8b4a066SPierre Jolivet DMCreateSectionPermutation - Create a permutation of the `PetscSection` chart and optionally a block structure. 4406adc21957SMatthew G. Knepley 4407adc21957SMatthew G. Knepley Input Parameter: 4408adc21957SMatthew G. Knepley . dm - The `DM` 4409adc21957SMatthew G. Knepley 44109cde84edSJose E. Roman Output Parameters: 4411adc21957SMatthew G. Knepley + perm - A permutation of the mesh points in the chart 4412b6971eaeSBarry Smith - blockStarts - A high bit is set for the point that begins every block, or `NULL` for default blocking 4413adc21957SMatthew G. Knepley 4414adc21957SMatthew G. Knepley Level: developer 4415adc21957SMatthew G. Knepley 4416adc21957SMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `PetscSection`, `DMGetLocalSection()`, `DMGetGlobalSection()` 4417adc21957SMatthew G. Knepley @*/ 4418adc21957SMatthew G. Knepley PetscErrorCode DMCreateSectionPermutation(DM dm, IS *perm, PetscBT *blockStarts) 4419adc21957SMatthew G. Knepley { 4420adc21957SMatthew G. Knepley PetscFunctionBegin; 4421adc21957SMatthew G. Knepley *perm = NULL; 4422adc21957SMatthew G. Knepley *blockStarts = NULL; 4423adc21957SMatthew G. Knepley PetscTryTypeMethod(dm, createsectionpermutation, perm, blockStarts); 4424adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 4425adc21957SMatthew G. Knepley } 4426adc21957SMatthew G. Knepley 44279435951eSToby Isaac /*@ 4428bb7acecfSBarry Smith DMGetDefaultConstraints - Get the `PetscSection` and `Mat` that specify the local constraint interpolation. See `DMSetDefaultConstraints()` for a description of the purpose of constraint interpolation. 44299435951eSToby Isaac 443020f4b53cSBarry Smith not Collective 4431e228b242SToby Isaac 44329435951eSToby Isaac Input Parameter: 4433bb7acecfSBarry Smith . dm - The `DM` 44349435951eSToby Isaac 4435d8d19677SJose E. Roman Output Parameters: 443620f4b53cSBarry Smith + section - The `PetscSection` describing the range of the constraint matrix: relates rows of the constraint matrix to dofs of the default section. Returns `NULL` if there are no local constraints. 443720f4b53cSBarry Smith . mat - The `Mat` that interpolates local constraints: its width should be the layout size of the default section. Returns `NULL` if there are no local constraints. 443879769bd5SJed Brown - bias - Vector containing bias to be added to constrained dofs 44399435951eSToby Isaac 44409435951eSToby Isaac Level: advanced 44419435951eSToby Isaac 4442bb7acecfSBarry Smith Note: 4443bb7acecfSBarry Smith This gets borrowed references, so the user should not destroy the `PetscSection`, `Mat`, or `Vec`. 44449435951eSToby Isaac 44451cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDefaultConstraints()` 44469435951eSToby Isaac @*/ 4447d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat, Vec *bias) 4448d71ae5a4SJacob Faibussowitsch { 44499435951eSToby Isaac PetscFunctionBegin; 44509435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4451dbbe0bcdSBarry Smith if (!dm->defaultConstraint.section && !dm->defaultConstraint.mat && dm->ops->createdefaultconstraints) PetscUseTypeMethod(dm, createdefaultconstraints); 44523b8ba7d1SJed Brown if (section) *section = dm->defaultConstraint.section; 44533b8ba7d1SJed Brown if (mat) *mat = dm->defaultConstraint.mat; 445479769bd5SJed Brown if (bias) *bias = dm->defaultConstraint.bias; 44553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44569435951eSToby Isaac } 44579435951eSToby Isaac 44589435951eSToby Isaac /*@ 4459bb7acecfSBarry Smith DMSetDefaultConstraints - Set the `PetscSection` and `Mat` that specify the local constraint interpolation. 44609435951eSToby Isaac 446120f4b53cSBarry Smith Collective 4462e228b242SToby Isaac 44639435951eSToby Isaac Input Parameters: 4464bb7acecfSBarry Smith + dm - The `DM` 4465bb7acecfSBarry Smith . section - The `PetscSection` describing the range of the constraint matrix: relates rows of the constraint matrix to dofs of the default section. Must have a local communicator (`PETSC_COMM_SELF` or derivative). 446620f4b53cSBarry Smith . mat - The `Mat` that interpolates local constraints: its width should be the layout size of the default section: `NULL` indicates no constraints. Must have a local communicator (`PETSC_COMM_SELF` or derivative). 446720f4b53cSBarry Smith - bias - A bias vector to be added to constrained values in the local vector. `NULL` indicates no bias. Must have a local communicator (`PETSC_COMM_SELF` or derivative). 44689435951eSToby Isaac 44699435951eSToby Isaac Level: advanced 44709435951eSToby Isaac 447120f4b53cSBarry Smith Notes: 447220f4b53cSBarry Smith If a constraint matrix is specified, then it is applied during `DMGlobalToLocalEnd()` when mode is `INSERT_VALUES`, `INSERT_BC_VALUES`, or `INSERT_ALL_VALUES`. Without a constraint matrix, the local vector l returned by `DMGlobalToLocalEnd()` contains values that have been scattered from a global vector without modification; with a constraint matrix A, l is modified by computing c = A * l + bias, l[s[i]] = c[i], where the scatter s is defined by the `PetscSection` returned by `DMGetDefaultConstraints()`. 447320f4b53cSBarry Smith 447420f4b53cSBarry Smith If a constraint matrix is specified, then its adjoint is applied during `DMLocalToGlobalBegin()` when mode is `ADD_VALUES`, `ADD_BC_VALUES`, or `ADD_ALL_VALUES`. Without a constraint matrix, the local vector l is accumulated into a global vector without modification; with a constraint matrix A, l is first modified by computing c[i] = l[s[i]], l[s[i]] = 0, l = l + A'*c, which is the adjoint of the operation described above. Any bias, if specified, is ignored when accumulating. 447520f4b53cSBarry Smith 4476bb7acecfSBarry Smith This increments the references of the `PetscSection`, `Mat`, and `Vec`, so they user can destroy them. 44779435951eSToby Isaac 44781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDefaultConstraints()` 44799435951eSToby Isaac @*/ 4480d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat, Vec bias) 4481d71ae5a4SJacob Faibussowitsch { 4482e228b242SToby Isaac PetscMPIInt result; 44839435951eSToby Isaac 44849435951eSToby Isaac PetscFunctionBegin; 44859435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4486e228b242SToby Isaac if (section) { 4487e228b242SToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 44889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)section), &result)); 44897a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint section must have local communicator"); 4490e228b242SToby Isaac } 4491e228b242SToby Isaac if (mat) { 4492e228b242SToby Isaac PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 44939566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)mat), &result)); 44947a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint matrix must have local communicator"); 4495e228b242SToby Isaac } 449679769bd5SJed Brown if (bias) { 449779769bd5SJed Brown PetscValidHeaderSpecific(bias, VEC_CLASSID, 4); 44989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)bias), &result)); 449979769bd5SJed Brown PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint bias must have local communicator"); 450079769bd5SJed Brown } 45019566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 45029566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->defaultConstraint.section)); 45033b8ba7d1SJed Brown dm->defaultConstraint.section = section; 45049566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 45059566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dm->defaultConstraint.mat)); 45063b8ba7d1SJed Brown dm->defaultConstraint.mat = mat; 45079566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)bias)); 45089566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dm->defaultConstraint.bias)); 450979769bd5SJed Brown dm->defaultConstraint.bias = bias; 45103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45119435951eSToby Isaac } 45129435951eSToby Isaac 4513497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4514507e4973SMatthew G. Knepley /* 4515bb7acecfSBarry Smith DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. Generates and error if they are not consistent. 4516507e4973SMatthew G. Knepley 4517507e4973SMatthew G. Knepley Input Parameters: 4518bb7acecfSBarry Smith + dm - The `DM` 4519bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4520bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 4521507e4973SMatthew G. Knepley 4522507e4973SMatthew G. Knepley Level: intermediate 4523507e4973SMatthew G. Knepley 45241cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()` 4525507e4973SMatthew G. Knepley */ 4526d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4527d71ae5a4SJacob Faibussowitsch { 4528507e4973SMatthew G. Knepley MPI_Comm comm; 4529507e4973SMatthew G. Knepley PetscLayout layout; 4530507e4973SMatthew G. Knepley const PetscInt *ranges; 4531507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4532507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4533507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4534507e4973SMatthew G. Knepley 4535507e4973SMatthew G. Knepley PetscFunctionBegin; 45369566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4537507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45389566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 45399566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 45409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(globalSection, &pStart, &pEnd)); 45419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(globalSection, &nroots)); 45429566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &layout)); 45439566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(layout, 1)); 45449566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(layout, nroots)); 45459566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(layout)); 45469566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRanges(layout, &ranges)); 4547507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4548f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4549507e4973SMatthew G. Knepley 45509566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(localSection, p, &dof)); 45519566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(localSection, p, &off)); 45529566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(localSection, p, &cdof)); 45539566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(globalSection, p, &gdof)); 45549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(globalSection, p, &gcdof)); 45559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(globalSection, p, &goff)); 4556507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 45579371c9d4SSatish Balay if ((gdof < 0 ? -(gdof + 1) : gdof) != dof) { 45589371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Global dof %" PetscInt_FMT " for point %" PetscInt_FMT " not equal to local dof %" PetscInt_FMT "\n", rank, gdof, p, dof)); 45599371c9d4SSatish Balay valid = PETSC_FALSE; 45609371c9d4SSatish Balay } 45619371c9d4SSatish Balay if (gcdof && (gcdof != cdof)) { 45629371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Global constraints %" PetscInt_FMT " for point %" PetscInt_FMT " not equal to local constraints %" PetscInt_FMT "\n", rank, gcdof, p, cdof)); 45639371c9d4SSatish Balay valid = PETSC_FALSE; 45649371c9d4SSatish Balay } 4565507e4973SMatthew G. Knepley if (gdof < 0) { 4566507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof + 1) - gcdof : gdof - gcdof; 4567507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4568507e4973SMatthew G. Knepley PetscInt offset = -(goff + 1) + d, r; 4569507e4973SMatthew G. Knepley 45709566063dSJacob Faibussowitsch PetscCall(PetscFindInt(offset, size + 1, ranges, &r)); 4571507e4973SMatthew G. Knepley if (r < 0) r = -(r + 2); 45729371c9d4SSatish Balay if ((r < 0) || (r >= size)) { 45739371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Point %" PetscInt_FMT " mapped to invalid process %" PetscInt_FMT " (%" PetscInt_FMT ", %" PetscInt_FMT ")\n", rank, p, r, gdof, goff)); 45749371c9d4SSatish Balay valid = PETSC_FALSE; 45759371c9d4SSatish Balay break; 45769371c9d4SSatish Balay } 4577507e4973SMatthew G. Knepley } 4578507e4973SMatthew G. Knepley } 4579507e4973SMatthew G. Knepley } 45809566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&layout)); 45819566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 4582462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm)); 4583507e4973SMatthew G. Knepley if (!gvalid) { 45849566063dSJacob Faibussowitsch PetscCall(DMView(dm, NULL)); 4585507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4586507e4973SMatthew G. Knepley } 45873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4588507e4973SMatthew G. Knepley } 4589f741bcd2SMatthew G. Knepley #endif 4590507e4973SMatthew G. Knepley 459190df3356SJames Wright PetscErrorCode DMGetIsoperiodicPointSF_Internal(DM dm, PetscSF *sf) 45926725e60dSJed Brown { 45936725e60dSJed Brown PetscErrorCode (*f)(DM, PetscSF *); 45944d86920dSPierre Jolivet 45956725e60dSJed Brown PetscFunctionBegin; 45966725e60dSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45974f572ea9SToby Isaac PetscAssertPointer(sf, 2); 45985f06a3ddSJed Brown PetscCall(PetscObjectQueryFunction((PetscObject)dm, "DMGetIsoperiodicPointSF_C", &f)); 45996725e60dSJed Brown if (f) PetscCall(f(dm, sf)); 46006725e60dSJed Brown else *sf = dm->sf; 46013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 46026725e60dSJed Brown } 46036725e60dSJed Brown 460488ed4aceSMatthew G Knepley /*@ 4605bb7acecfSBarry Smith DMGetGlobalSection - Get the `PetscSection` encoding the global data layout for the `DM`. 460688ed4aceSMatthew G Knepley 460720f4b53cSBarry Smith Collective 46088b1ab98fSJed Brown 460988ed4aceSMatthew G Knepley Input Parameter: 4610bb7acecfSBarry Smith . dm - The `DM` 461188ed4aceSMatthew G Knepley 461288ed4aceSMatthew G Knepley Output Parameter: 4613bb7acecfSBarry Smith . section - The `PetscSection` 461488ed4aceSMatthew G Knepley 461588ed4aceSMatthew G Knepley Level: intermediate 461688ed4aceSMatthew G Knepley 4617bb7acecfSBarry Smith Note: 4618bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 461988ed4aceSMatthew G Knepley 46201cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetLocalSection()` 462188ed4aceSMatthew G Knepley @*/ 4622d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 4623d71ae5a4SJacob Faibussowitsch { 462488ed4aceSMatthew G Knepley PetscFunctionBegin; 462588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46264f572ea9SToby Isaac PetscAssertPointer(section, 2); 46271bb6d2a8SBarry Smith if (!dm->globalSection) { 4628fd59a867SMatthew G. Knepley PetscSection s; 46296725e60dSJed Brown PetscSF sf; 4630fd59a867SMatthew G. Knepley 46319566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 46327a8be351SBarry Smith PetscCheck(s, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 46337a8be351SBarry Smith PetscCheck(dm->sf, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 46345f06a3ddSJed Brown PetscCall(DMGetIsoperiodicPointSF_Internal(dm, &sf)); 4635eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionCreateGlobalSection(s, sf, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &dm->globalSection)); 46369566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&dm->map)); 46379566063dSJacob Faibussowitsch PetscCall(PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map)); 46389566063dSJacob Faibussowitsch PetscCall(PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view")); 463988ed4aceSMatthew G Knepley } 46401bb6d2a8SBarry Smith *section = dm->globalSection; 46413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 464288ed4aceSMatthew G Knepley } 464388ed4aceSMatthew G Knepley 4644b21d0597SMatthew G Knepley /*@ 4645bb7acecfSBarry Smith DMSetGlobalSection - Set the `PetscSection` encoding the global data layout for the `DM`. 4646b21d0597SMatthew G Knepley 4647b21d0597SMatthew G Knepley Input Parameters: 4648bb7acecfSBarry Smith + dm - The `DM` 46492fe279fdSBarry Smith - section - The PetscSection, or `NULL` 4650b21d0597SMatthew G Knepley 4651b21d0597SMatthew G Knepley Level: intermediate 4652b21d0597SMatthew G Knepley 4653bb7acecfSBarry Smith Note: 4654bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4655b21d0597SMatthew G Knepley 46561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetGlobalSection()`, `DMSetLocalSection()` 4657b21d0597SMatthew G Knepley @*/ 4658d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 4659d71ae5a4SJacob Faibussowitsch { 4660b21d0597SMatthew G Knepley PetscFunctionBegin; 4661b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46625080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 46639566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 46649566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 46651bb6d2a8SBarry Smith dm->globalSection = section; 4666497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 46679566063dSJacob Faibussowitsch if (section) PetscCall(DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section)); 4668507e4973SMatthew G. Knepley #endif 466950350c8eSStefano Zampini /* Clear global scratch vectors and sectionSF */ 467050350c8eSStefano Zampini PetscCall(PetscSFDestroy(&dm->sectionSF)); 467152947b74SStefano Zampini PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 467250350c8eSStefano Zampini PetscCall(DMClearGlobalVectors(dm)); 467350350c8eSStefano Zampini PetscCall(DMClearNamedGlobalVectors(dm)); 46743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4675b21d0597SMatthew G Knepley } 4676b21d0597SMatthew G Knepley 467788ed4aceSMatthew G Knepley /*@ 4678bb7acecfSBarry Smith DMGetSectionSF - Get the `PetscSF` encoding the parallel dof overlap for the `DM`. If it has not been set, 4679bb7acecfSBarry Smith it is created from the default `PetscSection` layouts in the `DM`. 468088ed4aceSMatthew G Knepley 468188ed4aceSMatthew G Knepley Input Parameter: 4682bb7acecfSBarry Smith . dm - The `DM` 468388ed4aceSMatthew G Knepley 468488ed4aceSMatthew G Knepley Output Parameter: 4685bb7acecfSBarry Smith . sf - The `PetscSF` 468688ed4aceSMatthew G Knepley 468788ed4aceSMatthew G Knepley Level: intermediate 468888ed4aceSMatthew G Knepley 4689bb7acecfSBarry Smith Note: 4690bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 469188ed4aceSMatthew G Knepley 46921cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetSectionSF()`, `DMCreateSectionSF()` 469388ed4aceSMatthew G Knepley @*/ 4694d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 4695d71ae5a4SJacob Faibussowitsch { 469688ed4aceSMatthew G Knepley PetscInt nroots; 469788ed4aceSMatthew G Knepley 469888ed4aceSMatthew G Knepley PetscFunctionBegin; 469988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47004f572ea9SToby Isaac PetscAssertPointer(sf, 2); 470148a46eb9SPierre Jolivet if (!dm->sectionSF) PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 47029566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL)); 470388ed4aceSMatthew G Knepley if (nroots < 0) { 470488ed4aceSMatthew G Knepley PetscSection section, gSection; 470588ed4aceSMatthew G Knepley 47069566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 470731ea6d37SMatthew G Knepley if (section) { 47089566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gSection)); 47099566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSF(dm, section, gSection)); 471031ea6d37SMatthew G Knepley } else { 47110298fd71SBarry Smith *sf = NULL; 47123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 471331ea6d37SMatthew G Knepley } 471488ed4aceSMatthew G Knepley } 47151bb6d2a8SBarry Smith *sf = dm->sectionSF; 47163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 471788ed4aceSMatthew G Knepley } 471888ed4aceSMatthew G Knepley 471988ed4aceSMatthew G Knepley /*@ 4720bb7acecfSBarry Smith DMSetSectionSF - Set the `PetscSF` encoding the parallel dof overlap for the `DM` 472188ed4aceSMatthew G Knepley 472288ed4aceSMatthew G Knepley Input Parameters: 4723bb7acecfSBarry Smith + dm - The `DM` 4724bb7acecfSBarry Smith - sf - The `PetscSF` 472588ed4aceSMatthew G Knepley 472688ed4aceSMatthew G Knepley Level: intermediate 472788ed4aceSMatthew G Knepley 4728bb7acecfSBarry Smith Note: 4729bb7acecfSBarry Smith Any previous `PetscSF` is destroyed 473088ed4aceSMatthew G Knepley 47311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMCreateSectionSF()` 473288ed4aceSMatthew G Knepley @*/ 4733d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 4734d71ae5a4SJacob Faibussowitsch { 473588ed4aceSMatthew G Knepley PetscFunctionBegin; 473688ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4737b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47389566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47399566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sectionSF)); 47401bb6d2a8SBarry Smith dm->sectionSF = sf; 47413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 474288ed4aceSMatthew G Knepley } 474388ed4aceSMatthew G Knepley 4744cc4c1da9SBarry Smith /*@ 4745bb7acecfSBarry Smith DMCreateSectionSF - Create the `PetscSF` encoding the parallel dof overlap for the `DM` based upon the `PetscSection`s 474688ed4aceSMatthew G Knepley describing the data layout. 474788ed4aceSMatthew G Knepley 474888ed4aceSMatthew G Knepley Input Parameters: 4749bb7acecfSBarry Smith + dm - The `DM` 4750bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4751bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 475288ed4aceSMatthew G Knepley 47531bb6d2a8SBarry Smith Level: developer 47541bb6d2a8SBarry Smith 4755bb7acecfSBarry Smith Note: 4756bb7acecfSBarry Smith One usually uses `DMGetSectionSF()` to obtain the `PetscSF` 4757bb7acecfSBarry Smith 475873ff1848SBarry Smith Developer Note: 4759bb7acecfSBarry Smith Since this routine has for arguments the two sections from the `DM` and puts the resulting `PetscSF` 4760bb7acecfSBarry Smith directly into the `DM`, perhaps this function should not take the local and global sections as 4761b6971eaeSBarry Smith input and should just obtain them from the `DM`? Plus PETSc creation functions return the thing 4762b6971eaeSBarry Smith they create, this returns nothing 47631bb6d2a8SBarry Smith 47641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMGetLocalSection()`, `DMGetGlobalSection()` 476588ed4aceSMatthew G Knepley @*/ 4766d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 4767d71ae5a4SJacob Faibussowitsch { 476888ed4aceSMatthew G Knepley PetscFunctionBegin; 476988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47709566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection)); 47713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 477288ed4aceSMatthew G Knepley } 4773af122d2aSMatthew G Knepley 4774b21d0597SMatthew G Knepley /*@ 4775bb7acecfSBarry Smith DMGetPointSF - Get the `PetscSF` encoding the parallel section point overlap for the `DM`. 4776bb7acecfSBarry Smith 4777bb7acecfSBarry Smith Not collective but the resulting `PetscSF` is collective 4778b21d0597SMatthew G Knepley 4779b21d0597SMatthew G Knepley Input Parameter: 4780bb7acecfSBarry Smith . dm - The `DM` 4781b21d0597SMatthew G Knepley 4782b21d0597SMatthew G Knepley Output Parameter: 4783bb7acecfSBarry Smith . sf - The `PetscSF` 4784b21d0597SMatthew G Knepley 4785b21d0597SMatthew G Knepley Level: intermediate 4786b21d0597SMatthew G Knepley 4787bb7acecfSBarry Smith Note: 4788bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 4789b21d0597SMatthew G Knepley 47901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4791b21d0597SMatthew G Knepley @*/ 4792d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 4793d71ae5a4SJacob Faibussowitsch { 4794b21d0597SMatthew G Knepley PetscFunctionBegin; 4795b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47964f572ea9SToby Isaac PetscAssertPointer(sf, 2); 4797b21d0597SMatthew G Knepley *sf = dm->sf; 47983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4799b21d0597SMatthew G Knepley } 4800b21d0597SMatthew G Knepley 4801057b4bcdSMatthew G Knepley /*@ 4802bb7acecfSBarry Smith DMSetPointSF - Set the `PetscSF` encoding the parallel section point overlap for the `DM`. 4803bb7acecfSBarry Smith 480420f4b53cSBarry Smith Collective 4805057b4bcdSMatthew G Knepley 4806057b4bcdSMatthew G Knepley Input Parameters: 4807bb7acecfSBarry Smith + dm - The `DM` 4808bb7acecfSBarry Smith - sf - The `PetscSF` 4809057b4bcdSMatthew G Knepley 4810057b4bcdSMatthew G Knepley Level: intermediate 4811057b4bcdSMatthew G Knepley 48121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4813057b4bcdSMatthew G Knepley @*/ 4814d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 4815d71ae5a4SJacob Faibussowitsch { 4816057b4bcdSMatthew G Knepley PetscFunctionBegin; 4817057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4818b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 48199566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 48209566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sf)); 4821057b4bcdSMatthew G Knepley dm->sf = sf; 48223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4823057b4bcdSMatthew G Knepley } 4824057b4bcdSMatthew G Knepley 48254f37162bSMatthew G. Knepley /*@ 4826bb7acecfSBarry Smith DMGetNaturalSF - Get the `PetscSF` encoding the map back to the original mesh ordering 48274f37162bSMatthew G. Knepley 48284f37162bSMatthew G. Knepley Input Parameter: 4829bb7acecfSBarry Smith . dm - The `DM` 48304f37162bSMatthew G. Knepley 48314f37162bSMatthew G. Knepley Output Parameter: 4832bb7acecfSBarry Smith . sf - The `PetscSF` 48334f37162bSMatthew G. Knepley 48344f37162bSMatthew G. Knepley Level: intermediate 48354f37162bSMatthew G. Knepley 4836bb7acecfSBarry Smith Note: 4837bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 48384f37162bSMatthew G. Knepley 48391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 48404f37162bSMatthew G. Knepley @*/ 4841d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 4842d71ae5a4SJacob Faibussowitsch { 48434f37162bSMatthew G. Knepley PetscFunctionBegin; 48444f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48454f572ea9SToby Isaac PetscAssertPointer(sf, 2); 48464f37162bSMatthew G. Knepley *sf = dm->sfNatural; 48473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48484f37162bSMatthew G. Knepley } 48494f37162bSMatthew G. Knepley 48504f37162bSMatthew G. Knepley /*@ 48514f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 48524f37162bSMatthew G. Knepley 48534f37162bSMatthew G. Knepley Input Parameters: 48544f37162bSMatthew G. Knepley + dm - The DM 48554f37162bSMatthew G. Knepley - sf - The PetscSF 48564f37162bSMatthew G. Knepley 48574f37162bSMatthew G. Knepley Level: intermediate 48584f37162bSMatthew G. Knepley 48591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 48604f37162bSMatthew G. Knepley @*/ 4861d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 4862d71ae5a4SJacob Faibussowitsch { 48634f37162bSMatthew G. Knepley PetscFunctionBegin; 48644f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48654f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 48669566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 48679566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sfNatural)); 48684f37162bSMatthew G. Knepley dm->sfNatural = sf; 48693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48704f37162bSMatthew G. Knepley } 48714f37162bSMatthew G. Knepley 4872d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 4873d71ae5a4SJacob Faibussowitsch { 487434aa8a36SMatthew G. Knepley PetscClassId id; 487534aa8a36SMatthew G. Knepley 487634aa8a36SMatthew G. Knepley PetscFunctionBegin; 48779566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 487834aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 48799566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 488034aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 48819566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE)); 488217c1d62eSMatthew G. Knepley } else { 48839566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 488434aa8a36SMatthew G. Knepley } 48853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 488634aa8a36SMatthew G. Knepley } 488734aa8a36SMatthew G. Knepley 4888d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 4889d71ae5a4SJacob Faibussowitsch { 489044a7f3ddSMatthew G. Knepley RegionField *tmpr; 489144a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 489244a7f3ddSMatthew G. Knepley 489344a7f3ddSMatthew G. Knepley PetscFunctionBegin; 48943ba16761SJacob Faibussowitsch if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS); 48959566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NfNew, &tmpr)); 489644a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 48979371c9d4SSatish Balay for (f = Nf; f < NfNew; ++f) { 48989371c9d4SSatish Balay tmpr[f].disc = NULL; 48999371c9d4SSatish Balay tmpr[f].label = NULL; 49009371c9d4SSatish Balay tmpr[f].avoidTensor = PETSC_FALSE; 49019371c9d4SSatish Balay } 49029566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 490344a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 490444a7f3ddSMatthew G. Knepley dm->fields = tmpr; 49053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 490644a7f3ddSMatthew G. Knepley } 490744a7f3ddSMatthew G. Knepley 490844a7f3ddSMatthew G. Knepley /*@ 490920f4b53cSBarry Smith DMClearFields - Remove all fields from the `DM` 491044a7f3ddSMatthew G. Knepley 491120f4b53cSBarry Smith Logically Collective 491244a7f3ddSMatthew G. Knepley 491344a7f3ddSMatthew G. Knepley Input Parameter: 491420f4b53cSBarry Smith . dm - The `DM` 491544a7f3ddSMatthew G. Knepley 491644a7f3ddSMatthew G. Knepley Level: intermediate 491744a7f3ddSMatthew G. Knepley 49181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetNumFields()`, `DMSetField()` 491944a7f3ddSMatthew G. Knepley @*/ 4920d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearFields(DM dm) 4921d71ae5a4SJacob Faibussowitsch { 492244a7f3ddSMatthew G. Knepley PetscInt f; 492344a7f3ddSMatthew G. Knepley 492444a7f3ddSMatthew G. Knepley PetscFunctionBegin; 492544a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49264c4edb6fSBarry Smith if (!dm->fields) PetscFunctionReturn(PETSC_SUCCESS); // DMDA does not use fields field in DM 492744a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 49289566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 49299566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 493044a7f3ddSMatthew G. Knepley } 49319566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 493244a7f3ddSMatthew G. Knepley dm->fields = NULL; 493344a7f3ddSMatthew G. Knepley dm->Nf = 0; 49343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 493544a7f3ddSMatthew G. Knepley } 493644a7f3ddSMatthew G. Knepley 4937689b5837SMatthew G. Knepley /*@ 493820f4b53cSBarry Smith DMGetNumFields - Get the number of fields in the `DM` 4939689b5837SMatthew G. Knepley 494020f4b53cSBarry Smith Not Collective 4941689b5837SMatthew G. Knepley 4942689b5837SMatthew G. Knepley Input Parameter: 494320f4b53cSBarry Smith . dm - The `DM` 4944689b5837SMatthew G. Knepley 4945689b5837SMatthew G. Knepley Output Parameter: 494660225df5SJacob Faibussowitsch . numFields - The number of fields 4947689b5837SMatthew G. Knepley 4948689b5837SMatthew G. Knepley Level: intermediate 4949689b5837SMatthew G. Knepley 49501cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNumFields()`, `DMSetField()` 4951689b5837SMatthew G. Knepley @*/ 4952d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 4953d71ae5a4SJacob Faibussowitsch { 49540f21e855SMatthew G. Knepley PetscFunctionBegin; 49550f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49564f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 495744a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 49583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4959af122d2aSMatthew G Knepley } 4960af122d2aSMatthew G Knepley 4961689b5837SMatthew G. Knepley /*@ 496220f4b53cSBarry Smith DMSetNumFields - Set the number of fields in the `DM` 4963689b5837SMatthew G. Knepley 496420f4b53cSBarry Smith Logically Collective 4965689b5837SMatthew G. Knepley 4966689b5837SMatthew G. Knepley Input Parameters: 496720f4b53cSBarry Smith + dm - The `DM` 496860225df5SJacob Faibussowitsch - numFields - The number of fields 4969689b5837SMatthew G. Knepley 4970689b5837SMatthew G. Knepley Level: intermediate 4971689b5837SMatthew G. Knepley 49721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetField()` 4973689b5837SMatthew G. Knepley @*/ 4974d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4975d71ae5a4SJacob Faibussowitsch { 49760f21e855SMatthew G. Knepley PetscInt Nf, f; 4977af122d2aSMatthew G Knepley 4978af122d2aSMatthew G Knepley PetscFunctionBegin; 4979af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49809566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 49810f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 49820f21e855SMatthew G. Knepley PetscContainer obj; 49830f21e855SMatthew G. Knepley 49849566063dSJacob Faibussowitsch PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)dm), &obj)); 49859566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject)obj)); 49869566063dSJacob Faibussowitsch PetscCall(PetscContainerDestroy(&obj)); 4987af122d2aSMatthew G Knepley } 49883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4989af122d2aSMatthew G Knepley } 4990af122d2aSMatthew G Knepley 4991c1929be8SMatthew G. Knepley /*@ 4992bb7acecfSBarry Smith DMGetField - Return the `DMLabel` and discretization object for a given `DM` field 4993c1929be8SMatthew G. Knepley 499420f4b53cSBarry Smith Not Collective 4995c1929be8SMatthew G. Knepley 4996c1929be8SMatthew G. Knepley Input Parameters: 4997bb7acecfSBarry Smith + dm - The `DM` 4998c1929be8SMatthew G. Knepley - f - The field number 4999c1929be8SMatthew G. Knepley 500044a7f3ddSMatthew G. Knepley Output Parameters: 500120f4b53cSBarry Smith + label - The label indicating the support of the field, or `NULL` for the entire mesh (pass in `NULL` if not needed) 500220f4b53cSBarry Smith - disc - The discretization object (pass in `NULL` if not needed) 5003c1929be8SMatthew G. Knepley 500444a7f3ddSMatthew G. Knepley Level: intermediate 5005c1929be8SMatthew G. Knepley 50061cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()` 5007c1929be8SMatthew G. Knepley @*/ 5008d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *disc) 5009d71ae5a4SJacob Faibussowitsch { 5010af122d2aSMatthew G Knepley PetscFunctionBegin; 5011af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 50124f572ea9SToby Isaac PetscAssertPointer(disc, 4); 50137a8be351SBarry Smith PetscCheck((f >= 0) && (f < dm->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, dm->Nf); 50144c4edb6fSBarry Smith if (!dm->fields) { 50154c4edb6fSBarry Smith if (label) *label = NULL; 50164c4edb6fSBarry Smith if (disc) *disc = NULL; 50174c4edb6fSBarry Smith } else { // some DM such as DMDA do not have dm->fields 501844a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 5019bb7acecfSBarry Smith if (disc) *disc = dm->fields[f].disc; 50204c4edb6fSBarry Smith } 50213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5022decb47aaSMatthew G. Knepley } 5023decb47aaSMatthew G. Knepley 5024083401c6SMatthew G. Knepley /* Does not clear the DS */ 5025d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject disc) 5026d71ae5a4SJacob Faibussowitsch { 5027083401c6SMatthew G. Knepley PetscFunctionBegin; 50289566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, f + 1)); 50299566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 50309566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 5031083401c6SMatthew G. Knepley dm->fields[f].label = label; 5032bb7acecfSBarry Smith dm->fields[f].disc = disc; 50339566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5034835f2295SStefano Zampini PetscCall(PetscObjectReference(disc)); 50353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5036083401c6SMatthew G. Knepley } 5037083401c6SMatthew G. Knepley 5038ffeef943SBarry Smith /*@ 5039bb7acecfSBarry Smith DMSetField - Set the discretization object for a given `DM` field. Usually one would call `DMAddField()` which automatically handles 5040bb7acecfSBarry Smith the field numbering. 5041c1929be8SMatthew G. Knepley 504220f4b53cSBarry Smith Logically Collective 5043c1929be8SMatthew G. Knepley 5044c1929be8SMatthew G. Knepley Input Parameters: 5045bb7acecfSBarry Smith + dm - The `DM` 5046c1929be8SMatthew G. Knepley . f - The field number 504720f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 5048bb7acecfSBarry Smith - disc - The discretization object 5049c1929be8SMatthew G. Knepley 505044a7f3ddSMatthew G. Knepley Level: intermediate 5051c1929be8SMatthew G. Knepley 50521cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()` 5053c1929be8SMatthew G. Knepley @*/ 5054d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject disc) 5055d71ae5a4SJacob Faibussowitsch { 5056decb47aaSMatthew G. Knepley PetscFunctionBegin; 5057decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5058e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 5059bb7acecfSBarry Smith PetscValidHeader(disc, 4); 50607a8be351SBarry Smith PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f); 5061bb7acecfSBarry Smith PetscCall(DMSetField_Internal(dm, f, label, disc)); 5062bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, f, disc)); 50639566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 50643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 506544a7f3ddSMatthew G. Knepley } 506644a7f3ddSMatthew G. Knepley 5067ffeef943SBarry Smith /*@ 5068bb7acecfSBarry Smith DMAddField - Add a field to a `DM` object. A field is a function space defined by of a set of discretization points (geometric entities) 5069bb7acecfSBarry Smith and a discretization object that defines the function space associated with those points. 507044a7f3ddSMatthew G. Knepley 507120f4b53cSBarry Smith Logically Collective 507244a7f3ddSMatthew G. Knepley 507344a7f3ddSMatthew G. Knepley Input Parameters: 5074bb7acecfSBarry Smith + dm - The `DM` 507520f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 5076bb7acecfSBarry Smith - disc - The discretization object 507744a7f3ddSMatthew G. Knepley 507844a7f3ddSMatthew G. Knepley Level: intermediate 507944a7f3ddSMatthew G. Knepley 5080bb7acecfSBarry Smith Notes: 5081bb7acecfSBarry Smith The label already exists or will be added to the `DM` with `DMSetLabel()`. 5082bb7acecfSBarry Smith 5083da81f932SPierre Jolivet For example, a piecewise continuous pressure field can be defined by coefficients at the cell centers of a mesh and piecewise constant functions 5084bb7acecfSBarry Smith within each cell. Thus a specific function in the space is defined by the combination of a `Vec` containing the coefficients, a `DM` defining the 5085bb7acecfSBarry Smith geometry entities, a `DMLabel` indicating a subset of those geometric entities, and a discretization object, such as a `PetscFE`. 5086bb7acecfSBarry Smith 5087ce78bad3SBarry Smith Fortran Note: 5088ce78bad3SBarry Smith Use the argument `PetscObjectCast(disc)` as the second argument 5089ce78bad3SBarry Smith 50901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLabel()`, `DMSetField()`, `DMGetField()`, `PetscFE` 509144a7f3ddSMatthew G. Knepley @*/ 5092d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject disc) 5093d71ae5a4SJacob Faibussowitsch { 509444a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 509544a7f3ddSMatthew G. Knepley 509644a7f3ddSMatthew G. Knepley PetscFunctionBegin; 509744a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5098064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5099bb7acecfSBarry Smith PetscValidHeader(disc, 3); 51009566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, Nf + 1)); 510144a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 5102bb7acecfSBarry Smith dm->fields[Nf].disc = disc; 51039566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5104835f2295SStefano Zampini PetscCall(PetscObjectReference(disc)); 5105bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, Nf, disc)); 51069566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 51073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5108af122d2aSMatthew G Knepley } 51096636e97aSMatthew G Knepley 5110e5e52638SMatthew G. Knepley /*@ 5111e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 5112e0b68406SMatthew Knepley 511320f4b53cSBarry Smith Logically Collective 5114e0b68406SMatthew Knepley 5115e0b68406SMatthew Knepley Input Parameters: 5116bb7acecfSBarry Smith + dm - The `DM` 5117e0b68406SMatthew Knepley . f - The field index 5118bb7acecfSBarry Smith - avoidTensor - `PETSC_TRUE` to skip defining the field on tensor cells 5119e0b68406SMatthew Knepley 5120e0b68406SMatthew Knepley Level: intermediate 5121e0b68406SMatthew Knepley 51221cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5123e0b68406SMatthew Knepley @*/ 5124d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5125d71ae5a4SJacob Faibussowitsch { 5126e0b68406SMatthew Knepley PetscFunctionBegin; 512763a3b9bcSJacob Faibussowitsch PetscCheck((f >= 0) && (f < dm->Nf), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", f, dm->Nf); 5128e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 51293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5130e0b68406SMatthew Knepley } 5131e0b68406SMatthew Knepley 5132e0b68406SMatthew Knepley /*@ 5133e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5134e0b68406SMatthew Knepley 513520f4b53cSBarry Smith Not Collective 5136e0b68406SMatthew Knepley 5137e0b68406SMatthew Knepley Input Parameters: 5138bb7acecfSBarry Smith + dm - The `DM` 5139e0b68406SMatthew Knepley - f - The field index 5140e0b68406SMatthew Knepley 5141e0b68406SMatthew Knepley Output Parameter: 5142e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5143e0b68406SMatthew Knepley 5144e0b68406SMatthew Knepley Level: intermediate 5145e0b68406SMatthew Knepley 514660225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()`, `DMGetField()`, `DMSetFieldAvoidTensor()` 5147e0b68406SMatthew Knepley @*/ 5148d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5149d71ae5a4SJacob Faibussowitsch { 5150e0b68406SMatthew Knepley PetscFunctionBegin; 515163a3b9bcSJacob Faibussowitsch PetscCheck((f >= 0) && (f < dm->Nf), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", f, dm->Nf); 5152e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 51533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5154e0b68406SMatthew Knepley } 5155e0b68406SMatthew Knepley 5156e0b68406SMatthew Knepley /*@ 5157bb7acecfSBarry Smith DMCopyFields - Copy the discretizations for the `DM` into another `DM` 5158e5e52638SMatthew G. Knepley 515920f4b53cSBarry Smith Collective 5160e5e52638SMatthew G. Knepley 5161bb4b53efSMatthew G. Knepley Input Parameters: 5162bb4b53efSMatthew G. Knepley + dm - The `DM` 5163bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit 5164bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit 5165e5e52638SMatthew G. Knepley 5166e5e52638SMatthew G. Knepley Output Parameter: 5167bb7acecfSBarry Smith . newdm - The `DM` 5168e5e52638SMatthew G. Knepley 5169e5e52638SMatthew G. Knepley Level: advanced 5170e5e52638SMatthew G. Knepley 51711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetField()`, `DMSetField()`, `DMAddField()`, `DMCopyDS()`, `DMGetDS()`, `DMGetCellDS()` 5172e5e52638SMatthew G. Knepley @*/ 5173bb4b53efSMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, PetscInt minDegree, PetscInt maxDegree, DM newdm) 5174d71ae5a4SJacob Faibussowitsch { 5175e5e52638SMatthew G. Knepley PetscInt Nf, f; 5176e5e52638SMatthew G. Knepley 5177e5e52638SMatthew G. Knepley PetscFunctionBegin; 51783ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 51799566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51809566063dSJacob Faibussowitsch PetscCall(DMClearFields(newdm)); 5181e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5182e5e52638SMatthew G. Knepley DMLabel label; 5183e5e52638SMatthew G. Knepley PetscObject field; 5184bb4b53efSMatthew G. Knepley PetscClassId id; 518534aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5186e5e52638SMatthew G. Knepley 51879566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, &label, &field)); 5188bb4b53efSMatthew G. Knepley PetscCall(PetscObjectGetClassId(field, &id)); 5189bb4b53efSMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5190bb4b53efSMatthew G. Knepley PetscFE newfe; 5191bb4b53efSMatthew G. Knepley 5192bb4b53efSMatthew G. Knepley PetscCall(PetscFELimitDegree((PetscFE)field, minDegree, maxDegree, &newfe)); 5193bb4b53efSMatthew G. Knepley PetscCall(DMSetField(newdm, f, label, (PetscObject)newfe)); 5194bb4b53efSMatthew G. Knepley PetscCall(PetscFEDestroy(&newfe)); 5195bb4b53efSMatthew G. Knepley } else { 51969566063dSJacob Faibussowitsch PetscCall(DMSetField(newdm, f, label, field)); 5197bb4b53efSMatthew G. Knepley } 51989566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, f, &useCone, &useClosure)); 51999566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(newdm, f, useCone, useClosure)); 520034aa8a36SMatthew G. Knepley } 52013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 520234aa8a36SMatthew G. Knepley } 520334aa8a36SMatthew G. Knepley 520434aa8a36SMatthew G. Knepley /*@ 520534aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 520634aa8a36SMatthew G. Knepley 520720f4b53cSBarry Smith Not Collective 520834aa8a36SMatthew G. Knepley 520934aa8a36SMatthew G. Knepley Input Parameters: 521020f4b53cSBarry Smith + dm - The `DM` object 521120f4b53cSBarry Smith - f - The field number, or `PETSC_DEFAULT` for the default adjacency 521234aa8a36SMatthew G. Knepley 5213d8d19677SJose E. Roman Output Parameters: 521434aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 521534aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 521634aa8a36SMatthew G. Knepley 521734aa8a36SMatthew G. Knepley Level: developer 521834aa8a36SMatthew G. Knepley 521920f4b53cSBarry Smith Notes: 522020f4b53cSBarry Smith .vb 522120f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 522220f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 522320f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 522420f4b53cSBarry Smith .ve 522520f4b53cSBarry Smith Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 522620f4b53cSBarry Smith 52271cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetAdjacency()`, `DMGetField()`, `DMSetField()` 522834aa8a36SMatthew G. Knepley @*/ 5229d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 5230d71ae5a4SJacob Faibussowitsch { 523134aa8a36SMatthew G. Knepley PetscFunctionBegin; 523234aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52334f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 3); 52344f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 4); 523534aa8a36SMatthew G. Knepley if (f < 0) { 523634aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 523734aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 523834aa8a36SMatthew G. Knepley } else { 523934aa8a36SMatthew G. Knepley PetscInt Nf; 524034aa8a36SMatthew G. Knepley 52419566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 52427a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 524334aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 524434aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 524534aa8a36SMatthew G. Knepley } 52463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 524734aa8a36SMatthew G. Knepley } 524834aa8a36SMatthew G. Knepley 524934aa8a36SMatthew G. Knepley /*@ 525034aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 525134aa8a36SMatthew G. Knepley 525220f4b53cSBarry Smith Not Collective 525334aa8a36SMatthew G. Knepley 525434aa8a36SMatthew G. Knepley Input Parameters: 525520f4b53cSBarry Smith + dm - The `DM` object 525634aa8a36SMatthew G. Knepley . f - The field number 525734aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 525834aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 525934aa8a36SMatthew G. Knepley 526034aa8a36SMatthew G. Knepley Level: developer 526134aa8a36SMatthew G. Knepley 526220f4b53cSBarry Smith Notes: 526320f4b53cSBarry Smith .vb 526420f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 526520f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 526620f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 526720f4b53cSBarry Smith .ve 526820f4b53cSBarry Smith Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 526920f4b53cSBarry Smith 52701cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetAdjacency()`, `DMGetField()`, `DMSetField()` 527134aa8a36SMatthew G. Knepley @*/ 5272d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 5273d71ae5a4SJacob Faibussowitsch { 527434aa8a36SMatthew G. Knepley PetscFunctionBegin; 527534aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 527634aa8a36SMatthew G. Knepley if (f < 0) { 527734aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 527834aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 527934aa8a36SMatthew G. Knepley } else { 528034aa8a36SMatthew G. Knepley PetscInt Nf; 528134aa8a36SMatthew G. Knepley 52829566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 52837a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 528434aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 528534aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5286e5e52638SMatthew G. Knepley } 52873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5288e5e52638SMatthew G. Knepley } 5289e5e52638SMatthew G. Knepley 5290b0441da4SMatthew G. Knepley /*@ 5291b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5292b0441da4SMatthew G. Knepley 5293b0441da4SMatthew G. Knepley Not collective 5294b0441da4SMatthew G. Knepley 5295f899ff85SJose E. Roman Input Parameter: 529620f4b53cSBarry Smith . dm - The `DM` object 5297b0441da4SMatthew G. Knepley 5298d8d19677SJose E. Roman Output Parameters: 5299b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5300b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5301b0441da4SMatthew G. Knepley 5302b0441da4SMatthew G. Knepley Level: developer 5303b0441da4SMatthew G. Knepley 530420f4b53cSBarry Smith Notes: 530520f4b53cSBarry Smith .vb 530620f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 530720f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 530820f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 530920f4b53cSBarry Smith .ve 531020f4b53cSBarry Smith 53111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5312b0441da4SMatthew G. Knepley @*/ 5313d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5314d71ae5a4SJacob Faibussowitsch { 5315b0441da4SMatthew G. Knepley PetscInt Nf; 5316b0441da4SMatthew G. Knepley 5317b0441da4SMatthew G. Knepley PetscFunctionBegin; 5318b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 53194f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 2); 53204f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 3); 53219566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5322b0441da4SMatthew G. Knepley if (!Nf) { 53239566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5324b0441da4SMatthew G. Knepley } else { 53259566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, 0, useCone, useClosure)); 5326b0441da4SMatthew G. Knepley } 53273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5328b0441da4SMatthew G. Knepley } 5329b0441da4SMatthew G. Knepley 5330b0441da4SMatthew G. Knepley /*@ 5331b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5332b0441da4SMatthew G. Knepley 533320f4b53cSBarry Smith Not Collective 5334b0441da4SMatthew G. Knepley 5335b0441da4SMatthew G. Knepley Input Parameters: 533620f4b53cSBarry Smith + dm - The `DM` object 5337b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5338b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5339b0441da4SMatthew G. Knepley 5340b0441da4SMatthew G. Knepley Level: developer 5341b0441da4SMatthew G. Knepley 534220f4b53cSBarry Smith Notes: 534320f4b53cSBarry Smith .vb 534420f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 534520f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 534620f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 534720f4b53cSBarry Smith .ve 534820f4b53cSBarry Smith 53491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5350b0441da4SMatthew G. Knepley @*/ 5351d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5352d71ae5a4SJacob Faibussowitsch { 5353b0441da4SMatthew G. Knepley PetscInt Nf; 5354b0441da4SMatthew G. Knepley 5355b0441da4SMatthew G. Knepley PetscFunctionBegin; 5356b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 53579566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5358b0441da4SMatthew G. Knepley if (!Nf) { 53599566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5360b0441da4SMatthew G. Knepley } else { 53619566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, 0, useCone, useClosure)); 5362e5e52638SMatthew G. Knepley } 53633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5364e5e52638SMatthew G. Knepley } 5365e5e52638SMatthew G. Knepley 5366d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompleteBCLabels_Internal(DM dm) 5367d71ae5a4SJacob Faibussowitsch { 5368799db056SMatthew G. Knepley DM plex; 5369799db056SMatthew G. Knepley DMLabel *labels, *glabels; 5370799db056SMatthew G. Knepley const char **names; 5371799db056SMatthew G. Knepley char *sendNames, *recvNames; 5372799db056SMatthew G. Knepley PetscInt Nds, s, maxLabels = 0, maxLen = 0, gmaxLen, Nl = 0, gNl, l, gl, m; 5373799db056SMatthew G. Knepley size_t len; 5374799db056SMatthew G. Knepley MPI_Comm comm; 5375799db056SMatthew G. Knepley PetscMPIInt rank, size, p, *counts, *displs; 5376783e2ec8SMatthew G. Knepley 5377783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5378799db056SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5379799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 5380799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5381799db056SMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 5382799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5383799db056SMatthew G. Knepley PetscDS dsBC; 5384799db056SMatthew G. Knepley PetscInt numBd; 5385799db056SMatthew G. Knepley 538607218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5387799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5388799db056SMatthew G. Knepley maxLabels += numBd; 5389799db056SMatthew G. Knepley } 5390799db056SMatthew G. Knepley PetscCall(PetscCalloc1(maxLabels, &labels)); 5391799db056SMatthew G. Knepley /* Get list of labels to be completed */ 5392799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5393799db056SMatthew G. Knepley PetscDS dsBC; 5394799db056SMatthew G. Knepley PetscInt numBd, bd; 5395799db056SMatthew G. Knepley 539607218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5397799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5398799db056SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5399799db056SMatthew G. Knepley DMLabel label; 5400799db056SMatthew G. Knepley PetscInt field; 5401799db056SMatthew G. Knepley PetscObject obj; 5402799db056SMatthew G. Knepley PetscClassId id; 5403799db056SMatthew G. Knepley 5404799db056SMatthew G. Knepley PetscCall(PetscDSGetBoundary(dsBC, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 54059566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, field, NULL, &obj)); 54069566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(obj, &id)); 5407fa74d514SMatthew G. Knepley if (id != PETSCFE_CLASSID || !label) continue; 54089371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 54099371c9d4SSatish Balay if (labels[l] == label) break; 5410799db056SMatthew G. Knepley if (l == Nl) labels[Nl++] = label; 5411783e2ec8SMatthew G. Knepley } 5412799db056SMatthew G. Knepley } 5413799db056SMatthew G. Knepley /* Get label names */ 5414799db056SMatthew G. Knepley PetscCall(PetscMalloc1(Nl, &names)); 5415799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscObjectGetName((PetscObject)labels[l], &names[l])); 54169371c9d4SSatish Balay for (l = 0; l < Nl; ++l) { 54179371c9d4SSatish Balay PetscCall(PetscStrlen(names[l], &len)); 54189371c9d4SSatish Balay maxLen = PetscMax(maxLen, (PetscInt)len + 2); 54199371c9d4SSatish Balay } 5420799db056SMatthew G. Knepley PetscCall(PetscFree(labels)); 5421462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&maxLen, &gmaxLen, 1, MPIU_INT, MPI_MAX, comm)); 5422799db056SMatthew G. Knepley PetscCall(PetscCalloc1(Nl * gmaxLen, &sendNames)); 5423c6a7a370SJeremy L Thompson for (l = 0; l < Nl; ++l) PetscCall(PetscStrncpy(&sendNames[gmaxLen * l], names[l], gmaxLen)); 5424799db056SMatthew G. Knepley PetscCall(PetscFree(names)); 5425799db056SMatthew G. Knepley /* Put all names on all processes */ 5426799db056SMatthew G. Knepley PetscCall(PetscCalloc2(size, &counts, size + 1, &displs)); 5427799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgather(&Nl, 1, MPI_INT, counts, 1, MPI_INT, comm)); 5428799db056SMatthew G. Knepley for (p = 0; p < size; ++p) displs[p + 1] = displs[p] + counts[p]; 5429799db056SMatthew G. Knepley gNl = displs[size]; 54309371c9d4SSatish Balay for (p = 0; p < size; ++p) { 54319371c9d4SSatish Balay counts[p] *= gmaxLen; 54329371c9d4SSatish Balay displs[p] *= gmaxLen; 54339371c9d4SSatish Balay } 5434799db056SMatthew G. Knepley PetscCall(PetscCalloc2(gNl * gmaxLen, &recvNames, gNl, &glabels)); 5435799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgatherv(sendNames, counts[rank], MPI_CHAR, recvNames, counts, displs, MPI_CHAR, comm)); 5436799db056SMatthew G. Knepley PetscCall(PetscFree2(counts, displs)); 5437799db056SMatthew G. Knepley PetscCall(PetscFree(sendNames)); 5438799db056SMatthew G. Knepley for (l = 0, gl = 0; l < gNl; ++l) { 5439799db056SMatthew G. Knepley PetscCall(DMGetLabel(dm, &recvNames[l * gmaxLen], &glabels[gl])); 5440799db056SMatthew G. Knepley PetscCheck(glabels[gl], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Label %s missing on rank %d", &recvNames[l * gmaxLen], rank); 54419371c9d4SSatish Balay for (m = 0; m < gl; ++m) 54425d6b2bfcSJames Wright if (glabels[m] == glabels[gl]) goto next_label; 54439566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 5444799db056SMatthew G. Knepley PetscCall(DMPlexLabelComplete(plex, glabels[gl])); 54459566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5446799db056SMatthew G. Knepley ++gl; 54475d6b2bfcSJames Wright next_label: 54485d6b2bfcSJames Wright continue; 5449783e2ec8SMatthew G. Knepley } 5450799db056SMatthew G. Knepley PetscCall(PetscFree2(recvNames, glabels)); 54513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5452783e2ec8SMatthew G. Knepley } 5453783e2ec8SMatthew G. Knepley 5454d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5455d71ae5a4SJacob Faibussowitsch { 5456e5e52638SMatthew G. Knepley DMSpace *tmpd; 5457e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5458e5e52638SMatthew G. Knepley 5459e5e52638SMatthew G. Knepley PetscFunctionBegin; 54603ba16761SJacob Faibussowitsch if (Nds >= NdsNew) PetscFunctionReturn(PETSC_SUCCESS); 54619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NdsNew, &tmpd)); 5462e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 54639371c9d4SSatish Balay for (s = Nds; s < NdsNew; ++s) { 54649371c9d4SSatish Balay tmpd[s].ds = NULL; 54659371c9d4SSatish Balay tmpd[s].label = NULL; 54669371c9d4SSatish Balay tmpd[s].fields = NULL; 54679371c9d4SSatish Balay } 54689566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5469e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5470e5e52638SMatthew G. Knepley dm->probs = tmpd; 54713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5472e5e52638SMatthew G. Knepley } 5473e5e52638SMatthew G. Knepley 5474e5e52638SMatthew G. Knepley /*@ 547520f4b53cSBarry Smith DMGetNumDS - Get the number of discrete systems in the `DM` 5476e5e52638SMatthew G. Knepley 547720f4b53cSBarry Smith Not Collective 5478e5e52638SMatthew G. Knepley 5479e5e52638SMatthew G. Knepley Input Parameter: 548020f4b53cSBarry Smith . dm - The `DM` 5481e5e52638SMatthew G. Knepley 5482e5e52638SMatthew G. Knepley Output Parameter: 548320f4b53cSBarry Smith . Nds - The number of `PetscDS` objects 5484e5e52638SMatthew G. Knepley 5485e5e52638SMatthew G. Knepley Level: intermediate 5486e5e52638SMatthew G. Knepley 54871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMGetCellDS()` 5488e5e52638SMatthew G. Knepley @*/ 5489d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5490d71ae5a4SJacob Faibussowitsch { 5491e5e52638SMatthew G. Knepley PetscFunctionBegin; 5492e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54934f572ea9SToby Isaac PetscAssertPointer(Nds, 2); 5494e5e52638SMatthew G. Knepley *Nds = dm->Nds; 54953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5496e5e52638SMatthew G. Knepley } 5497e5e52638SMatthew G. Knepley 5498e5e52638SMatthew G. Knepley /*@ 549920f4b53cSBarry Smith DMClearDS - Remove all discrete systems from the `DM` 5500e5e52638SMatthew G. Knepley 550120f4b53cSBarry Smith Logically Collective 5502e5e52638SMatthew G. Knepley 5503e5e52638SMatthew G. Knepley Input Parameter: 550420f4b53cSBarry Smith . dm - The `DM` 5505e5e52638SMatthew G. Knepley 5506e5e52638SMatthew G. Knepley Level: intermediate 5507e5e52638SMatthew G. Knepley 55081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumDS()`, `DMGetDS()`, `DMSetField()` 5509e5e52638SMatthew G. Knepley @*/ 5510d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearDS(DM dm) 5511d71ae5a4SJacob Faibussowitsch { 5512e5e52638SMatthew G. Knepley PetscInt s; 5513e5e52638SMatthew G. Knepley 5514e5e52638SMatthew G. Knepley PetscFunctionBegin; 5515e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5516e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 55179566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 551807218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 55199566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[s].label)); 55209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[s].fields)); 5521e5e52638SMatthew G. Knepley } 55229566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5523e5e52638SMatthew G. Knepley dm->probs = NULL; 5524e5e52638SMatthew G. Knepley dm->Nds = 0; 55253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5526e5e52638SMatthew G. Knepley } 5527e5e52638SMatthew G. Knepley 5528e5e52638SMatthew G. Knepley /*@ 552920f4b53cSBarry Smith DMGetDS - Get the default `PetscDS` 5530e5e52638SMatthew G. Knepley 553120f4b53cSBarry Smith Not Collective 5532e5e52638SMatthew G. Knepley 5533e5e52638SMatthew G. Knepley Input Parameter: 553420f4b53cSBarry Smith . dm - The `DM` 5535e5e52638SMatthew G. Knepley 5536e5e52638SMatthew G. Knepley Output Parameter: 553707218a29SMatthew G. Knepley . ds - The default `PetscDS` 5538e5e52638SMatthew G. Knepley 5539e5e52638SMatthew G. Knepley Level: intermediate 5540e5e52638SMatthew G. Knepley 5541ce78bad3SBarry Smith Note: 5542ce78bad3SBarry Smith The `ds` is owned by the `dm` and should not be destroyed directly. 5543ce78bad3SBarry Smith 55441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCellDS()`, `DMGetRegionDS()` 5545e5e52638SMatthew G. Knepley @*/ 554607218a29SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *ds) 5547d71ae5a4SJacob Faibussowitsch { 5548e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5549e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55504f572ea9SToby Isaac PetscAssertPointer(ds, 2); 555107218a29SMatthew G. Knepley PetscCheck(dm->Nds > 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Need to call DMCreateDS() before calling DMGetDS()"); 555207218a29SMatthew G. Knepley *ds = dm->probs[0].ds; 55533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5554e5e52638SMatthew G. Knepley } 5555e5e52638SMatthew G. Knepley 5556e5e52638SMatthew G. Knepley /*@ 555720f4b53cSBarry Smith DMGetCellDS - Get the `PetscDS` defined on a given cell 5558e5e52638SMatthew G. Knepley 555920f4b53cSBarry Smith Not Collective 5560e5e52638SMatthew G. Knepley 5561e5e52638SMatthew G. Knepley Input Parameters: 556220f4b53cSBarry Smith + dm - The `DM` 556320f4b53cSBarry Smith - point - Cell for the `PetscDS` 5564e5e52638SMatthew G. Knepley 556507218a29SMatthew G. Knepley Output Parameters: 556607218a29SMatthew G. Knepley + ds - The `PetscDS` defined on the given cell 556707218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or NULL if the same ds 5568e5e52638SMatthew G. Knepley 5569e5e52638SMatthew G. Knepley Level: developer 5570e5e52638SMatthew G. Knepley 55711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMSetRegionDS()` 5572e5e52638SMatthew G. Knepley @*/ 557307218a29SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *ds, PetscDS *dsIn) 5574d71ae5a4SJacob Faibussowitsch { 557507218a29SMatthew G. Knepley PetscDS dsDef = NULL; 5576e5e52638SMatthew G. Knepley PetscInt s; 5577e5e52638SMatthew G. Knepley 5578e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5579e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55804f572ea9SToby Isaac if (ds) PetscAssertPointer(ds, 3); 55814f572ea9SToby Isaac if (dsIn) PetscAssertPointer(dsIn, 4); 558263a3b9bcSJacob Faibussowitsch PetscCheck(point >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %" PetscInt_FMT, point); 558307218a29SMatthew G. Knepley if (ds) *ds = NULL; 558407218a29SMatthew G. Knepley if (dsIn) *dsIn = NULL; 5585e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5586e5e52638SMatthew G. Knepley PetscInt val; 5587e5e52638SMatthew G. Knepley 55889371c9d4SSatish Balay if (!dm->probs[s].label) { 558907218a29SMatthew G. Knepley dsDef = dm->probs[s].ds; 55909371c9d4SSatish Balay } else { 55919566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dm->probs[s].label, point, &val)); 55929371c9d4SSatish Balay if (val >= 0) { 559307218a29SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 559407218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 55959371c9d4SSatish Balay break; 55969371c9d4SSatish Balay } 5597e5e52638SMatthew G. Knepley } 5598e5e52638SMatthew G. Knepley } 559907218a29SMatthew G. Knepley if (ds && !*ds) *ds = dsDef; 56003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5601e5e52638SMatthew G. Knepley } 5602e5e52638SMatthew G. Knepley 5603e5e52638SMatthew G. Knepley /*@ 560420f4b53cSBarry Smith DMGetRegionDS - Get the `PetscDS` for a given mesh region, defined by a `DMLabel` 5605e5e52638SMatthew G. Knepley 560620f4b53cSBarry Smith Not Collective 5607e5e52638SMatthew G. Knepley 5608e5e52638SMatthew G. Knepley Input Parameters: 560920f4b53cSBarry Smith + dm - The `DM` 561020f4b53cSBarry Smith - label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 5611e5e52638SMatthew G. Knepley 5612b3cf3223SMatthew G. Knepley Output Parameters: 561320f4b53cSBarry Smith + fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 561407218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 561507218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5616e5e52638SMatthew G. Knepley 5617e5e52638SMatthew G. Knepley Level: advanced 5618e5e52638SMatthew G. Knepley 561920f4b53cSBarry Smith Note: 562020f4b53cSBarry Smith If a non-`NULL` label is given, but there is no `PetscDS` on that specific label, 562120f4b53cSBarry Smith the `PetscDS` for the full domain (if present) is returned. Returns with 562207218a29SMatthew G. Knepley fields = `NULL` and ds = `NULL` if there is no `PetscDS` for the full domain. 562320f4b53cSBarry Smith 56241cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5625e5e52638SMatthew G. Knepley @*/ 562607218a29SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5627d71ae5a4SJacob Faibussowitsch { 5628e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5629e5e52638SMatthew G. Knepley 5630e5e52638SMatthew G. Knepley PetscFunctionBegin; 5631e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5632e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 56339371c9d4SSatish Balay if (fields) { 56344f572ea9SToby Isaac PetscAssertPointer(fields, 3); 56359371c9d4SSatish Balay *fields = NULL; 56369371c9d4SSatish Balay } 56379371c9d4SSatish Balay if (ds) { 56384f572ea9SToby Isaac PetscAssertPointer(ds, 4); 56399371c9d4SSatish Balay *ds = NULL; 56409371c9d4SSatish Balay } 564107218a29SMatthew G. Knepley if (dsIn) { 56424f572ea9SToby Isaac PetscAssertPointer(dsIn, 5); 564307218a29SMatthew G. Knepley *dsIn = NULL; 564407218a29SMatthew G. Knepley } 5645e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5646154ca461SJed Brown if (dm->probs[s].label == label || !dm->probs[s].label) { 5647b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5648b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 564907218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 56503ba16761SJacob Faibussowitsch if (dm->probs[s].label) PetscFunctionReturn(PETSC_SUCCESS); 5651b3cf3223SMatthew G. Knepley } 5652e5e52638SMatthew G. Knepley } 56533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5654e5e52638SMatthew G. Knepley } 5655e5e52638SMatthew G. Knepley 5656e5e52638SMatthew G. Knepley /*@ 5657bb7acecfSBarry Smith DMSetRegionDS - Set the `PetscDS` for a given mesh region, defined by a `DMLabel` 5658083401c6SMatthew G. Knepley 565920f4b53cSBarry Smith Collective 5660083401c6SMatthew G. Knepley 5661083401c6SMatthew G. Knepley Input Parameters: 5662bb7acecfSBarry Smith + dm - The `DM` 566320f4b53cSBarry Smith . label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 566407218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` for all fields 566507218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region 566607218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5667083401c6SMatthew G. Knepley 566820f4b53cSBarry Smith Level: advanced 566920f4b53cSBarry Smith 5670bb7acecfSBarry Smith Note: 5671bb7acecfSBarry Smith If the label has a `PetscDS` defined, it will be replaced. Otherwise, it will be added to the `DM`. If the `PetscDS` is replaced, 5672083401c6SMatthew G. Knepley the fields argument is ignored. 5673083401c6SMatthew G. Knepley 56741cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionNumDS()`, `DMGetDS()`, `DMGetCellDS()` 5675083401c6SMatthew G. Knepley @*/ 567607218a29SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5677d71ae5a4SJacob Faibussowitsch { 5678083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5679083401c6SMatthew G. Knepley 5680083401c6SMatthew G. Knepley PetscFunctionBegin; 5681083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5682083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 568307218a29SMatthew G. Knepley if (fields) PetscValidHeaderSpecific(fields, IS_CLASSID, 3); 5684064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 568507218a29SMatthew G. Knepley if (dsIn) PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 5); 5686083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5687083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 56889566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 568907218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 5690083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 569107218a29SMatthew G. Knepley dm->probs[s].dsIn = dsIn; 56923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5693083401c6SMatthew G. Knepley } 5694083401c6SMatthew G. Knepley } 56959566063dSJacob Faibussowitsch PetscCall(DMDSEnlarge_Static(dm, Nds + 1)); 56969566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 56979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 56989566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 569907218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 5700083401c6SMatthew G. Knepley if (!label) { 5701083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5702083401c6SMatthew G. Knepley for (s = Nds - 1; s >= 0; --s) dm->probs[s + 1] = dm->probs[s]; 5703083401c6SMatthew G. Knepley Nds = 0; 5704083401c6SMatthew G. Knepley } 5705083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5706083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5707083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 570807218a29SMatthew G. Knepley dm->probs[Nds].dsIn = dsIn; 57093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5710083401c6SMatthew G. Knepley } 5711083401c6SMatthew G. Knepley 5712083401c6SMatthew G. Knepley /*@ 571320f4b53cSBarry Smith DMGetRegionNumDS - Get the `PetscDS` for a given mesh region, defined by the region number 5714e5e52638SMatthew G. Knepley 571520f4b53cSBarry Smith Not Collective 5716e5e52638SMatthew G. Knepley 5717e5e52638SMatthew G. Knepley Input Parameters: 571820f4b53cSBarry Smith + dm - The `DM` 5719e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5720e5e52638SMatthew G. Knepley 5721e5e52638SMatthew G. Knepley Output Parameters: 572220f4b53cSBarry Smith + label - The region label, or `NULL` 572320f4b53cSBarry Smith . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 572407218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 572507218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5726e5e52638SMatthew G. Knepley 5727e5e52638SMatthew G. Knepley Level: advanced 5728e5e52638SMatthew G. Knepley 57291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5730e5e52638SMatthew G. Knepley @*/ 573107218a29SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5732d71ae5a4SJacob Faibussowitsch { 5733e5e52638SMatthew G. Knepley PetscInt Nds; 5734e5e52638SMatthew G. Knepley 5735e5e52638SMatthew G. Knepley PetscFunctionBegin; 5736e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57379566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 573863a3b9bcSJacob Faibussowitsch PetscCheck((num >= 0) && (num < Nds), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Region number %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", num, Nds); 5739e5e52638SMatthew G. Knepley if (label) { 57404f572ea9SToby Isaac PetscAssertPointer(label, 3); 5741e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5742e5e52638SMatthew G. Knepley } 5743b3cf3223SMatthew G. Knepley if (fields) { 57444f572ea9SToby Isaac PetscAssertPointer(fields, 4); 5745b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5746b3cf3223SMatthew G. Knepley } 5747e5e52638SMatthew G. Knepley if (ds) { 57484f572ea9SToby Isaac PetscAssertPointer(ds, 5); 5749e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5750e5e52638SMatthew G. Knepley } 575107218a29SMatthew G. Knepley if (dsIn) { 57524f572ea9SToby Isaac PetscAssertPointer(dsIn, 6); 575307218a29SMatthew G. Knepley *dsIn = dm->probs[num].dsIn; 575407218a29SMatthew G. Knepley } 57553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5756e5e52638SMatthew G. Knepley } 5757e5e52638SMatthew G. Knepley 5758e5e52638SMatthew G. Knepley /*@ 575920f4b53cSBarry Smith DMSetRegionNumDS - Set the `PetscDS` for a given mesh region, defined by the region number 5760e5e52638SMatthew G. Knepley 576120f4b53cSBarry Smith Not Collective 5762e5e52638SMatthew G. Knepley 5763e5e52638SMatthew G. Knepley Input Parameters: 576420f4b53cSBarry Smith + dm - The `DM` 5765083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 576620f4b53cSBarry Smith . label - The region label, or `NULL` 576707218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` to prevent setting 576807218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` to prevent setting 576907218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5770e5e52638SMatthew G. Knepley 5771e5e52638SMatthew G. Knepley Level: advanced 5772e5e52638SMatthew G. Knepley 57731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5774e5e52638SMatthew G. Knepley @*/ 577507218a29SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5776d71ae5a4SJacob Faibussowitsch { 5777083401c6SMatthew G. Knepley PetscInt Nds; 5778e5e52638SMatthew G. Knepley 5779e5e52638SMatthew G. Knepley PetscFunctionBegin; 5780e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5781ad540459SPierre Jolivet if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 57829566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 578363a3b9bcSJacob Faibussowitsch PetscCheck((num >= 0) && (num < Nds), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Region number %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", num, Nds); 57849566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 57859566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[num].label)); 5786083401c6SMatthew G. Knepley dm->probs[num].label = label; 5787083401c6SMatthew G. Knepley if (fields) { 5788083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 57899566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 57909566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[num].fields)); 5791083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5792e5e52638SMatthew G. Knepley } 5793083401c6SMatthew G. Knepley if (ds) { 5794083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 57959566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 57969566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[num].ds)); 5797083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5798083401c6SMatthew G. Knepley } 579907218a29SMatthew G. Knepley if (dsIn) { 580007218a29SMatthew G. Knepley PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 6); 580107218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 580207218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[num].dsIn)); 580307218a29SMatthew G. Knepley dm->probs[num].dsIn = dsIn; 580407218a29SMatthew G. Knepley } 58053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5806e5e52638SMatthew G. Knepley } 5807e5e52638SMatthew G. Knepley 5808e5e52638SMatthew G. Knepley /*@ 580920f4b53cSBarry Smith DMFindRegionNum - Find the region number for a given `PetscDS`, or -1 if it is not found. 58101d3af9e0SMatthew G. Knepley 581120f4b53cSBarry Smith Not Collective 58121d3af9e0SMatthew G. Knepley 58131d3af9e0SMatthew G. Knepley Input Parameters: 581420f4b53cSBarry Smith + dm - The `DM` 581520f4b53cSBarry Smith - ds - The `PetscDS` defined on the given region 58161d3af9e0SMatthew G. Knepley 58171d3af9e0SMatthew G. Knepley Output Parameter: 58181d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 58191d3af9e0SMatthew G. Knepley 58201d3af9e0SMatthew G. Knepley Level: advanced 58211d3af9e0SMatthew G. Knepley 58221cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 58231d3af9e0SMatthew G. Knepley @*/ 5824d71ae5a4SJacob Faibussowitsch PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 5825d71ae5a4SJacob Faibussowitsch { 58261d3af9e0SMatthew G. Knepley PetscInt Nds, n; 58271d3af9e0SMatthew G. Knepley 58281d3af9e0SMatthew G. Knepley PetscFunctionBegin; 58291d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58301d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 58314f572ea9SToby Isaac PetscAssertPointer(num, 3); 58329566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 58339371c9d4SSatish Balay for (n = 0; n < Nds; ++n) 58349371c9d4SSatish Balay if (ds == dm->probs[n].ds) break; 58351d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 58361d3af9e0SMatthew G. Knepley else *num = n; 58373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58381d3af9e0SMatthew G. Knepley } 58391d3af9e0SMatthew G. Knepley 5840cc4c1da9SBarry Smith /*@ 5841bb7acecfSBarry Smith DMCreateFEDefault - Create a `PetscFE` based on the celltype for the mesh 58422df84da0SMatthew G. Knepley 584320f4b53cSBarry Smith Not Collective 58442df84da0SMatthew G. Knepley 5845f1a722f8SMatthew G. Knepley Input Parameters: 5846bb7acecfSBarry Smith + dm - The `DM` 58472df84da0SMatthew G. Knepley . Nc - The number of components for the field 584820f4b53cSBarry Smith . prefix - The options prefix for the output `PetscFE`, or `NULL` 5849bb7acecfSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 58502df84da0SMatthew G. Knepley 58512df84da0SMatthew G. Knepley Output Parameter: 5852bb7acecfSBarry Smith . fem - The `PetscFE` 58532df84da0SMatthew G. Knepley 585420f4b53cSBarry Smith Level: intermediate 585520f4b53cSBarry Smith 5856bb7acecfSBarry Smith Note: 5857bb7acecfSBarry Smith This is a convenience method that just calls `PetscFECreateByCell()` underneath. 58582df84da0SMatthew G. Knepley 58591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscFECreateByCell()`, `DMAddField()`, `DMCreateDS()`, `DMGetCellDS()`, `DMGetRegionDS()` 58602df84da0SMatthew G. Knepley @*/ 5861d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFEDefault(DM dm, PetscInt Nc, const char prefix[], PetscInt qorder, PetscFE *fem) 5862d71ae5a4SJacob Faibussowitsch { 58632df84da0SMatthew G. Knepley DMPolytopeType ct; 58642df84da0SMatthew G. Knepley PetscInt dim, cStart; 58652df84da0SMatthew G. Knepley 58662df84da0SMatthew G. Knepley PetscFunctionBegin; 58672df84da0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58682df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 2); 58694f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 3); 58702df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, qorder, 4); 58714f572ea9SToby Isaac PetscAssertPointer(fem, 5); 58729566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 58739566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 58749566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 58759566063dSJacob Faibussowitsch PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, Nc, ct, prefix, qorder, fem)); 58763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58772df84da0SMatthew G. Knepley } 58782df84da0SMatthew G. Knepley 58791d3af9e0SMatthew G. Knepley /*@ 5880bb7acecfSBarry Smith DMCreateDS - Create the discrete systems for the `DM` based upon the fields added to the `DM` 5881e5e52638SMatthew G. Knepley 588220f4b53cSBarry Smith Collective 5883e5e52638SMatthew G. Knepley 5884e5e52638SMatthew G. Knepley Input Parameter: 5885bb7acecfSBarry Smith . dm - The `DM` 5886e5e52638SMatthew G. Knepley 588720f4b53cSBarry Smith Options Database Key: 5888bb7acecfSBarry Smith . -dm_petscds_view - View all the `PetscDS` objects in this `DM` 588945480ffeSMatthew G. Knepley 589020f4b53cSBarry Smith Level: intermediate 589120f4b53cSBarry Smith 5892ce78bad3SBarry Smith Developer Note: 5893ce78bad3SBarry Smith The name of this function is wrong. Create functions always return the created object as one of the arguments. 5894ce78bad3SBarry Smith 58951cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetField`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 5896e5e52638SMatthew G. Knepley @*/ 5897d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDS(DM dm) 5898d71ae5a4SJacob Faibussowitsch { 5899e5e52638SMatthew G. Knepley MPI_Comm comm; 5900083401c6SMatthew G. Knepley PetscDS dsDef; 5901083401c6SMatthew G. Knepley DMLabel *labelSet; 5902f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5903f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5904e5e52638SMatthew G. Knepley 5905e5e52638SMatthew G. Knepley PetscFunctionBegin; 5906e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 59073ba16761SJacob Faibussowitsch if (!dm->fields) PetscFunctionReturn(PETSC_SUCCESS); 59089566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 59099566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dE)); 5910083401c6SMatthew G. Knepley /* Determine how many regions we have */ 59119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &labelSet)); 5912083401c6SMatthew G. Knepley Nl = 0; 5913083401c6SMatthew G. Knepley Ndef = 0; 5914083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5915083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5916083401c6SMatthew G. Knepley PetscInt l; 5917083401c6SMatthew G. Knepley 5918f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5919f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5920f918ec44SMatthew G. Knepley { 5921f918ec44SMatthew G. Knepley PetscClassId id; 5922f918ec44SMatthew G. Knepley 59239566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(dm->fields[f].disc, &id)); 5924f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5925f918ec44SMatthew G. Knepley Ceed ceed; 5926f918ec44SMatthew G. Knepley 59279566063dSJacob Faibussowitsch PetscCall(DMGetCeed(dm, &ceed)); 59289566063dSJacob Faibussowitsch PetscCall(PetscFESetCeed((PetscFE)dm->fields[f].disc, ceed)); 5929f918ec44SMatthew G. Knepley } 5930f918ec44SMatthew G. Knepley } 5931f918ec44SMatthew G. Knepley #endif 59329371c9d4SSatish Balay if (!label) { 59339371c9d4SSatish Balay ++Ndef; 59349371c9d4SSatish Balay continue; 59359371c9d4SSatish Balay } 59369371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 59379371c9d4SSatish Balay if (label == labelSet[l]) break; 5938083401c6SMatthew G. Knepley if (l < Nl) continue; 5939083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5940083401c6SMatthew G. Knepley } 5941083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 594207218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 5943083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5944b3cf3223SMatthew G. Knepley IS fields; 5945b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5946b3cf3223SMatthew G. Knepley 59479371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59489371c9d4SSatish Balay if (!dm->fields[f].label) ++nf; 59497a8be351SBarry Smith PetscCheck(nf, comm, PETSC_ERR_PLIB, "All fields have labels, but we are trying to create a default DS"); 59509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 59519371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59529371c9d4SSatish Balay if (!dm->fields[f].label) fld[nf++] = f; 59539566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 59549566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 59559566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 59569566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 595788f0c812SMatthew G. Knepley 59589566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 595907218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, NULL, fields, dsDef, NULL)); 59609566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 59619566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 59622df9ee95SMatthew G. Knepley } 596307218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 59649566063dSJacob Faibussowitsch if (dsDef) PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 5965083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5966083401c6SMatthew G. Knepley if (Ndef && Nl) { 59670122748bSMatthew G. Knepley DM plex; 5968083401c6SMatthew G. Knepley DMLabel cellLabel; 5969083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5970083401c6SMatthew G. Knepley PetscInt *fields; 5971083401c6SMatthew G. Knepley const PetscInt *cells; 5972083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 59730122748bSMatthew G. Knepley 59749566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 59759566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(plex, &depth)); 59769566063dSJacob Faibussowitsch PetscCall(DMGetStratumIS(plex, "dim", depth, &allcellIS)); 59779566063dSJacob Faibussowitsch if (!allcellIS) PetscCall(DMGetStratumIS(plex, "depth", depth, &allcellIS)); 59785fedec97SMatthew G. Knepley /* TODO This looks like it only works for one label */ 5979083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5980083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5981083401c6SMatthew G. Knepley IS pointIS; 5982083401c6SMatthew G. Knepley 59839566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 59849566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, 1, &pointIS)); 59859566063dSJacob Faibussowitsch PetscCall(ISDifference(allcellIS, pointIS, &defcellIS)); 59869566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointIS)); 5987083401c6SMatthew G. Knepley } 59889566063dSJacob Faibussowitsch PetscCall(ISDestroy(&allcellIS)); 5989083401c6SMatthew G. Knepley 59909566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel)); 59919566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(defcellIS, &n)); 59929566063dSJacob Faibussowitsch PetscCall(ISGetIndices(defcellIS, &cells)); 59939566063dSJacob Faibussowitsch for (c = 0; c < n; ++c) PetscCall(DMLabelSetValue(cellLabel, cells[c], 1)); 59949566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(defcellIS, &cells)); 59959566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 59969566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(plex, cellLabel)); 5997083401c6SMatthew G. Knepley 59989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Ndef, &fields)); 59999371c9d4SSatish Balay for (f = 0; f < Nf; ++f) 60009371c9d4SSatish Balay if (!dm->fields[f].label) fields[nf++] = f; 60019566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fieldIS)); 60029566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fieldIS, "dm_fields_")); 60039566063dSJacob Faibussowitsch PetscCall(ISSetType(fieldIS, ISGENERAL)); 60049566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER)); 6005083401c6SMatthew G. Knepley 60069566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 600707218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, cellLabel, fieldIS, dsDef, NULL)); 60089566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 60099566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&cellLabel)); 60109566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 60119566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fieldIS)); 60129566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 6013083401c6SMatthew G. Knepley } 6014083401c6SMatthew G. Knepley /* Create label DSes 6015083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 6016083401c6SMatthew G. Knepley */ 6017083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 6018083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 6019083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 602007218a29SMatthew G. Knepley PetscDS ds, dsIn = NULL; 6021083401c6SMatthew G. Knepley IS fields; 6022083401c6SMatthew G. Knepley PetscInt *fld, nf; 6023083401c6SMatthew G. Knepley 60249566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 60259371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 60269371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 60279566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 60289371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 60299371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 60309566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 60319566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 60329566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 60339566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 60349566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(ds, dE)); 6035083401c6SMatthew G. Knepley { 6036083401c6SMatthew G. Knepley DMPolytopeType ct; 6037083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 60385fedec97SMatthew G. Knepley PetscBool isCohesiveLocal = PETSC_FALSE, isCohesive; 60390122748bSMatthew G. Knepley 60409566063dSJacob Faibussowitsch PetscCall(DMLabelGetBounds(label, &lStart, &lEnd)); 6041665f567fSMatthew G. Knepley if (lStart >= 0) { 60429566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, lStart, &ct)); 6043412e9a14SMatthew G. Knepley switch (ct) { 6044412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 6045412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 6046412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 6047d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 6048d71ae5a4SJacob Faibussowitsch isCohesiveLocal = PETSC_TRUE; 6049d71ae5a4SJacob Faibussowitsch break; 6050d71ae5a4SJacob Faibussowitsch default: 6051d71ae5a4SJacob Faibussowitsch break; 6052412e9a14SMatthew G. Knepley } 6053665f567fSMatthew G. Knepley } 6054462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&isCohesiveLocal, &isCohesive, 1, MPIU_BOOL, MPI_LOR, comm)); 605507218a29SMatthew G. Knepley if (isCohesive) { 605607218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsIn)); 605707218a29SMatthew G. Knepley PetscCall(PetscDSSetCoordinateDimension(dsIn, dE)); 605807218a29SMatthew G. Knepley } 60595fedec97SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) { 60605fedec97SMatthew G. Knepley if (label == dm->fields[f].label || !dm->fields[f].label) { 60615fedec97SMatthew G. Knepley if (label == dm->fields[f].label) { 60629566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, nf, NULL)); 60639566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(ds, nf, isCohesive)); 606407218a29SMatthew G. Knepley if (dsIn) { 606507218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, nf, NULL)); 606607218a29SMatthew G. Knepley PetscCall(PetscDSSetCohesive(dsIn, nf, isCohesive)); 606707218a29SMatthew G. Knepley } 60685fedec97SMatthew G. Knepley } 60695fedec97SMatthew G. Knepley ++nf; 60705fedec97SMatthew G. Knepley } 60715fedec97SMatthew G. Knepley } 6072e5e52638SMatthew G. Knepley } 607307218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, ds, dsIn)); 607407218a29SMatthew G. Knepley PetscCall(ISDestroy(&fields)); 60759566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 607607218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsIn)); 6077e5e52638SMatthew G. Knepley } 60789566063dSJacob Faibussowitsch PetscCall(PetscFree(labelSet)); 6079e5e52638SMatthew G. Knepley /* Set fields in DSes */ 6080083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 6081083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 608207218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 6083083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 6084083401c6SMatthew G. Knepley const PetscInt *fld; 60855fedec97SMatthew G. Knepley PetscInt nf, dsnf; 60865fedec97SMatthew G. Knepley PetscBool isCohesive; 6087e5e52638SMatthew G. Knepley 60889566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsnf)); 60899566063dSJacob Faibussowitsch PetscCall(PetscDSIsCohesive(ds, &isCohesive)); 60909566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(fields, &nf)); 60919566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fields, &fld)); 6092083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 6093083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 60945fedec97SMatthew G. Knepley PetscBool isCohesiveField; 6095e5e52638SMatthew G. Knepley PetscClassId id; 6096e5e52638SMatthew G. Knepley 60975fedec97SMatthew G. Knepley /* Handle DS with no fields */ 60989566063dSJacob Faibussowitsch if (dsnf) PetscCall(PetscDSGetCohesive(ds, f, &isCohesiveField)); 60995fedec97SMatthew G. Knepley /* If this is a cohesive cell, then regular fields need the lower dimensional discretization */ 610007218a29SMatthew G. Knepley if (isCohesive) { 610107218a29SMatthew G. Knepley if (!isCohesiveField) { 610207218a29SMatthew G. Knepley PetscObject bdDisc; 610307218a29SMatthew G. Knepley 610407218a29SMatthew G. Knepley PetscCall(PetscFEGetHeightSubspace((PetscFE)disc, 1, (PetscFE *)&bdDisc)); 610507218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, bdDisc)); 610607218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 610707218a29SMatthew G. Knepley } else { 61089566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, f, disc)); 610907218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 611007218a29SMatthew G. Knepley } 611107218a29SMatthew G. Knepley } else { 611207218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, disc)); 611307218a29SMatthew G. Knepley } 6114083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 61159566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 6116e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 6117e5e52638SMatthew G. Knepley } 61189566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fields, &fld)); 6119e5e52638SMatthew G. Knepley } 6120f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 61219566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)dm)->prefix, "-dm_ds_jet_degree", &k, &flg)); 6122f9244615SMatthew G. Knepley if (flg) { 61233b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 61243b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 612507218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 61263b4aee56SMatthew G. Knepley PetscInt Nf, f; 61273b4aee56SMatthew G. Knepley 61289566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 612907218a29SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 613007218a29SMatthew G. Knepley PetscCall(PetscDSSetJetDegree(ds, f, k)); 613107218a29SMatthew G. Knepley if (dsIn) PetscCall(PetscDSSetJetDegree(dsIn, f, k)); 613207218a29SMatthew G. Knepley } 61333b4aee56SMatthew G. Knepley } 6134f9244615SMatthew G. Knepley } 6135e5e52638SMatthew G. Knepley /* Setup DSes */ 6136e5e52638SMatthew G. Knepley if (doSetup) { 613707218a29SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 6138cf1363e4SMatthew G. Knepley if (dm->setfromoptionscalled) { 6139cf1363e4SMatthew G. Knepley PetscCall(PetscDSSetFromOptions(dm->probs[s].ds)); 6140cf1363e4SMatthew G. Knepley if (dm->probs[s].dsIn) PetscCall(PetscDSSetFromOptions(dm->probs[s].dsIn)); 6141cf1363e4SMatthew G. Knepley } 614207218a29SMatthew G. Knepley PetscCall(PetscDSSetUp(dm->probs[s].ds)); 614307218a29SMatthew G. Knepley if (dm->probs[s].dsIn) PetscCall(PetscDSSetUp(dm->probs[s].dsIn)); 614407218a29SMatthew G. Knepley } 6145e5e52638SMatthew G. Knepley } 61463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6147e5e52638SMatthew G. Knepley } 6148e5e52638SMatthew G. Knepley 6149e5e52638SMatthew G. Knepley /*@ 6150d2b2dc1eSMatthew G. Knepley DMUseTensorOrder - Use a tensor product closure ordering for the default section 6151d2b2dc1eSMatthew G. Knepley 6152d2b2dc1eSMatthew G. Knepley Input Parameters: 6153d2b2dc1eSMatthew G. Knepley + dm - The DM 6154d2b2dc1eSMatthew G. Knepley - tensor - Flag for tensor order 6155d2b2dc1eSMatthew G. Knepley 6156d2b2dc1eSMatthew G. Knepley Level: developer 6157d2b2dc1eSMatthew G. Knepley 6158d2b2dc1eSMatthew G. Knepley .seealso: `DMPlexSetClosurePermutationTensor()`, `PetscSectionResetClosurePermutation()` 6159d2b2dc1eSMatthew G. Knepley @*/ 6160d2b2dc1eSMatthew G. Knepley PetscErrorCode DMUseTensorOrder(DM dm, PetscBool tensor) 6161d2b2dc1eSMatthew G. Knepley { 6162d2b2dc1eSMatthew G. Knepley PetscInt Nf; 6163d2b2dc1eSMatthew G. Knepley PetscBool reorder = PETSC_TRUE, isPlex; 6164d2b2dc1eSMatthew G. Knepley 6165d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 6166d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMPLEX, &isPlex)); 6167d2b2dc1eSMatthew G. Knepley PetscCall(DMGetNumFields(dm, &Nf)); 6168d2b2dc1eSMatthew G. Knepley for (PetscInt f = 0; f < Nf; ++f) { 6169d2b2dc1eSMatthew G. Knepley PetscObject obj; 6170d2b2dc1eSMatthew G. Knepley PetscClassId id; 6171d2b2dc1eSMatthew G. Knepley 6172d2b2dc1eSMatthew G. Knepley PetscCall(DMGetField(dm, f, NULL, &obj)); 6173d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 6174d2b2dc1eSMatthew G. Knepley if (id == PETSCFE_CLASSID) { 6175d2b2dc1eSMatthew G. Knepley PetscSpace sp; 6176d2b2dc1eSMatthew G. Knepley PetscBool tensor; 6177d2b2dc1eSMatthew G. Knepley 6178d2b2dc1eSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace((PetscFE)obj, &sp)); 6179d2b2dc1eSMatthew G. Knepley PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 6180d2b2dc1eSMatthew G. Knepley reorder = reorder && tensor ? PETSC_TRUE : PETSC_FALSE; 6181d2b2dc1eSMatthew G. Knepley } else reorder = PETSC_FALSE; 6182d2b2dc1eSMatthew G. Knepley } 6183d2b2dc1eSMatthew G. Knepley if (tensor) { 6184d2b2dc1eSMatthew G. Knepley if (reorder && isPlex) PetscCall(DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, NULL)); 6185d2b2dc1eSMatthew G. Knepley } else { 6186d2b2dc1eSMatthew G. Knepley PetscSection s; 6187d2b2dc1eSMatthew G. Knepley 6188d2b2dc1eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm, &s)); 6189d2b2dc1eSMatthew G. Knepley if (s) PetscCall(PetscSectionResetClosurePermutation(s)); 6190d2b2dc1eSMatthew G. Knepley } 6191d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 6192d2b2dc1eSMatthew G. Knepley } 6193d2b2dc1eSMatthew G. Knepley 6194d2b2dc1eSMatthew G. Knepley /*@ 6195bb7acecfSBarry Smith DMComputeExactSolution - Compute the exact solution for a given `DM`, using the `PetscDS` information. 61967f96f943SMatthew G. Knepley 619720f4b53cSBarry Smith Collective 6198f2cacb80SMatthew G. Knepley 61997f96f943SMatthew G. Knepley Input Parameters: 6200bb7acecfSBarry Smith + dm - The `DM` 62017f96f943SMatthew G. Knepley - time - The time 62027f96f943SMatthew G. Knepley 62037f96f943SMatthew G. Knepley Output Parameters: 620420f4b53cSBarry Smith + u - The vector will be filled with exact solution values, or `NULL` 620520f4b53cSBarry Smith - u_t - The vector will be filled with the time derivative of exact solution values, or `NULL` 620620f4b53cSBarry Smith 620720f4b53cSBarry Smith Level: developer 62087f96f943SMatthew G. Knepley 6209bb7acecfSBarry Smith Note: 6210bb7acecfSBarry Smith The user must call `PetscDSSetExactSolution()` before using this routine 62117f96f943SMatthew G. Knepley 62121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscDSSetExactSolution()` 62137f96f943SMatthew G. Knepley @*/ 6214d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 6215d71ae5a4SJacob Faibussowitsch { 62167f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 62177f96f943SMatthew G. Knepley void **ectxs; 6218f60fa741SMatthew G. Knepley Vec locu, locu_t; 62197f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 62207f96f943SMatthew G. Knepley 62217f96f943SMatthew G. Knepley PetscFunctionBegin; 6222f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6223f60fa741SMatthew G. Knepley if (u) { 6224f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 6225f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu)); 6226f60fa741SMatthew G. Knepley PetscCall(VecSet(locu, 0.)); 6227f60fa741SMatthew G. Knepley } 6228f60fa741SMatthew G. Knepley if (u_t) { 6229f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 6230f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu_t)); 6231f60fa741SMatthew G. Knepley PetscCall(VecSet(locu_t, 0.)); 6232f60fa741SMatthew G. Knepley } 62339566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 62349566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exacts, Nf, &ectxs)); 62359566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 62367f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 62377f96f943SMatthew G. Knepley PetscDS ds; 62387f96f943SMatthew G. Knepley DMLabel label; 62397f96f943SMatthew G. Knepley IS fieldIS; 62407f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 62417f96f943SMatthew G. Knepley PetscInt dsNf, f; 62427f96f943SMatthew G. Knepley 624307218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 62449566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 62459566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fieldIS, &fields)); 62469566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 62479566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6248f2cacb80SMatthew G. Knepley if (u) { 6249f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolution(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6250f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu)); 6251f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu)); 62527f96f943SMatthew G. Knepley } 6253f2cacb80SMatthew G. Knepley if (u_t) { 62549566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 62559566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6256f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6257f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6258f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6259f2cacb80SMatthew G. Knepley } 62609566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 6261f2cacb80SMatthew G. Knepley } 6262f2cacb80SMatthew G. Knepley if (u) { 62639566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution")); 62649566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u, "exact_")); 6265f2cacb80SMatthew G. Knepley } 6266f2cacb80SMatthew G. Knepley if (u_t) { 62679566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution Time Derivative")); 62689566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u_t, "exact_t_")); 6269f2cacb80SMatthew G. Knepley } 62709566063dSJacob Faibussowitsch PetscCall(PetscFree2(exacts, ectxs)); 6271f60fa741SMatthew G. Knepley if (u) { 6272f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu, INSERT_ALL_VALUES, u)); 6273f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu, INSERT_ALL_VALUES, u)); 6274f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu)); 6275f60fa741SMatthew G. Knepley } 6276f60fa741SMatthew G. Knepley if (u_t) { 6277f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6278f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6279f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu_t)); 6280f60fa741SMatthew G. Knepley } 62813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62827f96f943SMatthew G. Knepley } 62837f96f943SMatthew G. Knepley 6284bb4b53efSMatthew G. Knepley static PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscInt minDegree, PetscInt maxDegree, PetscDS ds, PetscDS dsIn) 6285d71ae5a4SJacob Faibussowitsch { 628607218a29SMatthew G. Knepley PetscDS dsNew, dsInNew = NULL; 628745480ffeSMatthew G. Knepley 628845480ffeSMatthew G. Knepley PetscFunctionBegin; 62899566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)ds), &dsNew)); 6290bb4b53efSMatthew G. Knepley PetscCall(PetscDSCopy(ds, minDegree, maxDegree, dm, dsNew)); 629107218a29SMatthew G. Knepley if (dsIn) { 629207218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)dsIn), &dsInNew)); 6293bb4b53efSMatthew G. Knepley PetscCall(PetscDSCopy(dsIn, minDegree, maxDegree, dm, dsInNew)); 629445480ffeSMatthew G. Knepley } 629507218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, dsNew, dsInNew)); 62969566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsNew)); 629707218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsInNew)); 62983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 629945480ffeSMatthew G. Knepley } 630045480ffeSMatthew G. Knepley 63017f96f943SMatthew G. Knepley /*@ 6302bb7acecfSBarry Smith DMCopyDS - Copy the discrete systems for the `DM` into another `DM` 6303e5e52638SMatthew G. Knepley 630420f4b53cSBarry Smith Collective 6305e5e52638SMatthew G. Knepley 6306bb4b53efSMatthew G. Knepley Input Parameters: 6307bb4b53efSMatthew G. Knepley + dm - The `DM` 6308bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit 6309bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit 6310e5e52638SMatthew G. Knepley 6311e5e52638SMatthew G. Knepley Output Parameter: 6312bb7acecfSBarry Smith . newdm - The `DM` 6313e5e52638SMatthew G. Knepley 6314e5e52638SMatthew G. Knepley Level: advanced 6315e5e52638SMatthew G. Knepley 63161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 6317e5e52638SMatthew G. Knepley @*/ 6318bb4b53efSMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, PetscInt minDegree, PetscInt maxDegree, DM newdm) 6319d71ae5a4SJacob Faibussowitsch { 6320e5e52638SMatthew G. Knepley PetscInt Nds, s; 6321e5e52638SMatthew G. Knepley 6322e5e52638SMatthew G. Knepley PetscFunctionBegin; 63233ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 63249566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 63259566063dSJacob Faibussowitsch PetscCall(DMClearDS(newdm)); 6326e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6327e5e52638SMatthew G. Knepley DMLabel label; 6328b3cf3223SMatthew G. Knepley IS fields; 632907218a29SMatthew G. Knepley PetscDS ds, dsIn, newds; 6330783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6331e5e52638SMatthew G. Knepley 633207218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fields, &ds, &dsIn)); 6333b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 6334bb4b53efSMatthew G. Knepley PetscCall(DMTransferDS_Internal(newdm, label, fields, minDegree, maxDegree, ds, dsIn)); 6335d5b43468SJose E. Roman /* Complete new labels in the new DS */ 633607218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(newdm, label, NULL, &newds, NULL)); 63379566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumBoundary(newds, &Nbd)); 6338783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6339b8025e53SMatthew G. Knepley PetscWeakForm wf; 634045480ffeSMatthew G. Knepley DMLabel label; 6341783e2ec8SMatthew G. Knepley PetscInt field; 6342783e2ec8SMatthew G. Knepley 63439566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 63449566063dSJacob Faibussowitsch PetscCall(PetscWeakFormReplaceLabel(wf, label)); 6345783e2ec8SMatthew G. Knepley } 6346e5e52638SMatthew G. Knepley } 6347799db056SMatthew G. Knepley PetscCall(DMCompleteBCLabels_Internal(newdm)); 63483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6349e5e52638SMatthew G. Knepley } 6350e5e52638SMatthew G. Knepley 6351e5e52638SMatthew G. Knepley /*@ 6352bb7acecfSBarry Smith DMCopyDisc - Copy the fields and discrete systems for the `DM` into another `DM` 6353e5e52638SMatthew G. Knepley 635420f4b53cSBarry Smith Collective 6355e5e52638SMatthew G. Knepley 6356e5e52638SMatthew G. Knepley Input Parameter: 6357bb7acecfSBarry Smith . dm - The `DM` 6358e5e52638SMatthew G. Knepley 6359e5e52638SMatthew G. Knepley Output Parameter: 6360bb7acecfSBarry Smith . newdm - The `DM` 6361e5e52638SMatthew G. Knepley 6362e5e52638SMatthew G. Knepley Level: advanced 6363e5e52638SMatthew G. Knepley 636473ff1848SBarry Smith Developer Note: 6365bb7acecfSBarry Smith Really ugly name, nothing in PETSc is called a `Disc` plus it is an ugly abbreviation 6366bb7acecfSBarry Smith 63671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMCopyDS()` 6368e5e52638SMatthew G. Knepley @*/ 6369d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6370d71ae5a4SJacob Faibussowitsch { 6371e5e52638SMatthew G. Knepley PetscFunctionBegin; 6372bb4b53efSMatthew G. Knepley PetscCall(DMCopyFields(dm, PETSC_DETERMINE, PETSC_DETERMINE, newdm)); 6373bb4b53efSMatthew G. Knepley PetscCall(DMCopyDS(dm, PETSC_DETERMINE, PETSC_DETERMINE, newdm)); 63743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6375e5e52638SMatthew G. Knepley } 6376e5e52638SMatthew G. Knepley 6377c73cfb54SMatthew G. Knepley /*@ 6378bb7acecfSBarry Smith DMGetDimension - Return the topological dimension of the `DM` 6379c73cfb54SMatthew G. Knepley 638020f4b53cSBarry Smith Not Collective 6381c73cfb54SMatthew G. Knepley 6382c73cfb54SMatthew G. Knepley Input Parameter: 6383bb7acecfSBarry Smith . dm - The `DM` 6384c73cfb54SMatthew G. Knepley 6385c73cfb54SMatthew G. Knepley Output Parameter: 6386c73cfb54SMatthew G. Knepley . dim - The topological dimension 6387c73cfb54SMatthew G. Knepley 6388c73cfb54SMatthew G. Knepley Level: beginner 6389c73cfb54SMatthew G. Knepley 63901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDimension()`, `DMCreate()` 6391c73cfb54SMatthew G. Knepley @*/ 6392d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6393d71ae5a4SJacob Faibussowitsch { 6394c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6395c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63964f572ea9SToby Isaac PetscAssertPointer(dim, 2); 6397c73cfb54SMatthew G. Knepley *dim = dm->dim; 63983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6399c73cfb54SMatthew G. Knepley } 6400c73cfb54SMatthew G. Knepley 6401c73cfb54SMatthew G. Knepley /*@ 6402bb7acecfSBarry Smith DMSetDimension - Set the topological dimension of the `DM` 6403c73cfb54SMatthew G. Knepley 640420f4b53cSBarry Smith Collective 6405c73cfb54SMatthew G. Knepley 6406c73cfb54SMatthew G. Knepley Input Parameters: 6407bb7acecfSBarry Smith + dm - The `DM` 6408c73cfb54SMatthew G. Knepley - dim - The topological dimension 6409c73cfb54SMatthew G. Knepley 6410c73cfb54SMatthew G. Knepley Level: beginner 6411c73cfb54SMatthew G. Knepley 64121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDimension()`, `DMCreate()` 6413c73cfb54SMatthew G. Knepley @*/ 6414d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6415d71ae5a4SJacob Faibussowitsch { 6416e5e52638SMatthew G. Knepley PetscDS ds; 641745480ffeSMatthew G. Knepley PetscInt Nds, n; 6418f17e8794SMatthew G. Knepley 6419c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6420c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6421c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6422c73cfb54SMatthew G. Knepley dm->dim = dim; 6423d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 64249566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 642545480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 642607218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds, NULL)); 64279566063dSJacob Faibussowitsch if (ds->dimEmbed < 0) PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 642845480ffeSMatthew G. Knepley } 6429d17bd122SMatthew G. Knepley } 64303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6431c73cfb54SMatthew G. Knepley } 6432c73cfb54SMatthew G. Knepley 6433793f3fe5SMatthew G. Knepley /*@ 6434793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6435793f3fe5SMatthew G. Knepley 643620f4b53cSBarry Smith Collective 6437793f3fe5SMatthew G. Knepley 6438793f3fe5SMatthew G. Knepley Input Parameters: 6439bb7acecfSBarry Smith + dm - the `DM` 6440793f3fe5SMatthew G. Knepley - dim - the dimension 6441793f3fe5SMatthew G. Knepley 6442793f3fe5SMatthew G. Knepley Output Parameters: 6443793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6444aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6445793f3fe5SMatthew G. Knepley 644620f4b53cSBarry Smith Level: intermediate 644720f4b53cSBarry Smith 6448793f3fe5SMatthew G. Knepley Note: 6449793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6450a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6451793f3fe5SMatthew G. Knepley then the interval is empty. 6452793f3fe5SMatthew G. Knepley 64531cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPLEX`, `DMPlexGetDepthStratum()`, `DMPlexGetHeightStratum()` 6454793f3fe5SMatthew G. Knepley @*/ 6455d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6456d71ae5a4SJacob Faibussowitsch { 6457793f3fe5SMatthew G. Knepley PetscInt d; 6458793f3fe5SMatthew G. Knepley 6459793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6460793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64619566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &d)); 64627a8be351SBarry Smith PetscCheck((dim >= 0) && (dim <= d), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %" PetscInt_FMT, dim); 6463dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getdimpoints, dim, pStart, pEnd); 64643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6465793f3fe5SMatthew G. Knepley } 6466793f3fe5SMatthew G. Knepley 64676636e97aSMatthew G Knepley /*@ 6468bb7acecfSBarry Smith DMGetOutputDM - Retrieve the `DM` associated with the layout for output 6469f4d763aaSMatthew G. Knepley 647020f4b53cSBarry Smith Collective 64718f700142SStefano Zampini 6472f4d763aaSMatthew G. Knepley Input Parameter: 6473bb7acecfSBarry Smith . dm - The original `DM` 6474f4d763aaSMatthew G. Knepley 6475f4d763aaSMatthew G. Knepley Output Parameter: 6476bb7acecfSBarry Smith . odm - The `DM` which provides the layout for output 6477f4d763aaSMatthew G. Knepley 6478f4d763aaSMatthew G. Knepley Level: intermediate 6479f4d763aaSMatthew G. Knepley 6480bb7acecfSBarry Smith Note: 6481bb7acecfSBarry Smith In some situations the vector obtained with `DMCreateGlobalVector()` excludes points for degrees of freedom that are associated with fixed (Dirichelet) boundary 6482bb7acecfSBarry Smith conditions since the algebraic solver does not solve for those variables. The output `DM` includes these excluded points and its global vector contains the 6483bb7acecfSBarry Smith locations for those dof so that they can be output to a file or other viewer along with the unconstrained dof. 6484bb7acecfSBarry Smith 64851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()`, `DMGetGlobalSection()`, `DMCreateGlobalVector()`, `PetscSectionHasConstraints()`, `DMSetGlobalSection()` 6486f4d763aaSMatthew G. Knepley @*/ 6487d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 6488d71ae5a4SJacob Faibussowitsch { 6489c26acbdeSMatthew G. Knepley PetscSection section; 6490eb9d3e4dSMatthew G. Knepley IS perm; 6491eb9d3e4dSMatthew G. Knepley PetscBool hasConstraints, newDM, gnewDM; 649292a26154SJames Wright PetscInt num_face_sfs = 0; 649314f150ffSMatthew G. Knepley 649414f150ffSMatthew G. Knepley PetscFunctionBegin; 649514f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64964f572ea9SToby Isaac PetscAssertPointer(odm, 2); 64979566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 64989566063dSJacob Faibussowitsch PetscCall(PetscSectionHasConstraints(section, &hasConstraints)); 6499eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionGetPermutation(section, &perm)); 650092a26154SJames Wright PetscCall(DMPlexGetIsoperiodicFaceSF(dm, &num_face_sfs, NULL)); 650192a26154SJames Wright newDM = hasConstraints || perm || (num_face_sfs > 0) ? PETSC_TRUE : PETSC_FALSE; 6502462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&newDM, &gnewDM, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)dm))); 6503eb9d3e4dSMatthew G. Knepley if (!gnewDM) { 6504c26acbdeSMatthew G. Knepley *odm = dm; 65053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6506c26acbdeSMatthew G. Knepley } 650714f150ffSMatthew G. Knepley if (!dm->dmBC) { 6508c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 650992a26154SJames Wright PetscSF sf, sfNatural; 6510eb9d3e4dSMatthew G. Knepley PetscBool usePerm = dm->ignorePermOutput ? PETSC_FALSE : PETSC_TRUE; 651114f150ffSMatthew G. Knepley 65129566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->dmBC)); 65139566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, dm->dmBC)); 65149566063dSJacob Faibussowitsch PetscCall(PetscSectionClone(section, &newSection)); 65159566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm->dmBC, newSection)); 65169566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&newSection)); 651792a26154SJames Wright PetscCall(DMGetNaturalSF(dm, &sfNatural)); 651892a26154SJames Wright PetscCall(DMSetNaturalSF(dm->dmBC, sfNatural)); 65199566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm->dmBC, &sf)); 6520eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionCreateGlobalSection(section, sf, usePerm, PETSC_TRUE, PETSC_FALSE, &gsection)); 65219566063dSJacob Faibussowitsch PetscCall(DMSetGlobalSection(dm->dmBC, gsection)); 65229566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&gsection)); 652314f150ffSMatthew G. Knepley } 652414f150ffSMatthew G. Knepley *odm = dm->dmBC; 65253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 652614f150ffSMatthew G. Knepley } 6527f4d763aaSMatthew G. Knepley 6528f4d763aaSMatthew G. Knepley /*@ 6529cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 6530f4d763aaSMatthew G. Knepley 6531f4d763aaSMatthew G. Knepley Input Parameter: 6532bb7acecfSBarry Smith . dm - The original `DM` 6533f4d763aaSMatthew G. Knepley 6534cdb7a50dSMatthew G. Knepley Output Parameters: 6535cdb7a50dSMatthew G. Knepley + num - The output sequence number 6536cdb7a50dSMatthew G. Knepley - val - The output sequence value 6537f4d763aaSMatthew G. Knepley 6538f4d763aaSMatthew G. Knepley Level: intermediate 6539f4d763aaSMatthew G. Knepley 6540bb7acecfSBarry Smith Note: 6541bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6542bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6543bb7acecfSBarry Smith 654473ff1848SBarry Smith Developer Note: 6545bb7acecfSBarry Smith The `DM` serves as a convenient place to store the current iteration value. The iteration is not 6546bb7acecfSBarry Smith not directly related to the `DM`. 6547f4d763aaSMatthew G. Knepley 65481cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6549f4d763aaSMatthew G. Knepley @*/ 6550d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 6551d71ae5a4SJacob Faibussowitsch { 6552f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6553f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65549371c9d4SSatish Balay if (num) { 65554f572ea9SToby Isaac PetscAssertPointer(num, 2); 65569371c9d4SSatish Balay *num = dm->outputSequenceNum; 65579371c9d4SSatish Balay } 65589371c9d4SSatish Balay if (val) { 65594f572ea9SToby Isaac PetscAssertPointer(val, 3); 65609371c9d4SSatish Balay *val = dm->outputSequenceVal; 65619371c9d4SSatish Balay } 65623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6563f4d763aaSMatthew G. Knepley } 6564f4d763aaSMatthew G. Knepley 6565f4d763aaSMatthew G. Knepley /*@ 6566cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 6567f4d763aaSMatthew G. Knepley 6568f4d763aaSMatthew G. Knepley Input Parameters: 6569bb7acecfSBarry Smith + dm - The original `DM` 6570cdb7a50dSMatthew G. Knepley . num - The output sequence number 6571cdb7a50dSMatthew G. Knepley - val - The output sequence value 6572f4d763aaSMatthew G. Knepley 6573f4d763aaSMatthew G. Knepley Level: intermediate 6574f4d763aaSMatthew G. Knepley 6575bb7acecfSBarry Smith Note: 6576bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6577bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6578f4d763aaSMatthew G. Knepley 65791cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6580f4d763aaSMatthew G. Knepley @*/ 6581d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 6582d71ae5a4SJacob Faibussowitsch { 6583f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6584f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6585f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 6586cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 65873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6588cdb7a50dSMatthew G. Knepley } 6589cdb7a50dSMatthew G. Knepley 65905d83a8b1SBarry Smith /*@ 6591bb7acecfSBarry Smith DMOutputSequenceLoad - Retrieve the sequence value from a `PetscViewer` 6592cdb7a50dSMatthew G. Knepley 6593cdb7a50dSMatthew G. Knepley Input Parameters: 6594bb7acecfSBarry Smith + dm - The original `DM` 6595b2033f5dSMatthew G. Knepley . viewer - The `PetscViewer` to get it from 6596cdb7a50dSMatthew G. Knepley . name - The sequence name 6597cdb7a50dSMatthew G. Knepley - num - The output sequence number 6598cdb7a50dSMatthew G. Knepley 6599cdb7a50dSMatthew G. Knepley Output Parameter: 6600cdb7a50dSMatthew G. Knepley . val - The output sequence value 6601cdb7a50dSMatthew G. Knepley 6602cdb7a50dSMatthew G. Knepley Level: intermediate 6603cdb7a50dSMatthew G. Knepley 6604bb7acecfSBarry Smith Note: 6605bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6606bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6607bb7acecfSBarry Smith 660873ff1848SBarry Smith Developer Note: 6609bb7acecfSBarry Smith It is unclear at the user API level why a `DM` is needed as input 6610cdb7a50dSMatthew G. Knepley 66111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6612cdb7a50dSMatthew G. Knepley @*/ 6613b2033f5dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char name[], PetscInt num, PetscReal *val) 6614d71ae5a4SJacob Faibussowitsch { 6615cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 6616cdb7a50dSMatthew G. Knepley 6617cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 6618cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6619cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6620b2033f5dSMatthew G. Knepley PetscAssertPointer(name, 3); 66214f572ea9SToby Isaac PetscAssertPointer(val, 5); 66229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6623cdb7a50dSMatthew G. Knepley if (ishdf5) { 6624cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6625cdb7a50dSMatthew G. Knepley PetscScalar value; 6626cdb7a50dSMatthew G. Knepley 66279566063dSJacob Faibussowitsch PetscCall(DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer)); 66284aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 6629cdb7a50dSMatthew G. Knepley #endif 6630cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 66313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6632f4d763aaSMatthew G. Knepley } 66338e4ac7eaSMatthew G. Knepley 66348e4ac7eaSMatthew G. Knepley /*@ 6635b2033f5dSMatthew G. Knepley DMGetOutputSequenceLength - Retrieve the number of sequence values from a `PetscViewer` 6636b2033f5dSMatthew G. Knepley 6637b2033f5dSMatthew G. Knepley Input Parameters: 6638b2033f5dSMatthew G. Knepley + dm - The original `DM` 6639b2033f5dSMatthew G. Knepley . viewer - The `PetscViewer` to get it from 6640b2033f5dSMatthew G. Knepley - name - The sequence name 6641b2033f5dSMatthew G. Knepley 6642b2033f5dSMatthew G. Knepley Output Parameter: 6643b2033f5dSMatthew G. Knepley . len - The length of the output sequence 6644b2033f5dSMatthew G. Knepley 6645b2033f5dSMatthew G. Knepley Level: intermediate 6646b2033f5dSMatthew G. Knepley 6647b2033f5dSMatthew G. Knepley Note: 6648b2033f5dSMatthew G. Knepley This is intended for output that should appear in sequence, for instance 6649b2033f5dSMatthew G. Knepley a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6650b2033f5dSMatthew G. Knepley 6651b2033f5dSMatthew G. Knepley Developer Note: 6652b2033f5dSMatthew G. Knepley It is unclear at the user API level why a `DM` is needed as input 6653b2033f5dSMatthew G. Knepley 6654b2033f5dSMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6655b2033f5dSMatthew G. Knepley @*/ 6656b2033f5dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceLength(DM dm, PetscViewer viewer, const char name[], PetscInt *len) 6657b2033f5dSMatthew G. Knepley { 6658b2033f5dSMatthew G. Knepley PetscBool ishdf5; 6659b2033f5dSMatthew G. Knepley 6660b2033f5dSMatthew G. Knepley PetscFunctionBegin; 6661b2033f5dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6662b2033f5dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6663b2033f5dSMatthew G. Knepley PetscAssertPointer(name, 3); 6664b2033f5dSMatthew G. Knepley PetscAssertPointer(len, 4); 6665b2033f5dSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6666b2033f5dSMatthew G. Knepley if (ishdf5) { 6667b2033f5dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6668b2033f5dSMatthew G. Knepley PetscCall(DMSequenceGetLength_HDF5_Internal(dm, name, len, viewer)); 6669b2033f5dSMatthew G. Knepley #endif 6670b2033f5dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 6671b2033f5dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 6672b2033f5dSMatthew G. Knepley } 6673b2033f5dSMatthew G. Knepley 6674b2033f5dSMatthew G. Knepley /*@ 6675bb7acecfSBarry Smith DMGetUseNatural - Get the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 66768e4ac7eaSMatthew G. Knepley 667720f4b53cSBarry Smith Not Collective 66788e4ac7eaSMatthew G. Knepley 66798e4ac7eaSMatthew G. Knepley Input Parameter: 6680bb7acecfSBarry Smith . dm - The `DM` 66818e4ac7eaSMatthew G. Knepley 66828e4ac7eaSMatthew G. Knepley Output Parameter: 6683bb7acecfSBarry Smith . useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 66848e4ac7eaSMatthew G. Knepley 66858e4ac7eaSMatthew G. Knepley Level: beginner 66868e4ac7eaSMatthew G. Knepley 66871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetUseNatural()`, `DMCreate()` 66888e4ac7eaSMatthew G. Knepley @*/ 6689d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 6690d71ae5a4SJacob Faibussowitsch { 66918e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 66928e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66934f572ea9SToby Isaac PetscAssertPointer(useNatural, 2); 66948e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 66953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66968e4ac7eaSMatthew G. Knepley } 66978e4ac7eaSMatthew G. Knepley 66988e4ac7eaSMatthew G. Knepley /*@ 6699bb7acecfSBarry Smith DMSetUseNatural - Set the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 67008e4ac7eaSMatthew G. Knepley 670120f4b53cSBarry Smith Collective 67028e4ac7eaSMatthew G. Knepley 67038e4ac7eaSMatthew G. Knepley Input Parameters: 6704bb7acecfSBarry Smith + dm - The `DM` 6705bb7acecfSBarry Smith - useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 67068e4ac7eaSMatthew G. Knepley 670773ff1848SBarry Smith Level: beginner 670873ff1848SBarry Smith 6709bb7acecfSBarry Smith Note: 6710bb7acecfSBarry Smith This also causes the map to be build after `DMCreateSubDM()` and `DMCreateSuperDM()` 67115d3b26e6SMatthew G. Knepley 67121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetUseNatural()`, `DMCreate()`, `DMPlexDistribute()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 67138e4ac7eaSMatthew G. Knepley @*/ 6714d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 6715d71ae5a4SJacob Faibussowitsch { 67168e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 67178e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67188833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 67198e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 67203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 67218e4ac7eaSMatthew G. Knepley } 6722c58f1c22SToby Isaac 6723cc4c1da9SBarry Smith /*@ 6724bb7acecfSBarry Smith DMCreateLabel - Create a label of the given name if it does not already exist in the `DM` 6725c58f1c22SToby Isaac 6726c58f1c22SToby Isaac Not Collective 6727c58f1c22SToby Isaac 6728c58f1c22SToby Isaac Input Parameters: 6729bb7acecfSBarry Smith + dm - The `DM` object 6730c58f1c22SToby Isaac - name - The label name 6731c58f1c22SToby Isaac 6732c58f1c22SToby Isaac Level: intermediate 6733c58f1c22SToby Isaac 67341cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6735c58f1c22SToby Isaac @*/ 6736d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabel(DM dm, const char name[]) 6737d71ae5a4SJacob Faibussowitsch { 67385d80c0bfSVaclav Hapla PetscBool flg; 67395d80c0bfSVaclav Hapla DMLabel label; 6740c58f1c22SToby Isaac 6741c58f1c22SToby Isaac PetscFunctionBegin; 6742c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67434f572ea9SToby Isaac PetscAssertPointer(name, 2); 67449566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 6745c58f1c22SToby Isaac if (!flg) { 67469566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 67479566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 67489566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 6749c58f1c22SToby Isaac } 67503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6751c58f1c22SToby Isaac } 6752c58f1c22SToby Isaac 6753cc4c1da9SBarry Smith /*@ 6754bb7acecfSBarry Smith DMCreateLabelAtIndex - Create a label of the given name at the given index. If it already exists in the `DM`, move it to this index. 67550fdc7489SMatthew Knepley 67560fdc7489SMatthew Knepley Not Collective 67570fdc7489SMatthew Knepley 67580fdc7489SMatthew Knepley Input Parameters: 6759bb7acecfSBarry Smith + dm - The `DM` object 67600fdc7489SMatthew Knepley . l - The index for the label 67610fdc7489SMatthew Knepley - name - The label name 67620fdc7489SMatthew Knepley 67630fdc7489SMatthew Knepley Level: intermediate 67640fdc7489SMatthew Knepley 67651cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateLabel()`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 67660fdc7489SMatthew Knepley @*/ 6767d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 6768d71ae5a4SJacob Faibussowitsch { 67690fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 67700fdc7489SMatthew Knepley DMLabel label; 67710fdc7489SMatthew Knepley PetscInt Nl, m; 67720fdc7489SMatthew Knepley PetscBool flg, match; 67730fdc7489SMatthew Knepley const char *lname; 67740fdc7489SMatthew Knepley 67750fdc7489SMatthew Knepley PetscFunctionBegin; 67760fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67774f572ea9SToby Isaac PetscAssertPointer(name, 3); 67789566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 67790fdc7489SMatthew Knepley if (!flg) { 67809566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 67819566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 67829566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 67830fdc7489SMatthew Knepley } 67849566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 678563a3b9bcSJacob Faibussowitsch PetscCheck(l < Nl, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", l, Nl); 67860fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 67879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)orig->label, &lname)); 67889566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &match)); 67890fdc7489SMatthew Knepley if (match) break; 67900fdc7489SMatthew Knepley } 67913ba16761SJacob Faibussowitsch if (m == l) PetscFunctionReturn(PETSC_SUCCESS); 67920fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 67930fdc7489SMatthew Knepley else prev->next = orig->next; 67940fdc7489SMatthew Knepley if (!l) { 67950fdc7489SMatthew Knepley orig->next = dm->labels; 67960fdc7489SMatthew Knepley dm->labels = orig; 67970fdc7489SMatthew Knepley } else { 6798fbccb6d4SPierre Jolivet for (m = 0, prev = dm->labels; m < l - 1; ++m, prev = prev->next); 67990fdc7489SMatthew Knepley orig->next = prev->next; 68000fdc7489SMatthew Knepley prev->next = orig; 68010fdc7489SMatthew Knepley } 68023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68030fdc7489SMatthew Knepley } 68040fdc7489SMatthew Knepley 6805cc4c1da9SBarry Smith /*@ 6806bb7acecfSBarry Smith DMGetLabelValue - Get the value in a `DMLabel` for the given point, with -1 as the default 6807c58f1c22SToby Isaac 6808c58f1c22SToby Isaac Not Collective 6809c58f1c22SToby Isaac 6810c58f1c22SToby Isaac Input Parameters: 6811bb7acecfSBarry Smith + dm - The `DM` object 6812c58f1c22SToby Isaac . name - The label name 6813c58f1c22SToby Isaac - point - The mesh point 6814c58f1c22SToby Isaac 6815c58f1c22SToby Isaac Output Parameter: 6816c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 6817c58f1c22SToby Isaac 6818c58f1c22SToby Isaac Level: beginner 6819c58f1c22SToby Isaac 68201cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6821c58f1c22SToby Isaac @*/ 6822d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 6823d71ae5a4SJacob Faibussowitsch { 6824c58f1c22SToby Isaac DMLabel label; 6825c58f1c22SToby Isaac 6826c58f1c22SToby Isaac PetscFunctionBegin; 6827c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68284f572ea9SToby Isaac PetscAssertPointer(name, 2); 68299566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 68307a8be351SBarry Smith PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 68319566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, point, value)); 68323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6833c58f1c22SToby Isaac } 6834c58f1c22SToby Isaac 6835cc4c1da9SBarry Smith /*@ 6836bb7acecfSBarry Smith DMSetLabelValue - Add a point to a `DMLabel` with given value 6837c58f1c22SToby Isaac 6838c58f1c22SToby Isaac Not Collective 6839c58f1c22SToby Isaac 6840c58f1c22SToby Isaac Input Parameters: 6841bb7acecfSBarry Smith + dm - The `DM` object 6842c58f1c22SToby Isaac . name - The label name 6843c58f1c22SToby Isaac . point - The mesh point 6844c58f1c22SToby Isaac - value - The label value for this point 6845c58f1c22SToby Isaac 6846c58f1c22SToby Isaac Output Parameter: 6847c58f1c22SToby Isaac 6848c58f1c22SToby Isaac Level: beginner 6849c58f1c22SToby Isaac 68501cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelSetValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6851c58f1c22SToby Isaac @*/ 6852d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6853d71ae5a4SJacob Faibussowitsch { 6854c58f1c22SToby Isaac DMLabel label; 6855c58f1c22SToby Isaac 6856c58f1c22SToby Isaac PetscFunctionBegin; 6857c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68584f572ea9SToby Isaac PetscAssertPointer(name, 2); 68599566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6860c58f1c22SToby Isaac if (!label) { 68619566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 68629566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6863c58f1c22SToby Isaac } 68649566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, point, value)); 68653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6866c58f1c22SToby Isaac } 6867c58f1c22SToby Isaac 6868cc4c1da9SBarry Smith /*@ 6869bb7acecfSBarry Smith DMClearLabelValue - Remove a point from a `DMLabel` with given value 6870c58f1c22SToby Isaac 6871c58f1c22SToby Isaac Not Collective 6872c58f1c22SToby Isaac 6873c58f1c22SToby Isaac Input Parameters: 6874bb7acecfSBarry Smith + dm - The `DM` object 6875c58f1c22SToby Isaac . name - The label name 6876c58f1c22SToby Isaac . point - The mesh point 6877c58f1c22SToby Isaac - value - The label value for this point 6878c58f1c22SToby Isaac 6879c58f1c22SToby Isaac Level: beginner 6880c58f1c22SToby Isaac 68811cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelClearValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6882c58f1c22SToby Isaac @*/ 6883d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6884d71ae5a4SJacob Faibussowitsch { 6885c58f1c22SToby Isaac DMLabel label; 6886c58f1c22SToby Isaac 6887c58f1c22SToby Isaac PetscFunctionBegin; 6888c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68894f572ea9SToby Isaac PetscAssertPointer(name, 2); 68909566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 68913ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68929566063dSJacob Faibussowitsch PetscCall(DMLabelClearValue(label, point, value)); 68933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6894c58f1c22SToby Isaac } 6895c58f1c22SToby Isaac 6896cc4c1da9SBarry Smith /*@ 6897bb7acecfSBarry Smith DMGetLabelSize - Get the value of `DMLabelGetNumValues()` of a `DMLabel` in the `DM` 6898c58f1c22SToby Isaac 6899c58f1c22SToby Isaac Not Collective 6900c58f1c22SToby Isaac 6901c58f1c22SToby Isaac Input Parameters: 6902bb7acecfSBarry Smith + dm - The `DM` object 6903c58f1c22SToby Isaac - name - The label name 6904c58f1c22SToby Isaac 6905c58f1c22SToby Isaac Output Parameter: 6906c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 6907c58f1c22SToby Isaac 6908c58f1c22SToby Isaac Level: beginner 6909c58f1c22SToby Isaac 691073ff1848SBarry Smith Developer Note: 6911bb7acecfSBarry Smith This should be renamed to something like `DMGetLabelNumValues()` or removed. 6912bb7acecfSBarry Smith 69131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetNumValues()`, `DMSetLabelValue()`, `DMGetLabel()` 6914c58f1c22SToby Isaac @*/ 6915d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 6916d71ae5a4SJacob Faibussowitsch { 6917c58f1c22SToby Isaac DMLabel label; 6918c58f1c22SToby Isaac 6919c58f1c22SToby Isaac PetscFunctionBegin; 6920c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69214f572ea9SToby Isaac PetscAssertPointer(name, 2); 69224f572ea9SToby Isaac PetscAssertPointer(size, 3); 69239566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6924c58f1c22SToby Isaac *size = 0; 69253ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69269566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, size)); 69273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6928c58f1c22SToby Isaac } 6929c58f1c22SToby Isaac 6930cc4c1da9SBarry Smith /*@ 6931bb7acecfSBarry Smith DMGetLabelIdIS - Get the `DMLabelGetValueIS()` from a `DMLabel` in the `DM` 6932c58f1c22SToby Isaac 6933c58f1c22SToby Isaac Not Collective 6934c58f1c22SToby Isaac 6935c58f1c22SToby Isaac Input Parameters: 693660225df5SJacob Faibussowitsch + dm - The `DM` object 6937c58f1c22SToby Isaac - name - The label name 6938c58f1c22SToby Isaac 6939c58f1c22SToby Isaac Output Parameter: 694020f4b53cSBarry Smith . ids - The integer ids, or `NULL` if the label does not exist 6941c58f1c22SToby Isaac 6942c58f1c22SToby Isaac Level: beginner 6943c58f1c22SToby Isaac 69441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValueIS()`, `DMGetLabelSize()` 6945c58f1c22SToby Isaac @*/ 6946d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 6947d71ae5a4SJacob Faibussowitsch { 6948c58f1c22SToby Isaac DMLabel label; 6949c58f1c22SToby Isaac 6950c58f1c22SToby Isaac PetscFunctionBegin; 6951c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69524f572ea9SToby Isaac PetscAssertPointer(name, 2); 69534f572ea9SToby Isaac PetscAssertPointer(ids, 3); 69549566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6955c58f1c22SToby Isaac *ids = NULL; 6956dab2e251SBlaise Bourdin if (label) { 69579566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, ids)); 6958dab2e251SBlaise Bourdin } else { 6959dab2e251SBlaise Bourdin /* returning an empty IS */ 69609566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 0, NULL, PETSC_USE_POINTER, ids)); 6961dab2e251SBlaise Bourdin } 69623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6963c58f1c22SToby Isaac } 6964c58f1c22SToby Isaac 6965cc4c1da9SBarry Smith /*@ 6966c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 6967c58f1c22SToby Isaac 6968c58f1c22SToby Isaac Not Collective 6969c58f1c22SToby Isaac 6970c58f1c22SToby Isaac Input Parameters: 6971bb7acecfSBarry Smith + dm - The `DM` object 6972b6971eaeSBarry Smith . name - The label name of the stratum 6973c58f1c22SToby Isaac - value - The stratum value 6974c58f1c22SToby Isaac 6975c58f1c22SToby Isaac Output Parameter: 6976bb7acecfSBarry Smith . size - The number of points, also called the stratum size 6977c58f1c22SToby Isaac 6978c58f1c22SToby Isaac Level: beginner 6979c58f1c22SToby Isaac 69801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumSize()`, `DMGetLabelSize()`, `DMGetLabelIds()` 6981c58f1c22SToby Isaac @*/ 6982d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 6983d71ae5a4SJacob Faibussowitsch { 6984c58f1c22SToby Isaac DMLabel label; 6985c58f1c22SToby Isaac 6986c58f1c22SToby Isaac PetscFunctionBegin; 6987c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69884f572ea9SToby Isaac PetscAssertPointer(name, 2); 69894f572ea9SToby Isaac PetscAssertPointer(size, 4); 69909566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6991c58f1c22SToby Isaac *size = 0; 69923ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69939566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, value, size)); 69943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6995c58f1c22SToby Isaac } 6996c58f1c22SToby Isaac 6997cc4c1da9SBarry Smith /*@ 6998c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 6999c58f1c22SToby Isaac 7000c58f1c22SToby Isaac Not Collective 7001c58f1c22SToby Isaac 7002c58f1c22SToby Isaac Input Parameters: 7003bb7acecfSBarry Smith + dm - The `DM` object 7004c58f1c22SToby Isaac . name - The label name 7005c58f1c22SToby Isaac - value - The stratum value 7006c58f1c22SToby Isaac 7007c58f1c22SToby Isaac Output Parameter: 700820f4b53cSBarry Smith . points - The stratum points, or `NULL` if the label does not exist or does not have that value 7009c58f1c22SToby Isaac 7010c58f1c22SToby Isaac Level: beginner 7011c58f1c22SToby Isaac 70121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumIS()`, `DMGetStratumSize()` 7013c58f1c22SToby Isaac @*/ 7014d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 7015d71ae5a4SJacob Faibussowitsch { 7016c58f1c22SToby Isaac DMLabel label; 7017c58f1c22SToby Isaac 7018c58f1c22SToby Isaac PetscFunctionBegin; 7019c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70204f572ea9SToby Isaac PetscAssertPointer(name, 2); 70214f572ea9SToby Isaac PetscAssertPointer(points, 4); 70229566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 7023c58f1c22SToby Isaac *points = NULL; 70243ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 70259566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, value, points)); 70263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7027c58f1c22SToby Isaac } 7028c58f1c22SToby Isaac 7029cc4c1da9SBarry Smith /*@ 70309044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 70314de306b1SToby Isaac 70324de306b1SToby Isaac Not Collective 70334de306b1SToby Isaac 70344de306b1SToby Isaac Input Parameters: 7035bb7acecfSBarry Smith + dm - The `DM` object 70364de306b1SToby Isaac . name - The label name 70374de306b1SToby Isaac . value - The stratum value 70384de306b1SToby Isaac - points - The stratum points 70394de306b1SToby Isaac 70404de306b1SToby Isaac Level: beginner 70414de306b1SToby Isaac 70421cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMClearLabelStratum()`, `DMLabelClearStratum()`, `DMLabelSetStratumIS()`, `DMGetStratumSize()` 70434de306b1SToby Isaac @*/ 7044d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 7045d71ae5a4SJacob Faibussowitsch { 70464de306b1SToby Isaac DMLabel label; 70474de306b1SToby Isaac 70484de306b1SToby Isaac PetscFunctionBegin; 70494de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70504f572ea9SToby Isaac PetscAssertPointer(name, 2); 7051292bffcbSToby Isaac PetscValidHeaderSpecific(points, IS_CLASSID, 4); 70529566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 70533ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 70549566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, points)); 70553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 70564de306b1SToby Isaac } 70574de306b1SToby Isaac 7058cc4c1da9SBarry Smith /*@ 7059bb7acecfSBarry Smith DMClearLabelStratum - Remove all points from a stratum from a `DMLabel` 7060c58f1c22SToby Isaac 7061c58f1c22SToby Isaac Not Collective 7062c58f1c22SToby Isaac 7063c58f1c22SToby Isaac Input Parameters: 7064bb7acecfSBarry Smith + dm - The `DM` object 7065c58f1c22SToby Isaac . name - The label name 7066c58f1c22SToby Isaac - value - The label value for this point 7067c58f1c22SToby Isaac 7068c58f1c22SToby Isaac Output Parameter: 7069c58f1c22SToby Isaac 7070c58f1c22SToby Isaac Level: beginner 7071c58f1c22SToby Isaac 70721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMLabelClearStratum()`, `DMSetLabelValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 7073c58f1c22SToby Isaac @*/ 7074d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 7075d71ae5a4SJacob Faibussowitsch { 7076c58f1c22SToby Isaac DMLabel label; 7077c58f1c22SToby Isaac 7078c58f1c22SToby Isaac PetscFunctionBegin; 7079c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70804f572ea9SToby Isaac PetscAssertPointer(name, 2); 70819566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 70823ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 70839566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 70843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7085c58f1c22SToby Isaac } 7086c58f1c22SToby Isaac 7087c58f1c22SToby Isaac /*@ 7088bb7acecfSBarry Smith DMGetNumLabels - Return the number of labels defined by on the `DM` 7089c58f1c22SToby Isaac 7090c58f1c22SToby Isaac Not Collective 7091c58f1c22SToby Isaac 7092c58f1c22SToby Isaac Input Parameter: 7093bb7acecfSBarry Smith . dm - The `DM` object 7094c58f1c22SToby Isaac 7095c58f1c22SToby Isaac Output Parameter: 7096c58f1c22SToby Isaac . numLabels - the number of Labels 7097c58f1c22SToby Isaac 7098c58f1c22SToby Isaac Level: intermediate 7099c58f1c22SToby Isaac 71001cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabelName()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7101c58f1c22SToby Isaac @*/ 7102d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7103d71ae5a4SJacob Faibussowitsch { 71045d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7105c58f1c22SToby Isaac PetscInt n = 0; 7106c58f1c22SToby Isaac 7107c58f1c22SToby Isaac PetscFunctionBegin; 7108c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71094f572ea9SToby Isaac PetscAssertPointer(numLabels, 2); 71109371c9d4SSatish Balay while (next) { 71119371c9d4SSatish Balay ++n; 71129371c9d4SSatish Balay next = next->next; 71139371c9d4SSatish Balay } 7114c58f1c22SToby Isaac *numLabels = n; 71153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7116c58f1c22SToby Isaac } 7117c58f1c22SToby Isaac 7118cc4c1da9SBarry Smith /*@ 7119c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7120c58f1c22SToby Isaac 7121c58f1c22SToby Isaac Not Collective 7122c58f1c22SToby Isaac 7123c58f1c22SToby Isaac Input Parameters: 7124bb7acecfSBarry Smith + dm - The `DM` object 7125c58f1c22SToby Isaac - n - the label number 7126c58f1c22SToby Isaac 7127c58f1c22SToby Isaac Output Parameter: 7128c58f1c22SToby Isaac . name - the label name 7129c58f1c22SToby Isaac 7130c58f1c22SToby Isaac Level: intermediate 7131c58f1c22SToby Isaac 713273ff1848SBarry Smith Developer Note: 7133bb7acecfSBarry Smith Some of the functions that appropriate on labels using their number have the suffix ByNum, others do not. 7134bb7acecfSBarry Smith 71351cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7136c58f1c22SToby Isaac @*/ 7137cc4c1da9SBarry Smith PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char *name[]) 7138d71ae5a4SJacob Faibussowitsch { 71395d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7140c58f1c22SToby Isaac PetscInt l = 0; 7141c58f1c22SToby Isaac 7142c58f1c22SToby Isaac PetscFunctionBegin; 7143c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71444f572ea9SToby Isaac PetscAssertPointer(name, 3); 7145c58f1c22SToby Isaac while (next) { 7146c58f1c22SToby Isaac if (l == n) { 71479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, name)); 71483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7149c58f1c22SToby Isaac } 7150c58f1c22SToby Isaac ++l; 7151c58f1c22SToby Isaac next = next->next; 7152c58f1c22SToby Isaac } 715363a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7154c58f1c22SToby Isaac } 7155c58f1c22SToby Isaac 7156cc4c1da9SBarry Smith /*@ 7157bb7acecfSBarry Smith DMHasLabel - Determine whether the `DM` has a label of a given name 7158c58f1c22SToby Isaac 7159c58f1c22SToby Isaac Not Collective 7160c58f1c22SToby Isaac 7161c58f1c22SToby Isaac Input Parameters: 7162bb7acecfSBarry Smith + dm - The `DM` object 7163c58f1c22SToby Isaac - name - The label name 7164c58f1c22SToby Isaac 7165c58f1c22SToby Isaac Output Parameter: 7166bb7acecfSBarry Smith . hasLabel - `PETSC_TRUE` if the label is present 7167c58f1c22SToby Isaac 7168c58f1c22SToby Isaac Level: intermediate 7169c58f1c22SToby Isaac 71701cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabel()`, `DMGetLabelByNum()`, `DMCreateLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7171c58f1c22SToby Isaac @*/ 7172d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7173d71ae5a4SJacob Faibussowitsch { 71745d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7175d67d17b1SMatthew G. Knepley const char *lname; 7176c58f1c22SToby Isaac 7177c58f1c22SToby Isaac PetscFunctionBegin; 7178c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71794f572ea9SToby Isaac PetscAssertPointer(name, 2); 71804f572ea9SToby Isaac PetscAssertPointer(hasLabel, 3); 7181c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7182c58f1c22SToby Isaac while (next) { 71839566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 71849566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, hasLabel)); 7185c58f1c22SToby Isaac if (*hasLabel) break; 7186c58f1c22SToby Isaac next = next->next; 7187c58f1c22SToby Isaac } 71883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7189c58f1c22SToby Isaac } 7190c58f1c22SToby Isaac 7191a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7192cc4c1da9SBarry Smith /*@ 719320f4b53cSBarry Smith DMGetLabel - Return the label of a given name, or `NULL`, from a `DM` 7194c58f1c22SToby Isaac 7195c58f1c22SToby Isaac Not Collective 7196c58f1c22SToby Isaac 7197c58f1c22SToby Isaac Input Parameters: 7198bb7acecfSBarry Smith + dm - The `DM` object 7199c58f1c22SToby Isaac - name - The label name 7200c58f1c22SToby Isaac 7201c58f1c22SToby Isaac Output Parameter: 720220f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent 7203c58f1c22SToby Isaac 7204bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7205bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7206bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7207bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7208bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7209bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7210bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 72116d7c9049SMatthew G. Knepley 7212c58f1c22SToby Isaac Level: intermediate 7213c58f1c22SToby Isaac 721460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMHasLabel()`, `DMGetLabelByNum()`, `DMAddLabel()`, `DMCreateLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 7215c58f1c22SToby Isaac @*/ 7216d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7217d71ae5a4SJacob Faibussowitsch { 72185d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7219c58f1c22SToby Isaac PetscBool hasLabel; 7220d67d17b1SMatthew G. Knepley const char *lname; 7221c58f1c22SToby Isaac 7222c58f1c22SToby Isaac PetscFunctionBegin; 7223c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72244f572ea9SToby Isaac PetscAssertPointer(name, 2); 72254f572ea9SToby Isaac PetscAssertPointer(label, 3); 7226c58f1c22SToby Isaac *label = NULL; 7227c58f1c22SToby Isaac while (next) { 72289566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 72299566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7230c58f1c22SToby Isaac if (hasLabel) { 7231c58f1c22SToby Isaac *label = next->label; 7232c58f1c22SToby Isaac break; 7233c58f1c22SToby Isaac } 7234c58f1c22SToby Isaac next = next->next; 7235c58f1c22SToby Isaac } 72363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7237c58f1c22SToby Isaac } 7238c58f1c22SToby Isaac 7239cc4c1da9SBarry Smith /*@ 7240bb7acecfSBarry Smith DMGetLabelByNum - Return the nth label on a `DM` 7241c58f1c22SToby Isaac 7242c58f1c22SToby Isaac Not Collective 7243c58f1c22SToby Isaac 7244c58f1c22SToby Isaac Input Parameters: 7245bb7acecfSBarry Smith + dm - The `DM` object 7246c58f1c22SToby Isaac - n - the label number 7247c58f1c22SToby Isaac 7248c58f1c22SToby Isaac Output Parameter: 7249c58f1c22SToby Isaac . label - the label 7250c58f1c22SToby Isaac 7251c58f1c22SToby Isaac Level: intermediate 7252c58f1c22SToby Isaac 72531cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7254c58f1c22SToby Isaac @*/ 7255d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7256d71ae5a4SJacob Faibussowitsch { 72575d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7258c58f1c22SToby Isaac PetscInt l = 0; 7259c58f1c22SToby Isaac 7260c58f1c22SToby Isaac PetscFunctionBegin; 7261c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72624f572ea9SToby Isaac PetscAssertPointer(label, 3); 7263c58f1c22SToby Isaac while (next) { 7264c58f1c22SToby Isaac if (l == n) { 7265c58f1c22SToby Isaac *label = next->label; 72663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7267c58f1c22SToby Isaac } 7268c58f1c22SToby Isaac ++l; 7269c58f1c22SToby Isaac next = next->next; 7270c58f1c22SToby Isaac } 727163a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7272c58f1c22SToby Isaac } 7273c58f1c22SToby Isaac 7274cc4c1da9SBarry Smith /*@ 7275bb7acecfSBarry Smith DMAddLabel - Add the label to this `DM` 7276c58f1c22SToby Isaac 7277c58f1c22SToby Isaac Not Collective 7278c58f1c22SToby Isaac 7279c58f1c22SToby Isaac Input Parameters: 7280bb7acecfSBarry Smith + dm - The `DM` object 7281bb7acecfSBarry Smith - label - The `DMLabel` 7282c58f1c22SToby Isaac 7283c58f1c22SToby Isaac Level: developer 7284c58f1c22SToby Isaac 728560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7286c58f1c22SToby Isaac @*/ 7287d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7288d71ae5a4SJacob Faibussowitsch { 72895d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7290c58f1c22SToby Isaac PetscBool hasLabel; 7291d67d17b1SMatthew G. Knepley const char *lname; 72925d80c0bfSVaclav Hapla PetscBool flg; 7293c58f1c22SToby Isaac 7294c58f1c22SToby Isaac PetscFunctionBegin; 7295c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72969566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 72979566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, lname, &hasLabel)); 72987a8be351SBarry Smith PetscCheck(!hasLabel, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 72999566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(1, &tmpLabel)); 7300c58f1c22SToby Isaac tmpLabel->label = label; 7301c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 73025d80c0bfSVaclav Hapla for (p = &dm->labels; (l = *p); p = &l->next) { } 73035d80c0bfSVaclav Hapla *p = tmpLabel; 73049566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 73059566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 73065d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 73079566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 7308ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 73093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7310c58f1c22SToby Isaac } 7311c58f1c22SToby Isaac 7312a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7313cc4c1da9SBarry Smith /*@ 73144a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 73154a7ee7d0SMatthew G. Knepley 73164a7ee7d0SMatthew G. Knepley Not Collective 73174a7ee7d0SMatthew G. Knepley 73184a7ee7d0SMatthew G. Knepley Input Parameters: 7319bb7acecfSBarry Smith + dm - The `DM` object 7320bb7acecfSBarry Smith - label - The `DMLabel`, having the same name, to substitute 73214a7ee7d0SMatthew G. Knepley 7322bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7323bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7324bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7325bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7326bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7327bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7328bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 73294a7ee7d0SMatthew G. Knepley 73304a7ee7d0SMatthew G. Knepley Level: intermediate 73314a7ee7d0SMatthew G. Knepley 73321cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 73334a7ee7d0SMatthew G. Knepley @*/ 7334d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabel(DM dm, DMLabel label) 7335d71ae5a4SJacob Faibussowitsch { 73364a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 73374a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 73384a7ee7d0SMatthew G. Knepley const char *name, *lname; 73394a7ee7d0SMatthew G. Knepley 73404a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 73414a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73424a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 73439566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 73444a7ee7d0SMatthew G. Knepley while (next) { 73459566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 73469566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 73474a7ee7d0SMatthew G. Knepley if (hasLabel) { 73489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 73499566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 73504a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 73519566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 73524a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 73539566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 73544a7ee7d0SMatthew G. Knepley next->label = label; 73554a7ee7d0SMatthew G. Knepley break; 73564a7ee7d0SMatthew G. Knepley } 73574a7ee7d0SMatthew G. Knepley next = next->next; 73584a7ee7d0SMatthew G. Knepley } 73593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 73604a7ee7d0SMatthew G. Knepley } 73614a7ee7d0SMatthew G. Knepley 7362cc4c1da9SBarry Smith /*@ 7363bb7acecfSBarry Smith DMRemoveLabel - Remove the label given by name from this `DM` 7364c58f1c22SToby Isaac 7365c58f1c22SToby Isaac Not Collective 7366c58f1c22SToby Isaac 7367c58f1c22SToby Isaac Input Parameters: 7368bb7acecfSBarry Smith + dm - The `DM` object 7369c58f1c22SToby Isaac - name - The label name 7370c58f1c22SToby Isaac 7371c58f1c22SToby Isaac Output Parameter: 737220f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent. Pass in `NULL` to call `DMLabelDestroy()` on the label, otherwise the 7373bb7acecfSBarry Smith caller is responsible for calling `DMLabelDestroy()`. 7374c58f1c22SToby Isaac 7375c58f1c22SToby Isaac Level: developer 7376c58f1c22SToby Isaac 73771cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabelBySelf()` 7378c58f1c22SToby Isaac @*/ 7379d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7380d71ae5a4SJacob Faibussowitsch { 738195d578d6SVaclav Hapla DMLabelLink link, *pnext; 7382c58f1c22SToby Isaac PetscBool hasLabel; 7383d67d17b1SMatthew G. Knepley const char *lname; 7384c58f1c22SToby Isaac 7385c58f1c22SToby Isaac PetscFunctionBegin; 7386c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73874f572ea9SToby Isaac PetscAssertPointer(name, 2); 7388e5472504SVaclav Hapla if (label) { 73894f572ea9SToby Isaac PetscAssertPointer(label, 3); 7390c58f1c22SToby Isaac *label = NULL; 7391e5472504SVaclav Hapla } 73925d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 73939566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)link->label, &lname)); 73949566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7395c58f1c22SToby Isaac if (hasLabel) { 739695d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 73979566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &hasLabel)); 739895d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 73999566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &hasLabel)); 7400ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 740195d578d6SVaclav Hapla if (label) *label = link->label; 74029566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&link->label)); 74039566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7404c58f1c22SToby Isaac break; 7405c58f1c22SToby Isaac } 7406c58f1c22SToby Isaac } 74073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7408c58f1c22SToby Isaac } 7409c58f1c22SToby Isaac 7410306894acSVaclav Hapla /*@ 7411bb7acecfSBarry Smith DMRemoveLabelBySelf - Remove the label from this `DM` 7412306894acSVaclav Hapla 7413306894acSVaclav Hapla Not Collective 7414306894acSVaclav Hapla 7415306894acSVaclav Hapla Input Parameters: 7416bb7acecfSBarry Smith + dm - The `DM` object 7417bb7acecfSBarry Smith . label - The `DMLabel` to be removed from the `DM` 741820f4b53cSBarry Smith - failNotFound - Should it fail if the label is not found in the `DM`? 7419306894acSVaclav Hapla 7420306894acSVaclav Hapla Level: developer 7421306894acSVaclav Hapla 7422bb7acecfSBarry Smith Note: 7423306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7424bb7acecfSBarry Smith If the `DM` has an exclusive reference to the label, the label gets destroyed and 7425306894acSVaclav Hapla *label nullified. 7426306894acSVaclav Hapla 74271cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()` `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabel()` 7428306894acSVaclav Hapla @*/ 7429d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7430d71ae5a4SJacob Faibussowitsch { 743143e45a93SVaclav Hapla DMLabelLink link, *pnext; 7432306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7433306894acSVaclav Hapla 7434306894acSVaclav Hapla PetscFunctionBegin; 7435306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 74364f572ea9SToby Isaac PetscAssertPointer(label, 2); 74373ba16761SJacob Faibussowitsch if (!*label && !failNotFound) PetscFunctionReturn(PETSC_SUCCESS); 7438306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7439306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm, failNotFound, 3); 74405d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 744143e45a93SVaclav Hapla if (*label == link->label) { 7442306894acSVaclav Hapla hasLabel = PETSC_TRUE; 744343e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7444306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7445ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 744643e45a93SVaclav Hapla if (((PetscObject)link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 74479566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&link->label)); 74489566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7449306894acSVaclav Hapla break; 7450306894acSVaclav Hapla } 7451306894acSVaclav Hapla } 74527a8be351SBarry Smith PetscCheck(hasLabel || !failNotFound, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 74533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7454306894acSVaclav Hapla } 7455306894acSVaclav Hapla 7456cc4c1da9SBarry Smith /*@ 7457c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7458c58f1c22SToby Isaac 7459c58f1c22SToby Isaac Not Collective 7460c58f1c22SToby Isaac 7461c58f1c22SToby Isaac Input Parameters: 7462bb7acecfSBarry Smith + dm - The `DM` object 7463c58f1c22SToby Isaac - name - The label name 7464c58f1c22SToby Isaac 7465c58f1c22SToby Isaac Output Parameter: 7466c58f1c22SToby Isaac . output - The flag for output 7467c58f1c22SToby Isaac 7468c58f1c22SToby Isaac Level: developer 7469c58f1c22SToby Isaac 74701cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMSetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7471c58f1c22SToby Isaac @*/ 7472d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7473d71ae5a4SJacob Faibussowitsch { 74745d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7475d67d17b1SMatthew G. Knepley const char *lname; 7476c58f1c22SToby Isaac 7477c58f1c22SToby Isaac PetscFunctionBegin; 7478c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 74794f572ea9SToby Isaac PetscAssertPointer(name, 2); 74804f572ea9SToby Isaac PetscAssertPointer(output, 3); 7481c58f1c22SToby Isaac while (next) { 7482c58f1c22SToby Isaac PetscBool flg; 7483c58f1c22SToby Isaac 74849566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 74859566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 74869371c9d4SSatish Balay if (flg) { 74879371c9d4SSatish Balay *output = next->output; 74883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74899371c9d4SSatish Balay } 7490c58f1c22SToby Isaac next = next->next; 7491c58f1c22SToby Isaac } 749298921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7493c58f1c22SToby Isaac } 7494c58f1c22SToby Isaac 7495cc4c1da9SBarry Smith /*@ 7496bb7acecfSBarry Smith DMSetLabelOutput - Set if a given label should be saved to a `PetscViewer` in calls to `DMView()` 7497c58f1c22SToby Isaac 7498c58f1c22SToby Isaac Not Collective 7499c58f1c22SToby Isaac 7500c58f1c22SToby Isaac Input Parameters: 7501bb7acecfSBarry Smith + dm - The `DM` object 7502c58f1c22SToby Isaac . name - The label name 7503bb7acecfSBarry Smith - output - `PETSC_TRUE` to save the label to the viewer 7504c58f1c22SToby Isaac 7505c58f1c22SToby Isaac Level: developer 7506c58f1c22SToby Isaac 75071cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetOutputFlag()`, `DMGetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7508c58f1c22SToby Isaac @*/ 7509d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7510d71ae5a4SJacob Faibussowitsch { 75115d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7512d67d17b1SMatthew G. Knepley const char *lname; 7513c58f1c22SToby Isaac 7514c58f1c22SToby Isaac PetscFunctionBegin; 7515c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 75164f572ea9SToby Isaac PetscAssertPointer(name, 2); 7517c58f1c22SToby Isaac while (next) { 7518c58f1c22SToby Isaac PetscBool flg; 7519c58f1c22SToby Isaac 75209566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 75219566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 75229371c9d4SSatish Balay if (flg) { 75239371c9d4SSatish Balay next->output = output; 75243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 75259371c9d4SSatish Balay } 7526c58f1c22SToby Isaac next = next->next; 7527c58f1c22SToby Isaac } 752898921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7529c58f1c22SToby Isaac } 7530c58f1c22SToby Isaac 7531c58f1c22SToby Isaac /*@ 7532bb7acecfSBarry Smith DMCopyLabels - Copy labels from one `DM` mesh to another `DM` with a superset of the points 7533c58f1c22SToby Isaac 753420f4b53cSBarry Smith Collective 7535c58f1c22SToby Isaac 7536d8d19677SJose E. Roman Input Parameters: 7537bb7acecfSBarry Smith + dmA - The `DM` object with initial labels 7538bb7acecfSBarry Smith . dmB - The `DM` object to which labels are copied 7539bb7acecfSBarry Smith . mode - Copy labels by pointers (`PETSC_OWN_POINTER`) or duplicate them (`PETSC_COPY_VALUES`) 7540bb7acecfSBarry Smith . all - Copy all labels including "depth", "dim", and "celltype" (`PETSC_TRUE`) which are otherwise ignored (`PETSC_FALSE`) 7541bb7acecfSBarry Smith - emode - How to behave when a `DMLabel` in the source and destination `DM`s with the same name is encountered (see `DMCopyLabelsMode`) 7542c58f1c22SToby Isaac 7543c58f1c22SToby Isaac Level: intermediate 7544c58f1c22SToby Isaac 7545bb7acecfSBarry Smith Note: 75462cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 7547c58f1c22SToby Isaac 75481cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode` 7549c58f1c22SToby Isaac @*/ 7550d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 7551d71ae5a4SJacob Faibussowitsch { 75522cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 7553c58f1c22SToby Isaac const char *name; 7554c58f1c22SToby Isaac PetscBool flg; 75555d80c0bfSVaclav Hapla DMLabelLink link; 7556c58f1c22SToby Isaac 75575d80c0bfSVaclav Hapla PetscFunctionBegin; 75585d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 75595d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 75605d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode, 3); 75615d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 75627a8be351SBarry Smith PetscCheck(mode != PETSC_USE_POINTER, PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 75633ba16761SJacob Faibussowitsch if (dmA == dmB) PetscFunctionReturn(PETSC_SUCCESS); 75645d80c0bfSVaclav Hapla for (link = dmA->labels; link; link = link->next) { 75655d80c0bfSVaclav Hapla label = link->label; 75669566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 75675d80c0bfSVaclav Hapla if (!all) { 75689566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &flg)); 7569c58f1c22SToby Isaac if (flg) continue; 75709566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "dim", &flg)); 75717d5acc75SStefano Zampini if (flg) continue; 75729566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &flg)); 7573ba2698f1SMatthew G. Knepley if (flg) continue; 75745d80c0bfSVaclav Hapla } 75759566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmB, name, &labelOld)); 75762cbb9b06SVaclav Hapla if (labelOld) { 75772cbb9b06SVaclav Hapla switch (emode) { 7578d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_KEEP: 7579d71ae5a4SJacob Faibussowitsch continue; 7580d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_REPLACE: 7581d71ae5a4SJacob Faibussowitsch PetscCall(DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE)); 7582d71ae5a4SJacob Faibussowitsch break; 7583d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_FAIL: 7584d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 7585d71ae5a4SJacob Faibussowitsch default: 7586d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", (int)emode); 75872cbb9b06SVaclav Hapla } 75882cbb9b06SVaclav Hapla } 75895d80c0bfSVaclav Hapla if (mode == PETSC_COPY_VALUES) { 75909566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, &labelNew)); 75915d80c0bfSVaclav Hapla } else { 75925d80c0bfSVaclav Hapla labelNew = label; 75935d80c0bfSVaclav Hapla } 75949566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmB, labelNew)); 75959566063dSJacob Faibussowitsch if (mode == PETSC_COPY_VALUES) PetscCall(DMLabelDestroy(&labelNew)); 7596c58f1c22SToby Isaac } 75973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7598c58f1c22SToby Isaac } 7599461a15a0SLisandro Dalcin 7600609dae6eSVaclav Hapla /*@C 7601b4028c23SStefano Zampini DMCompareLabels - Compare labels between two `DM` objects 7602609dae6eSVaclav Hapla 760320f4b53cSBarry Smith Collective; No Fortran Support 7604609dae6eSVaclav Hapla 7605609dae6eSVaclav Hapla Input Parameters: 7606bb7acecfSBarry Smith + dm0 - First `DM` object 7607bb7acecfSBarry Smith - dm1 - Second `DM` object 7608609dae6eSVaclav Hapla 7609a4e35b19SJacob Faibussowitsch Output Parameters: 7610ce78bad3SBarry Smith + equal - (Optional) Flag whether labels of `dm0` and `dm1` are the same 761120f4b53cSBarry Smith - message - (Optional) Message describing the difference, or `NULL` if there is no difference 7612609dae6eSVaclav Hapla 7613609dae6eSVaclav Hapla Level: intermediate 7614609dae6eSVaclav Hapla 7615609dae6eSVaclav Hapla Notes: 7616bb7acecfSBarry Smith The output flag equal will be the same on all processes. 7617bb7acecfSBarry Smith 761820f4b53cSBarry Smith If equal is passed as `NULL` and difference is found, an error is thrown on all processes. 7619bb7acecfSBarry Smith 762020f4b53cSBarry Smith Make sure to pass equal is `NULL` on all processes or none of them. 7621609dae6eSVaclav Hapla 76225efe38ccSVaclav Hapla The output message is set independently on each rank. 7623bb7acecfSBarry Smith 7624bb7acecfSBarry Smith message must be freed with `PetscFree()` 7625bb7acecfSBarry Smith 7626ce78bad3SBarry Smith If message is passed as `NULL` and a difference is found, the difference description is printed to `stderr` in synchronized manner. 7627bb7acecfSBarry Smith 762820f4b53cSBarry Smith Make sure to pass message as `NULL` on all processes or no processes. 7629609dae6eSVaclav Hapla 7630609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 7631bb7acecfSBarry Smith `DMLabelCompare()` is used to compare each pair of labels with the same name. 7632609dae6eSVaclav Hapla 7633cc4c1da9SBarry Smith Developer Note: 7634ce78bad3SBarry Smith Cannot automatically generate the Fortran stub because `message` must be freed with `PetscFree()` 7635cc4c1da9SBarry Smith 76361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode`, `DMLabelCompare()` 7637609dae6eSVaclav Hapla @*/ 7638ce78bad3SBarry Smith PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *equal, char *message[]) PeNS 7639d71ae5a4SJacob Faibussowitsch { 76405efe38ccSVaclav Hapla PetscInt n, i; 7641609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 76425efe38ccSVaclav Hapla PetscBool eq; 7643609dae6eSVaclav Hapla MPI_Comm comm; 76445efe38ccSVaclav Hapla PetscMPIInt rank; 7645609dae6eSVaclav Hapla 7646609dae6eSVaclav Hapla PetscFunctionBegin; 7647609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0, DM_CLASSID, 1); 7648609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1, DM_CLASSID, 2); 7649609dae6eSVaclav Hapla PetscCheckSameComm(dm0, 1, dm1, 2); 76504f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 3); 76514f572ea9SToby Isaac if (message) PetscAssertPointer(message, 4); 76529566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm0, &comm)); 76539566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 76545efe38ccSVaclav Hapla { 76555efe38ccSVaclav Hapla PetscInt n1; 76565efe38ccSVaclav Hapla 76579566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm0, &n)); 76589566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm1, &n1)); 76595efe38ccSVaclav Hapla eq = (PetscBool)(n == n1); 766048a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %" PetscInt_FMT " != %" PetscInt_FMT " = Number of labels in dm1", n, n1)); 7661462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 76625efe38ccSVaclav Hapla if (!eq) goto finish; 76635efe38ccSVaclav Hapla } 76645efe38ccSVaclav Hapla for (i = 0; i < n; i++) { 7665609dae6eSVaclav Hapla DMLabel l0, l1; 7666609dae6eSVaclav Hapla const char *name; 7667609dae6eSVaclav Hapla char *msgInner; 7668609dae6eSVaclav Hapla 7669609dae6eSVaclav Hapla /* Ignore label order */ 76709566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm0, i, &l0)); 76719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name)); 76729566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm1, name, &l1)); 7673609dae6eSVaclav Hapla if (!l1) { 767463a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%" PetscInt_FMT " in dm0) not found in dm1", name, i)); 76755efe38ccSVaclav Hapla eq = PETSC_FALSE; 76765efe38ccSVaclav Hapla break; 7677609dae6eSVaclav Hapla } 76789566063dSJacob Faibussowitsch PetscCall(DMLabelCompare(comm, l0, l1, &eq, &msgInner)); 76799566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(msg, msgInner, sizeof(msg))); 76809566063dSJacob Faibussowitsch PetscCall(PetscFree(msgInner)); 76815efe38ccSVaclav Hapla if (!eq) break; 7682609dae6eSVaclav Hapla } 7683462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 7684609dae6eSVaclav Hapla finish: 76855efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 7686609dae6eSVaclav Hapla if (message) { 7687609dae6eSVaclav Hapla *message = NULL; 768848a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 76895efe38ccSVaclav Hapla } else { 769048a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 76919566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 76925efe38ccSVaclav Hapla } 76935efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 76945efe38ccSVaclav Hapla if (equal) *equal = eq; 76957a8be351SBarry Smith else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels are not the same in dm0 and dm1"); 76963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7697609dae6eSVaclav Hapla } 7698609dae6eSVaclav Hapla 7699d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 7700d71ae5a4SJacob Faibussowitsch { 7701461a15a0SLisandro Dalcin PetscFunctionBegin; 77024f572ea9SToby Isaac PetscAssertPointer(label, 2); 7703461a15a0SLisandro Dalcin if (!*label) { 77049566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 77059566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, label)); 7706461a15a0SLisandro Dalcin } 77079566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(*label, point, value)); 77083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7709461a15a0SLisandro Dalcin } 7710461a15a0SLisandro Dalcin 77110fdc7489SMatthew Knepley /* 77120fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 77130fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 77140fdc7489SMatthew Knepley (label, id) pair in the DM. 77150fdc7489SMatthew Knepley 77160fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 77170fdc7489SMatthew Knepley each label. 77180fdc7489SMatthew Knepley */ 7719d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 7720d71ae5a4SJacob Faibussowitsch { 77210fdc7489SMatthew Knepley DMUniversalLabel ul; 77220fdc7489SMatthew Knepley PetscBool *active; 77230fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 77240fdc7489SMatthew Knepley 77250fdc7489SMatthew Knepley PetscFunctionBegin; 77269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &ul)); 77279566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label)); 77289566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 77299566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nl, &active)); 77300fdc7489SMatthew Knepley ul->Nl = 0; 77310fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 77320fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 77330fdc7489SMatthew Knepley const char *name; 77340fdc7489SMatthew Knepley 77359566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 77369566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "depth", 6, &isdepth)); 77379566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "celltype", 9, &iscelltype)); 77380fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 77390fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 77400fdc7489SMatthew Knepley } 77419566063dSJacob Faibussowitsch PetscCall(PetscCalloc5(ul->Nl, &ul->names, ul->Nl, &ul->indices, ul->Nl + 1, &ul->offsets, ul->Nl + 1, &ul->bits, ul->Nl, &ul->masks)); 77420fdc7489SMatthew Knepley ul->Nv = 0; 77430fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 77440fdc7489SMatthew Knepley DMLabel label; 77450fdc7489SMatthew Knepley PetscInt nv; 77460fdc7489SMatthew Knepley const char *name; 77470fdc7489SMatthew Knepley 77480fdc7489SMatthew Knepley if (!active[l]) continue; 77499566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 77509566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 77519566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 77529566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &ul->names[m])); 77530fdc7489SMatthew Knepley ul->indices[m] = l; 77540fdc7489SMatthew Knepley ul->Nv += nv; 77550fdc7489SMatthew Knepley ul->offsets[m + 1] = nv; 77560fdc7489SMatthew Knepley ul->bits[m + 1] = PetscCeilReal(PetscLog2Real(nv + 1)); 77570fdc7489SMatthew Knepley ++m; 77580fdc7489SMatthew Knepley } 77590fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 77600fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l - 1] + ul->offsets[l]; 77610fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l - 1] + ul->bits[l]; 77620fdc7489SMatthew Knepley } 77630fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 77640fdc7489SMatthew Knepley PetscInt b; 77650fdc7489SMatthew Knepley 77660fdc7489SMatthew Knepley ul->masks[l] = 0; 77670fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l + 1]; ++b) ul->masks[l] |= 1 << b; 77680fdc7489SMatthew Knepley } 77699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ul->Nv, &ul->values)); 77700fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 77710fdc7489SMatthew Knepley DMLabel label; 77720fdc7489SMatthew Knepley IS valueIS; 77730fdc7489SMatthew Knepley const PetscInt *varr; 77740fdc7489SMatthew Knepley PetscInt nv, v; 77750fdc7489SMatthew Knepley 77760fdc7489SMatthew Knepley if (!active[l]) continue; 77779566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 77789566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 77799566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &valueIS)); 77809566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &varr)); 7781ad540459SPierre Jolivet for (v = 0; v < nv; ++v) ul->values[ul->offsets[m] + v] = varr[v]; 77829566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(valueIS, &varr)); 77839566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valueIS)); 77849566063dSJacob Faibussowitsch PetscCall(PetscSortInt(nv, &ul->values[ul->offsets[m]])); 77850fdc7489SMatthew Knepley ++m; 77860fdc7489SMatthew Knepley } 77879566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 77880fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 77890fdc7489SMatthew Knepley PetscInt uval = 0; 77900fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 77910fdc7489SMatthew Knepley 77920fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 77930fdc7489SMatthew Knepley DMLabel label; 77940649b39aSStefano Zampini PetscInt val, defval, loc, nv; 77950fdc7489SMatthew Knepley 77960fdc7489SMatthew Knepley if (!active[l]) continue; 77979566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 77989566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &val)); 77999566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &defval)); 78009371c9d4SSatish Balay if (val == defval) { 78019371c9d4SSatish Balay ++m; 78029371c9d4SSatish Balay continue; 78039371c9d4SSatish Balay } 78040649b39aSStefano Zampini nv = ul->offsets[m + 1] - ul->offsets[m]; 78050fdc7489SMatthew Knepley marked = PETSC_TRUE; 78069566063dSJacob Faibussowitsch PetscCall(PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc)); 780763a3b9bcSJacob Faibussowitsch PetscCheck(loc >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %" PetscInt_FMT " not found in compression array", val); 78080fdc7489SMatthew Knepley uval += (loc + 1) << ul->bits[m]; 78090fdc7489SMatthew Knepley ++m; 78100fdc7489SMatthew Knepley } 78119566063dSJacob Faibussowitsch if (marked) PetscCall(DMLabelSetValue(ul->label, p, uval)); 78120fdc7489SMatthew Knepley } 78139566063dSJacob Faibussowitsch PetscCall(PetscFree(active)); 78140fdc7489SMatthew Knepley *universal = ul; 78153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78160fdc7489SMatthew Knepley } 78170fdc7489SMatthew Knepley 7818d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 7819d71ae5a4SJacob Faibussowitsch { 78200fdc7489SMatthew Knepley PetscInt l; 78210fdc7489SMatthew Knepley 78220fdc7489SMatthew Knepley PetscFunctionBegin; 78239566063dSJacob Faibussowitsch for (l = 0; l < (*universal)->Nl; ++l) PetscCall(PetscFree((*universal)->names[l])); 78249566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&(*universal)->label)); 78259566063dSJacob Faibussowitsch PetscCall(PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks)); 78269566063dSJacob Faibussowitsch PetscCall(PetscFree((*universal)->values)); 78279566063dSJacob Faibussowitsch PetscCall(PetscFree(*universal)); 78280fdc7489SMatthew Knepley *universal = NULL; 78293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78300fdc7489SMatthew Knepley } 78310fdc7489SMatthew Knepley 7832d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 7833d71ae5a4SJacob Faibussowitsch { 78340fdc7489SMatthew Knepley PetscFunctionBegin; 78354f572ea9SToby Isaac PetscAssertPointer(ulabel, 2); 78360fdc7489SMatthew Knepley *ulabel = ul->label; 78373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78380fdc7489SMatthew Knepley } 78390fdc7489SMatthew Knepley 7840d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 7841d71ae5a4SJacob Faibussowitsch { 78420fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 78430fdc7489SMatthew Knepley 78440fdc7489SMatthew Knepley PetscFunctionBegin; 7845064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 78460fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 78479566063dSJacob Faibussowitsch if (preserveOrder) PetscCall(DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l])); 78489566063dSJacob Faibussowitsch else PetscCall(DMCreateLabel(dm, ul->names[l])); 78490fdc7489SMatthew Knepley } 78500fdc7489SMatthew Knepley if (preserveOrder) { 78510fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 78520fdc7489SMatthew Knepley const char *name; 78530fdc7489SMatthew Knepley PetscBool match; 78540fdc7489SMatthew Knepley 78559566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, ul->indices[l], &name)); 78569566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, ul->names[l], &match)); 785763a3b9bcSJacob Faibussowitsch PetscCheck(match, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Label %" PetscInt_FMT " name %s does not match new name %s", l, name, ul->names[l]); 78580fdc7489SMatthew Knepley } 78590fdc7489SMatthew Knepley } 78603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78610fdc7489SMatthew Knepley } 78620fdc7489SMatthew Knepley 7863d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 7864d71ae5a4SJacob Faibussowitsch { 78650fdc7489SMatthew Knepley PetscInt l; 78660fdc7489SMatthew Knepley 78670fdc7489SMatthew Knepley PetscFunctionBegin; 78680fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 78690fdc7489SMatthew Knepley DMLabel label; 78700fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 78710fdc7489SMatthew Knepley 78720fdc7489SMatthew Knepley if (lval) { 78739566063dSJacob Faibussowitsch if (useIndex) PetscCall(DMGetLabelByNum(dm, ul->indices[l], &label)); 78749566063dSJacob Faibussowitsch else PetscCall(DMGetLabel(dm, ul->names[l], &label)); 78759566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, p, ul->values[ul->offsets[l] + lval - 1])); 78760fdc7489SMatthew Knepley } 78770fdc7489SMatthew Knepley } 78783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78790fdc7489SMatthew Knepley } 7880a8fb8f29SToby Isaac 7881a8fb8f29SToby Isaac /*@ 7882bb7acecfSBarry Smith DMGetCoarseDM - Get the coarse `DM`from which this `DM` was obtained by refinement 7883bb7acecfSBarry Smith 788420f4b53cSBarry Smith Not Collective 7885a8fb8f29SToby Isaac 7886a8fb8f29SToby Isaac Input Parameter: 7887bb7acecfSBarry Smith . dm - The `DM` object 7888a8fb8f29SToby Isaac 7889a8fb8f29SToby Isaac Output Parameter: 7890bb7acecfSBarry Smith . cdm - The coarse `DM` 7891a8fb8f29SToby Isaac 7892a8fb8f29SToby Isaac Level: intermediate 7893a8fb8f29SToby Isaac 78941cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetCoarseDM()`, `DMCoarsen()` 7895a8fb8f29SToby Isaac @*/ 7896d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 7897d71ae5a4SJacob Faibussowitsch { 7898a8fb8f29SToby Isaac PetscFunctionBegin; 7899a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 79004f572ea9SToby Isaac PetscAssertPointer(cdm, 2); 7901a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 79023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7903a8fb8f29SToby Isaac } 7904a8fb8f29SToby Isaac 7905a8fb8f29SToby Isaac /*@ 7906bb7acecfSBarry Smith DMSetCoarseDM - Set the coarse `DM` from which this `DM` was obtained by refinement 7907a8fb8f29SToby Isaac 7908a8fb8f29SToby Isaac Input Parameters: 7909bb7acecfSBarry Smith + dm - The `DM` object 7910bb7acecfSBarry Smith - cdm - The coarse `DM` 7911a8fb8f29SToby Isaac 7912a8fb8f29SToby Isaac Level: intermediate 7913a8fb8f29SToby Isaac 7914bb7acecfSBarry Smith Note: 7915bb7acecfSBarry Smith Normally this is set automatically by `DMRefine()` 7916bb7acecfSBarry Smith 79171cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCoarseDM()`, `DMCoarsen()`, `DMSetRefine()`, `DMSetFineDM()` 7918a8fb8f29SToby Isaac @*/ 7919d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 7920d71ae5a4SJacob Faibussowitsch { 7921a8fb8f29SToby Isaac PetscFunctionBegin; 7922a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7923a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 792489d734beSBarry Smith if (dm == cdm) cdm = NULL; 79259566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cdm)); 79269566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->coarseMesh)); 7927a8fb8f29SToby Isaac dm->coarseMesh = cdm; 79283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7929a8fb8f29SToby Isaac } 7930a8fb8f29SToby Isaac 793188bdff64SToby Isaac /*@ 7932bb7acecfSBarry Smith DMGetFineDM - Get the fine mesh from which this `DM` was obtained by coarsening 793388bdff64SToby Isaac 793488bdff64SToby Isaac Input Parameter: 7935bb7acecfSBarry Smith . dm - The `DM` object 793688bdff64SToby Isaac 793788bdff64SToby Isaac Output Parameter: 7938bb7acecfSBarry Smith . fdm - The fine `DM` 793988bdff64SToby Isaac 794088bdff64SToby Isaac Level: intermediate 794188bdff64SToby Isaac 79421cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetFineDM()`, `DMCoarsen()`, `DMRefine()` 794388bdff64SToby Isaac @*/ 7944d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 7945d71ae5a4SJacob Faibussowitsch { 794688bdff64SToby Isaac PetscFunctionBegin; 794788bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 79484f572ea9SToby Isaac PetscAssertPointer(fdm, 2); 794988bdff64SToby Isaac *fdm = dm->fineMesh; 79503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 795188bdff64SToby Isaac } 795288bdff64SToby Isaac 795388bdff64SToby Isaac /*@ 7954bb7acecfSBarry Smith DMSetFineDM - Set the fine mesh from which this was obtained by coarsening 795588bdff64SToby Isaac 795688bdff64SToby Isaac Input Parameters: 7957bb7acecfSBarry Smith + dm - The `DM` object 7958bb7acecfSBarry Smith - fdm - The fine `DM` 795988bdff64SToby Isaac 7960bb7acecfSBarry Smith Level: developer 796188bdff64SToby Isaac 7962bb7acecfSBarry Smith Note: 7963bb7acecfSBarry Smith Normally this is set automatically by `DMCoarsen()` 7964bb7acecfSBarry Smith 79651cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFineDM()`, `DMCoarsen()`, `DMRefine()` 796688bdff64SToby Isaac @*/ 7967d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFineDM(DM dm, DM fdm) 7968d71ae5a4SJacob Faibussowitsch { 796988bdff64SToby Isaac PetscFunctionBegin; 797088bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 797188bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 797289d734beSBarry Smith if (dm == fdm) fdm = NULL; 79739566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fdm)); 79749566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->fineMesh)); 797588bdff64SToby Isaac dm->fineMesh = fdm; 79763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 797788bdff64SToby Isaac } 797888bdff64SToby Isaac 7979a6ba4734SToby Isaac /*@C 7980bb7acecfSBarry Smith DMAddBoundary - Add a boundary condition to a model represented by a `DM` 7981a6ba4734SToby Isaac 798220f4b53cSBarry Smith Collective 7983783e2ec8SMatthew G. Knepley 7984a6ba4734SToby Isaac Input Parameters: 7985bb7acecfSBarry Smith + dm - The `DM`, with a `PetscDS` that matches the problem being constrained 7986bb7acecfSBarry Smith . type - The type of condition, e.g. `DM_BC_ESSENTIAL_ANALYTIC`, `DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann) 7987a6ba4734SToby Isaac . name - The BC name 798845480ffeSMatthew G. Knepley . label - The label defining constrained points 7989bb7acecfSBarry Smith . Nv - The number of `DMLabel` values for constrained points 799045480ffeSMatthew G. Knepley . values - An array of values for constrained points 7991a6ba4734SToby Isaac . field - The field to constrain 7992258f4e96SStefano Zampini . Nc - The number of constrained field components (0 will constrain all components) 7993a6ba4734SToby Isaac . comps - An array of constrained component numbers 7994a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 799556cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 7996a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 7997a6ba4734SToby Isaac 799845480ffeSMatthew G. Knepley Output Parameter: 799945480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 800045480ffeSMatthew G. Knepley 8001a6ba4734SToby Isaac Options Database Keys: 8002a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 8003a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 8004a6ba4734SToby Isaac 800520f4b53cSBarry Smith Level: intermediate 800620f4b53cSBarry Smith 8007bb7acecfSBarry Smith Notes: 8008fa74d514SMatthew G. Knepley If the `DM` is of type `DMPLEX` and the field is of type `PetscFE`, then this function completes the label using `DMPlexLabelComplete()`. 8009fa74d514SMatthew G. Knepley 8010aeebefc2SPierre Jolivet Both bcFunc and bcFunc_t will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, then the calling sequence is\: 801173ff1848SBarry Smith .vb 801273ff1848SBarry Smith void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 801373ff1848SBarry Smith .ve 801456cf3b9cSMatthew G. Knepley 8015a4e35b19SJacob Faibussowitsch If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\: 801656cf3b9cSMatthew G. Knepley 801720f4b53cSBarry Smith .vb 801820f4b53cSBarry Smith void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 801920f4b53cSBarry Smith const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 802020f4b53cSBarry Smith const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 802120f4b53cSBarry Smith PetscReal time, const PetscReal x[], PetscScalar bcval[]) 802220f4b53cSBarry Smith .ve 802356cf3b9cSMatthew G. Knepley + dim - the spatial dimension 802456cf3b9cSMatthew G. Knepley . Nf - the number of fields 802556cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 802656cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 802756cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 802856cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 802956cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 803056cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 803156cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 803256cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 803356cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 803456cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 803556cf3b9cSMatthew G. Knepley . t - current time 803656cf3b9cSMatthew G. Knepley . x - coordinates of the current point 803756cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 803856cf3b9cSMatthew G. Knepley . constants - constant parameters 803956cf3b9cSMatthew G. Knepley - bcval - output values at the current point 804056cf3b9cSMatthew G. Knepley 80411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DSGetBoundary()`, `PetscDSAddBoundary()` 8042a6ba4734SToby Isaac @*/ 8043d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddBoundary(DM dm, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd) 8044d71ae5a4SJacob Faibussowitsch { 8045e5e52638SMatthew G. Knepley PetscDS ds; 8046a6ba4734SToby Isaac 8047a6ba4734SToby Isaac PetscFunctionBegin; 8048a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8049783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 805045480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 805145480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 805245480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 805345480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 805401a5d20dSJed Brown PetscCheck(!dm->localSection, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot add boundary to DM after creating local section"); 80559566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 8056799db056SMatthew G. Knepley /* Complete label */ 8057799db056SMatthew G. Knepley if (label) { 8058799db056SMatthew G. Knepley PetscObject obj; 8059799db056SMatthew G. Knepley PetscClassId id; 8060799db056SMatthew G. Knepley 8061799db056SMatthew G. Knepley PetscCall(DMGetField(dm, field, NULL, &obj)); 8062799db056SMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 8063799db056SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 8064799db056SMatthew G. Knepley DM plex; 8065799db056SMatthew G. Knepley 8066799db056SMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 8067799db056SMatthew G. Knepley if (plex) PetscCall(DMPlexLabelComplete(plex, label)); 8068799db056SMatthew G. Knepley PetscCall(DMDestroy(&plex)); 8069799db056SMatthew G. Knepley } 8070799db056SMatthew G. Knepley } 80719566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd)); 80723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8073a6ba4734SToby Isaac } 8074a6ba4734SToby Isaac 807545480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 8076d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPopulateBoundary(DM dm) 8077d71ae5a4SJacob Faibussowitsch { 8078e5e52638SMatthew G. Knepley PetscDS ds; 8079dff059c6SToby Isaac DMBoundary *lastnext; 8080e6f8dbb6SToby Isaac DSBoundary dsbound; 8081e6f8dbb6SToby Isaac 8082e6f8dbb6SToby Isaac PetscFunctionBegin; 80839566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 8084e5e52638SMatthew G. Knepley dsbound = ds->boundary; 808547a1f5adSToby Isaac if (dm->boundary) { 808647a1f5adSToby Isaac DMBoundary next = dm->boundary; 808747a1f5adSToby Isaac 808847a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 80893ba16761SJacob Faibussowitsch if (next->dsboundary == dsbound) PetscFunctionReturn(PETSC_SUCCESS); 809047a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 809147a1f5adSToby Isaac while (next) { 809247a1f5adSToby Isaac DMBoundary b = next; 809347a1f5adSToby Isaac 809447a1f5adSToby Isaac next = b->next; 80959566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 8096a6ba4734SToby Isaac } 809747a1f5adSToby Isaac dm->boundary = NULL; 8098a6ba4734SToby Isaac } 809947a1f5adSToby Isaac 8100f4f49eeaSPierre Jolivet lastnext = &dm->boundary; 8101e6f8dbb6SToby Isaac while (dsbound) { 8102e6f8dbb6SToby Isaac DMBoundary dmbound; 8103e6f8dbb6SToby Isaac 81049566063dSJacob Faibussowitsch PetscCall(PetscNew(&dmbound)); 8105e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 810645480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 810747a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8108dff059c6SToby Isaac *lastnext = dmbound; 8109f4f49eeaSPierre Jolivet lastnext = &dmbound->next; 8110dff059c6SToby Isaac dsbound = dsbound->next; 8111a6ba4734SToby Isaac } 81123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8113a6ba4734SToby Isaac } 8114a6ba4734SToby Isaac 8115bb7acecfSBarry Smith /* TODO: missing manual page */ 8116d71ae5a4SJacob Faibussowitsch PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8117d71ae5a4SJacob Faibussowitsch { 8118b95f2879SToby Isaac DMBoundary b; 8119a6ba4734SToby Isaac 8120a6ba4734SToby Isaac PetscFunctionBegin; 8121a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 81224f572ea9SToby Isaac PetscAssertPointer(isBd, 3); 8123a6ba4734SToby Isaac *isBd = PETSC_FALSE; 81249566063dSJacob Faibussowitsch PetscCall(DMPopulateBoundary(dm)); 8125b95f2879SToby Isaac b = dm->boundary; 812657508eceSPierre Jolivet while (b && !*isBd) { 8127e6f8dbb6SToby Isaac DMLabel label = b->label; 8128e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 8129a6ba4734SToby Isaac PetscInt i; 8130a6ba4734SToby Isaac 813145480ffeSMatthew G. Knepley if (label) { 813257508eceSPierre Jolivet for (i = 0; i < dsb->Nv && !*isBd; ++i) PetscCall(DMLabelStratumHasPoint(label, dsb->values[i], point, isBd)); 8133a6ba4734SToby Isaac } 8134a6ba4734SToby Isaac b = b->next; 8135a6ba4734SToby Isaac } 81363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8137a6ba4734SToby Isaac } 81384d6f44ffSToby Isaac 813901468941SMatthew G. Knepley /*@ 814001468941SMatthew G. Knepley DMHasBound - Determine whether a bound condition was specified 814101468941SMatthew G. Knepley 814201468941SMatthew G. Knepley Logically collective 814301468941SMatthew G. Knepley 814401468941SMatthew G. Knepley Input Parameter: 814501468941SMatthew G. Knepley . dm - The `DM`, with a `PetscDS` that matches the problem being constrained 814601468941SMatthew G. Knepley 814701468941SMatthew G. Knepley Output Parameter: 814801468941SMatthew G. Knepley . hasBound - Flag indicating if a bound condition was specified 814901468941SMatthew G. Knepley 815001468941SMatthew G. Knepley Level: intermediate 815101468941SMatthew G. Knepley 815201468941SMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `DSAddBoundary()`, `PetscDSAddBoundary()` 815301468941SMatthew G. Knepley @*/ 815401468941SMatthew G. Knepley PetscErrorCode DMHasBound(DM dm, PetscBool *hasBound) 815501468941SMatthew G. Knepley { 815601468941SMatthew G. Knepley PetscDS ds; 815701468941SMatthew G. Knepley PetscInt Nf, numBd; 815801468941SMatthew G. Knepley 815901468941SMatthew G. Knepley PetscFunctionBegin; 816001468941SMatthew G. Knepley *hasBound = PETSC_FALSE; 816101468941SMatthew G. Knepley PetscCall(DMGetDS(dm, &ds)); 816201468941SMatthew G. Knepley PetscCall(PetscDSGetNumFields(ds, &Nf)); 816301468941SMatthew G. Knepley for (PetscInt f = 0; f < Nf; ++f) { 8164*2192575eSBarry Smith PetscSimplePointFn *lfunc, *ufunc; 816501468941SMatthew G. Knepley 816601468941SMatthew G. Knepley PetscCall(PetscDSGetLowerBound(ds, f, &lfunc, NULL)); 816701468941SMatthew G. Knepley PetscCall(PetscDSGetUpperBound(ds, f, &ufunc, NULL)); 816801468941SMatthew G. Knepley if (lfunc || ufunc) *hasBound = PETSC_TRUE; 816901468941SMatthew G. Knepley } 817001468941SMatthew G. Knepley 817101468941SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(ds, &numBd)); 817201468941SMatthew G. Knepley PetscCall(PetscDSUpdateBoundaryLabels(ds, dm)); 817301468941SMatthew G. Knepley for (PetscInt b = 0; b < numBd; ++b) { 817401468941SMatthew G. Knepley PetscWeakForm wf; 817501468941SMatthew G. Knepley DMBoundaryConditionType type; 817601468941SMatthew G. Knepley const char *name; 817701468941SMatthew G. Knepley DMLabel label; 817801468941SMatthew G. Knepley PetscInt numids; 817901468941SMatthew G. Knepley const PetscInt *ids; 818001468941SMatthew G. Knepley PetscInt field, Nc; 818101468941SMatthew G. Knepley const PetscInt *comps; 818201468941SMatthew G. Knepley void (*bvfunc)(void); 818301468941SMatthew G. Knepley void *ctx; 818401468941SMatthew G. Knepley 818501468941SMatthew G. Knepley PetscCall(PetscDSGetBoundary(ds, b, &wf, &type, &name, &label, &numids, &ids, &field, &Nc, &comps, &bvfunc, NULL, &ctx)); 818601468941SMatthew G. Knepley if (type == DM_BC_LOWER_BOUND || type == DM_BC_UPPER_BOUND) *hasBound = PETSC_TRUE; 818701468941SMatthew G. Knepley } 818801468941SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 818901468941SMatthew G. Knepley } 819001468941SMatthew G. Knepley 81914d6f44ffSToby Isaac /*@C 8192bb7acecfSBarry Smith DMProjectFunction - This projects the given function into the function space provided by a `DM`, putting the coefficients in a global vector. 8193a6e0b375SMatthew G. Knepley 819420f4b53cSBarry Smith Collective 81954d6f44ffSToby Isaac 81964d6f44ffSToby Isaac Input Parameters: 8197bb7acecfSBarry Smith + dm - The `DM` 81980709b2feSToby Isaac . time - The time 81994d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 82004d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 82014d6f44ffSToby Isaac - mode - The insertion mode for values 82024d6f44ffSToby Isaac 82034d6f44ffSToby Isaac Output Parameter: 82044d6f44ffSToby Isaac . X - vector 82054d6f44ffSToby Isaac 820620f4b53cSBarry Smith Calling sequence of `funcs`: 82074d6f44ffSToby Isaac + dim - The spatial dimension 82088ec8862eSJed Brown . time - The time at which to sample 82094d6f44ffSToby Isaac . x - The coordinates 821077b739a6SMatthew Knepley . Nc - The number of components 82114d6f44ffSToby Isaac . u - The output field values 82124d6f44ffSToby Isaac - ctx - optional user-defined function context 82134d6f44ffSToby Isaac 82144d6f44ffSToby Isaac Level: developer 82154d6f44ffSToby Isaac 8216bb7acecfSBarry Smith Developer Notes: 8217bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8218bb7acecfSBarry Smith 8219bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8220bb7acecfSBarry Smith 82211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 82224d6f44ffSToby Isaac @*/ 8223a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec X) 8224d71ae5a4SJacob Faibussowitsch { 82254d6f44ffSToby Isaac Vec localX; 82264d6f44ffSToby Isaac 82274d6f44ffSToby Isaac PetscFunctionBegin; 82284d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8229708be2fdSJed Brown PetscCall(PetscLogEventBegin(DM_ProjectFunction, dm, X, 0, 0)); 82309566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8231f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 82329566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX)); 82339566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 82349566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 82359566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 8236708be2fdSJed Brown PetscCall(PetscLogEventEnd(DM_ProjectFunction, dm, X, 0, 0)); 82373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82384d6f44ffSToby Isaac } 82394d6f44ffSToby Isaac 8240a6e0b375SMatthew G. Knepley /*@C 8241bb7acecfSBarry Smith DMProjectFunctionLocal - This projects the given function into the function space provided by a `DM`, putting the coefficients in a local vector. 8242a6e0b375SMatthew G. Knepley 824320f4b53cSBarry Smith Not Collective 8244a6e0b375SMatthew G. Knepley 8245a6e0b375SMatthew G. Knepley Input Parameters: 8246bb7acecfSBarry Smith + dm - The `DM` 8247a6e0b375SMatthew G. Knepley . time - The time 8248a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8249a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8250a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8251a6e0b375SMatthew G. Knepley 8252a6e0b375SMatthew G. Knepley Output Parameter: 8253a6e0b375SMatthew G. Knepley . localX - vector 8254a6e0b375SMatthew G. Knepley 825520f4b53cSBarry Smith Calling sequence of `funcs`: 8256a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8257a4e35b19SJacob Faibussowitsch . time - The current timestep 8258a6e0b375SMatthew G. Knepley . x - The coordinates 825977b739a6SMatthew Knepley . Nc - The number of components 8260a6e0b375SMatthew G. Knepley . u - The output field values 8261a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8262a6e0b375SMatthew G. Knepley 8263a6e0b375SMatthew G. Knepley Level: developer 8264a6e0b375SMatthew G. Knepley 8265bb7acecfSBarry Smith Developer Notes: 8266bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8267bb7acecfSBarry Smith 8268bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8269bb7acecfSBarry Smith 82701cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8271a6e0b375SMatthew G. Knepley @*/ 8272a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec localX) 8273d71ae5a4SJacob Faibussowitsch { 82744d6f44ffSToby Isaac PetscFunctionBegin; 82754d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8276064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 8277fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfunctionlocal, time, funcs, ctxs, mode, localX); 82783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82794d6f44ffSToby Isaac } 82804d6f44ffSToby Isaac 8281a6e0b375SMatthew G. Knepley /*@C 8282bb7acecfSBarry Smith DMProjectFunctionLabel - This projects the given function into the function space provided by the `DM`, putting the coefficients in a global vector, setting values only for points in the given label. 8283a6e0b375SMatthew G. Knepley 828420f4b53cSBarry Smith Collective 8285a6e0b375SMatthew G. Knepley 8286a6e0b375SMatthew G. Knepley Input Parameters: 8287bb7acecfSBarry Smith + dm - The `DM` 8288a6e0b375SMatthew G. Knepley . time - The time 8289a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8290a4e35b19SJacob Faibussowitsch . ids - The ids 8291a4e35b19SJacob Faibussowitsch . Nc - The number of components 8292a4e35b19SJacob Faibussowitsch . comps - The components 8293bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8294a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8295bb7acecfSBarry Smith . ctxs - Optional array of contexts to pass to each coordinate function. ctxs may be null. 8296a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8297a6e0b375SMatthew G. Knepley 8298a6e0b375SMatthew G. Knepley Output Parameter: 8299a6e0b375SMatthew G. Knepley . X - vector 8300a6e0b375SMatthew G. Knepley 830120f4b53cSBarry Smith Calling sequence of `funcs`: 8302a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8303a4e35b19SJacob Faibussowitsch . time - The current timestep 8304a6e0b375SMatthew G. Knepley . x - The coordinates 830577b739a6SMatthew Knepley . Nc - The number of components 8306a6e0b375SMatthew G. Knepley . u - The output field values 8307a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8308a6e0b375SMatthew G. Knepley 8309a6e0b375SMatthew G. Knepley Level: developer 8310a6e0b375SMatthew G. Knepley 8311bb7acecfSBarry Smith Developer Notes: 8312bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8313bb7acecfSBarry Smith 8314bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8315bb7acecfSBarry Smith 83161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabelLocal()`, `DMComputeL2Diff()` 8317a6e0b375SMatthew G. Knepley @*/ 8318a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec X) 8319d71ae5a4SJacob Faibussowitsch { 83202c53366bSMatthew G. Knepley Vec localX; 83212c53366bSMatthew G. Knepley 83222c53366bSMatthew G. Knepley PetscFunctionBegin; 83232c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 83249566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8325f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 83269566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 83279566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 83289566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 83299566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 83303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83312c53366bSMatthew G. Knepley } 83322c53366bSMatthew G. Knepley 8333a6e0b375SMatthew G. Knepley /*@C 8334bb7acecfSBarry Smith DMProjectFunctionLabelLocal - This projects the given function into the function space provided by the `DM`, putting the coefficients in a local vector, setting values only for points in the given label. 8335a6e0b375SMatthew G. Knepley 833620f4b53cSBarry Smith Not Collective 8337a6e0b375SMatthew G. Knepley 8338a6e0b375SMatthew G. Knepley Input Parameters: 8339bb7acecfSBarry Smith + dm - The `DM` 8340a6e0b375SMatthew G. Knepley . time - The time 8341bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8342a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8343a4e35b19SJacob Faibussowitsch . ids - The ids 8344a4e35b19SJacob Faibussowitsch . Nc - The number of components 8345a4e35b19SJacob Faibussowitsch . comps - The components 8346a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8347a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8348a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8349a6e0b375SMatthew G. Knepley 8350a6e0b375SMatthew G. Knepley Output Parameter: 8351a6e0b375SMatthew G. Knepley . localX - vector 8352a6e0b375SMatthew G. Knepley 835320f4b53cSBarry Smith Calling sequence of `funcs`: 8354a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8355a4e35b19SJacob Faibussowitsch . time - The current time 8356a6e0b375SMatthew G. Knepley . x - The coordinates 835777b739a6SMatthew Knepley . Nc - The number of components 8358a6e0b375SMatthew G. Knepley . u - The output field values 8359a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8360a6e0b375SMatthew G. Knepley 8361a6e0b375SMatthew G. Knepley Level: developer 8362a6e0b375SMatthew G. Knepley 8363bb7acecfSBarry Smith Developer Notes: 8364bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8365bb7acecfSBarry Smith 8366bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8367bb7acecfSBarry Smith 83681cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8369a6e0b375SMatthew G. Knepley @*/ 8370a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec localX) 8371d71ae5a4SJacob Faibussowitsch { 83724d6f44ffSToby Isaac PetscFunctionBegin; 83734d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8374064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8375fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfunctionlabellocal, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX); 83763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83774d6f44ffSToby Isaac } 83782716604bSToby Isaac 8379a6e0b375SMatthew G. Knepley /*@C 8380bb7acecfSBarry Smith DMProjectFieldLocal - This projects the given function of the input fields into the function space provided by the `DM`, putting the coefficients in a local vector. 8381a6e0b375SMatthew G. Knepley 838220f4b53cSBarry Smith Not Collective 8383a6e0b375SMatthew G. Knepley 8384a6e0b375SMatthew G. Knepley Input Parameters: 8385bb7acecfSBarry Smith + dm - The `DM` 8386a6e0b375SMatthew G. Knepley . time - The time 838720f4b53cSBarry Smith . localU - The input field vector; may be `NULL` if projection is defined purely by coordinates 8388a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8389a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8390a6e0b375SMatthew G. Knepley 8391a6e0b375SMatthew G. Knepley Output Parameter: 8392a6e0b375SMatthew G. Knepley . localX - The output vector 8393a6e0b375SMatthew G. Knepley 839420f4b53cSBarry Smith Calling sequence of `funcs`: 8395a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8396a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8397a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8398a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8399a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8400a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8401a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8402a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8403a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8404a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8405a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8406a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8407a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8408a6e0b375SMatthew G. Knepley . t - The current time 8409a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8410a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8411a6e0b375SMatthew G. Knepley . constants - The value of each constant 8412a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8413a6e0b375SMatthew G. Knepley 841473ff1848SBarry Smith Level: intermediate 841573ff1848SBarry Smith 8416bb7acecfSBarry Smith Note: 8417bb7acecfSBarry Smith There are three different `DM`s that potentially interact in this function. The output `DM`, dm, specifies the layout of the values calculates by funcs. 8418bb7acecfSBarry Smith The input `DM`, attached to U, may be different. For example, you can input the solution over the full domain, but output over a piece of the boundary, or 8419bb7acecfSBarry Smith a subdomain. You can also output a different number of fields than the input, with different discretizations. Last the auxiliary `DM`, attached to the 8420a6e0b375SMatthew G. Knepley auxiliary field vector, which is attached to dm, can also be different. It can have a different topology, number of fields, and discretizations. 8421a6e0b375SMatthew G. Knepley 8422bb7acecfSBarry Smith Developer Notes: 8423bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8424bb7acecfSBarry Smith 8425bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8426bb7acecfSBarry Smith 8427a4e35b19SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, 8428a4e35b19SJacob Faibussowitsch `DMProjectFunction()`, `DMComputeL2Diff()` 8429a6e0b375SMatthew G. Knepley @*/ 8430a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec localX) 8431d71ae5a4SJacob Faibussowitsch { 84328c6c5593SMatthew G. Knepley PetscFunctionBegin; 84338c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8434eb8f539aSJed Brown if (localU) PetscValidHeaderSpecific(localU, VEC_CLASSID, 3); 84358c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 8436fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfieldlocal, time, localU, funcs, mode, localX); 84373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 84388c6c5593SMatthew G. Knepley } 84398c6c5593SMatthew G. Knepley 8440a6e0b375SMatthew G. Knepley /*@C 8441a6e0b375SMatthew G. Knepley DMProjectFieldLabelLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector, calculating only over the portion of the domain specified by the label. 8442a6e0b375SMatthew G. Knepley 844320f4b53cSBarry Smith Not Collective 8444a6e0b375SMatthew G. Knepley 8445a6e0b375SMatthew G. Knepley Input Parameters: 8446bb7acecfSBarry Smith + dm - The `DM` 8447a6e0b375SMatthew G. Knepley . time - The time 8448bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8449a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8450a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8451bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 845220f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8453a6e0b375SMatthew G. Knepley . localU - The input field vector 8454a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8455a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8456a6e0b375SMatthew G. Knepley 8457a6e0b375SMatthew G. Knepley Output Parameter: 8458a6e0b375SMatthew G. Knepley . localX - The output vector 8459a6e0b375SMatthew G. Knepley 846020f4b53cSBarry Smith Calling sequence of `funcs`: 8461a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8462a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8463a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8464a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8465a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8466a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8467a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8468a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8469a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8470a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8471a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8472a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8473a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8474a6e0b375SMatthew G. Knepley . t - The current time 8475a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8476a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8477a6e0b375SMatthew G. Knepley . constants - The value of each constant 8478a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8479a6e0b375SMatthew G. Knepley 848073ff1848SBarry Smith Level: intermediate 848173ff1848SBarry Smith 8482bb7acecfSBarry Smith Note: 8483bb7acecfSBarry Smith There are three different `DM`s that potentially interact in this function. The output `DM`, dm, specifies the layout of the values calculates by funcs. 8484bb7acecfSBarry Smith The input `DM`, attached to localU, may be different. For example, you can input the solution over the full domain, but output over a piece of the boundary, or 8485bb7acecfSBarry Smith a subdomain. You can also output a different number of fields than the input, with different discretizations. Last the auxiliary `DM`, attached to the 8486a6e0b375SMatthew G. Knepley auxiliary field vector, which is attached to dm, can also be different. It can have a different topology, number of fields, and discretizations. 8487a6e0b375SMatthew G. Knepley 8488bb7acecfSBarry Smith Developer Notes: 8489bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8490bb7acecfSBarry Smith 8491bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8492bb7acecfSBarry Smith 84931cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabel()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8494a6e0b375SMatthew G. Knepley @*/ 8495a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec localX) 8496d71ae5a4SJacob Faibussowitsch { 84978c6c5593SMatthew G. Knepley PetscFunctionBegin; 84988c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8499064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8500064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8501fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfieldlabellocal, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX); 85023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85038c6c5593SMatthew G. Knepley } 85048c6c5593SMatthew G. Knepley 85052716604bSToby Isaac /*@C 8506d29d7c6eSMatthew G. Knepley DMProjectFieldLabel - This projects the given function of the input fields into the function space provided, putting the coefficients in a global vector, calculating only over the portion of the domain specified by the label. 8507d29d7c6eSMatthew G. Knepley 850820f4b53cSBarry Smith Not Collective 8509d29d7c6eSMatthew G. Knepley 8510d29d7c6eSMatthew G. Knepley Input Parameters: 8511bb7acecfSBarry Smith + dm - The `DM` 8512d29d7c6eSMatthew G. Knepley . time - The time 8513bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8514d29d7c6eSMatthew G. Knepley . numIds - The number of label ids to use 8515d29d7c6eSMatthew G. Knepley . ids - The label ids to use for marking 8516bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 851720f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8518d29d7c6eSMatthew G. Knepley . U - The input field vector 8519d29d7c6eSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8520d29d7c6eSMatthew G. Knepley - mode - The insertion mode for values 8521d29d7c6eSMatthew G. Knepley 8522d29d7c6eSMatthew G. Knepley Output Parameter: 8523d29d7c6eSMatthew G. Knepley . X - The output vector 8524d29d7c6eSMatthew G. Knepley 852520f4b53cSBarry Smith Calling sequence of `funcs`: 8526d29d7c6eSMatthew G. Knepley + dim - The spatial dimension 8527d29d7c6eSMatthew G. Knepley . Nf - The number of input fields 8528d29d7c6eSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8529d29d7c6eSMatthew G. Knepley . uOff - The offset of each field in u[] 8530d29d7c6eSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8531d29d7c6eSMatthew G. Knepley . u - The field values at this point in space 8532d29d7c6eSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8533d29d7c6eSMatthew G. Knepley . u_x - The field derivatives at this point in space 8534d29d7c6eSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8535d29d7c6eSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8536d29d7c6eSMatthew G. Knepley . a - The auxiliary field values at this point in space 8537d29d7c6eSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8538d29d7c6eSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8539d29d7c6eSMatthew G. Knepley . t - The current time 8540d29d7c6eSMatthew G. Knepley . x - The coordinates of this point 8541d29d7c6eSMatthew G. Knepley . numConstants - The number of constants 8542d29d7c6eSMatthew G. Knepley . constants - The value of each constant 8543d29d7c6eSMatthew G. Knepley - f - The value of the function at this point in space 8544d29d7c6eSMatthew G. Knepley 854573ff1848SBarry Smith Level: intermediate 854673ff1848SBarry Smith 8547bb7acecfSBarry Smith Note: 8548bb7acecfSBarry Smith There are three different `DM`s that potentially interact in this function. The output `DM`, dm, specifies the layout of the values calculates by funcs. 8549bb7acecfSBarry Smith The input `DM`, attached to U, may be different. For example, you can input the solution over the full domain, but output over a piece of the boundary, or 8550bb7acecfSBarry Smith a subdomain. You can also output a different number of fields than the input, with different discretizations. Last the auxiliary `DM`, attached to the 8551d29d7c6eSMatthew G. Knepley auxiliary field vector, which is attached to dm, can also be different. It can have a different topology, number of fields, and discretizations. 8552d29d7c6eSMatthew G. Knepley 8553bb7acecfSBarry Smith Developer Notes: 8554bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8555bb7acecfSBarry Smith 8556bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8557bb7acecfSBarry Smith 85581cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8559d29d7c6eSMatthew G. Knepley @*/ 8560a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFieldLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec U, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec X) 8561d71ae5a4SJacob Faibussowitsch { 8562d29d7c6eSMatthew G. Knepley DM dmIn; 8563d29d7c6eSMatthew G. Knepley Vec localU, localX; 8564d29d7c6eSMatthew G. Knepley 8565d29d7c6eSMatthew G. Knepley PetscFunctionBegin; 8566d29d7c6eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8567d29d7c6eSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn)); 8568d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dmIn, &localU)); 8569d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &localX)); 8570f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 857172fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dmIn, U, mode, localU)); 857272fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dmIn, U, mode, localU)); 8573d29d7c6eSMatthew G. Knepley PetscCall(DMProjectFieldLabelLocal(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8574d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 8575d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 8576d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &localX)); 8577d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dmIn, &localU)); 85783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8579d29d7c6eSMatthew G. Knepley } 8580d29d7c6eSMatthew G. Knepley 8581d29d7c6eSMatthew G. Knepley /*@C 8582ece3a9fcSMatthew G. Knepley DMProjectBdFieldLabelLocal - This projects the given function of the input fields into the function space provided, putting the coefficients in a local vector, calculating only over the portion of the domain boundary specified by the label. 8583ece3a9fcSMatthew G. Knepley 858420f4b53cSBarry Smith Not Collective 8585ece3a9fcSMatthew G. Knepley 8586ece3a9fcSMatthew G. Knepley Input Parameters: 8587bb7acecfSBarry Smith + dm - The `DM` 8588ece3a9fcSMatthew G. Knepley . time - The time 8589bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain boundary to output 8590ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8591ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8592bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 859320f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8594ece3a9fcSMatthew G. Knepley . localU - The input field vector 8595ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8596ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8597ece3a9fcSMatthew G. Knepley 8598ece3a9fcSMatthew G. Knepley Output Parameter: 8599ece3a9fcSMatthew G. Knepley . localX - The output vector 8600ece3a9fcSMatthew G. Knepley 860120f4b53cSBarry Smith Calling sequence of `funcs`: 8602ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8603ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8604ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8605ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8606ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8607ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8608ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8609ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8610ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8611ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8612ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8613ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8614ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8615ece3a9fcSMatthew G. Knepley . t - The current time 8616ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8617ece3a9fcSMatthew G. Knepley . n - The face normal 8618ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8619ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8620ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8621ece3a9fcSMatthew G. Knepley 862273ff1848SBarry Smith Level: intermediate 862373ff1848SBarry Smith 8624ece3a9fcSMatthew G. Knepley Note: 8625bb7acecfSBarry Smith There are three different `DM`s that potentially interact in this function. The output `DM`, dm, specifies the layout of the values calculates by funcs. 8626bb7acecfSBarry Smith The input `DM`, attached to U, may be different. For example, you can input the solution over the full domain, but output over a piece of the boundary, or 8627bb7acecfSBarry Smith a subdomain. You can also output a different number of fields than the input, with different discretizations. Last the auxiliary `DM`, attached to the 8628ece3a9fcSMatthew G. Knepley auxiliary field vector, which is attached to dm, can also be different. It can have a different topology, number of fields, and discretizations. 8629ece3a9fcSMatthew G. Knepley 8630bb7acecfSBarry Smith Developer Notes: 8631bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8632bb7acecfSBarry Smith 8633bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8634bb7acecfSBarry Smith 86351cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8636ece3a9fcSMatthew G. Knepley @*/ 8637a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec localX) 8638d71ae5a4SJacob Faibussowitsch { 8639ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8640ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8641064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8642064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8643fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectbdfieldlabellocal, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX); 86443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8645ece3a9fcSMatthew G. Knepley } 8646ece3a9fcSMatthew G. Knepley 8647ece3a9fcSMatthew G. Knepley /*@C 86482716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 86492716604bSToby Isaac 865020f4b53cSBarry Smith Collective 8651bb7acecfSBarry Smith 86522716604bSToby Isaac Input Parameters: 8653bb7acecfSBarry Smith + dm - The `DM` 86540709b2feSToby Isaac . time - The time 86552716604bSToby Isaac . funcs - The functions to evaluate for each field component 86562716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8657574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 86582716604bSToby Isaac 86592716604bSToby Isaac Output Parameter: 86602716604bSToby Isaac . diff - The diff ||u - u_h||_2 86612716604bSToby Isaac 86622716604bSToby Isaac Level: developer 86632716604bSToby Isaac 8664bb7acecfSBarry Smith Developer Notes: 8665bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8666bb7acecfSBarry Smith 8667bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8668bb7acecfSBarry Smith 86691cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 86702716604bSToby Isaac @*/ 8671d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 8672d71ae5a4SJacob Faibussowitsch { 86732716604bSToby Isaac PetscFunctionBegin; 86742716604bSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8675b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8676fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2diff, time, funcs, ctxs, X, diff); 86773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86782716604bSToby Isaac } 8679b698f381SToby Isaac 8680b698f381SToby Isaac /*@C 8681b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8682b698f381SToby Isaac 868320f4b53cSBarry Smith Collective 8684d083f849SBarry Smith 8685b698f381SToby Isaac Input Parameters: 8686bb7acecfSBarry Smith + dm - The `DM` 8687a4e35b19SJacob Faibussowitsch . time - The time 8688b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8689b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8690574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8691b698f381SToby Isaac - n - The vector to project along 8692b698f381SToby Isaac 8693b698f381SToby Isaac Output Parameter: 8694b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8695b698f381SToby Isaac 8696b698f381SToby Isaac Level: developer 8697b698f381SToby Isaac 8698bb7acecfSBarry Smith Developer Notes: 8699bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8700bb7acecfSBarry Smith 8701bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8702bb7acecfSBarry Smith 87031cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2Diff()`, `DMComputeL2FieldDiff()` 8704b698f381SToby Isaac @*/ 8705d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2GradientDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, const PetscReal n[], PetscReal *diff) 8706d71ae5a4SJacob Faibussowitsch { 8707b698f381SToby Isaac PetscFunctionBegin; 8708b698f381SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8709b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8710fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2gradientdiff, time, funcs, ctxs, X, n, diff); 87113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8712b698f381SToby Isaac } 8713b698f381SToby Isaac 87142a16baeaSToby Isaac /*@C 87152a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 87162a16baeaSToby Isaac 871720f4b53cSBarry Smith Collective 8718d083f849SBarry Smith 87192a16baeaSToby Isaac Input Parameters: 8720bb7acecfSBarry Smith + dm - The `DM` 87212a16baeaSToby Isaac . time - The time 87222a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 87232a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8724574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 87252a16baeaSToby Isaac 87262a16baeaSToby Isaac Output Parameter: 87272a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 87282a16baeaSToby Isaac 87292a16baeaSToby Isaac Level: developer 87302a16baeaSToby Isaac 8731bb7acecfSBarry Smith Developer Notes: 8732bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8733bb7acecfSBarry Smith 8734bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8735bb7acecfSBarry Smith 873642747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2GradientDiff()` 87372a16baeaSToby Isaac @*/ 8738d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 8739d71ae5a4SJacob Faibussowitsch { 87402a16baeaSToby Isaac PetscFunctionBegin; 87412a16baeaSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 87422a16baeaSToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8743fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2fielddiff, time, funcs, ctxs, X, diff); 87443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 87452a16baeaSToby Isaac } 87462a16baeaSToby Isaac 8747df0b854cSToby Isaac /*@C 8748bb7acecfSBarry Smith DMGetNeighbors - Gets an array containing the MPI ranks of all the processes neighbors 8749502a2867SDave May 8750502a2867SDave May Not Collective 8751502a2867SDave May 8752502a2867SDave May Input Parameter: 8753bb7acecfSBarry Smith . dm - The `DM` 8754502a2867SDave May 87550a19bb7dSprj- Output Parameters: 87560a19bb7dSprj- + nranks - the number of neighbours 87570a19bb7dSprj- - ranks - the neighbors ranks 8758502a2867SDave May 87599bdbcad8SBarry Smith Level: beginner 87609bdbcad8SBarry Smith 8761bb7acecfSBarry Smith Note: 8762bb7acecfSBarry Smith Do not free the array, it is freed when the `DM` is destroyed. 8763502a2867SDave May 87641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDAGetNeighbors()`, `PetscSFGetRootRanks()` 8765502a2867SDave May @*/ 8766d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNeighbors(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 8767d71ae5a4SJacob Faibussowitsch { 8768502a2867SDave May PetscFunctionBegin; 8769502a2867SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8770fa1e479aSStefano Zampini PetscUseTypeMethod(dm, getneighbors, nranks, ranks); 87713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8772502a2867SDave May } 8773502a2867SDave May 8774531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 8775531c7667SBarry Smith 8776531c7667SBarry Smith /* 8777531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 87782b6f951bSStefano Zampini This must be a different function because it requires DM which is not defined in the Mat library 8779531c7667SBarry Smith */ 878066976f2fSJacob Faibussowitsch static PetscErrorCode MatFDColoringApply_AIJDM(Mat J, MatFDColoring coloring, Vec x1, void *sctx) 8781d71ae5a4SJacob Faibussowitsch { 8782531c7667SBarry Smith PetscFunctionBegin; 8783531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8784531c7667SBarry Smith Vec x1local; 8785531c7667SBarry Smith DM dm; 87869566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 87877a8be351SBarry Smith PetscCheck(dm, PetscObjectComm((PetscObject)J), PETSC_ERR_ARG_INCOMP, "IS_COLORING_LOCAL requires a DM"); 87889566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &x1local)); 87899566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, x1, INSERT_VALUES, x1local)); 87909566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, x1, INSERT_VALUES, x1local)); 8791531c7667SBarry Smith x1 = x1local; 8792531c7667SBarry Smith } 87939566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply_AIJ(J, coloring, x1, sctx)); 8794531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8795531c7667SBarry Smith DM dm; 87969566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 87979566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &x1)); 8798531c7667SBarry Smith } 87993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8800531c7667SBarry Smith } 8801531c7667SBarry Smith 8802531c7667SBarry Smith /*@ 8803bb7acecfSBarry Smith MatFDColoringUseDM - allows a `MatFDColoring` object to use the `DM` associated with the matrix to compute a `IS_COLORING_LOCAL` coloring 8804531c7667SBarry Smith 8805a4e35b19SJacob Faibussowitsch Input Parameters: 8806a4e35b19SJacob Faibussowitsch + coloring - The matrix to get the `DM` from 8807a4e35b19SJacob Faibussowitsch - fdcoloring - the `MatFDColoring` object 8808531c7667SBarry Smith 88099bdbcad8SBarry Smith Level: advanced 88109bdbcad8SBarry Smith 881173ff1848SBarry Smith Developer Note: 881273ff1848SBarry Smith This routine exists because the PETSc `Mat` library does not know about the `DM` objects 8813531c7667SBarry Smith 88141cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatFDColoring`, `MatFDColoringCreate()`, `ISColoringType` 8815531c7667SBarry Smith @*/ 8816d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringUseDM(Mat coloring, MatFDColoring fdcoloring) 8817d71ae5a4SJacob Faibussowitsch { 8818531c7667SBarry Smith PetscFunctionBegin; 8819531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 88203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8821531c7667SBarry Smith } 88228320bc6fSPatrick Sanan 88238320bc6fSPatrick Sanan /*@ 8824bb7acecfSBarry Smith DMGetCompatibility - determine if two `DM`s are compatible 88258320bc6fSPatrick Sanan 88268320bc6fSPatrick Sanan Collective 88278320bc6fSPatrick Sanan 88288320bc6fSPatrick Sanan Input Parameters: 8829bb7acecfSBarry Smith + dm1 - the first `DM` 8830bb7acecfSBarry Smith - dm2 - the second `DM` 88318320bc6fSPatrick Sanan 88328320bc6fSPatrick Sanan Output Parameters: 8833bb7acecfSBarry Smith + compatible - whether or not the two `DM`s are compatible 8834bb7acecfSBarry Smith - set - whether or not the compatible value was actually determined and set 88358320bc6fSPatrick Sanan 883620f4b53cSBarry Smith Level: advanced 883720f4b53cSBarry Smith 88388320bc6fSPatrick Sanan Notes: 8839bb7acecfSBarry Smith Two `DM`s are deemed compatible if they represent the same parallel decomposition 88403d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 88418320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 8842bb7acecfSBarry Smith Loosely speaking, compatible `DM`s represent the same domain and parallel 88433d862458SPatrick Sanan decomposition, but hold different data. 88448320bc6fSPatrick Sanan 88458320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 8846bb7acecfSBarry Smith over a pair of vectors obtained from different `DM`s. 88478320bc6fSPatrick Sanan 8848bb7acecfSBarry Smith For example, two `DMDA` objects are compatible if they have the same local 88498320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 88508320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 8851bb7acecfSBarry Smith either `DM` in bounds for a loop over vectors derived from either `DM`. 88528320bc6fSPatrick Sanan 8853bb7acecfSBarry Smith Consider the operation of summing data living on a 2-dof `DMDA` to data living 8854bb7acecfSBarry Smith on a 1-dof `DMDA`, which should be compatible, as in the following snippet. 88558320bc6fSPatrick Sanan .vb 88568320bc6fSPatrick Sanan ... 88579566063dSJacob Faibussowitsch PetscCall(DMGetCompatibility(da1,da2,&compatible,&set)); 88588320bc6fSPatrick Sanan if (set && compatible) { 88599566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1)); 88609566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2)); 88619566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL)); 88628320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 88638320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 88648320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 88658320bc6fSPatrick Sanan } 88668320bc6fSPatrick Sanan } 88679566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1)); 88689566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2)); 88698320bc6fSPatrick Sanan } else { 88708320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 88718320bc6fSPatrick Sanan } 88728320bc6fSPatrick Sanan ... 88738320bc6fSPatrick Sanan .ve 88748320bc6fSPatrick Sanan 8875bb7acecfSBarry Smith Checking compatibility might be expensive for a given implementation of `DM`, 88768320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 88778320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 88788320bc6fSPatrick Sanan always check the "set" output parameter. 88798320bc6fSPatrick Sanan 8880bb7acecfSBarry Smith A `DM` is always compatible with itself. 88818320bc6fSPatrick Sanan 8882bb7acecfSBarry Smith In the current implementation, `DM`s which live on "unequal" communicators 88838320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 88848320bc6fSPatrick Sanan incompatible. 88858320bc6fSPatrick Sanan 88868320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 8887bb7acecfSBarry Smith is required on each rank. However, in `DM` implementations which store all this 88888320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 88898320bc6fSPatrick Sanan 889073ff1848SBarry Smith Developer Note: 8891bb7acecfSBarry Smith Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B 88923d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 8893a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 8894bb7acecfSBarry Smith compatibility. It is left to `DM` implementers to ensure that symmetry is 88958320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 88963d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 8897bb7acecfSBarry Smith of other `DM` types and let *set = PETSC_FALSE if found. 88988320bc6fSPatrick Sanan 88991cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()` 89008320bc6fSPatrick Sanan @*/ 8901d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCompatibility(DM dm1, DM dm2, PetscBool *compatible, PetscBool *set) 8902d71ae5a4SJacob Faibussowitsch { 89038320bc6fSPatrick Sanan PetscMPIInt compareResult; 89048320bc6fSPatrick Sanan DMType type, type2; 89058320bc6fSPatrick Sanan PetscBool sameType; 89068320bc6fSPatrick Sanan 89078320bc6fSPatrick Sanan PetscFunctionBegin; 8908a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 89098320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 89108320bc6fSPatrick Sanan 89118320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 8912a5bc1bf3SBarry Smith if (dm1 == dm2) { 89138320bc6fSPatrick Sanan *set = PETSC_TRUE; 89148320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 89153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89168320bc6fSPatrick Sanan } 89178320bc6fSPatrick Sanan 89188320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 89198320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 89208320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 89218320bc6fSPatrick Sanan determined by the implementation-specific logic */ 89229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)dm1), PetscObjectComm((PetscObject)dm2), &compareResult)); 89238320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 89248320bc6fSPatrick Sanan *set = PETSC_TRUE; 89258320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 89263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89278320bc6fSPatrick Sanan } 89288320bc6fSPatrick Sanan 89298320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 8930a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 8931dbbe0bcdSBarry Smith PetscUseTypeMethod(dm1, getcompatibility, dm2, compatible, set); 89323ba16761SJacob Faibussowitsch if (*set) PetscFunctionReturn(PETSC_SUCCESS); 89338320bc6fSPatrick Sanan } 89348320bc6fSPatrick Sanan 8935a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 89368320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 89379566063dSJacob Faibussowitsch PetscCall(DMGetType(dm1, &type)); 89389566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2, &type2)); 89399566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, type2, &sameType)); 89408320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 8941dbbe0bcdSBarry Smith PetscUseTypeMethod(dm2, getcompatibility, dm1, compatible, set); /* Note argument order */ 89428320bc6fSPatrick Sanan } else { 89438320bc6fSPatrick Sanan *set = PETSC_FALSE; 89448320bc6fSPatrick Sanan } 89453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89468320bc6fSPatrick Sanan } 8947c0f0dcc3SMatthew G. Knepley 8948c0f0dcc3SMatthew G. Knepley /*@C 8949bb7acecfSBarry Smith DMMonitorSet - Sets an additional monitor function that is to be used after a solve to monitor discretization performance. 8950c0f0dcc3SMatthew G. Knepley 895120f4b53cSBarry Smith Logically Collective 8952c0f0dcc3SMatthew G. Knepley 8953c0f0dcc3SMatthew G. Knepley Input Parameters: 895460225df5SJacob Faibussowitsch + dm - the `DM` 8955c0f0dcc3SMatthew G. Knepley . f - the monitor function 895620f4b53cSBarry Smith . mctx - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired) 895749abdd8aSBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for the calling sequence 8958c0f0dcc3SMatthew G. Knepley 895920f4b53cSBarry Smith Options Database Key: 896060225df5SJacob Faibussowitsch . -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `DMMonitorSet()`, but 8961c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 8962c0f0dcc3SMatthew G. Knepley 89639bdbcad8SBarry Smith Level: intermediate 89649bdbcad8SBarry Smith 8965bb7acecfSBarry Smith Note: 8966c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 8967bb7acecfSBarry Smith `DMMonitorSet()` multiple times or with `DMMonitorSetFromOptions()`; all will be called in the 8968c0f0dcc3SMatthew G. Knepley order in which they were set. 8969c0f0dcc3SMatthew G. Knepley 897073ff1848SBarry Smith Fortran Note: 8971bb7acecfSBarry Smith Only a single monitor function can be set for each `DM` object 8972bb7acecfSBarry Smith 897373ff1848SBarry Smith Developer Note: 8974bb7acecfSBarry Smith This API has a generic name but seems specific to a very particular aspect of the use of `DM` 8975c0f0dcc3SMatthew G. Knepley 897649abdd8aSBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorCancel()`, `DMMonitorSetFromOptions()`, `DMMonitor()`, `PetscCtxDestroyFn` 8977c0f0dcc3SMatthew G. Knepley @*/ 897849abdd8aSBarry Smith PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscCtxDestroyFn *monitordestroy) 8979d71ae5a4SJacob Faibussowitsch { 8980c0f0dcc3SMatthew G. Knepley PetscInt m; 8981c0f0dcc3SMatthew G. Knepley 8982c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8983c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8984c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 8985c0f0dcc3SMatthew G. Knepley PetscBool identical; 8986c0f0dcc3SMatthew G. Knepley 89879566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f, mctx, monitordestroy, (PetscErrorCode (*)(void))dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical)); 89883ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 8989c0f0dcc3SMatthew G. Knepley } 89907a8be351SBarry Smith PetscCheck(dm->numbermonitors < MAXDMMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 8991c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 8992c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 8993835f2295SStefano Zampini dm->monitorcontext[dm->numbermonitors++] = mctx; 89943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8995c0f0dcc3SMatthew G. Knepley } 8996c0f0dcc3SMatthew G. Knepley 8997c0f0dcc3SMatthew G. Knepley /*@ 8998bb7acecfSBarry Smith DMMonitorCancel - Clears all the monitor functions for a `DM` object. 8999c0f0dcc3SMatthew G. Knepley 900020f4b53cSBarry Smith Logically Collective 9001c0f0dcc3SMatthew G. Knepley 9002c0f0dcc3SMatthew G. Knepley Input Parameter: 9003c0f0dcc3SMatthew G. Knepley . dm - the DM 9004c0f0dcc3SMatthew G. Knepley 9005c0f0dcc3SMatthew G. Knepley Options Database Key: 9006c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 9007bb7acecfSBarry Smith into a code by calls to `DMonitorSet()`, but does not cancel those 9008c0f0dcc3SMatthew G. Knepley set via the options database 9009c0f0dcc3SMatthew G. Knepley 90109bdbcad8SBarry Smith Level: intermediate 90119bdbcad8SBarry Smith 9012bb7acecfSBarry Smith Note: 9013bb7acecfSBarry Smith There is no way to clear one specific monitor from a `DM` object. 9014c0f0dcc3SMatthew G. Knepley 90151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 9016c0f0dcc3SMatthew G. Knepley @*/ 9017d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorCancel(DM dm) 9018d71ae5a4SJacob Faibussowitsch { 9019c0f0dcc3SMatthew G. Knepley PetscInt m; 9020c0f0dcc3SMatthew G. Knepley 9021c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9022c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9023c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 90249566063dSJacob Faibussowitsch if (dm->monitordestroy[m]) PetscCall((*dm->monitordestroy[m])(&dm->monitorcontext[m])); 9025c0f0dcc3SMatthew G. Knepley } 9026c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 90273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9028c0f0dcc3SMatthew G. Knepley } 9029c0f0dcc3SMatthew G. Knepley 9030c0f0dcc3SMatthew G. Knepley /*@C 9031c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 9032c0f0dcc3SMatthew G. Knepley 903320f4b53cSBarry Smith Collective 9034c0f0dcc3SMatthew G. Knepley 9035c0f0dcc3SMatthew G. Knepley Input Parameters: 9036bb7acecfSBarry Smith + dm - `DM` object you wish to monitor 9037c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 9038c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 9039c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 904049abdd8aSBarry Smith . monitor - the monitor function, this must use a `PetscViewerFormat` as its context 9041bb7acecfSBarry Smith - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the `DM` or `PetscViewer` objects 9042c0f0dcc3SMatthew G. Knepley 9043c0f0dcc3SMatthew G. Knepley Output Parameter: 9044c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 9045c0f0dcc3SMatthew G. Knepley 9046c0f0dcc3SMatthew G. Knepley Level: developer 9047c0f0dcc3SMatthew G. Knepley 9048648c30bcSBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscOptionsCreateViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 9049db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 905060225df5SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 9051db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 9052c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 9053db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 9054bb7acecfSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `DMMonitor()`, `DMMonitorSet()` 9055c0f0dcc3SMatthew G. Knepley @*/ 9056d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 9057d71ae5a4SJacob Faibussowitsch { 9058c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 9059c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 9060c0f0dcc3SMatthew G. Knepley 9061c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9062c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9063648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)dm), ((PetscObject)dm)->options, ((PetscObject)dm)->prefix, name, &viewer, &format, flg)); 9064c0f0dcc3SMatthew G. Knepley if (*flg) { 9065c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 9066c0f0dcc3SMatthew G. Knepley 90679566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 9068648c30bcSBarry Smith PetscCall(PetscViewerDestroy(&viewer)); 90699566063dSJacob Faibussowitsch if (monitorsetup) PetscCall((*monitorsetup)(dm, vf)); 9070835f2295SStefano Zampini PetscCall(DMMonitorSet(dm, monitor, vf, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy)); 9071c0f0dcc3SMatthew G. Knepley } 90723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9073c0f0dcc3SMatthew G. Knepley } 9074c0f0dcc3SMatthew G. Knepley 9075c0f0dcc3SMatthew G. Knepley /*@ 9076c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 9077c0f0dcc3SMatthew G. Knepley 907820f4b53cSBarry Smith Collective 9079c0f0dcc3SMatthew G. Knepley 90802fe279fdSBarry Smith Input Parameter: 9081bb7acecfSBarry Smith . dm - The `DM` 9082c0f0dcc3SMatthew G. Knepley 9083c0f0dcc3SMatthew G. Knepley Level: developer 9084c0f0dcc3SMatthew G. Knepley 908573ff1848SBarry Smith Developer Note: 9086a4e35b19SJacob Faibussowitsch Note should indicate when during the life of the `DM` the monitor is run. It appears to be 9087a4e35b19SJacob Faibussowitsch related to the discretization process seems rather specialized since some `DM` have no 9088a4e35b19SJacob Faibussowitsch concept of discretization. 9089bb7acecfSBarry Smith 90901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()` 9091c0f0dcc3SMatthew G. Knepley @*/ 9092d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitor(DM dm) 9093d71ae5a4SJacob Faibussowitsch { 9094c0f0dcc3SMatthew G. Knepley PetscInt m; 9095c0f0dcc3SMatthew G. Knepley 9096c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 90973ba16761SJacob Faibussowitsch if (!dm) PetscFunctionReturn(PETSC_SUCCESS); 9098c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 909948a46eb9SPierre Jolivet for (m = 0; m < dm->numbermonitors; ++m) PetscCall((*dm->monitor[m])(dm, dm->monitorcontext[m])); 91003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9101c0f0dcc3SMatthew G. Knepley } 91022e4af2aeSMatthew G. Knepley 91032e4af2aeSMatthew G. Knepley /*@ 9104bb7acecfSBarry Smith DMComputeError - Computes the error assuming the user has provided the exact solution functions 91052e4af2aeSMatthew G. Knepley 910620f4b53cSBarry Smith Collective 91072e4af2aeSMatthew G. Knepley 91082e4af2aeSMatthew G. Knepley Input Parameters: 9109bb7acecfSBarry Smith + dm - The `DM` 91106b867d5aSJose E. Roman - sol - The solution vector 91112e4af2aeSMatthew G. Knepley 91126b867d5aSJose E. Roman Input/Output Parameter: 911320f4b53cSBarry Smith . errors - An array of length Nf, the number of fields, or `NULL` for no output; on output 91146b867d5aSJose E. Roman contains the error in each field 91156b867d5aSJose E. Roman 91166b867d5aSJose E. Roman Output Parameter: 911720f4b53cSBarry Smith . errorVec - A vector to hold the cellwise error (may be `NULL`) 911820f4b53cSBarry Smith 911920f4b53cSBarry Smith Level: developer 91202e4af2aeSMatthew G. Knepley 9121bb7acecfSBarry Smith Note: 9122bb7acecfSBarry Smith The exact solutions come from the `PetscDS` object, and the time comes from `DMGetOutputSequenceNumber()`. 91232e4af2aeSMatthew G. Knepley 91241cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMGetRegionNumDS()`, `PetscDSGetExactSolution()`, `DMGetOutputSequenceNumber()` 91252e4af2aeSMatthew G. Knepley @*/ 9126d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 9127d71ae5a4SJacob Faibussowitsch { 91282e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 91292e4af2aeSMatthew G. Knepley void **ctxs; 91302e4af2aeSMatthew G. Knepley PetscReal time; 91312e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 91322e4af2aeSMatthew G. Knepley 91332e4af2aeSMatthew G. Knepley PetscFunctionBegin; 91349566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 91359566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nf, &exactSol, Nf, &ctxs)); 91369566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 91372e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 91382e4af2aeSMatthew G. Knepley PetscDS ds; 91392e4af2aeSMatthew G. Knepley DMLabel label; 91402e4af2aeSMatthew G. Knepley IS fieldIS; 91412e4af2aeSMatthew G. Knepley const PetscInt *fields; 91422e4af2aeSMatthew G. Knepley PetscInt dsNf; 91432e4af2aeSMatthew G. Knepley 914407218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 91459566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 91469566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISGetIndices(fieldIS, &fields)); 91472e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 91482e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 91499566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field])); 91502e4af2aeSMatthew G. Knepley } 91519566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISRestoreIndices(fieldIS, &fields)); 91522e4af2aeSMatthew G. Knepley } 9153ad540459SPierre Jolivet for (f = 0; f < Nf; ++f) PetscCheck(exactSol[f], PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "DS must contain exact solution functions in order to calculate error, missing for field %" PetscInt_FMT, f); 91549566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, NULL, &time)); 91559566063dSJacob Faibussowitsch if (errors) PetscCall(DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors)); 91562e4af2aeSMatthew G. Knepley if (errorVec) { 91572e4af2aeSMatthew G. Knepley DM edm; 91582e4af2aeSMatthew G. Knepley DMPolytopeType ct; 91592e4af2aeSMatthew G. Knepley PetscBool simplex; 91602e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 91612e4af2aeSMatthew G. Knepley 91629566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &edm)); 91639566063dSJacob Faibussowitsch PetscCall(DMGetDimension(edm, &dim)); 91649566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 91659566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 91662e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 91679566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 91682e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 91692e4af2aeSMatthew G. Knepley PetscFE fe, efe; 91702e4af2aeSMatthew G. Knepley PetscQuadrature q; 91712e4af2aeSMatthew G. Knepley const char *name; 91722e4af2aeSMatthew G. Knepley 91739566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, (PetscObject *)&fe)); 91749566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe)); 91759566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 91769566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)efe, name)); 91779566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 91789566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(efe, q)); 91799566063dSJacob Faibussowitsch PetscCall(DMSetField(edm, f, NULL, (PetscObject)efe)); 91809566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&efe)); 91812e4af2aeSMatthew G. Knepley } 91829566063dSJacob Faibussowitsch PetscCall(DMCreateDS(edm)); 91832e4af2aeSMatthew G. Knepley 91849566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(edm, errorVec)); 91859566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*errorVec, "Error")); 91869566063dSJacob Faibussowitsch PetscCall(DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec)); 91879566063dSJacob Faibussowitsch PetscCall(DMDestroy(&edm)); 91882e4af2aeSMatthew G. Knepley } 91899566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, ctxs)); 91903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91912e4af2aeSMatthew G. Knepley } 91929a2a23afSMatthew G. Knepley 91939a2a23afSMatthew G. Knepley /*@ 9194bb7acecfSBarry Smith DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this `DM` 91959a2a23afSMatthew G. Knepley 919620f4b53cSBarry Smith Not Collective 91979a2a23afSMatthew G. Knepley 91989a2a23afSMatthew G. Knepley Input Parameter: 9199bb7acecfSBarry Smith . dm - The `DM` 92009a2a23afSMatthew G. Knepley 92019a2a23afSMatthew G. Knepley Output Parameter: 9202a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 92039a2a23afSMatthew G. Knepley 92049a2a23afSMatthew G. Knepley Level: advanced 92059a2a23afSMatthew G. Knepley 9206e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMGetAuxiliaryVec()` 92079a2a23afSMatthew G. Knepley @*/ 9208d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 9209d71ae5a4SJacob Faibussowitsch { 92109a2a23afSMatthew G. Knepley PetscFunctionBegin; 92119a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 92129566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize(dm->auxData, numAux)); 92133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92149a2a23afSMatthew G. Knepley } 92159a2a23afSMatthew G. Knepley 92169a2a23afSMatthew G. Knepley /*@ 9217ac17215fSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value, and equation part 92189a2a23afSMatthew G. Knepley 921920f4b53cSBarry Smith Not Collective 92209a2a23afSMatthew G. Knepley 92219a2a23afSMatthew G. Knepley Input Parameters: 9222bb7acecfSBarry Smith + dm - The `DM` 9223bb7acecfSBarry Smith . label - The `DMLabel` 9224ac17215fSMatthew G. Knepley . value - The label value indicating the region 9225ac17215fSMatthew G. Knepley - part - The equation part, or 0 if unused 92269a2a23afSMatthew G. Knepley 92279a2a23afSMatthew G. Knepley Output Parameter: 9228bb7acecfSBarry Smith . aux - The `Vec` holding auxiliary field data 92299a2a23afSMatthew G. Knepley 92309bdbcad8SBarry Smith Level: advanced 92319bdbcad8SBarry Smith 9232bb7acecfSBarry Smith Note: 9233bb7acecfSBarry Smith If no auxiliary vector is found for this (label, value), (NULL, 0, 0) is checked as well. 923404c51a94SMatthew G. Knepley 9235e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryLabels()` 92369a2a23afSMatthew G. Knepley @*/ 9237d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec *aux) 9238d71ae5a4SJacob Faibussowitsch { 9239ac17215fSMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0, 0}; 924004c51a94SMatthew G. Knepley PetscBool has; 92419a2a23afSMatthew G. Knepley 92429a2a23afSMatthew G. Knepley PetscFunctionBegin; 92439a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 92449a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 92459a2a23afSMatthew G. Knepley key.label = label; 92469a2a23afSMatthew G. Knepley key.value = value; 9247ac17215fSMatthew G. Knepley key.part = part; 92489566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxHas(dm->auxData, key, &has)); 92499566063dSJacob Faibussowitsch if (has) PetscCall(PetscHMapAuxGet(dm->auxData, key, aux)); 92509566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxGet(dm->auxData, wild, aux)); 92513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92529a2a23afSMatthew G. Knepley } 92539a2a23afSMatthew G. Knepley 92549a2a23afSMatthew G. Knepley /*@ 9255bb7acecfSBarry Smith DMSetAuxiliaryVec - Set an auxiliary vector for region specified by the given label and value, and equation part 92569a2a23afSMatthew G. Knepley 925720f4b53cSBarry Smith Not Collective because auxiliary vectors are not parallel 92589a2a23afSMatthew G. Knepley 92599a2a23afSMatthew G. Knepley Input Parameters: 9260bb7acecfSBarry Smith + dm - The `DM` 9261bb7acecfSBarry Smith . label - The `DMLabel` 92629a2a23afSMatthew G. Knepley . value - The label value indicating the region 9263ac17215fSMatthew G. Knepley . part - The equation part, or 0 if unused 9264bb7acecfSBarry Smith - aux - The `Vec` holding auxiliary field data 92659a2a23afSMatthew G. Knepley 92669a2a23afSMatthew G. Knepley Level: advanced 92679a2a23afSMatthew G. Knepley 9268e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMCopyAuxiliaryVec()` 92699a2a23afSMatthew G. Knepley @*/ 9270d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec aux) 9271d71ae5a4SJacob Faibussowitsch { 92729a2a23afSMatthew G. Knepley Vec old; 92739a2a23afSMatthew G. Knepley PetscHashAuxKey key; 92749a2a23afSMatthew G. Knepley 92759a2a23afSMatthew G. Knepley PetscFunctionBegin; 92769a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 92779a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 92789a2a23afSMatthew G. Knepley key.label = label; 92799a2a23afSMatthew G. Knepley key.value = value; 9280ac17215fSMatthew G. Knepley key.part = part; 92819566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGet(dm->auxData, key, &old)); 92829566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)aux)); 92839566063dSJacob Faibussowitsch if (!aux) PetscCall(PetscHMapAuxDel(dm->auxData, key)); 92849566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxSet(dm->auxData, key, aux)); 9285d705d0eaSStefano Zampini PetscCall(VecDestroy(&old)); 92863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92879a2a23afSMatthew G. Knepley } 92889a2a23afSMatthew G. Knepley 9289cc4c1da9SBarry Smith /*@ 9290bb7acecfSBarry Smith DMGetAuxiliaryLabels - Get the labels, values, and parts for all auxiliary vectors in this `DM` 92919a2a23afSMatthew G. Knepley 929220f4b53cSBarry Smith Not Collective 92939a2a23afSMatthew G. Knepley 92949a2a23afSMatthew G. Knepley Input Parameter: 9295bb7acecfSBarry Smith . dm - The `DM` 92969a2a23afSMatthew G. Knepley 92979a2a23afSMatthew G. Knepley Output Parameters: 9298bb7acecfSBarry Smith + labels - The `DMLabel`s for each `Vec` 9299bb7acecfSBarry Smith . values - The label values for each `Vec` 9300bb7acecfSBarry Smith - parts - The equation parts for each `Vec` 93019a2a23afSMatthew G. Knepley 93029bdbcad8SBarry Smith Level: advanced 93039bdbcad8SBarry Smith 9304bb7acecfSBarry Smith Note: 9305bb7acecfSBarry Smith The arrays passed in must be at least as large as `DMGetNumAuxiliaryVec()`. 93069a2a23afSMatthew G. Knepley 9307e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMCopyAuxiliaryVec()` 93089a2a23afSMatthew G. Knepley @*/ 9309d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[], PetscInt parts[]) 9310d71ae5a4SJacob Faibussowitsch { 93119a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 93129a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 93139a2a23afSMatthew G. Knepley 93149a2a23afSMatthew G. Knepley PetscFunctionBegin; 93159a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93164f572ea9SToby Isaac PetscAssertPointer(labels, 2); 93174f572ea9SToby Isaac PetscAssertPointer(values, 3); 93184f572ea9SToby Isaac PetscAssertPointer(parts, 4); 93199566063dSJacob Faibussowitsch PetscCall(DMGetNumAuxiliaryVec(dm, &n)); 93209566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &keys)); 93219566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetKeys(dm->auxData, &off, keys)); 93229371c9d4SSatish Balay for (i = 0; i < n; ++i) { 93239371c9d4SSatish Balay labels[i] = keys[i].label; 93249371c9d4SSatish Balay values[i] = keys[i].value; 93259371c9d4SSatish Balay parts[i] = keys[i].part; 93269371c9d4SSatish Balay } 93279566063dSJacob Faibussowitsch PetscCall(PetscFree(keys)); 93283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 93299a2a23afSMatthew G. Knepley } 93309a2a23afSMatthew G. Knepley 93319a2a23afSMatthew G. Knepley /*@ 9332bb7acecfSBarry Smith DMCopyAuxiliaryVec - Copy the auxiliary vector data on a `DM` to a new `DM` 93339a2a23afSMatthew G. Knepley 933420f4b53cSBarry Smith Not Collective 93359a2a23afSMatthew G. Knepley 93369a2a23afSMatthew G. Knepley Input Parameter: 9337bb7acecfSBarry Smith . dm - The `DM` 93389a2a23afSMatthew G. Knepley 93399a2a23afSMatthew G. Knepley Output Parameter: 9340bb7acecfSBarry Smith . dmNew - The new `DM`, now with the same auxiliary data 93419a2a23afSMatthew G. Knepley 93429a2a23afSMatthew G. Knepley Level: advanced 93439a2a23afSMatthew G. Knepley 9344bb7acecfSBarry Smith Note: 9345bb7acecfSBarry Smith This is a shallow copy of the auxiliary vectors 9346bb7acecfSBarry Smith 9347e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 93489a2a23afSMatthew G. Knepley @*/ 9349d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 9350d71ae5a4SJacob Faibussowitsch { 93519a2a23afSMatthew G. Knepley PetscFunctionBegin; 93529a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9353d705d0eaSStefano Zampini PetscValidHeaderSpecific(dmNew, DM_CLASSID, 2); 9354d705d0eaSStefano Zampini if (dm == dmNew) PetscFunctionReturn(PETSC_SUCCESS); 9355e4d5475eSStefano Zampini PetscCall(DMClearAuxiliaryVec(dmNew)); 9356e4d5475eSStefano Zampini 9357e4d5475eSStefano Zampini PetscCall(PetscHMapAuxDestroy(&dmNew->auxData)); 93589566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData)); 9359d705d0eaSStefano Zampini { 9360d705d0eaSStefano Zampini Vec *auxData; 9361d705d0eaSStefano Zampini PetscInt n, i, off = 0; 9362d705d0eaSStefano Zampini 9363d705d0eaSStefano Zampini PetscCall(PetscHMapAuxGetSize(dmNew->auxData, &n)); 9364d705d0eaSStefano Zampini PetscCall(PetscMalloc1(n, &auxData)); 9365d705d0eaSStefano Zampini PetscCall(PetscHMapAuxGetVals(dmNew->auxData, &off, auxData)); 9366d705d0eaSStefano Zampini for (i = 0; i < n; ++i) PetscCall(PetscObjectReference((PetscObject)auxData[i])); 9367d705d0eaSStefano Zampini PetscCall(PetscFree(auxData)); 9368e4d5475eSStefano Zampini } 9369e4d5475eSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 9370e4d5475eSStefano Zampini } 9371e4d5475eSStefano Zampini 9372e4d5475eSStefano Zampini /*@ 9373e4d5475eSStefano Zampini DMClearAuxiliaryVec - Destroys the auxiliary vector information and creates a new empty one 9374e4d5475eSStefano Zampini 9375e4d5475eSStefano Zampini Not Collective 9376e4d5475eSStefano Zampini 9377e4d5475eSStefano Zampini Input Parameter: 9378e4d5475eSStefano Zampini . dm - The `DM` 9379e4d5475eSStefano Zampini 9380e4d5475eSStefano Zampini Level: advanced 9381e4d5475eSStefano Zampini 9382e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMCopyAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 9383e4d5475eSStefano Zampini @*/ 9384e4d5475eSStefano Zampini PetscErrorCode DMClearAuxiliaryVec(DM dm) 9385e4d5475eSStefano Zampini { 9386e4d5475eSStefano Zampini Vec *auxData; 9387e4d5475eSStefano Zampini PetscInt n, i, off = 0; 9388e4d5475eSStefano Zampini 9389e4d5475eSStefano Zampini PetscFunctionBegin; 9390e4d5475eSStefano Zampini PetscCall(PetscHMapAuxGetSize(dm->auxData, &n)); 9391d705d0eaSStefano Zampini PetscCall(PetscMalloc1(n, &auxData)); 9392e4d5475eSStefano Zampini PetscCall(PetscHMapAuxGetVals(dm->auxData, &off, auxData)); 9393d705d0eaSStefano Zampini for (i = 0; i < n; ++i) PetscCall(VecDestroy(&auxData[i])); 9394d705d0eaSStefano Zampini PetscCall(PetscFree(auxData)); 9395e4d5475eSStefano Zampini PetscCall(PetscHMapAuxDestroy(&dm->auxData)); 9396e4d5475eSStefano Zampini PetscCall(PetscHMapAuxCreate(&dm->auxData)); 93973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 93989a2a23afSMatthew G. Knepley } 9399b5a892a1SMatthew G. Knepley 9400cc4c1da9SBarry Smith /*@ 9401bb7acecfSBarry Smith DMPolytopeMatchOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9402b5a892a1SMatthew G. Knepley 940320f4b53cSBarry Smith Not Collective 9404b5a892a1SMatthew G. Knepley 9405b5a892a1SMatthew G. Knepley Input Parameters: 9406bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9407b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9408b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9409b5a892a1SMatthew G. Knepley 9410b5a892a1SMatthew G. Knepley Output Parameters: 9411bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9412b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9413b5a892a1SMatthew G. Knepley 9414b5a892a1SMatthew G. Knepley Level: advanced 9415b5a892a1SMatthew G. Knepley 9416bb7acecfSBarry Smith Note: 9417bb7acecfSBarry Smith An arrangement is a face order combined with an orientation for each face 9418bb7acecfSBarry Smith 941985036b15SMatthew G. Knepley Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangements(ct)`/2 to `DMPolytopeTypeGetNumArrangements(ct)`/2 9420bb7acecfSBarry Smith that labels each arrangement (face ordering plus orientation for each face). 9421bb7acecfSBarry Smith 9422bb7acecfSBarry Smith See `DMPolytopeMatchVertexOrientation()` to find a new vertex orientation that takes the source vertex arrangement to the target vertex arrangement 9423bb7acecfSBarry Smith 94241cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetVertexOrientation()` 9425b5a892a1SMatthew G. Knepley @*/ 9426d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9427d71ae5a4SJacob Faibussowitsch { 9428b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 942985036b15SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangements(ct) / 2; 9430b5a892a1SMatthew G. Knepley PetscInt o, c; 9431b5a892a1SMatthew G. Knepley 9432b5a892a1SMatthew G. Knepley PetscFunctionBegin; 94339371c9d4SSatish Balay if (!nO) { 94349371c9d4SSatish Balay *ornt = 0; 94359371c9d4SSatish Balay *found = PETSC_TRUE; 94363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 94379371c9d4SSatish Balay } 9438b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 943985036b15SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangement(ct, o); 9440b5a892a1SMatthew G. Knepley 94419371c9d4SSatish Balay for (c = 0; c < cS; ++c) 94429371c9d4SSatish Balay if (sourceCone[arr[c * 2]] != targetCone[c]) break; 94439371c9d4SSatish Balay if (c == cS) { 94449371c9d4SSatish Balay *ornt = o; 94459371c9d4SSatish Balay break; 94469371c9d4SSatish Balay } 9447b5a892a1SMatthew G. Knepley } 9448b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 94493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9450b5a892a1SMatthew G. Knepley } 9451b5a892a1SMatthew G. Knepley 9452cc4c1da9SBarry Smith /*@ 9453bb7acecfSBarry Smith DMPolytopeGetOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9454b5a892a1SMatthew G. Knepley 945520f4b53cSBarry Smith Not Collective 9456b5a892a1SMatthew G. Knepley 9457b5a892a1SMatthew G. Knepley Input Parameters: 9458bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9459b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9460b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9461b5a892a1SMatthew G. Knepley 94622fe279fdSBarry Smith Output Parameter: 9463bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9464b5a892a1SMatthew G. Knepley 9465b5a892a1SMatthew G. Knepley Level: advanced 9466b5a892a1SMatthew G. Knepley 9467bb7acecfSBarry Smith Note: 9468bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchOrientation()` except it will generate an error if no suitable orientation can be found. 9469bb7acecfSBarry Smith 947073ff1848SBarry Smith Developer Note: 9471bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchOrientation()` and error if none is found 9472bb7acecfSBarry Smith 94731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchOrientation()`, `DMPolytopeGetVertexOrientation()`, `DMPolytopeMatchVertexOrientation()` 9474b5a892a1SMatthew G. Knepley @*/ 9475d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9476d71ae5a4SJacob Faibussowitsch { 9477b5a892a1SMatthew G. Knepley PetscBool found; 9478b5a892a1SMatthew G. Knepley 9479b5a892a1SMatthew G. Knepley PetscFunctionBegin; 94809566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found)); 94817a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 94823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9483b5a892a1SMatthew G. Knepley } 9484b5a892a1SMatthew G. Knepley 9485cc4c1da9SBarry Smith /*@ 9486bb7acecfSBarry Smith DMPolytopeMatchVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9487b5a892a1SMatthew G. Knepley 948820f4b53cSBarry Smith Not Collective 9489b5a892a1SMatthew G. Knepley 9490b5a892a1SMatthew G. Knepley Input Parameters: 9491bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9492b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 9493b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 9494b5a892a1SMatthew G. Knepley 9495b5a892a1SMatthew G. Knepley Output Parameters: 9496bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9497b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9498b5a892a1SMatthew G. Knepley 9499b5a892a1SMatthew G. Knepley Level: advanced 9500b5a892a1SMatthew G. Knepley 950173ff1848SBarry Smith Notes: 9502bb7acecfSBarry Smith An arrangement is a vertex order 9503bb7acecfSBarry Smith 950485036b15SMatthew G. Knepley Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangements(ct)`/2 to `DMPolytopeTypeGetNumArrangements(ct)`/2 9505bb7acecfSBarry Smith that labels each arrangement (vertex ordering). 9506bb7acecfSBarry Smith 9507bb7acecfSBarry Smith See `DMPolytopeMatchOrientation()` to find a new face orientation that takes the source face arrangement to the target face arrangement 9508bb7acecfSBarry Smith 950985036b15SMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchOrientation()`, `DMPolytopeTypeGetNumVertices()`, `DMPolytopeTypeGetVertexArrangement()` 9510b5a892a1SMatthew G. Knepley @*/ 9511d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 9512d71ae5a4SJacob Faibussowitsch { 9513b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 951485036b15SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangements(ct) / 2; 9515b5a892a1SMatthew G. Knepley PetscInt o, c; 9516b5a892a1SMatthew G. Knepley 9517b5a892a1SMatthew G. Knepley PetscFunctionBegin; 95189371c9d4SSatish Balay if (!nO) { 95199371c9d4SSatish Balay *ornt = 0; 95209371c9d4SSatish Balay *found = PETSC_TRUE; 95213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 95229371c9d4SSatish Balay } 9523b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 952485036b15SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangement(ct, o); 9525b5a892a1SMatthew G. Knepley 95269371c9d4SSatish Balay for (c = 0; c < cS; ++c) 95279371c9d4SSatish Balay if (sourceVert[arr[c]] != targetVert[c]) break; 95289371c9d4SSatish Balay if (c == cS) { 95299371c9d4SSatish Balay *ornt = o; 95309371c9d4SSatish Balay break; 95319371c9d4SSatish Balay } 9532b5a892a1SMatthew G. Knepley } 9533b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 95343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9535b5a892a1SMatthew G. Knepley } 9536b5a892a1SMatthew G. Knepley 9537cc4c1da9SBarry Smith /*@ 9538bb7acecfSBarry Smith DMPolytopeGetVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9539b5a892a1SMatthew G. Knepley 954020f4b53cSBarry Smith Not Collective 9541b5a892a1SMatthew G. Knepley 9542b5a892a1SMatthew G. Knepley Input Parameters: 9543bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9544b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 9545b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 9546b5a892a1SMatthew G. Knepley 95472fe279fdSBarry Smith Output Parameter: 9548bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9549b5a892a1SMatthew G. Knepley 9550b5a892a1SMatthew G. Knepley Level: advanced 9551b5a892a1SMatthew G. Knepley 9552bb7acecfSBarry Smith Note: 9553bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchVertexOrientation()` except it errors if not orientation is possible. 9554bb7acecfSBarry Smith 955573ff1848SBarry Smith Developer Note: 9556bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchVertexOrientation()` and error if none is found 9557bb7acecfSBarry Smith 95581cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetOrientation()` 9559b5a892a1SMatthew G. Knepley @*/ 9560d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9561d71ae5a4SJacob Faibussowitsch { 9562b5a892a1SMatthew G. Knepley PetscBool found; 9563b5a892a1SMatthew G. Knepley 9564b5a892a1SMatthew G. Knepley PetscFunctionBegin; 95659566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found)); 95667a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 95673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9568b5a892a1SMatthew G. Knepley } 9569012bc364SMatthew G. Knepley 9570cc4c1da9SBarry Smith /*@ 9571012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 9572012bc364SMatthew G. Knepley 957320f4b53cSBarry Smith Not Collective 9574012bc364SMatthew G. Knepley 9575012bc364SMatthew G. Knepley Input Parameters: 9576bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9577012bc364SMatthew G. Knepley - point - Coordinates of the point 9578012bc364SMatthew G. Knepley 95792fe279fdSBarry Smith Output Parameter: 9580012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 9581012bc364SMatthew G. Knepley 9582012bc364SMatthew G. Knepley Level: advanced 9583012bc364SMatthew G. Knepley 95841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMLocatePoints()` 9585012bc364SMatthew G. Knepley @*/ 9586d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 9587d71ae5a4SJacob Faibussowitsch { 9588012bc364SMatthew G. Knepley PetscReal sum = 0.0; 9589012bc364SMatthew G. Knepley PetscInt d; 9590012bc364SMatthew G. Knepley 9591012bc364SMatthew G. Knepley PetscFunctionBegin; 9592012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 9593012bc364SMatthew G. Knepley switch (ct) { 9594012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 9595012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 9596012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 95979371c9d4SSatish Balay if (point[d] < -1.0) { 95989371c9d4SSatish Balay *inside = PETSC_FALSE; 95999371c9d4SSatish Balay break; 96009371c9d4SSatish Balay } 9601012bc364SMatthew G. Knepley sum += point[d]; 9602012bc364SMatthew G. Knepley } 96039371c9d4SSatish Balay if (sum > PETSC_SMALL) { 96049371c9d4SSatish Balay *inside = PETSC_FALSE; 96059371c9d4SSatish Balay break; 96069371c9d4SSatish Balay } 9607012bc364SMatthew G. Knepley break; 9608012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 9609012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 9610012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 96119371c9d4SSatish Balay if (PetscAbsReal(point[d]) > 1. + PETSC_SMALL) { 96129371c9d4SSatish Balay *inside = PETSC_FALSE; 9613012bc364SMatthew G. Knepley break; 96149371c9d4SSatish Balay } 96159371c9d4SSatish Balay break; 9616d71ae5a4SJacob Faibussowitsch default: 9617d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 9618012bc364SMatthew G. Knepley } 96193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9620012bc364SMatthew G. Knepley } 9621adc21957SMatthew G. Knepley 9622adc21957SMatthew G. Knepley /*@ 9623adc21957SMatthew G. Knepley DMReorderSectionSetDefault - Set flag indicating whether the local section should be reordered by default 9624adc21957SMatthew G. Knepley 9625adc21957SMatthew G. Knepley Logically collective 9626adc21957SMatthew G. Knepley 9627adc21957SMatthew G. Knepley Input Parameters: 9628adc21957SMatthew G. Knepley + dm - The DM 9629adc21957SMatthew G. Knepley - reorder - Flag for reordering 9630adc21957SMatthew G. Knepley 9631adc21957SMatthew G. Knepley Level: intermediate 9632adc21957SMatthew G. Knepley 9633adc21957SMatthew G. Knepley .seealso: `DMReorderSectionGetDefault()` 9634adc21957SMatthew G. Knepley @*/ 9635adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionSetDefault(DM dm, DMReorderDefaultFlag reorder) 9636adc21957SMatthew G. Knepley { 9637adc21957SMatthew G. Knepley PetscFunctionBegin; 9638adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9639adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionSetDefault_C", (DM, DMReorderDefaultFlag), (dm, reorder)); 9640adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9641adc21957SMatthew G. Knepley } 9642adc21957SMatthew G. Knepley 9643adc21957SMatthew G. Knepley /*@ 9644adc21957SMatthew G. Knepley DMReorderSectionGetDefault - Get flag indicating whether the local section should be reordered by default 9645adc21957SMatthew G. Knepley 9646adc21957SMatthew G. Knepley Not collective 9647adc21957SMatthew G. Knepley 9648adc21957SMatthew G. Knepley Input Parameter: 9649adc21957SMatthew G. Knepley . dm - The DM 9650adc21957SMatthew G. Knepley 9651adc21957SMatthew G. Knepley Output Parameter: 9652adc21957SMatthew G. Knepley . reorder - Flag for reordering 9653adc21957SMatthew G. Knepley 9654adc21957SMatthew G. Knepley Level: intermediate 9655adc21957SMatthew G. Knepley 9656adc21957SMatthew G. Knepley .seealso: `DMReorderSetDefault()` 9657adc21957SMatthew G. Knepley @*/ 9658adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionGetDefault(DM dm, DMReorderDefaultFlag *reorder) 9659adc21957SMatthew G. Knepley { 9660adc21957SMatthew G. Knepley PetscFunctionBegin; 9661adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9662adc21957SMatthew G. Knepley PetscAssertPointer(reorder, 2); 9663adc21957SMatthew G. Knepley *reorder = DM_REORDER_DEFAULT_NOTSET; 9664adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionGetDefault_C", (DM, DMReorderDefaultFlag *), (dm, reorder)); 9665adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9666adc21957SMatthew G. Knepley } 9667adc21957SMatthew G. Knepley 9668cc4c1da9SBarry Smith /*@ 9669adc21957SMatthew G. Knepley DMReorderSectionSetType - Set the type of local section reordering 9670adc21957SMatthew G. Knepley 9671adc21957SMatthew G. Knepley Logically collective 9672adc21957SMatthew G. Knepley 9673adc21957SMatthew G. Knepley Input Parameters: 9674adc21957SMatthew G. Knepley + dm - The DM 9675adc21957SMatthew G. Knepley - reorder - The reordering method 9676adc21957SMatthew G. Knepley 9677adc21957SMatthew G. Knepley Level: intermediate 9678adc21957SMatthew G. Knepley 9679adc21957SMatthew G. Knepley .seealso: `DMReorderSectionGetType()`, `DMReorderSectionSetDefault()` 9680adc21957SMatthew G. Knepley @*/ 9681adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionSetType(DM dm, MatOrderingType reorder) 9682adc21957SMatthew G. Knepley { 9683adc21957SMatthew G. Knepley PetscFunctionBegin; 9684adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9685adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionSetType_C", (DM, MatOrderingType), (dm, reorder)); 9686adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9687adc21957SMatthew G. Knepley } 9688adc21957SMatthew G. Knepley 9689cc4c1da9SBarry Smith /*@ 9690adc21957SMatthew G. Knepley DMReorderSectionGetType - Get the reordering type for the local section 9691adc21957SMatthew G. Knepley 9692adc21957SMatthew G. Knepley Not collective 9693adc21957SMatthew G. Knepley 9694adc21957SMatthew G. Knepley Input Parameter: 9695adc21957SMatthew G. Knepley . dm - The DM 9696adc21957SMatthew G. Knepley 9697adc21957SMatthew G. Knepley Output Parameter: 9698adc21957SMatthew G. Knepley . reorder - The reordering method 9699adc21957SMatthew G. Knepley 9700adc21957SMatthew G. Knepley Level: intermediate 9701adc21957SMatthew G. Knepley 9702adc21957SMatthew G. Knepley .seealso: `DMReorderSetDefault()`, `DMReorderSectionGetDefault()` 9703adc21957SMatthew G. Knepley @*/ 9704adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionGetType(DM dm, MatOrderingType *reorder) 9705adc21957SMatthew G. Knepley { 9706adc21957SMatthew G. Knepley PetscFunctionBegin; 9707adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9708adc21957SMatthew G. Knepley PetscAssertPointer(reorder, 2); 9709adc21957SMatthew G. Knepley *reorder = NULL; 9710adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionGetType_C", (DM, MatOrderingType *), (dm, reorder)); 9711adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9712adc21957SMatthew G. Knepley } 9713