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 55673ff1848SBarry Smith Fortran Note: 55720f4b53cSBarry Smith Pass in a string 'prefix' of 55820f4b53cSBarry Smith sufficient length to hold the prefix. 55920f4b53cSBarry Smith 5601cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetOptionsPrefix()`, `DMAppendOptionsPrefix()`, `DMSetFromOptions()` 56131697293SDave May @*/ 562d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOptionsPrefix(DM dm, const char *prefix[]) 563d71ae5a4SJacob Faibussowitsch { 56431697293SDave May PetscFunctionBegin; 56531697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5669566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, prefix)); 5673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56831697293SDave May } 56931697293SDave May 57062e5d2d2SJDBetteridge static PetscErrorCode DMCountNonCyclicReferences_Internal(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 571d71ae5a4SJacob Faibussowitsch { 5726eb26441SStefano Zampini PetscInt refct = ((PetscObject)dm)->refct; 57388bdff64SToby Isaac 57488bdff64SToby Isaac PetscFunctionBegin; 575aab5bcd8SJed Brown *ncrefct = 0; 57688bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 57788bdff64SToby Isaac refct--; 57888bdff64SToby Isaac if (recurseCoarse) { 57988bdff64SToby Isaac PetscInt coarseCount; 58088bdff64SToby Isaac 58162e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE, &coarseCount)); 58288bdff64SToby Isaac refct += coarseCount; 58388bdff64SToby Isaac } 58488bdff64SToby Isaac } 58588bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 58688bdff64SToby Isaac refct--; 58788bdff64SToby Isaac if (recurseFine) { 58888bdff64SToby Isaac PetscInt fineCount; 58988bdff64SToby Isaac 59062e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->fineMesh, PETSC_FALSE, PETSC_TRUE, &fineCount)); 59188bdff64SToby Isaac refct += fineCount; 59288bdff64SToby Isaac } 59388bdff64SToby Isaac } 59488bdff64SToby Isaac *ncrefct = refct; 5953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 59688bdff64SToby Isaac } 59788bdff64SToby Isaac 59862e5d2d2SJDBetteridge /* Generic wrapper for DMCountNonCyclicReferences_Internal() */ 59962e5d2d2SJDBetteridge PetscErrorCode DMCountNonCyclicReferences(PetscObject dm, PetscInt *ncrefct) 60062e5d2d2SJDBetteridge { 60162e5d2d2SJDBetteridge PetscFunctionBegin; 60262e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal((DM)dm, PETSC_TRUE, PETSC_TRUE, ncrefct)); 6033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 60462e5d2d2SJDBetteridge } 60562e5d2d2SJDBetteridge 606d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 607d71ae5a4SJacob Faibussowitsch { 6085d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 609354557abSToby Isaac 610354557abSToby Isaac PetscFunctionBegin; 611354557abSToby Isaac /* destroy the labels */ 612354557abSToby Isaac while (next) { 613354557abSToby Isaac DMLabelLink tmp = next->next; 614354557abSToby Isaac 6155d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 616ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 6179566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 6189566063dSJacob Faibussowitsch PetscCall(PetscFree(next)); 619354557abSToby Isaac next = tmp; 620354557abSToby Isaac } 6215d80c0bfSVaclav Hapla dm->labels = NULL; 6223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 623354557abSToby Isaac } 624354557abSToby Isaac 62566976f2fSJacob Faibussowitsch static PetscErrorCode DMDestroyCoordinates_Private(DMCoordinates *c) 626d71ae5a4SJacob Faibussowitsch { 6276858538eSMatthew G. Knepley PetscFunctionBegin; 6286858538eSMatthew G. Knepley c->dim = PETSC_DEFAULT; 6296858538eSMatthew G. Knepley PetscCall(DMDestroy(&c->dm)); 6306858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->x)); 6316858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->xl)); 6326858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&c->field)); 6333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6346858538eSMatthew G. Knepley } 6356858538eSMatthew G. Knepley 6360764c050SBarry Smith /*@ 637bb7acecfSBarry Smith DMDestroy - Destroys a `DM`. 63847c6ae99SBarry Smith 63920f4b53cSBarry Smith Collective 64047c6ae99SBarry Smith 64147c6ae99SBarry Smith Input Parameter: 642bb7acecfSBarry Smith . dm - the `DM` object to destroy 64347c6ae99SBarry Smith 64447c6ae99SBarry Smith Level: developer 64547c6ae99SBarry Smith 6461cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMType`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 64747c6ae99SBarry Smith @*/ 648d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroy(DM *dm) 649d71ae5a4SJacob Faibussowitsch { 6506eb26441SStefano Zampini PetscInt cnt; 65147c6ae99SBarry Smith 65247c6ae99SBarry Smith PetscFunctionBegin; 6533ba16761SJacob Faibussowitsch if (!*dm) PetscFunctionReturn(PETSC_SUCCESS); 654f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*dm, DM_CLASSID, 1); 65587e657c6SBarry Smith 65688bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 65762e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(*dm, PETSC_TRUE, PETSC_TRUE, &cnt)); 658f4f49eeaSPierre Jolivet --((PetscObject)*dm)->refct; 6599371c9d4SSatish Balay if (--cnt > 0) { 6609371c9d4SSatish Balay *dm = NULL; 6613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6629371c9d4SSatish Balay } 663f4f49eeaSPierre Jolivet if (((PetscObject)*dm)->refct < 0) PetscFunctionReturn(PETSC_SUCCESS); 664f4f49eeaSPierre Jolivet ((PetscObject)*dm)->refct = 0; 6656eb26441SStefano Zampini 6669566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(*dm)); 6679566063dSJacob Faibussowitsch PetscCall(DMClearLocalVectors(*dm)); 668974ca4ecSStefano Zampini PetscCall(DMClearNamedGlobalVectors(*dm)); 669974ca4ecSStefano Zampini PetscCall(DMClearNamedLocalVectors(*dm)); 6702348bcf4SPeter Brune 671b17ce1afSJed Brown /* Destroy the list of hooks */ 672c833c3b5SJed Brown { 673c833c3b5SJed Brown DMCoarsenHookLink link, next; 674b17ce1afSJed Brown for (link = (*dm)->coarsenhook; link; link = next) { 675b17ce1afSJed Brown next = link->next; 6769566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 677b17ce1afSJed Brown } 6780298fd71SBarry Smith (*dm)->coarsenhook = NULL; 679c833c3b5SJed Brown } 680c833c3b5SJed Brown { 681c833c3b5SJed Brown DMRefineHookLink link, next; 682c833c3b5SJed Brown for (link = (*dm)->refinehook; link; link = next) { 683c833c3b5SJed Brown next = link->next; 6849566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 685c833c3b5SJed Brown } 6860298fd71SBarry Smith (*dm)->refinehook = NULL; 687c833c3b5SJed Brown } 688be081cd6SPeter Brune { 689be081cd6SPeter Brune DMSubDomainHookLink link, next; 690be081cd6SPeter Brune for (link = (*dm)->subdomainhook; link; link = next) { 691be081cd6SPeter Brune next = link->next; 6929566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 693be081cd6SPeter Brune } 6940298fd71SBarry Smith (*dm)->subdomainhook = NULL; 695be081cd6SPeter Brune } 696baf369e7SPeter Brune { 697baf369e7SPeter Brune DMGlobalToLocalHookLink link, next; 698baf369e7SPeter Brune for (link = (*dm)->gtolhook; link; link = next) { 699baf369e7SPeter Brune next = link->next; 7009566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 701baf369e7SPeter Brune } 7020298fd71SBarry Smith (*dm)->gtolhook = NULL; 703baf369e7SPeter Brune } 704d4d07f1eSToby Isaac { 705d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, next; 706d4d07f1eSToby Isaac for (link = (*dm)->ltoghook; link; link = next) { 707d4d07f1eSToby Isaac next = link->next; 7089566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 709d4d07f1eSToby Isaac } 710d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 711d4d07f1eSToby Isaac } 712aa1993deSMatthew G Knepley /* Destroy the work arrays */ 713aa1993deSMatthew G Knepley { 714aa1993deSMatthew G Knepley DMWorkLink link, next; 715835f2295SStefano Zampini PetscCheck(!(*dm)->workout, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Work array still checked out %p %p", (void *)(*dm)->workout, (*dm)->workout->mem); 716aa1993deSMatthew G Knepley for (link = (*dm)->workin; link; link = next) { 717aa1993deSMatthew G Knepley next = link->next; 7189566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 7199566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 720aa1993deSMatthew G Knepley } 7210298fd71SBarry Smith (*dm)->workin = NULL; 722aa1993deSMatthew G Knepley } 723c58f1c22SToby Isaac /* destroy the labels */ 7249566063dSJacob Faibussowitsch PetscCall(DMDestroyLabelLinkList_Internal(*dm)); 725f4cdcedcSVaclav Hapla /* destroy the fields */ 7269566063dSJacob Faibussowitsch PetscCall(DMClearFields(*dm)); 727f4cdcedcSVaclav Hapla /* destroy the boundaries */ 728e6f8dbb6SToby Isaac { 729e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 730e6f8dbb6SToby Isaac while (next) { 731e6f8dbb6SToby Isaac DMBoundary b = next; 732e6f8dbb6SToby Isaac 733e6f8dbb6SToby Isaac next = b->next; 7349566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 735e6f8dbb6SToby Isaac } 736e6f8dbb6SToby Isaac } 737b17ce1afSJed Brown 7389566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmksp)); 7399566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmsnes)); 7409566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmts)); 74152536dc3SBarry Smith 74248a46eb9SPierre Jolivet if ((*dm)->ctx && (*dm)->ctxdestroy) PetscCall((*(*dm)->ctxdestroy)(&(*dm)->ctx)); 7439566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&(*dm)->fd)); 7449566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap)); 7459566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->vectype)); 7469566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->mattype)); 74788ed4aceSMatthew G Knepley 7489566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->localSection)); 7499566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->globalSection)); 750adc21957SMatthew G. Knepley PetscCall(PetscFree((*dm)->reorderSectionType)); 7519566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&(*dm)->map)); 7529566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->defaultConstraint.section)); 7539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&(*dm)->defaultConstraint.mat)); 7549566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sf)); 7559566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sectionSF)); 75648a46eb9SPierre Jolivet if ((*dm)->sfNatural) PetscCall(PetscSFDestroy(&(*dm)->sfNatural)); 7579566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)(*dm)->sfMigration)); 758e4d5475eSStefano Zampini PetscCall(DMClearAuxiliaryVec(*dm)); 7599566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&(*dm)->auxData)); 76048a46eb9SPierre Jolivet if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) PetscCall(DMSetFineDM((*dm)->coarseMesh, NULL)); 7616eb26441SStefano Zampini 7629566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->coarseMesh)); 76348a46eb9SPierre Jolivet if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) PetscCall(DMSetCoarseDM((*dm)->fineMesh, NULL)); 7649566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->fineMesh)); 7654fb89dddSMatthew G. Knepley PetscCall(PetscFree((*dm)->Lstart)); 7669566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->L)); 7679566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->maxCell)); 7686858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[0])); 7696858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[1])); 7709566063dSJacob Faibussowitsch if ((*dm)->transformDestroy) PetscCall((*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx)); 7719566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->transformDM)); 7729566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*dm)->transform)); 773ddedc8f6SJames Wright for (PetscInt i = 0; i < (*dm)->periodic.num_affines; i++) { 774ddedc8f6SJames Wright PetscCall(VecScatterDestroy(&(*dm)->periodic.affine_to_local[i])); 775ddedc8f6SJames Wright PetscCall(VecDestroy(&(*dm)->periodic.affine[i])); 776ddedc8f6SJames Wright } 777ddedc8f6SJames Wright if ((*dm)->periodic.num_affines > 0) PetscCall(PetscFree2((*dm)->periodic.affine_to_local, (*dm)->periodic.affine)); 7786636e97aSMatthew G Knepley 7799566063dSJacob Faibussowitsch PetscCall(DMClearDS(*dm)); 7809566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->dmBC)); 781e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 7829566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*dm)); 783732e2eb9SMatthew G Knepley 784213acdd3SPierre Jolivet PetscTryTypeMethod(*dm, destroy); 7859566063dSJacob Faibussowitsch PetscCall(DMMonitorCancel(*dm)); 786d2b2dc1eSMatthew G. Knepley PetscCall(DMCeedDestroy(&(*dm)->dmceed)); 787f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 7889566063dSJacob Faibussowitsch PetscCallCEED(CeedElemRestrictionDestroy(&(*dm)->ceedERestrict)); 7899566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*dm)->ceed)); 790f918ec44SMatthew G. Knepley #endif 791435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 7929566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(dm)); 7933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 79447c6ae99SBarry Smith } 79547c6ae99SBarry Smith 796d7bf68aeSBarry Smith /*@ 797bb7acecfSBarry Smith DMSetUp - sets up the data structures inside a `DM` object 798d7bf68aeSBarry Smith 79920f4b53cSBarry Smith Collective 800d7bf68aeSBarry Smith 801d7bf68aeSBarry Smith Input Parameter: 802bb7acecfSBarry Smith . dm - the `DM` object to setup 803d7bf68aeSBarry Smith 804bb7acecfSBarry Smith Level: intermediate 805d7bf68aeSBarry Smith 806bb7acecfSBarry Smith Note: 807bb7acecfSBarry Smith This is usually called after various parameter setting operations and `DMSetFromOptions()` are called on the `DM` 808bb7acecfSBarry Smith 8091cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 810d7bf68aeSBarry Smith @*/ 811d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUp(DM dm) 812d71ae5a4SJacob Faibussowitsch { 813d7bf68aeSBarry Smith PetscFunctionBegin; 814171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8153ba16761SJacob Faibussowitsch if (dm->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 816dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setup); 8178387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 8183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 819d7bf68aeSBarry Smith } 820d7bf68aeSBarry Smith 821d7bf68aeSBarry Smith /*@ 822bb7acecfSBarry Smith DMSetFromOptions - sets parameters in a `DM` from the options database 823d7bf68aeSBarry Smith 82420f4b53cSBarry Smith Collective 825d7bf68aeSBarry Smith 826d7bf68aeSBarry Smith Input Parameter: 827bb7acecfSBarry Smith . dm - the `DM` object to set options for 828d7bf68aeSBarry Smith 82920f4b53cSBarry Smith Options Database Keys: 830bb7acecfSBarry Smith + -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 831bb7acecfSBarry Smith . -dm_vec_type <type> - type of vector to create inside `DM` 832bb7acecfSBarry Smith . -dm_mat_type <type> - type of matrix to create inside `DM` 833a4ea9b21SRichard Tran Mills . -dm_is_coloring_type - <global or local> 83420f4b53cSBarry 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` 83522d6dc08SStefano Zampini . -dm_plex_option_phases <ph0_, ph1_, ...> - List of prefixes for option processing phases 83620f4b53cSBarry Smith . -dm_plex_filename <str> - File containing a mesh 8379318fe57SMatthew G. Knepley . -dm_plex_boundary_filename <str> - File containing a mesh boundary 838cd7e8a5eSksagiyam . -dm_plex_name <str> - Name of the mesh in the file 8395dca41c3SJed Brown . -dm_plex_shape <shape> - The domain shape, such as `BOX`, `SPHERE`, etc. 8409318fe57SMatthew G. Knepley . -dm_plex_cell <ct> - Cell shape 8419318fe57SMatthew G. Knepley . -dm_plex_reference_cell_domain <bool> - Use a reference cell domain 8429318fe57SMatthew G. Knepley . -dm_plex_dim <dim> - Set the topological dimension 843bb7acecfSBarry Smith . -dm_plex_simplex <bool> - `PETSC_TRUE` for simplex elements, `PETSC_FALSE` for tensor elements 844bb7acecfSBarry Smith . -dm_plex_interpolate <bool> - `PETSC_TRUE` turns on topological interpolation (creating edges and faces) 845b9da1bb3SMatthew G. Knepley . -dm_plex_orient <bool> - `PETSC_TRUE` turns on topological orientation (flipping edges and faces) 8469318fe57SMatthew G. Knepley . -dm_plex_scale <sc> - Scale factor for mesh coordinates 847be664eb1SMatthew G. Knepley . -dm_coord_remap <bool> - Map coordinates using a function 848ac9d17c7SMatthew G. Knepley . -dm_plex_coordinate_dim <dim> - Change the coordinate dimension of a mesh (usually given with cdm_ prefix) 849be664eb1SMatthew G. Knepley . -dm_coord_map <mapname> - Select a builtin coordinate map 850be664eb1SMatthew G. Knepley . -dm_coord_map_params <p0,p1,p2,...> - Set coordinate mapping parameters 8519318fe57SMatthew G. Knepley . -dm_plex_box_faces <m,n,p> - Number of faces along each dimension 8529318fe57SMatthew G. Knepley . -dm_plex_box_lower <x,y,z> - Specify lower-left-bottom coordinates for the box 8539318fe57SMatthew G. Knepley . -dm_plex_box_upper <x,y,z> - Specify upper-right-top coordinates for the box 854bb7acecfSBarry Smith . -dm_plex_box_bd <bx,by,bz> - Specify the `DMBoundaryType` for each direction 8559318fe57SMatthew G. Knepley . -dm_plex_sphere_radius <r> - The sphere radius 8569318fe57SMatthew G. Knepley . -dm_plex_ball_radius <r> - Radius of the ball 8579318fe57SMatthew G. Knepley . -dm_plex_cylinder_bd <bz> - Boundary type in the z direction 8589318fe57SMatthew G. Knepley . -dm_plex_cylinder_num_wedges <n> - Number of wedges around the cylinder 859bdf63967SMatthew G. Knepley . -dm_plex_reorder <order> - Reorder the mesh using the specified algorithm 8609318fe57SMatthew G. Knepley . -dm_refine_pre <n> - The number of refinements before distribution 8619318fe57SMatthew G. Knepley . -dm_refine_uniform_pre <bool> - Flag for uniform refinement before distribution 8629318fe57SMatthew G. Knepley . -dm_refine_volume_limit_pre <v> - The maximum cell volume after refinement before distribution 8639318fe57SMatthew G. Knepley . -dm_refine <n> - The number of refinements after distribution 864bdf63967SMatthew G. Knepley . -dm_extrude <l> - Activate extrusion and specify the number of layers to extrude 865d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers 866d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding 867d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface 868d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction 869d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer 870909dfd52SMatthew G. Knepley . -dm_plex_create_fv_ghost_cells - Flag to create finite volume ghost cells on the boundary 871909dfd52SMatthew G. Knepley . -dm_plex_fv_ghost_cells_label <name> - Label name for ghost cells boundary 8729318fe57SMatthew G. Knepley . -dm_distribute <bool> - Flag to redistribute a mesh among processes 8739318fe57SMatthew G. Knepley . -dm_distribute_overlap <n> - The size of the overlap halo 8749318fe57SMatthew G. Knepley . -dm_plex_adj_cone <bool> - Set adjacency direction 87520f4b53cSBarry Smith . -dm_plex_adj_closure <bool> - Set adjacency size 876d2b2dc1eSMatthew G. Knepley . -dm_plex_use_ceed <bool> - Use LibCEED as the FEM backend 87720f4b53cSBarry Smith . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - `DMPlexCheckSymmetry()` 878bb7acecfSBarry Smith . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - `DMPlexCheckSkeleton()` 879bb7acecfSBarry 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()` 880bb7acecfSBarry Smith . -dm_plex_check_geometry - Check that cells have positive volume - `DMPlexCheckGeometry()` 881bb7acecfSBarry Smith . -dm_plex_check_pointsf - Check some necessary conditions for `PointSF` - `DMPlexCheckPointSF()` 882bb7acecfSBarry Smith . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - `DMPlexCheckInterfaceCones()` 883384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 884d7bf68aeSBarry Smith 88595eb5ee5SVaclav Hapla Level: intermediate 88695eb5ee5SVaclav Hapla 8878e704042SBarry Smith Note: 8888e704042SBarry Smith For some `DMType` such as `DMDA` this cannot be called after `DMSetUp()` has been called. 8898e704042SBarry Smith 8901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 891bb7acecfSBarry Smith `DMPlexCheckSymmetry()`, `DMPlexCheckSkeleton()`, `DMPlexCheckFaces()`, `DMPlexCheckGeometry()`, `DMPlexCheckPointSF()`, `DMPlexCheckInterfaceCones()`, 8928e704042SBarry Smith `DMSetOptionsPrefix()`, `DMType`, `DMPLEX`, `DMDA`, `DMSetUp()` 893d7bf68aeSBarry Smith @*/ 894d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFromOptions(DM dm) 895d71ae5a4SJacob Faibussowitsch { 8967781c08eSBarry Smith char typeName[256]; 897ca266f36SBarry Smith PetscBool flg; 898d7bf68aeSBarry Smith 899d7bf68aeSBarry Smith PetscFunctionBegin; 900171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90149be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 9029566063dSJacob Faibussowitsch if (dm->sf) PetscCall(PetscSFSetFromOptions(dm->sf)); 9039566063dSJacob Faibussowitsch if (dm->sectionSF) PetscCall(PetscSFSetFromOptions(dm->sectionSF)); 904dd4c3f67SMatthew G. Knepley if (dm->coordinates[0].dm) PetscCall(DMSetFromOptions(dm->coordinates[0].dm)); 905d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)dm); 9069566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-dm_preallocate_only", "only preallocate matrix, but do not set column indices", "DMSetMatrixPreallocateOnly", dm->prealloc_only, &dm->prealloc_only, NULL)); 9079566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_vec_type", "Vector type used for created vectors", "DMSetVecType", VecList, dm->vectype, typeName, 256, &flg)); 9081baa6e33SBarry Smith if (flg) PetscCall(DMSetVecType(dm, typeName)); 9099566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_mat_type", "Matrix type used for created matrices", "DMSetMatType", MatList, dm->mattype ? dm->mattype : typeName, typeName, sizeof(typeName), &flg)); 9101baa6e33SBarry Smith if (flg) PetscCall(DMSetMatType(dm, typeName)); 911863027abSJed Brown PetscCall(PetscOptionsEnum("-dm_blocking_type", "Topological point or field node blocking", "DMSetBlockingType", DMBlockingTypes, (PetscEnum)dm->blocking_type, (PetscEnum *)&dm->blocking_type, NULL)); 9129566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-dm_is_coloring_type", "Global or local coloring of Jacobian", "DMSetISColoringType", ISColoringTypes, (PetscEnum)dm->coloringtype, (PetscEnum *)&dm->coloringtype, NULL)); 9139566063dSJacob 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)); 914eb9d3e4dSMatthew G. Knepley PetscCall(PetscOptionsBool("-dm_ignore_perm_output", "Ignore the local section permutation on output", "DMGetOutputDM", dm->ignorePermOutput, &dm->ignorePermOutput, NULL)); 915dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setfromoptions, PetscOptionsObject); 916f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 917dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)dm, PetscOptionsObject)); 918d0609cedSBarry Smith PetscOptionsEnd(); 9193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 920d7bf68aeSBarry Smith } 921d7bf68aeSBarry Smith 922ffeef943SBarry Smith /*@ 923bb7acecfSBarry Smith DMViewFromOptions - View a `DM` in a particular way based on a request in the options database 924fe2efc57SMark 92520f4b53cSBarry Smith Collective 926fe2efc57SMark 927fe2efc57SMark Input Parameters: 928bb7acecfSBarry Smith + dm - the `DM` object 92920f4b53cSBarry Smith . obj - optional object that provides the prefix for the options database (if `NULL` then the prefix in obj is used) 93060225df5SJacob Faibussowitsch - name - option string that is used to activate viewing 931fe2efc57SMark 932fe2efc57SMark Level: intermediate 933bb7acecfSBarry Smith 934bb7acecfSBarry Smith Note: 935bb7acecfSBarry Smith See `PetscObjectViewFromOptions()` for a list of values that can be provided in the options database to determine how the `DM` is viewed 936bb7acecfSBarry Smith 93760225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `PetscObjectViewFromOptions()`, `DMCreate()` 938fe2efc57SMark @*/ 939d71ae5a4SJacob Faibussowitsch PetscErrorCode DMViewFromOptions(DM dm, PetscObject obj, const char name[]) 940d71ae5a4SJacob Faibussowitsch { 941fe2efc57SMark PetscFunctionBegin; 942fe2efc57SMark PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9439566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)dm, obj, name)); 9443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 945fe2efc57SMark } 946fe2efc57SMark 947ffeef943SBarry Smith /*@ 948bb7acecfSBarry 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 949bb7acecfSBarry Smith save the `DM` in a binary file to be loaded later or create a visualization of the `DM` 95047c6ae99SBarry Smith 95120f4b53cSBarry Smith Collective 95247c6ae99SBarry Smith 953d8d19677SJose E. Roman Input Parameters: 954bb7acecfSBarry Smith + dm - the `DM` object to view 95547c6ae99SBarry Smith - v - the viewer 95647c6ae99SBarry Smith 957*c8a418c4SMatthew G. Knepley Options Database Keys: 958*c8a418c4SMatthew G. Knepley + -view_pyvista_warp <f> - Warps the mesh by the active scalar with factor f 959*c8a418c4SMatthew G. Knepley - -view_pyvista_clip <xl,xu,yl,yu,zl,zu> - Defines the clipping box 960*c8a418c4SMatthew G. Knepley 96120f4b53cSBarry Smith Level: beginner 96220f4b53cSBarry Smith 96349c89c76SBlaise Bourdin Notes: 96449c89c76SBlaise Bourdin 96549c89c76SBlaise Bourdin `PetscViewer` = `PETSCVIEWERHDF5` i.e. HDF5 format can be used with `PETSC_VIEWER_HDF5_PETSC` as the `PetscViewerFormat` to save multiple `DMPLEX` 966bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 967bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 968cd7e8a5eSksagiyam 96949c89c76SBlaise Bourdin `PetscViewer` = `PETSCVIEWEREXODUSII` i.e. ExodusII format assumes that element blocks (mapped to "Cell sets" labels) 97049c89c76SBlaise Bourdin consists of sequentially numbered cells. 97149c89c76SBlaise Bourdin 97249c89c76SBlaise Bourdin If `dm` has been distributed, only the part of the `DM` on MPI rank 0 (including "ghost" cells and vertices) will be written. 97349c89c76SBlaise Bourdin 974*c8a418c4SMatthew G. Knepley Only TRI, TET, QUAD, and HEX cells are supported in ExodusII. 97549c89c76SBlaise Bourdin 97649c89c76SBlaise 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. 97749c89c76SBlaise Bourdin The order of the mesh shall be set using `PetscViewerExodusIISetOrder()` 97849c89c76SBlaise Bourdin 979d7c1f440SPierre Jolivet Variable names can be set and queried using `PetscViewerExodusII[Set/Get][Nodal/Zonal]VariableNames[s]`. 98049c89c76SBlaise Bourdin 9811cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewer`, `PetscViewerFormat`, `PetscViewerSetFormat()`, `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMLoad()`, `PetscObjectSetName()` 98247c6ae99SBarry Smith @*/ 983d71ae5a4SJacob Faibussowitsch PetscErrorCode DMView(DM dm, PetscViewer v) 984d71ae5a4SJacob Faibussowitsch { 98532c0f0efSBarry Smith PetscBool isbinary; 98676a8abe0SBarry Smith PetscMPIInt size; 98776a8abe0SBarry Smith PetscViewerFormat format; 98847c6ae99SBarry Smith 98947c6ae99SBarry Smith PetscFunctionBegin; 990171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 99148a46eb9SPierre Jolivet if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm), &v)); 992b1b135c8SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 99374903a4fSStefano Zampini /* Ideally, we would like to have this test on. 99474903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 99574903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 99674903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 99774903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 99874903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 99974903a4fSStefano Zampini in an error here */ 100074903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 10019566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckWritable(v)); 1002b1b135c8SBarry Smith 100342d0c57aSJames Wright PetscCall(PetscLogEventBegin(DM_View, v, 0, 0, 0)); 10049566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(v, &format)); 10059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 10063ba16761SJacob Faibussowitsch if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS); 10079566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)dm, v)); 10089566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERBINARY, &isbinary)); 100932c0f0efSBarry Smith if (isbinary) { 101055849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 101132c0f0efSBarry Smith char type[256]; 101232c0f0efSBarry Smith 10139566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, &classid, 1, PETSC_INT)); 1014c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(type, ((PetscObject)dm)->type_name, sizeof(type))); 10159566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, type, 256, PETSC_CHAR)); 101632c0f0efSBarry Smith } 1017dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, view, v); 101842d0c57aSJames Wright PetscCall(PetscLogEventEnd(DM_View, v, 0, 0, 0)); 10193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 102047c6ae99SBarry Smith } 102147c6ae99SBarry Smith 102247c6ae99SBarry Smith /*@ 1023bb7acecfSBarry 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, 1024bb7acecfSBarry Smith that is it has no ghost locations. 102547c6ae99SBarry Smith 102620f4b53cSBarry Smith Collective 102747c6ae99SBarry Smith 102847c6ae99SBarry Smith Input Parameter: 1029bb7acecfSBarry Smith . dm - the `DM` object 103047c6ae99SBarry Smith 103147c6ae99SBarry Smith Output Parameter: 103247c6ae99SBarry Smith . vec - the global vector 103347c6ae99SBarry Smith 1034073dac72SJed Brown Level: beginner 103547c6ae99SBarry Smith 10361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1037bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 103847c6ae99SBarry Smith @*/ 1039d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector(DM dm, Vec *vec) 1040d71ae5a4SJacob Faibussowitsch { 104147c6ae99SBarry Smith PetscFunctionBegin; 1042171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10434f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1044dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createglobalvector, vec); 104576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1046c6b011d8SStefano Zampini DM vdm; 1047c6b011d8SStefano Zampini 10489566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10497a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1050c6b011d8SStefano Zampini } 10513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 105247c6ae99SBarry Smith } 105347c6ae99SBarry Smith 105447c6ae99SBarry Smith /*@ 1055bb7acecfSBarry Smith DMCreateLocalVector - Creates a local vector from a `DM` object. 105647c6ae99SBarry Smith 105747c6ae99SBarry Smith Not Collective 105847c6ae99SBarry Smith 105947c6ae99SBarry Smith Input Parameter: 1060bb7acecfSBarry Smith . dm - the `DM` object 106147c6ae99SBarry Smith 106247c6ae99SBarry Smith Output Parameter: 106347c6ae99SBarry Smith . vec - the local vector 106447c6ae99SBarry Smith 1065073dac72SJed Brown Level: beginner 106647c6ae99SBarry Smith 106720f4b53cSBarry Smith Note: 1068bb7acecfSBarry 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. 1069bb7acecfSBarry Smith 10701cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateGlobalVector()`, `DMGetLocalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 1071bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 107247c6ae99SBarry Smith @*/ 1073d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector(DM dm, Vec *vec) 1074d71ae5a4SJacob Faibussowitsch { 107547c6ae99SBarry Smith PetscFunctionBegin; 1076171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10774f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1078dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalvector, vec); 107976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1080c6b011d8SStefano Zampini DM vdm; 1081c6b011d8SStefano Zampini 10829566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10837a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_LIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1084c6b011d8SStefano Zampini } 10853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 108647c6ae99SBarry Smith } 108747c6ae99SBarry Smith 10881411c6eeSJed Brown /*@ 1089bb7acecfSBarry Smith DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a `DM`. 10901411c6eeSJed Brown 109120f4b53cSBarry Smith Collective 10921411c6eeSJed Brown 10931411c6eeSJed Brown Input Parameter: 1094bb7acecfSBarry Smith . dm - the `DM` that provides the mapping 10951411c6eeSJed Brown 10961411c6eeSJed Brown Output Parameter: 10971411c6eeSJed Brown . ltog - the mapping 10981411c6eeSJed Brown 1099bb7acecfSBarry Smith Level: advanced 11001411c6eeSJed Brown 11011411c6eeSJed Brown Notes: 1102bb7acecfSBarry Smith The global to local mapping allows one to set values into the global vector or matrix using `VecSetValuesLocal()` and `MatSetValuesLocal()` 11031411c6eeSJed Brown 1104bb7acecfSBarry Smith Vectors obtained with `DMCreateGlobalVector()` and matrices obtained with `DMCreateMatrix()` already contain the global mapping so you do 1105bb7acecfSBarry Smith need to use this function with those objects. 1106bb7acecfSBarry Smith 1107bb7acecfSBarry Smith This mapping can then be used by `VecSetLocalToGlobalMapping()` or `MatSetLocalToGlobalMapping()`. 1108bb7acecfSBarry Smith 110960225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `VecSetLocalToGlobalMapping()`, `MatSetLocalToGlobalMapping()`, 1110bb7acecfSBarry Smith `DMCreateMatrix()` 11111411c6eeSJed Brown @*/ 1112d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalToGlobalMapping(DM dm, ISLocalToGlobalMapping *ltog) 1113d71ae5a4SJacob Faibussowitsch { 11140be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 11151411c6eeSJed Brown 11161411c6eeSJed Brown PetscFunctionBegin; 11171411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11184f572ea9SToby Isaac PetscAssertPointer(ltog, 2); 11191411c6eeSJed Brown if (!dm->ltogmap) { 112037d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 112137d0c07bSMatthew G Knepley 11229566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 112337d0c07bSMatthew G Knepley if (section) { 1124a974ec88SMatthew G. Knepley const PetscInt *cdofs; 112537d0c07bSMatthew G Knepley PetscInt *ltog; 1126ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 112737d0c07bSMatthew G Knepley 11289566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 11299566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 11309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(section, &n)); 11319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, <og)); /* We want the local+overlap size */ 113237d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1133e6befd46SJed Brown PetscInt bdof, cdof, dof, off, c, cind; 113437d0c07bSMatthew G Knepley 113537d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 11369566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(section, p, &dof)); 11379566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(section, p, &cdof)); 11389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(section, p, &cdofs)); 11399566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &off)); 11401a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 11411a7dc684SMatthew G. Knepley bdof = cdof && (dof - cdof) ? 1 : dof; 1142ad540459SPierre Jolivet if (dof) bs = bs < 0 ? bdof : PetscGCD(bs, bdof); 11435227eafbSStefano Zampini 1144e6befd46SJed Brown for (c = 0, cind = 0; c < dof; ++c, ++l) { 11455227eafbSStefano Zampini if (cind < cdof && c == cdofs[cind]) { 1146e6befd46SJed Brown ltog[l] = off < 0 ? off - c : -(off + c + 1); 1147e6befd46SJed Brown cind++; 1148e6befd46SJed Brown } else { 11495227eafbSStefano Zampini ltog[l] = (off < 0 ? -(off + 1) : off) + c - cind; 1150e6befd46SJed Brown } 115137d0c07bSMatthew G Knepley } 115237d0c07bSMatthew G Knepley } 1153bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 11541690c2aeSBarry Smith bsLocal[0] = bs < 0 ? PETSC_INT_MAX : bs; 11559371c9d4SSatish Balay bsLocal[1] = bs; 11569566063dSJacob Faibussowitsch PetscCall(PetscGlobalMinMaxInt(PetscObjectComm((PetscObject)dm), bsLocal, bsMinMax)); 11579371c9d4SSatish Balay if (bsMinMax[0] != bsMinMax[1]) { 11589371c9d4SSatish Balay bs = 1; 11599371c9d4SSatish Balay } else { 11609371c9d4SSatish Balay bs = bsMinMax[0]; 11619371c9d4SSatish Balay } 11627591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 11637591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1164ccf3bd66SMatthew G. Knepley if (bs > 1) { 1165ca469d19SJed Brown for (l = 0, k = 0; l < n; l += bs, ++k) { 1166ca469d19SJed Brown // Integer division of negative values truncates toward zero(!), not toward negative infinity 1167ca469d19SJed Brown ltog[k] = ltog[l] >= 0 ? ltog[l] / bs : -(-(ltog[l] + 1) / bs + 1); 1168ca469d19SJed Brown } 1169ccf3bd66SMatthew G. Knepley n /= bs; 1170ccf3bd66SMatthew G. Knepley } 11719566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap)); 1172dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, getlocaltoglobalmapping); 117337d0c07bSMatthew G Knepley } 11741411c6eeSJed Brown *ltog = dm->ltogmap; 11753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11761411c6eeSJed Brown } 11771411c6eeSJed Brown 11781411c6eeSJed Brown /*@ 1179bb7acecfSBarry Smith DMGetBlockSize - Gets the inherent block size associated with a `DM` 11801411c6eeSJed Brown 11811411c6eeSJed Brown Not Collective 11821411c6eeSJed Brown 11831411c6eeSJed Brown Input Parameter: 1184bb7acecfSBarry Smith . dm - the `DM` with block structure 11851411c6eeSJed Brown 11861411c6eeSJed Brown Output Parameter: 11871411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11881411c6eeSJed Brown 11891411c6eeSJed Brown Level: intermediate 11901411c6eeSJed Brown 119173ff1848SBarry Smith Notes: 1192bb7acecfSBarry Smith This might be the number of degrees of freedom at each grid point for a structured grid. 1193bb7acecfSBarry Smith 1194bb7acecfSBarry Smith Complex `DM` that represent multiphysics or staggered grids or mixed-methods do not generally have a single inherent block size, but 1195bb7acecfSBarry Smith rather different locations in the vectors may have a different block size. 1196bb7acecfSBarry Smith 11971cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISCreateBlock()`, `VecSetBlockSize()`, `MatSetBlockSize()`, `DMGetLocalToGlobalMapping()` 11981411c6eeSJed Brown @*/ 1199d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBlockSize(DM dm, PetscInt *bs) 1200d71ae5a4SJacob Faibussowitsch { 12011411c6eeSJed Brown PetscFunctionBegin; 12021411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12034f572ea9SToby Isaac PetscAssertPointer(bs, 2); 12047a8be351SBarry Smith PetscCheck(dm->bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM does not have enough information to provide a block size yet"); 12051411c6eeSJed Brown *bs = dm->bs; 12063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12071411c6eeSJed Brown } 12081411c6eeSJed Brown 1209ffeef943SBarry Smith /*@ 1210bb7acecfSBarry Smith DMCreateInterpolation - Gets the interpolation matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1211bb7acecfSBarry Smith `DMCreateGlobalVector()` on the coarse `DM` to similar vectors on the fine grid `DM`. 121247c6ae99SBarry Smith 121320f4b53cSBarry Smith Collective 121447c6ae99SBarry Smith 1215d8d19677SJose E. Roman Input Parameters: 1216bb7acecfSBarry Smith + dmc - the `DM` object 1217bb7acecfSBarry Smith - dmf - the second, finer `DM` object 121847c6ae99SBarry Smith 1219d8d19677SJose E. Roman Output Parameters: 122047c6ae99SBarry Smith + mat - the interpolation 1221b6971eaeSBarry Smith - vec - the scaling (optional, pass `NULL` if not needed), see `DMCreateInterpolationScale()` 122247c6ae99SBarry Smith 122347c6ae99SBarry Smith Level: developer 122447c6ae99SBarry Smith 122595452b02SPatrick Sanan Notes: 1226bb7acecfSBarry 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 1227bb7acecfSBarry Smith DMCoarsen(). The coordinates set into the `DMDA` are completely ignored in computing the interpolation. 1228d52bd9f3SBarry Smith 1229bb7acecfSBarry Smith For `DMDA` objects you can use this interpolation (more precisely the interpolation from the `DMGetCoordinateDM()`) to interpolate the mesh coordinate 1230bb7acecfSBarry Smith vectors EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 123185afcc9aSBarry Smith 12321cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolationScale()` 123347c6ae99SBarry Smith @*/ 1234d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolation(DM dmc, DM dmf, Mat *mat, Vec *vec) 1235d71ae5a4SJacob Faibussowitsch { 123647c6ae99SBarry Smith PetscFunctionBegin; 1237a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1238a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 12394f572ea9SToby Isaac PetscAssertPointer(mat, 3); 12409566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInterpolation, dmc, dmf, 0, 0)); 1241dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createinterpolation, dmf, mat, vec); 12429566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInterpolation, dmc, dmf, 0, 0)); 12433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 124447c6ae99SBarry Smith } 124547c6ae99SBarry Smith 12463ad4599aSBarry Smith /*@ 1247a4e35b19SJacob Faibussowitsch DMCreateInterpolationScale - Forms L = 1/(R*1) where 1 is the vector of all ones, and R is 1248a4e35b19SJacob Faibussowitsch the transpose of the interpolation between the `DM`. 12492ed6491fSPatrick Sanan 12502ed6491fSPatrick Sanan Input Parameters: 1251bb7acecfSBarry Smith + dac - `DM` that defines a coarse mesh 1252bb7acecfSBarry Smith . daf - `DM` that defines a fine mesh 12532ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 12542ed6491fSPatrick Sanan 12552ed6491fSPatrick Sanan Output Parameter: 12562ed6491fSPatrick Sanan . scale - the scaled vector 12572ed6491fSPatrick Sanan 1258bb7acecfSBarry Smith Level: advanced 12592ed6491fSPatrick Sanan 126073ff1848SBarry Smith Note: 1261a4e35b19SJacob Faibussowitsch xcoarse = diag(L)*R*xfine preserves scale and is thus suitable for state (versus residual) 1262a4e35b19SJacob Faibussowitsch restriction. In other words xcoarse is the coarse representation of xfine. 1263a4e35b19SJacob Faibussowitsch 126473ff1848SBarry Smith Developer Note: 1265bb7acecfSBarry Smith If the fine-scale `DMDA` has the -dm_bind_below option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 1266e9c74fd6SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 1267e9c74fd6SRichard Tran Mills 126860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `MatRestrict()`, `MatInterpolate()`, `DMCreateInterpolation()`, `DMCreateRestriction()`, `DMCreateGlobalVector()` 12692ed6491fSPatrick Sanan @*/ 1270d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolationScale(DM dac, DM daf, Mat mat, Vec *scale) 1271d71ae5a4SJacob Faibussowitsch { 12722ed6491fSPatrick Sanan Vec fine; 12732ed6491fSPatrick Sanan PetscScalar one = 1.0; 12749704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 1275e9c74fd6SRichard Tran Mills PetscBool bindingpropagates, isbound; 12769704db99SRichard Tran Mills #endif 12772ed6491fSPatrick Sanan 12782ed6491fSPatrick Sanan PetscFunctionBegin; 12799566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(daf, &fine)); 12809566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dac, scale)); 12819566063dSJacob Faibussowitsch PetscCall(VecSet(fine, one)); 12829704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 12839704db99SRichard Tran Mills /* If the 'fine' Vec is bound to the CPU, it makes sense to bind 'mat' as well. 12849704db99SRichard Tran Mills * Note that we only do this for the CUDA case, right now, but if we add support for MatMultTranspose() via ViennaCL, 12859704db99SRichard Tran Mills * we'll need to do it for that case, too.*/ 12869566063dSJacob Faibussowitsch PetscCall(VecGetBindingPropagates(fine, &bindingpropagates)); 1287e9c74fd6SRichard Tran Mills if (bindingpropagates) { 12889566063dSJacob Faibussowitsch PetscCall(MatSetBindingPropagates(mat, PETSC_TRUE)); 12899566063dSJacob Faibussowitsch PetscCall(VecBoundToCPU(fine, &isbound)); 12909566063dSJacob Faibussowitsch PetscCall(MatBindToCPU(mat, isbound)); 129183aa49f4SRichard Tran Mills } 12929704db99SRichard Tran Mills #endif 12939566063dSJacob Faibussowitsch PetscCall(MatRestrict(mat, fine, *scale)); 12949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fine)); 12959566063dSJacob Faibussowitsch PetscCall(VecReciprocal(*scale)); 12963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12972ed6491fSPatrick Sanan } 12982ed6491fSPatrick Sanan 12992ed6491fSPatrick Sanan /*@ 1300bb7acecfSBarry Smith DMCreateRestriction - Gets restriction matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1301bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine `DM` to similar vectors on the coarse grid `DM`. 13023ad4599aSBarry Smith 130320f4b53cSBarry Smith Collective 13043ad4599aSBarry Smith 1305d8d19677SJose E. Roman Input Parameters: 1306bb7acecfSBarry Smith + dmc - the `DM` object 1307bb7acecfSBarry Smith - dmf - the second, finer `DM` object 13083ad4599aSBarry Smith 13093ad4599aSBarry Smith Output Parameter: 13103ad4599aSBarry Smith . mat - the restriction 13113ad4599aSBarry Smith 13123ad4599aSBarry Smith Level: developer 13133ad4599aSBarry Smith 1314bb7acecfSBarry Smith Note: 1315bb7acecfSBarry Smith This only works for `DMSTAG`. For many situations either the transpose of the operator obtained with `DMCreateInterpolation()` or that 1316bb7acecfSBarry Smith matrix multiplied by the vector obtained with `DMCreateInterpolationScale()` provides the desired object. 13173ad4599aSBarry Smith 13181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRestrict()`, `DMInterpolate()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateInterpolation()` 13193ad4599aSBarry Smith @*/ 1320d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateRestriction(DM dmc, DM dmf, Mat *mat) 1321d71ae5a4SJacob Faibussowitsch { 13223ad4599aSBarry Smith PetscFunctionBegin; 1323a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1324a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13254f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13269566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateRestriction, dmc, dmf, 0, 0)); 1327dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createrestriction, dmf, mat); 13289566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateRestriction, dmc, dmf, 0, 0)); 13293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13303ad4599aSBarry Smith } 13313ad4599aSBarry Smith 133247c6ae99SBarry Smith /*@ 1333a4e35b19SJacob Faibussowitsch DMCreateInjection - Gets injection matrix between two `DM` objects. 133447c6ae99SBarry Smith 133520f4b53cSBarry Smith Collective 133647c6ae99SBarry Smith 1337d8d19677SJose E. Roman Input Parameters: 1338bb7acecfSBarry Smith + dac - the `DM` object 1339bb7acecfSBarry Smith - daf - the second, finer `DM` object 134047c6ae99SBarry Smith 134147c6ae99SBarry Smith Output Parameter: 13426dbf9973SLawrence Mitchell . mat - the injection 134347c6ae99SBarry Smith 134447c6ae99SBarry Smith Level: developer 134547c6ae99SBarry Smith 1346a4e35b19SJacob Faibussowitsch Notes: 1347a4e35b19SJacob Faibussowitsch This is an operator that applied to a vector obtained with `DMCreateGlobalVector()` on the 1348a4e35b19SJacob Faibussowitsch fine grid maps the values to a vector on the vector on the coarse `DM` by simply selecting 1349a4e35b19SJacob Faibussowitsch the values on the coarse grid points. This compares to the operator obtained by 1350a4e35b19SJacob Faibussowitsch `DMCreateRestriction()` or the transpose of the operator obtained by 1351a4e35b19SJacob Faibussowitsch `DMCreateInterpolation()` that uses a "local weighted average" of the values around the 1352a4e35b19SJacob Faibussowitsch coarse grid point as the coarse grid value. 1353a4e35b19SJacob Faibussowitsch 1354bb7acecfSBarry 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 1355bb7acecfSBarry Smith `DMCoarsen()`. The coordinates set into the `DMDA` are completely ignored in computing the injection. 135685afcc9aSBarry Smith 13571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateInterpolation()`, 1358bb7acecfSBarry Smith `DMCreateRestriction()`, `MatRestrict()`, `MatInterpolate()` 135947c6ae99SBarry Smith @*/ 1360d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInjection(DM dac, DM daf, Mat *mat) 1361d71ae5a4SJacob Faibussowitsch { 136247c6ae99SBarry Smith PetscFunctionBegin; 1363a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac, DM_CLASSID, 1); 1364a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf, DM_CLASSID, 2); 13654f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13669566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInjection, dac, daf, 0, 0)); 1367dbbe0bcdSBarry Smith PetscUseTypeMethod(dac, createinjection, daf, mat); 13689566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInjection, dac, daf, 0, 0)); 13693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 137047c6ae99SBarry Smith } 137147c6ae99SBarry Smith 1372b412c318SBarry Smith /*@ 1373bb7acecfSBarry 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 1374bb7acecfSBarry Smith a Galerkin finite element model on the `DM` 1375bd041c0cSMatthew G. Knepley 137620f4b53cSBarry Smith Collective 1377bd041c0cSMatthew G. Knepley 1378d8d19677SJose E. Roman Input Parameters: 1379bb7acecfSBarry Smith + dmc - the target `DM` object 13808c1c0954SStefano Zampini - dmf - the source `DM` object, can be `NULL` 1381bd041c0cSMatthew G. Knepley 1382bd041c0cSMatthew G. Knepley Output Parameter: 1383b4937a87SMatthew G. Knepley . mat - the mass matrix 1384bd041c0cSMatthew G. Knepley 1385bd041c0cSMatthew G. Knepley Level: developer 1386bd041c0cSMatthew G. Knepley 1387bb7acecfSBarry Smith Notes: 1388bb7acecfSBarry Smith For `DMPLEX` the finite element model for the `DM` must have been already provided. 1389bb7acecfSBarry Smith 13908c1c0954SStefano 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()` 1391bb7acecfSBarry Smith 139242747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrixLumped()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1393bd041c0cSMatthew G. Knepley @*/ 1394d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrix(DM dmc, DM dmf, Mat *mat) 1395d71ae5a4SJacob Faibussowitsch { 1396bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1397b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 13988c1c0954SStefano Zampini if (!dmf) dmf = dmc; 1399b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 14004f572ea9SToby Isaac PetscAssertPointer(mat, 3); 14018c1c0954SStefano Zampini PetscCall(PetscLogEventBegin(DM_CreateMassMatrix, dmc, dmf, 0, 0)); 1402dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createmassmatrix, dmf, mat); 14038c1c0954SStefano Zampini PetscCall(PetscLogEventEnd(DM_CreateMassMatrix, dmc, dmf, 0, 0)); 14043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1405b4937a87SMatthew G. Knepley } 1406b4937a87SMatthew G. Knepley 1407b4937a87SMatthew G. Knepley /*@ 1408bb7acecfSBarry Smith DMCreateMassMatrixLumped - Gets the lumped mass matrix for a given `DM` 1409b4937a87SMatthew G. Knepley 141020f4b53cSBarry Smith Collective 1411b4937a87SMatthew G. Knepley 1412b4937a87SMatthew G. Knepley Input Parameter: 1413bb7acecfSBarry Smith . dm - the `DM` object 1414b4937a87SMatthew G. Knepley 14157dcfde4dSJose E. Roman Output Parameters: 14168e9849d2SStefano Zampini + llm - the local lumped mass matrix, which is a diagonal matrix, represented as a vector 14178e9849d2SStefano Zampini - lm - the global lumped mass matrix, which is a diagonal matrix, represented as a vector 1418b4937a87SMatthew G. Knepley 1419b4937a87SMatthew G. Knepley Level: developer 1420b4937a87SMatthew G. Knepley 1421bb7acecfSBarry Smith Note: 1422bb7acecfSBarry Smith See `DMCreateMassMatrix()` for how to create the non-lumped version of the mass matrix. 1423bb7acecfSBarry Smith 142460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrix()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1425b4937a87SMatthew G. Knepley @*/ 14268e9849d2SStefano Zampini PetscErrorCode DMCreateMassMatrixLumped(DM dm, Vec *llm, Vec *lm) 1427d71ae5a4SJacob Faibussowitsch { 1428b4937a87SMatthew G. Knepley PetscFunctionBegin; 1429b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14308e9849d2SStefano Zampini if (llm) PetscAssertPointer(llm, 2); 14318e9849d2SStefano Zampini if (lm) PetscAssertPointer(lm, 3); 14328e9849d2SStefano Zampini if (llm || lm) PetscUseTypeMethod(dm, createmassmatrixlumped, llm, lm); 14333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1434bd041c0cSMatthew G. Knepley } 1435bd041c0cSMatthew G. Knepley 1436bd041c0cSMatthew G. Knepley /*@ 1437bb7acecfSBarry Smith DMCreateColoring - Gets coloring of a graph associated with the `DM`. Often the graph represents the operator matrix associated with the discretization 1438bb7acecfSBarry Smith of a PDE on the `DM`. 143947c6ae99SBarry Smith 144020f4b53cSBarry Smith Collective 144147c6ae99SBarry Smith 1442d8d19677SJose E. Roman Input Parameters: 1443bb7acecfSBarry Smith + dm - the `DM` object 1444bb7acecfSBarry Smith - ctype - `IS_COLORING_LOCAL` or `IS_COLORING_GLOBAL` 144547c6ae99SBarry Smith 144647c6ae99SBarry Smith Output Parameter: 144747c6ae99SBarry Smith . coloring - the coloring 144847c6ae99SBarry Smith 14491bf8429eSBarry Smith Level: developer 14501bf8429eSBarry Smith 1451ec5066bdSBarry Smith Notes: 1452bb7acecfSBarry 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 1453bb7acecfSBarry Smith matrix comes from (what this function provides). In general using the mesh produces a more optimal coloring (fewer colors). 1454ec5066bdSBarry Smith 1455bb7acecfSBarry Smith This produces a coloring with the distance of 2, see `MatSetColoringDistance()` which can be used for efficiently computing Jacobians with `MatFDColoringCreate()` 14561bf8429eSBarry 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, 14571bf8429eSBarry Smith otherwise an error will be generated. 1458ec5066bdSBarry Smith 14591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISColoring`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatType()`, `MatColoring`, `MatFDColoringCreate()` 1460aab9d709SJed Brown @*/ 1461d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateColoring(DM dm, ISColoringType ctype, ISColoring *coloring) 1462d71ae5a4SJacob Faibussowitsch { 146347c6ae99SBarry Smith PetscFunctionBegin; 1464171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14654f572ea9SToby Isaac PetscAssertPointer(coloring, 3); 1466dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getcoloring, ctype, coloring); 14673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 146847c6ae99SBarry Smith } 146947c6ae99SBarry Smith 1470b412c318SBarry Smith /*@ 1471bb7acecfSBarry Smith DMCreateMatrix - Gets an empty matrix for a `DM` that is most commonly used to store the Jacobian of a discrete PDE operator. 147247c6ae99SBarry Smith 147320f4b53cSBarry Smith Collective 147447c6ae99SBarry Smith 147547c6ae99SBarry Smith Input Parameter: 1476bb7acecfSBarry Smith . dm - the `DM` object 147747c6ae99SBarry Smith 147847c6ae99SBarry Smith Output Parameter: 147947c6ae99SBarry Smith . mat - the empty Jacobian 148047c6ae99SBarry Smith 148120f4b53cSBarry Smith Options Database Key: 1482bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 1483f27dd7c6SMatthew G. Knepley 148420f4b53cSBarry Smith Level: beginner 148520f4b53cSBarry Smith 148695452b02SPatrick Sanan Notes: 148795452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 148894013140SBarry Smith do not need to do it yourself. 148994013140SBarry Smith 149094013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 1491bb7acecfSBarry Smith the nonzero pattern call `DMSetMatrixPreallocateOnly()` 149294013140SBarry Smith 1493bb7acecfSBarry Smith For `DMDA`, when you call `MatView()` on this matrix it is displayed using the global natural ordering, NOT in the ordering used 149494013140SBarry Smith internally by PETSc. 149594013140SBarry Smith 1496bb7acecfSBarry Smith For `DMDA`, in general it is easiest to use `MatSetValuesStencil()` or `MatSetValuesLocal()` to put values into the matrix because 1497bb7acecfSBarry Smith `MatSetValues()` requires the indices for the global numbering for the `DMDA` which is complic`ated to compute 149894013140SBarry Smith 14991cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMSetMatType()`, `DMCreateMassMatrix()` 1500aab9d709SJed Brown @*/ 1501d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMatrix(DM dm, Mat *mat) 1502d71ae5a4SJacob Faibussowitsch { 150347c6ae99SBarry Smith PetscFunctionBegin; 1504171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 15054f572ea9SToby Isaac PetscAssertPointer(mat, 2); 15069566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 15079566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateMatrix, 0, 0, 0, 0)); 1508dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, creatematrix, mat); 150976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1510c6b011d8SStefano Zampini DM mdm; 1511c6b011d8SStefano Zampini 15129566063dSJacob Faibussowitsch PetscCall(MatGetDM(*mat, &mdm)); 15137a8be351SBarry Smith PetscCheck(mdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the matrix", ((PetscObject)dm)->type_name); 1514c6b011d8SStefano Zampini } 1515e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1516e5e52638SMatthew G. Knepley if (dm->Nf) { 1517e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1518649ef022SMatthew Knepley PetscInt Nf, f; 1519e571a35bSMatthew G. Knepley 15209566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1521649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1522649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 15239566063dSJacob Faibussowitsch PetscCall((*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace)); 15249566063dSJacob Faibussowitsch PetscCall(MatSetNullSpace(*mat, nullSpace)); 15259566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1526649ef022SMatthew Knepley break; 1527e571a35bSMatthew G. Knepley } 1528649ef022SMatthew Knepley } 1529649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1530649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 15319566063dSJacob Faibussowitsch PetscCall((*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace)); 15329566063dSJacob Faibussowitsch PetscCall(MatSetNearNullSpace(*mat, nullSpace)); 15339566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1534e571a35bSMatthew G. Knepley } 1535e571a35bSMatthew G. Knepley } 1536e571a35bSMatthew G. Knepley } 15379566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateMatrix, 0, 0, 0, 0)); 15383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 153947c6ae99SBarry Smith } 154047c6ae99SBarry Smith 1541732e2eb9SMatthew G Knepley /*@ 1542a4e35b19SJacob Faibussowitsch DMSetMatrixPreallocateSkip - When `DMCreateMatrix()` is called the matrix sizes and 1543a4e35b19SJacob Faibussowitsch `ISLocalToGlobalMapping` will be properly set, but the data structures to store values in the 1544a4e35b19SJacob Faibussowitsch matrices will not be preallocated. 1545aa0f6e3cSJed Brown 154620f4b53cSBarry Smith Logically Collective 1547aa0f6e3cSJed Brown 1548aa0f6e3cSJed Brown Input Parameters: 1549bb7acecfSBarry Smith + dm - the `DM` 1550bb7acecfSBarry Smith - skip - `PETSC_TRUE` to skip preallocation 1551aa0f6e3cSJed Brown 1552aa0f6e3cSJed Brown Level: developer 1553aa0f6e3cSJed Brown 155473ff1848SBarry Smith Note: 1555a4e35b19SJacob Faibussowitsch This is most useful to reduce initialization costs when `MatSetPreallocationCOO()` and 1556a4e35b19SJacob Faibussowitsch `MatSetValuesCOO()` will be used. 1557a4e35b19SJacob Faibussowitsch 15581cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateOnly()` 1559aa0f6e3cSJed Brown @*/ 1560d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateSkip(DM dm, PetscBool skip) 1561d71ae5a4SJacob Faibussowitsch { 1562aa0f6e3cSJed Brown PetscFunctionBegin; 1563aa0f6e3cSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1564aa0f6e3cSJed Brown dm->prealloc_skip = skip; 15653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1566aa0f6e3cSJed Brown } 1567aa0f6e3cSJed Brown 1568aa0f6e3cSJed Brown /*@ 1569bb7acecfSBarry Smith DMSetMatrixPreallocateOnly - When `DMCreateMatrix()` is called the matrix will be properly 1570732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1571732e2eb9SMatthew G Knepley 157220f4b53cSBarry Smith Logically Collective 1573732e2eb9SMatthew G Knepley 1574d8d19677SJose E. Roman Input Parameters: 1575bb7acecfSBarry Smith + dm - the `DM` 1576bb7acecfSBarry Smith - only - `PETSC_TRUE` if only want preallocation 1577732e2eb9SMatthew G Knepley 157820f4b53cSBarry Smith Options Database Key: 1579bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()`, `DMCreateMassMatrix()`, but do not fill it with zeros 1580f27dd7c6SMatthew G. Knepley 158120f4b53cSBarry Smith Level: developer 158220f4b53cSBarry Smith 15831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateSkip()` 1584732e2eb9SMatthew G Knepley @*/ 1585d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1586d71ae5a4SJacob Faibussowitsch { 1587732e2eb9SMatthew G Knepley PetscFunctionBegin; 1588732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1589732e2eb9SMatthew G Knepley dm->prealloc_only = only; 15903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1591732e2eb9SMatthew G Knepley } 1592732e2eb9SMatthew G Knepley 1593b06ff27eSHong Zhang /*@ 15940b4b7b1cSBarry Smith DMSetMatrixStructureOnly - When `DMCreateMatrix()` is called, the matrix nonzero structure will be created 1595bb7acecfSBarry Smith but the array for numerical values will not be allocated. 1596b06ff27eSHong Zhang 159720f4b53cSBarry Smith Logically Collective 1598b06ff27eSHong Zhang 1599d8d19677SJose E. Roman Input Parameters: 1600bb7acecfSBarry Smith + dm - the `DM` 16010b4b7b1cSBarry Smith - only - `PETSC_TRUE` if you only want matrix nonzero structure 1602b06ff27eSHong Zhang 1603b06ff27eSHong Zhang Level: developer 1604bb7acecfSBarry Smith 16051cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMSetMatrixPreallocateSkip()` 1606b06ff27eSHong Zhang @*/ 1607d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1608d71ae5a4SJacob Faibussowitsch { 1609b06ff27eSHong Zhang PetscFunctionBegin; 1610b06ff27eSHong Zhang PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1611b06ff27eSHong Zhang dm->structure_only = only; 16123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1613b06ff27eSHong Zhang } 1614b06ff27eSHong Zhang 1615863027abSJed Brown /*@ 1616863027abSJed Brown DMSetBlockingType - set the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1617863027abSJed Brown 161820f4b53cSBarry Smith Logically Collective 1619863027abSJed Brown 1620863027abSJed Brown Input Parameters: 1621863027abSJed Brown + dm - the `DM` 1622863027abSJed Brown - btype - block by topological point or field node 1623863027abSJed Brown 162420f4b53cSBarry Smith Options Database Key: 16250e762ea3SJed Brown . -dm_blocking_type [topological_point, field_node] - use topological point blocking or field node blocking 1626863027abSJed Brown 162720f4b53cSBarry Smith Level: advanced 162820f4b53cSBarry Smith 16291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1630863027abSJed Brown @*/ 1631863027abSJed Brown PetscErrorCode DMSetBlockingType(DM dm, DMBlockingType btype) 1632863027abSJed Brown { 1633863027abSJed Brown PetscFunctionBegin; 1634863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1635863027abSJed Brown dm->blocking_type = btype; 16363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1637863027abSJed Brown } 1638863027abSJed Brown 1639863027abSJed Brown /*@ 1640863027abSJed Brown DMGetBlockingType - get the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1641863027abSJed Brown 1642863027abSJed Brown Not Collective 1643863027abSJed Brown 16442fe279fdSBarry Smith Input Parameter: 1645863027abSJed Brown . dm - the `DM` 1646863027abSJed Brown 16472fe279fdSBarry Smith Output Parameter: 1648863027abSJed Brown . btype - block by topological point or field node 1649863027abSJed Brown 1650863027abSJed Brown Level: advanced 1651863027abSJed Brown 16521cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1653863027abSJed Brown @*/ 1654863027abSJed Brown PetscErrorCode DMGetBlockingType(DM dm, DMBlockingType *btype) 1655863027abSJed Brown { 1656863027abSJed Brown PetscFunctionBegin; 1657863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16584f572ea9SToby Isaac PetscAssertPointer(btype, 2); 1659863027abSJed Brown *btype = dm->blocking_type; 16603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1661863027abSJed Brown } 1662863027abSJed Brown 1663a89ea682SMatthew G Knepley /*@C 1664bb7acecfSBarry Smith DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with `DMRestoreWorkArray()` 1665a89ea682SMatthew G Knepley 1666a89ea682SMatthew G Knepley Not Collective 1667a89ea682SMatthew G Knepley 1668a89ea682SMatthew G Knepley Input Parameters: 1669bb7acecfSBarry Smith + dm - the `DM` object 1670a5b23f4aSJose E. Roman . count - The minimum size 167120f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, or `MPIU_INT`) 1672a89ea682SMatthew G Knepley 1673a89ea682SMatthew G Knepley Output Parameter: 167460225df5SJacob Faibussowitsch . mem - the work array 1675a89ea682SMatthew G Knepley 1676a89ea682SMatthew G Knepley Level: developer 1677a89ea682SMatthew G Knepley 167873ff1848SBarry Smith Notes: 1679da81f932SPierre Jolivet A `DM` may stash the array between instantiations so using this routine may be more efficient than calling `PetscMalloc()` 1680bb7acecfSBarry Smith 1681bb7acecfSBarry Smith The array may contain nonzero values 1682bb7acecfSBarry Smith 16831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMRestoreWorkArray()`, `PetscMalloc()` 1684a89ea682SMatthew G Knepley @*/ 1685d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1686d71ae5a4SJacob Faibussowitsch { 1687aa1993deSMatthew G Knepley DMWorkLink link; 168869291d52SBarry Smith PetscMPIInt dsize; 1689a89ea682SMatthew G Knepley 1690a89ea682SMatthew G Knepley PetscFunctionBegin; 1691a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16924f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1693442f3b32SStefano Zampini if (!count) { 1694442f3b32SStefano Zampini *(void **)mem = NULL; 1695442f3b32SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 1696442f3b32SStefano Zampini } 1697aa1993deSMatthew G Knepley if (dm->workin) { 1698aa1993deSMatthew G Knepley link = dm->workin; 1699aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1700aa1993deSMatthew G Knepley } else { 17014dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&link)); 1702a89ea682SMatthew G Knepley } 1703b77fa653SStefano Zampini /* Avoid MPI_Type_size for most used datatypes 1704b77fa653SStefano Zampini Get size directly */ 1705b77fa653SStefano Zampini if (dtype == MPIU_INT) dsize = sizeof(PetscInt); 1706b77fa653SStefano Zampini else if (dtype == MPIU_REAL) dsize = sizeof(PetscReal); 1707b77fa653SStefano Zampini #if defined(PETSC_USE_64BIT_INDICES) 1708b77fa653SStefano Zampini else if (dtype == MPI_INT) dsize = sizeof(int); 1709b77fa653SStefano Zampini #endif 1710b77fa653SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1711b77fa653SStefano Zampini else if (dtype == MPIU_SCALAR) dsize = sizeof(PetscScalar); 1712b77fa653SStefano Zampini #endif 1713b77fa653SStefano Zampini else PetscCallMPI(MPI_Type_size(dtype, &dsize)); 1714b77fa653SStefano Zampini 17155056fcd2SBarry Smith if (((size_t)dsize * count) > link->bytes) { 17169566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 17179566063dSJacob Faibussowitsch PetscCall(PetscMalloc(dsize * count, &link->mem)); 1718854ce69bSBarry Smith link->bytes = dsize * count; 1719aa1993deSMatthew G Knepley } 1720aa1993deSMatthew G Knepley link->next = dm->workout; 1721aa1993deSMatthew G Knepley dm->workout = link; 1722aa1993deSMatthew G Knepley *(void **)mem = link->mem; 17233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1724a89ea682SMatthew G Knepley } 1725a89ea682SMatthew G Knepley 1726aa1993deSMatthew G Knepley /*@C 1727bb7acecfSBarry Smith DMRestoreWorkArray - Restores a work array obtained with `DMCreateWorkArray()` 1728aa1993deSMatthew G Knepley 1729aa1993deSMatthew G Knepley Not Collective 1730aa1993deSMatthew G Knepley 1731aa1993deSMatthew G Knepley Input Parameters: 1732bb7acecfSBarry Smith + dm - the `DM` object 1733a5b23f4aSJose E. Roman . count - The minimum size 173420f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_INT` 1735aa1993deSMatthew G Knepley 1736aa1993deSMatthew G Knepley Output Parameter: 173760225df5SJacob Faibussowitsch . mem - the work array 1738aa1993deSMatthew G Knepley 1739aa1993deSMatthew G Knepley Level: developer 1740aa1993deSMatthew G Knepley 174173ff1848SBarry Smith Developer Note: 1742bb7acecfSBarry Smith count and dtype are ignored, they are only needed for `DMGetWorkArray()` 1743147403d9SBarry Smith 17441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMGetWorkArray()` 1745aa1993deSMatthew G Knepley @*/ 1746d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1747d71ae5a4SJacob Faibussowitsch { 1748aa1993deSMatthew G Knepley DMWorkLink *p, link; 1749aa1993deSMatthew G Knepley 1750aa1993deSMatthew G Knepley PetscFunctionBegin; 1751aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17524f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1753a4e35b19SJacob Faibussowitsch (void)count; 1754a4e35b19SJacob Faibussowitsch (void)dtype; 1755442f3b32SStefano Zampini if (!*(void **)mem) PetscFunctionReturn(PETSC_SUCCESS); 1756aa1993deSMatthew G Knepley for (p = &dm->workout; (link = *p); p = &link->next) { 1757aa1993deSMatthew G Knepley if (link->mem == *(void **)mem) { 1758aa1993deSMatthew G Knepley *p = link->next; 1759aa1993deSMatthew G Knepley link->next = dm->workin; 1760aa1993deSMatthew G Knepley dm->workin = link; 17610298fd71SBarry Smith *(void **)mem = NULL; 17623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1763aa1993deSMatthew G Knepley } 1764aa1993deSMatthew G Knepley } 1765aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Array was not checked out"); 1766aa1993deSMatthew G Knepley } 1767e7c4fc90SDmitry Karpeev 17688cda7954SMatthew G. Knepley /*@C 1769bb7acecfSBarry Smith DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field, defined with `DMAddField()`, when function spaces 1770bb7acecfSBarry Smith are joined or split, such as in `DMCreateSubDM()` 17718cda7954SMatthew G. Knepley 177220f4b53cSBarry Smith Logically Collective; No Fortran Support 17738cda7954SMatthew G. Knepley 17748cda7954SMatthew G. Knepley Input Parameters: 1775bb7acecfSBarry Smith + dm - The `DM` 17768cda7954SMatthew G. Knepley . field - The field number for the nullspace 17778cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 17788cda7954SMatthew G. Knepley 177920f4b53cSBarry Smith Calling sequence of `nullsp`: 1780bb7acecfSBarry Smith + dm - The present `DM` 1781bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1782147403d9SBarry Smith . field - The field number in dm 1783147403d9SBarry Smith - nullSpace - The nullspace for the given field 17848cda7954SMatthew G. Knepley 178549762cbcSSatish Balay Level: intermediate 178649762cbcSSatish Balay 17871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1788147403d9SBarry Smith @*/ 1789a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1790d71ae5a4SJacob Faibussowitsch { 1791435a35e8SMatthew G Knepley PetscFunctionBegin; 1792435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17937a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1794435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 17953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1796435a35e8SMatthew G Knepley } 1797435a35e8SMatthew G Knepley 17988cda7954SMatthew G. Knepley /*@C 1799bb7acecfSBarry Smith DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, defined with `DMAddField()` 18008cda7954SMatthew G. Knepley 180120f4b53cSBarry Smith Not Collective; No Fortran Support 18028cda7954SMatthew G. Knepley 18038cda7954SMatthew G. Knepley Input Parameters: 1804bb7acecfSBarry Smith + dm - The `DM` 18058cda7954SMatthew G. Knepley - field - The field number for the nullspace 18068cda7954SMatthew G. Knepley 18078cda7954SMatthew G. Knepley Output Parameter: 18088cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 18098cda7954SMatthew G. Knepley 181020f4b53cSBarry Smith Calling sequence of `nullsp`: 1811147403d9SBarry Smith + dm - The present DM 1812147403d9SBarry Smith . origField - The field number given above, in the original DM 1813147403d9SBarry Smith . field - The field number in dm 1814147403d9SBarry Smith - nullSpace - The nullspace for the given field 18158cda7954SMatthew G. Knepley 181649762cbcSSatish Balay Level: intermediate 181749762cbcSSatish Balay 18181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1819147403d9SBarry Smith @*/ 1820a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1821d71ae5a4SJacob Faibussowitsch { 18220a50eb56SMatthew G. Knepley PetscFunctionBegin; 18230a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18244f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 18257a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 18260a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 18273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18280a50eb56SMatthew G. Knepley } 18290a50eb56SMatthew G. Knepley 18308cda7954SMatthew G. Knepley /*@C 1831bb7acecfSBarry Smith DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 18328cda7954SMatthew G. Knepley 183320f4b53cSBarry Smith Logically Collective; No Fortran Support 18348cda7954SMatthew G. Knepley 18358cda7954SMatthew G. Knepley Input Parameters: 1836bb7acecfSBarry Smith + dm - The `DM` 18378cda7954SMatthew G. Knepley . field - The field number for the nullspace 18388cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 18398cda7954SMatthew G. Knepley 184020f4b53cSBarry Smith Calling sequence of `nullsp`: 1841bb7acecfSBarry Smith + dm - The present `DM` 1842bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1843147403d9SBarry Smith . field - The field number in dm 1844147403d9SBarry Smith - nullSpace - The nullspace for the given field 18458cda7954SMatthew G. Knepley 184649762cbcSSatish Balay Level: intermediate 184749762cbcSSatish Balay 18481cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()`, 1849bb7acecfSBarry Smith `MatNullSpace` 1850147403d9SBarry Smith @*/ 1851a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1852d71ae5a4SJacob Faibussowitsch { 1853f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1854f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18557a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1856f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 18573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1858f9d4088aSMatthew G. Knepley } 1859f9d4088aSMatthew G. Knepley 18608cda7954SMatthew G. Knepley /*@C 1861bb7acecfSBarry Smith DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 18628cda7954SMatthew G. Knepley 186320f4b53cSBarry Smith Not Collective; No Fortran Support 18648cda7954SMatthew G. Knepley 18658cda7954SMatthew G. Knepley Input Parameters: 1866bb7acecfSBarry Smith + dm - The `DM` 18678cda7954SMatthew G. Knepley - field - The field number for the nullspace 18688cda7954SMatthew G. Knepley 18698cda7954SMatthew G. Knepley Output Parameter: 18708cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 18718cda7954SMatthew G. Knepley 187220f4b53cSBarry Smith Calling sequence of `nullsp`: 1873bb7acecfSBarry Smith + dm - The present `DM` 1874bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1875147403d9SBarry Smith . field - The field number in dm 1876147403d9SBarry Smith - nullSpace - The nullspace for the given field 18778cda7954SMatthew G. Knepley 187849762cbcSSatish Balay Level: intermediate 187949762cbcSSatish Balay 18801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, 1881bb7acecfSBarry Smith `MatNullSpace`, `DMCreateSuperDM()` 1882147403d9SBarry Smith @*/ 1883a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1884d71ae5a4SJacob Faibussowitsch { 1885f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1886f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18874f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 18887a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1889f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 18903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1891f9d4088aSMatthew G. Knepley } 1892f9d4088aSMatthew G. Knepley 18934f3b5142SJed Brown /*@C 1894bb7acecfSBarry Smith DMCreateFieldIS - Creates a set of `IS` objects with the global indices of dofs for each field defined with `DMAddField()` 18954d343eeaSMatthew G Knepley 189620f4b53cSBarry Smith Not Collective; No Fortran Support 18974d343eeaSMatthew G Knepley 18984d343eeaSMatthew G Knepley Input Parameter: 1899bb7acecfSBarry Smith . dm - the `DM` object 19004d343eeaSMatthew G Knepley 19014d343eeaSMatthew G Knepley Output Parameters: 190220f4b53cSBarry Smith + numFields - The number of fields (or `NULL` if not requested) 190320f4b53cSBarry Smith . fieldNames - The number of each field (or `NULL` if not requested) 190420f4b53cSBarry Smith - fields - The global indices for each field (or `NULL` if not requested) 19054d343eeaSMatthew G Knepley 19064d343eeaSMatthew G Knepley Level: intermediate 19074d343eeaSMatthew G Knepley 1908bb7acecfSBarry Smith Note: 190973ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `fieldNames` should be freed with 191073ff1848SBarry Smith `PetscFree()`, every entry of `fields` should be destroyed with `ISDestroy()`, and both arrays should be freed with 1911bb7acecfSBarry Smith `PetscFree()`. 191221c9b008SJed Brown 191373ff1848SBarry Smith Developer Note: 1914bb7acecfSBarry Smith It is not clear why both this function and `DMCreateFieldDecomposition()` exist. Having two seems redundant and confusing. This function should 1915bb7acecfSBarry Smith likely be removed. 1916bb7acecfSBarry Smith 19171cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1918bb7acecfSBarry Smith `DMCreateFieldDecomposition()` 19194d343eeaSMatthew G Knepley @*/ 1920d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 1921d71ae5a4SJacob Faibussowitsch { 192237d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 19234d343eeaSMatthew G Knepley 19244d343eeaSMatthew G Knepley PetscFunctionBegin; 19254d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 192669ca1f37SDmitry Karpeev if (numFields) { 19274f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 192869ca1f37SDmitry Karpeev *numFields = 0; 192969ca1f37SDmitry Karpeev } 193037d0c07bSMatthew G Knepley if (fieldNames) { 19314f572ea9SToby Isaac PetscAssertPointer(fieldNames, 3); 19320298fd71SBarry Smith *fieldNames = NULL; 193369ca1f37SDmitry Karpeev } 193469ca1f37SDmitry Karpeev if (fields) { 19354f572ea9SToby Isaac PetscAssertPointer(fields, 4); 19360298fd71SBarry Smith *fields = NULL; 193769ca1f37SDmitry Karpeev } 19389566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 193937d0c07bSMatthew G Knepley if (section) { 19403a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 194137d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 194237d0c07bSMatthew G Knepley 19439566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 19449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nF)); 19459566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nF, &fieldSizes, nF, &fieldNc, nF, &fieldIndices)); 19469566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(sectionGlobal, &pStart, &pEnd)); 194737d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 194837d0c07bSMatthew G Knepley fieldSizes[f] = 0; 19499566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(section, f, &fieldNc[f])); 195037d0c07bSMatthew G Knepley } 195137d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 195237d0c07bSMatthew G Knepley PetscInt gdof; 195337d0c07bSMatthew G Knepley 19549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 195537d0c07bSMatthew G Knepley if (gdof > 0) { 195637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19573a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 195837d0c07bSMatthew G Knepley 19599566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19609566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 19613a544194SStefano Zampini fpdof = fdof - fcdof; 19623a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 19633a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 19643a544194SStefano Zampini fieldNc[f] = 1; 19653a544194SStefano Zampini } 19663a544194SStefano Zampini fieldSizes[f] += fpdof; 196737d0c07bSMatthew G Knepley } 196837d0c07bSMatthew G Knepley } 196937d0c07bSMatthew G Knepley } 197037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fieldSizes[f], &fieldIndices[f])); 197237d0c07bSMatthew G Knepley fieldSizes[f] = 0; 197337d0c07bSMatthew G Knepley } 197437d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 197537d0c07bSMatthew G Knepley PetscInt gdof, goff; 197637d0c07bSMatthew G Knepley 19779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 197837d0c07bSMatthew G Knepley if (gdof > 0) { 19799566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &goff)); 198037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 198137d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 198237d0c07bSMatthew G Knepley 19839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19849566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 1985ad540459SPierre Jolivet for (fc = 0; fc < fdof - fcdof; ++fc, ++fieldSizes[f]) fieldIndices[f][fieldSizes[f]] = goff++; 198637d0c07bSMatthew G Knepley } 198737d0c07bSMatthew G Knepley } 198837d0c07bSMatthew G Knepley } 19898865f1eaSKarl Rupp if (numFields) *numFields = nF; 199037d0c07bSMatthew G Knepley if (fieldNames) { 19919566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fieldNames)); 199237d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 199337d0c07bSMatthew G Knepley const char *fieldName; 199437d0c07bSMatthew G Knepley 19959566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 1996835f2295SStefano Zampini PetscCall(PetscStrallocpy(fieldName, &(*fieldNames)[f])); 199737d0c07bSMatthew G Knepley } 199837d0c07bSMatthew G Knepley } 199937d0c07bSMatthew G Knepley if (fields) { 20009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fields)); 200137d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 20023a544194SStefano Zampini PetscInt bs, in[2], out[2]; 20033a544194SStefano Zampini 20049566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f])); 20053a544194SStefano Zampini in[0] = -fieldNc[f]; 20063a544194SStefano Zampini in[1] = fieldNc[f]; 2007462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 20083a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 20099566063dSJacob Faibussowitsch PetscCall(ISSetBlockSize((*fields)[f], bs)); 201037d0c07bSMatthew G Knepley } 201137d0c07bSMatthew G Knepley } 20129566063dSJacob Faibussowitsch PetscCall(PetscFree3(fieldSizes, fieldNc, fieldIndices)); 2013dbbe0bcdSBarry Smith } else PetscTryTypeMethod(dm, createfieldis, numFields, fieldNames, fields); 20143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20154d343eeaSMatthew G Knepley } 20164d343eeaSMatthew G Knepley 201716621825SDmitry Karpeev /*@C 2018bb7acecfSBarry Smith DMCreateFieldDecomposition - Returns a list of `IS` objects defining a decomposition of a problem into subproblems 2019a4e35b19SJacob Faibussowitsch corresponding to different fields. 2020e7c4fc90SDmitry Karpeev 202120f4b53cSBarry Smith Not Collective; No Fortran Support 2022e7c4fc90SDmitry Karpeev 2023e7c4fc90SDmitry Karpeev Input Parameter: 2024bb7acecfSBarry Smith . dm - the `DM` object 2025e7c4fc90SDmitry Karpeev 2026e7c4fc90SDmitry Karpeev Output Parameters: 202720f4b53cSBarry Smith + len - The number of fields (or `NULL` if not requested) 202820f4b53cSBarry Smith . namelist - The name for each field (or `NULL` if not requested) 202920f4b53cSBarry Smith . islist - The global indices for each field (or `NULL` if not requested) 203020f4b53cSBarry Smith - dmlist - The `DM`s for each field subproblem (or `NULL`, if not requested; if `NULL` is returned, no `DM`s are defined) 2031e7c4fc90SDmitry Karpeev 2032e7c4fc90SDmitry Karpeev Level: intermediate 2033e7c4fc90SDmitry Karpeev 2034a4e35b19SJacob Faibussowitsch Notes: 2035a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding field, defined by 2036a4e35b19SJacob Faibussowitsch `DMAddField()`. The optional list of `DM`s define the `DM` for each subproblem. 2037a4e35b19SJacob Faibussowitsch 2038a4e35b19SJacob Faibussowitsch The same as `DMCreateFieldIS()` but also returns a `DM` for each field. 2039a4e35b19SJacob Faibussowitsch 204073ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `namelist` should be freed with 204173ff1848SBarry Smith `PetscFree()`, every entry of `islist` should be destroyed with `ISDestroy()`, every entry of `dmlist` should be destroyed with `DMDestroy()`, 2042bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 2043e7c4fc90SDmitry Karpeev 204460225df5SJacob Faibussowitsch Developer Notes: 2045bb7acecfSBarry Smith It is not clear why this function and `DMCreateFieldIS()` exist. Having two seems redundant and confusing. 2046bb7acecfSBarry Smith 204773ff1848SBarry Smith Unlike `DMRefine()`, `DMCoarsen()`, and `DMCreateDomainDecomposition()` this provides no mechanism to provide hooks that are called after the 204873ff1848SBarry Smith decomposition is computed. 204973ff1848SBarry Smith 205073ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMCreateFieldIS()`, `DMCreateSubDM()`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()` 2051e7c4fc90SDmitry Karpeev @*/ 2052d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 2053d71ae5a4SJacob Faibussowitsch { 2054e7c4fc90SDmitry Karpeev PetscFunctionBegin; 2055e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20568865f1eaSKarl Rupp if (len) { 20574f572ea9SToby Isaac PetscAssertPointer(len, 2); 20588865f1eaSKarl Rupp *len = 0; 20598865f1eaSKarl Rupp } 20608865f1eaSKarl Rupp if (namelist) { 20614f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 2062ea78f98cSLisandro Dalcin *namelist = NULL; 20638865f1eaSKarl Rupp } 20648865f1eaSKarl Rupp if (islist) { 20654f572ea9SToby Isaac PetscAssertPointer(islist, 4); 2066ea78f98cSLisandro Dalcin *islist = NULL; 20678865f1eaSKarl Rupp } 20688865f1eaSKarl Rupp if (dmlist) { 20694f572ea9SToby Isaac PetscAssertPointer(dmlist, 5); 2070ea78f98cSLisandro Dalcin *dmlist = NULL; 20718865f1eaSKarl Rupp } 2072f3f0edfdSDmitry Karpeev /* 2073f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2074f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2075f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2076f3f0edfdSDmitry Karpeev */ 20777a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 207816621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 2079435a35e8SMatthew G Knepley PetscSection section; 2080435a35e8SMatthew G Knepley PetscInt numFields, f; 2081435a35e8SMatthew G Knepley 20829566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 20839566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(section, &numFields)); 2084435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 2085f25d98f1SMatthew G. Knepley if (len) *len = numFields; 20869566063dSJacob Faibussowitsch if (namelist) PetscCall(PetscMalloc1(numFields, namelist)); 20879566063dSJacob Faibussowitsch if (islist) PetscCall(PetscMalloc1(numFields, islist)); 20889566063dSJacob Faibussowitsch if (dmlist) PetscCall(PetscMalloc1(numFields, dmlist)); 2089435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 2090435a35e8SMatthew G Knepley const char *fieldName; 2091435a35e8SMatthew G Knepley 20929566063dSJacob Faibussowitsch PetscCall(DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL)); 209303dc3394SMatthew G. Knepley if (namelist) { 20949566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 2095835f2295SStefano Zampini PetscCall(PetscStrallocpy(fieldName, &(*namelist)[f])); 2096435a35e8SMatthew G Knepley } 209703dc3394SMatthew G. Knepley } 2098435a35e8SMatthew G Knepley } else { 20999566063dSJacob Faibussowitsch PetscCall(DMCreateFieldIS(dm, len, namelist, islist)); 2100e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 21010298fd71SBarry Smith if (dmlist) *dmlist = NULL; 2102e7c4fc90SDmitry Karpeev } 2103dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, createfielddecomposition, len, namelist, islist, dmlist); 21043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 210516621825SDmitry Karpeev } 210616621825SDmitry Karpeev 21075d83a8b1SBarry Smith /*@ 210820f4b53cSBarry Smith DMCreateSubDM - Returns an `IS` and `DM` encapsulating a subproblem defined by the fields passed in. 210920f4b53cSBarry Smith The fields are defined by `DMCreateFieldIS()`. 2110435a35e8SMatthew G Knepley 2111435a35e8SMatthew G Knepley Not collective 2112435a35e8SMatthew G Knepley 2113435a35e8SMatthew G Knepley Input Parameters: 2114bb7acecfSBarry Smith + dm - The `DM` object 2115bb7acecfSBarry Smith . numFields - The number of fields to select 21162adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 2117435a35e8SMatthew G Knepley 2118435a35e8SMatthew G Knepley Output Parameters: 2119b6971eaeSBarry Smith + is - The global indices for all the degrees of freedom in the new sub `DM`, use `NULL` if not needed 2120b6971eaeSBarry Smith - subdm - The `DM` for the subproblem, use `NULL` if not needed 2121435a35e8SMatthew G Knepley 212220f4b53cSBarry Smith Level: intermediate 212320f4b53cSBarry Smith 2124bb7acecfSBarry Smith Note: 2125bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 21265d3b26e6SMatthew G. Knepley 212760225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateFieldIS()`, `DMCreateFieldDecomposition()`, `DMAddField()`, `DMCreateSuperDM()`, `IS`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 2128435a35e8SMatthew G Knepley @*/ 2129d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2130d71ae5a4SJacob Faibussowitsch { 2131435a35e8SMatthew G Knepley PetscFunctionBegin; 2132435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21334f572ea9SToby Isaac PetscAssertPointer(fields, 3); 21344f572ea9SToby Isaac if (is) PetscAssertPointer(is, 4); 21354f572ea9SToby Isaac if (subdm) PetscAssertPointer(subdm, 5); 2136dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createsubdm, numFields, fields, is, subdm); 21373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2138435a35e8SMatthew G Knepley } 2139435a35e8SMatthew G Knepley 21402adcc780SMatthew G. Knepley /*@C 2141bb7acecfSBarry Smith DMCreateSuperDM - Returns an arrays of `IS` and `DM` encapsulating a superproblem defined by multiple `DM`s passed in. 21422adcc780SMatthew G. Knepley 21432adcc780SMatthew G. Knepley Not collective 21442adcc780SMatthew G. Knepley 2145d8d19677SJose E. Roman Input Parameters: 2146bb7acecfSBarry Smith + dms - The `DM` objects 2147bb7acecfSBarry Smith - n - The number of `DM`s 21482adcc780SMatthew G. Knepley 21492adcc780SMatthew G. Knepley Output Parameters: 2150bb7acecfSBarry Smith + is - The global indices for each of subproblem within the super `DM`, or NULL 2151bb7acecfSBarry Smith - superdm - The `DM` for the superproblem 21522adcc780SMatthew G. Knepley 215320f4b53cSBarry Smith Level: intermediate 215420f4b53cSBarry Smith 2155bb7acecfSBarry Smith Note: 2156bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 21575d3b26e6SMatthew G. Knepley 215873ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateSubDM()`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()`, `DMCreateDomainDecomposition()` 21592adcc780SMatthew G. Knepley @*/ 21605d83a8b1SBarry Smith PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt n, IS *is[], DM *superdm) 2161d71ae5a4SJacob Faibussowitsch { 21622adcc780SMatthew G. Knepley PetscInt i; 21632adcc780SMatthew G. Knepley 21642adcc780SMatthew G. Knepley PetscFunctionBegin; 21654f572ea9SToby Isaac PetscAssertPointer(dms, 1); 2166ad540459SPierre Jolivet for (i = 0; i < n; ++i) PetscValidHeaderSpecific(dms[i], DM_CLASSID, 1); 21674f572ea9SToby Isaac if (is) PetscAssertPointer(is, 3); 21684f572ea9SToby Isaac PetscAssertPointer(superdm, 4); 2169bb7acecfSBarry Smith PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %" PetscInt_FMT, n); 2170bb7acecfSBarry Smith if (n) { 2171b9d85ea2SLisandro Dalcin DM dm = dms[0]; 217200045ab3SPierre Jolivet PetscCheck(dm->ops->createsuperdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No method createsuperdm for DM of type %s", ((PetscObject)dm)->type_name); 2173dbbe0bcdSBarry Smith PetscCall((*dm->ops->createsuperdm)(dms, n, is, superdm)); 21742adcc780SMatthew G. Knepley } 21753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21762adcc780SMatthew G. Knepley } 21772adcc780SMatthew G. Knepley 217816621825SDmitry Karpeev /*@C 2179a4e35b19SJacob Faibussowitsch DMCreateDomainDecomposition - Returns lists of `IS` objects defining a decomposition of a 2180a4e35b19SJacob Faibussowitsch problem into subproblems corresponding to restrictions to pairs of nested subdomains. 218116621825SDmitry Karpeev 218220f4b53cSBarry Smith Not Collective 218316621825SDmitry Karpeev 218416621825SDmitry Karpeev Input Parameter: 2185bb7acecfSBarry Smith . dm - the `DM` object 218616621825SDmitry Karpeev 218716621825SDmitry Karpeev Output Parameters: 218820f4b53cSBarry Smith + n - The number of subproblems in the domain decomposition (or `NULL` if not requested) 218920f4b53cSBarry Smith . namelist - The name for each subdomain (or `NULL` if not requested) 219073ff1848SBarry Smith . innerislist - The global indices for each inner subdomain (or `NULL`, if not requested) 219173ff1848SBarry Smith . outerislist - The global indices for each outer subdomain (or `NULL`, if not requested) 219273ff1848SBarry Smith - dmlist - The `DM`s for each subdomain subproblem (or `NULL`, if not requested; if `NULL` is returned, no `DM`s are defined) 219316621825SDmitry Karpeev 219416621825SDmitry Karpeev Level: intermediate 219516621825SDmitry Karpeev 219673ff1848SBarry Smith Notes: 2197a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding subdomains with in the 2198a4e35b19SJacob Faibussowitsch dofs of the original `DM`. The inner subdomains conceptually define a nonoverlapping 2199a4e35b19SJacob Faibussowitsch covering, while outer subdomains can overlap. 2200a4e35b19SJacob Faibussowitsch 2201a4e35b19SJacob Faibussowitsch The optional list of `DM`s define a `DM` for each subproblem. 2202a4e35b19SJacob Faibussowitsch 220373ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `namelist` should be freed with 220473ff1848SBarry Smith `PetscFree()`, every entry of `innerislist` and `outerislist` should be destroyed with `ISDestroy()`, every entry of `dmlist` should be destroyed with `DMDestroy()`, 2205bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 220616621825SDmitry Karpeev 2207a4e35b19SJacob Faibussowitsch Developer Notes: 220820f4b53cSBarry Smith The `dmlist` is for the inner subdomains or the outer subdomains or all subdomains? 2209bb7acecfSBarry Smith 221073ff1848SBarry Smith The names are inconsistent, the hooks use `DMSubDomainHook` which is nothing like `DMCreateDomainDecomposition()` while `DMRefineHook` is used for `DMRefine()`. 221173ff1848SBarry Smith 221273ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateFieldDecomposition()`, `DMDestroy()`, `DMCreateDomainDecompositionScatters()`, `DMView()`, `DMCreateInterpolation()`, 221373ff1848SBarry Smith `DMSubDomainHookAdd()`, `DMSubDomainHookRemove()`,`DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()` 221416621825SDmitry Karpeev @*/ 2215d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *n, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 2216d71ae5a4SJacob Faibussowitsch { 2217be081cd6SPeter Brune DMSubDomainHookLink link; 2218be081cd6SPeter Brune PetscInt i, l; 221916621825SDmitry Karpeev 222016621825SDmitry Karpeev PetscFunctionBegin; 222116621825SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22229371c9d4SSatish Balay if (n) { 22234f572ea9SToby Isaac PetscAssertPointer(n, 2); 22249371c9d4SSatish Balay *n = 0; 22259371c9d4SSatish Balay } 22269371c9d4SSatish Balay if (namelist) { 22274f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 22289371c9d4SSatish Balay *namelist = NULL; 22299371c9d4SSatish Balay } 22309371c9d4SSatish Balay if (innerislist) { 22314f572ea9SToby Isaac PetscAssertPointer(innerislist, 4); 22329371c9d4SSatish Balay *innerislist = NULL; 22339371c9d4SSatish Balay } 22349371c9d4SSatish Balay if (outerislist) { 22354f572ea9SToby Isaac PetscAssertPointer(outerislist, 5); 22369371c9d4SSatish Balay *outerislist = NULL; 22379371c9d4SSatish Balay } 22389371c9d4SSatish Balay if (dmlist) { 22394f572ea9SToby Isaac PetscAssertPointer(dmlist, 6); 22409371c9d4SSatish Balay *dmlist = NULL; 22419371c9d4SSatish Balay } 2242f3f0edfdSDmitry Karpeev /* 2243f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2244f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2245f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2246f3f0edfdSDmitry Karpeev */ 22477a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 224816621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 2249dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createdomaindecomposition, &l, namelist, innerislist, outerislist, dmlist); 225014a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 2251f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2252be081cd6SPeter Brune for (i = 0; i < l; i++) { 2253be081cd6SPeter Brune for (link = dm->subdomainhook; link; link = link->next) { 22549566063dSJacob Faibussowitsch if (link->ddhook) PetscCall((*link->ddhook)(dm, (*dmlist)[i], link->ctx)); 2255be081cd6SPeter Brune } 2256648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2257e7c4fc90SDmitry Karpeev } 225814a18fd3SPeter Brune } 2259bb7acecfSBarry Smith if (n) *n = l; 226014a18fd3SPeter Brune } 22613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2262e30e807fSPeter Brune } 2263e30e807fSPeter Brune 2264e30e807fSPeter Brune /*@C 226573ff1848SBarry Smith DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector for subdomains created with 226673ff1848SBarry Smith `DMCreateDomainDecomposition()` 2267e30e807fSPeter Brune 226820f4b53cSBarry Smith Not Collective 2269e30e807fSPeter Brune 2270e30e807fSPeter Brune Input Parameters: 2271bb7acecfSBarry Smith + dm - the `DM` object 227273ff1848SBarry Smith . n - the number of subdomains 2273e30e807fSPeter Brune - subdms - the local subdomains 2274e30e807fSPeter Brune 2275e30e807fSPeter Brune Output Parameters: 22766b867d5aSJose E. Roman + iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2277e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2278e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2279e30e807fSPeter Brune 228020f4b53cSBarry Smith Level: developer 228120f4b53cSBarry Smith 2282bb7acecfSBarry Smith Note: 2283bb7acecfSBarry Smith This is an alternative to the iis and ois arguments in `DMCreateDomainDecomposition()` that allow for the solution 2284e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2285e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2286e30e807fSPeter Brune solution and residual data. 2287e30e807fSPeter Brune 228873ff1848SBarry Smith Developer Note: 2289a4e35b19SJacob Faibussowitsch Can the subdms input be anything or are they exactly the `DM` obtained from 2290a4e35b19SJacob Faibussowitsch `DMCreateDomainDecomposition()`? 2291bb7acecfSBarry Smith 22921cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2293e30e807fSPeter Brune @*/ 22945d83a8b1SBarry Smith PetscErrorCode DMCreateDomainDecompositionScatters(DM dm, PetscInt n, DM *subdms, VecScatter *iscat[], VecScatter *oscat[], VecScatter *gscat[]) 2295d71ae5a4SJacob Faibussowitsch { 2296e30e807fSPeter Brune PetscFunctionBegin; 2297e30e807fSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22984f572ea9SToby Isaac PetscAssertPointer(subdms, 3); 2299dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createddscatters, n, subdms, iscat, oscat, gscat); 23003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2301e7c4fc90SDmitry Karpeev } 2302e7c4fc90SDmitry Karpeev 230347c6ae99SBarry Smith /*@ 2304bb7acecfSBarry Smith DMRefine - Refines a `DM` object using a standard nonadaptive refinement of the underlying mesh 230547c6ae99SBarry Smith 230620f4b53cSBarry Smith Collective 230747c6ae99SBarry Smith 2308d8d19677SJose E. Roman Input Parameters: 2309bb7acecfSBarry Smith + dm - the `DM` object 2310bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 231147c6ae99SBarry Smith 231247c6ae99SBarry Smith Output Parameter: 231320f4b53cSBarry Smith . dmf - the refined `DM`, or `NULL` 2314ae0a1c52SMatthew G Knepley 231520f4b53cSBarry Smith Options Database Key: 2316412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2317412e9a14SMatthew G. Knepley 231847c6ae99SBarry Smith Level: developer 231947c6ae99SBarry Smith 232020f4b53cSBarry Smith Note: 232120f4b53cSBarry Smith If no refinement was done, the return value is `NULL` 232220f4b53cSBarry Smith 232373ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateDomainDecomposition()`, 232473ff1848SBarry Smith `DMRefineHookAdd()`, `DMRefineHookRemove()` 232547c6ae99SBarry Smith @*/ 2326d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine(DM dm, MPI_Comm comm, DM *dmf) 2327d71ae5a4SJacob Faibussowitsch { 2328c833c3b5SJed Brown DMRefineHookLink link; 232947c6ae99SBarry Smith 233047c6ae99SBarry Smith PetscFunctionBegin; 2331732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 23329566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Refine, dm, 0, 0, 0)); 2333dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refine, comm, dmf); 23344057135bSMatthew G Knepley if (*dmf) { 233543842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 23368865f1eaSKarl Rupp 23379566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmf)); 23388865f1eaSKarl Rupp 2339644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 23400598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2341656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 23428865f1eaSKarl Rupp 23439566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmf, dm->mattype)); 2344c833c3b5SJed Brown for (link = dm->refinehook; link; link = link->next) { 23451baa6e33SBarry Smith if (link->refinehook) PetscCall((*link->refinehook)(dm, *dmf, link->ctx)); 2346c833c3b5SJed Brown } 2347c833c3b5SJed Brown } 23489566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Refine, dm, 0, 0, 0)); 23493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2350c833c3b5SJed Brown } 2351c833c3b5SJed Brown 2352bb9467b5SJed Brown /*@C 2353c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2354c833c3b5SJed Brown 235520f4b53cSBarry Smith Logically Collective; No Fortran Support 2356c833c3b5SJed Brown 23574165533cSJose E. Roman Input Parameters: 2358bb7acecfSBarry Smith + coarse - `DM` on which to run a hook when interpolating to a finer level 2359bb7acecfSBarry Smith . refinehook - function to run when setting up the finer level 2360f826b5fcSPierre Jolivet . interphook - function to run to update data on finer levels (once per `SNESSolve()`) 236120f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2362c833c3b5SJed Brown 236320f4b53cSBarry Smith Calling sequence of `refinehook`: 2364bb7acecfSBarry Smith + coarse - coarse level `DM` 2365bb7acecfSBarry Smith . fine - fine level `DM` to interpolate problem to 2366c833c3b5SJed Brown - ctx - optional user-defined function context 2367c833c3b5SJed Brown 236820f4b53cSBarry Smith Calling sequence of `interphook`: 2369bb7acecfSBarry Smith + coarse - coarse level `DM` 2370c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2371bb7acecfSBarry Smith . fine - fine level `DM` to update 2372c833c3b5SJed Brown - ctx - optional user-defined function context 2373c833c3b5SJed Brown 2374c833c3b5SJed Brown Level: advanced 2375c833c3b5SJed Brown 2376c833c3b5SJed Brown Notes: 2377bb7acecfSBarry Smith This function is only needed if auxiliary data that is attached to the `DM`s via, for example, `PetscObjectCompose()`, needs to be 2378bb7acecfSBarry Smith passed to fine grids while grid sequencing. 2379bb7acecfSBarry Smith 2380bb7acecfSBarry Smith The actual interpolation is done when `DMInterpolate()` is called. 2381c833c3b5SJed Brown 2382c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2383c833c3b5SJed Brown 23841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2385c833c3b5SJed Brown @*/ 2386a4e35b19SJacob 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) 2387d71ae5a4SJacob Faibussowitsch { 2388c833c3b5SJed Brown DMRefineHookLink link, *p; 2389c833c3b5SJed Brown 2390c833c3b5SJed Brown PetscFunctionBegin; 2391c833c3b5SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 23923d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 23933ba16761SJacob Faibussowitsch if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 23943d8e3701SJed Brown } 23959566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2396c833c3b5SJed Brown link->refinehook = refinehook; 2397c833c3b5SJed Brown link->interphook = interphook; 2398c833c3b5SJed Brown link->ctx = ctx; 23990298fd71SBarry Smith link->next = NULL; 2400c833c3b5SJed Brown *p = link; 24013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2402c833c3b5SJed Brown } 2403c833c3b5SJed Brown 24043d8e3701SJed Brown /*@C 2405bb7acecfSBarry Smith DMRefineHookRemove - remove a callback from the list of hooks, that have been set with `DMRefineHookAdd()`, to be run when interpolating 2406bb7acecfSBarry Smith a nonlinear problem to a finer grid 24073d8e3701SJed Brown 240820f4b53cSBarry Smith Logically Collective; No Fortran Support 24093d8e3701SJed Brown 24104165533cSJose E. Roman Input Parameters: 2411bb7acecfSBarry Smith + coarse - the `DM` on which to run a hook when restricting to a coarser level 2412bb7acecfSBarry Smith . refinehook - function to run when setting up a finer level 2413bb7acecfSBarry Smith . interphook - function to run to update data on finer levels 241420f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 24153d8e3701SJed Brown 24163d8e3701SJed Brown Level: advanced 24173d8e3701SJed Brown 2418bb7acecfSBarry Smith Note: 24193d8e3701SJed Brown This function does nothing if the hook is not in the list. 24203d8e3701SJed Brown 24211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `DMCoarsenHookRemove()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 24223d8e3701SJed Brown @*/ 2423d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHookRemove(DM coarse, PetscErrorCode (*refinehook)(DM, DM, void *), PetscErrorCode (*interphook)(DM, Mat, DM, void *), void *ctx) 2424d71ae5a4SJacob Faibussowitsch { 24253d8e3701SJed Brown DMRefineHookLink link, *p; 24263d8e3701SJed Brown 24273d8e3701SJed Brown PetscFunctionBegin; 24283d8e3701SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 24293d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 24303d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 24313d8e3701SJed Brown link = *p; 24323d8e3701SJed Brown *p = link->next; 24339566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 24343d8e3701SJed Brown break; 24353d8e3701SJed Brown } 24363d8e3701SJed Brown } 24373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24383d8e3701SJed Brown } 24393d8e3701SJed Brown 2440c833c3b5SJed Brown /*@ 2441bb7acecfSBarry Smith DMInterpolate - interpolates user-defined problem data attached to a `DM` to a finer `DM` by running hooks registered by `DMRefineHookAdd()` 2442c833c3b5SJed Brown 2443c833c3b5SJed Brown Collective if any hooks are 2444c833c3b5SJed Brown 24454165533cSJose E. Roman Input Parameters: 2446bb7acecfSBarry Smith + coarse - coarser `DM` to use as a base 2447bb7acecfSBarry Smith . interp - interpolation matrix, apply using `MatInterpolate()` 2448bb7acecfSBarry Smith - fine - finer `DM` to update 2449c833c3b5SJed Brown 2450c833c3b5SJed Brown Level: developer 2451c833c3b5SJed Brown 245273ff1848SBarry Smith Developer Note: 2453bb7acecfSBarry Smith This routine is called `DMInterpolate()` while the hook is called `DMRefineHookAdd()`. It would be better to have an 2454bb7acecfSBarry Smith an API with consistent terminology. 2455bb7acecfSBarry Smith 24561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `MatInterpolate()` 2457c833c3b5SJed Brown @*/ 2458d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolate(DM coarse, Mat interp, DM fine) 2459d71ae5a4SJacob Faibussowitsch { 2460c833c3b5SJed Brown DMRefineHookLink link; 2461c833c3b5SJed Brown 2462c833c3b5SJed Brown PetscFunctionBegin; 2463c833c3b5SJed Brown for (link = fine->refinehook; link; link = link->next) { 24641baa6e33SBarry Smith if (link->interphook) PetscCall((*link->interphook)(coarse, interp, fine, link->ctx)); 24654057135bSMatthew G Knepley } 24663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 246747c6ae99SBarry Smith } 246847c6ae99SBarry Smith 2469eb3f98d2SBarry Smith /*@ 24701f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 24711f3379b2SToby Isaac 247220f4b53cSBarry Smith Collective 24731f3379b2SToby Isaac 24744165533cSJose E. Roman Input Parameters: 2475bb7acecfSBarry Smith + coarse - coarse `DM` 2476bb7acecfSBarry Smith . fine - fine `DM` 2477bb7acecfSBarry Smith . interp - (optional) the matrix computed by `DMCreateInterpolation()`. Implementations may not need this, but if it 2478bb7acecfSBarry Smith is available it can avoid some recomputation. If it is provided, `MatInterpolate()` will be used if 2479bb7acecfSBarry Smith the coarse `DM` does not have a specialized implementation. 24801f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 24811f3379b2SToby Isaac 24824165533cSJose E. Roman Output Parameter: 24831f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 24841f3379b2SToby Isaac 24851f3379b2SToby Isaac Level: developer 24861f3379b2SToby Isaac 2487bb7acecfSBarry Smith Note: 2488bb7acecfSBarry Smith This function exists because the interpolation of a solution vector between meshes is not always a linear 24891f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 24901f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 24911f3379b2SToby Isaac slope-limiting reconstruction. 24921f3379b2SToby Isaac 249373ff1848SBarry Smith Developer Note: 2494bb7acecfSBarry Smith This doesn't just interpolate "solutions" so its API name is questionable. 2495bb7acecfSBarry Smith 24961cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMInterpolate()`, `DMCreateInterpolation()` 24971f3379b2SToby Isaac @*/ 2498d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 2499d71ae5a4SJacob Faibussowitsch { 25001f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM, DM, Mat, Vec, Vec) = NULL; 25011f3379b2SToby Isaac 25021f3379b2SToby Isaac PetscFunctionBegin; 25031f3379b2SToby Isaac PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 25041f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp, MAT_CLASSID, 3); 25051f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol, VEC_CLASSID, 4); 25061f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol, VEC_CLASSID, 5); 25071f3379b2SToby Isaac 25089566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)coarse, "DMInterpolateSolution_C", &interpsol)); 25091f3379b2SToby Isaac if (interpsol) { 25109566063dSJacob Faibussowitsch PetscCall((*interpsol)(coarse, fine, interp, coarseSol, fineSol)); 25111f3379b2SToby Isaac } else if (interp) { 25129566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, coarseSol, fineSol)); 251398921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 25143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25151f3379b2SToby Isaac } 25161f3379b2SToby Isaac 25171f3379b2SToby Isaac /*@ 2518bb7acecfSBarry Smith DMGetRefineLevel - Gets the number of refinements that have generated this `DM` from some initial `DM`. 2519eb3f98d2SBarry Smith 2520eb3f98d2SBarry Smith Not Collective 2521eb3f98d2SBarry Smith 2522eb3f98d2SBarry Smith Input Parameter: 2523bb7acecfSBarry Smith . dm - the `DM` object 2524eb3f98d2SBarry Smith 2525eb3f98d2SBarry Smith Output Parameter: 2526eb3f98d2SBarry Smith . level - number of refinements 2527eb3f98d2SBarry Smith 2528eb3f98d2SBarry Smith Level: developer 2529eb3f98d2SBarry Smith 2530bb7acecfSBarry Smith Note: 2531bb7acecfSBarry Smith This can be used, by example, to set the number of coarser levels associated with this `DM` for a multigrid solver. 2532bb7acecfSBarry Smith 25331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2534eb3f98d2SBarry Smith @*/ 2535d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRefineLevel(DM dm, PetscInt *level) 2536d71ae5a4SJacob Faibussowitsch { 2537eb3f98d2SBarry Smith PetscFunctionBegin; 2538eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2539eb3f98d2SBarry Smith *level = dm->levelup; 25403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2541eb3f98d2SBarry Smith } 2542eb3f98d2SBarry Smith 2543fef3a512SBarry Smith /*@ 2544bb7acecfSBarry Smith DMSetRefineLevel - Sets the number of refinements that have generated this `DM`. 2545fef3a512SBarry Smith 2546fef3a512SBarry Smith Not Collective 2547fef3a512SBarry Smith 2548d8d19677SJose E. Roman Input Parameters: 2549bb7acecfSBarry Smith + dm - the `DM` object 2550fef3a512SBarry Smith - level - number of refinements 2551fef3a512SBarry Smith 2552fef3a512SBarry Smith Level: advanced 2553fef3a512SBarry Smith 255495452b02SPatrick Sanan Notes: 2555bb7acecfSBarry Smith This value is used by `PCMG` to determine how many multigrid levels to use 2556fef3a512SBarry Smith 2557bb7acecfSBarry Smith The values are usually set automatically by the process that is causing the refinements of an initial `DM` by calling this routine. 2558bb7acecfSBarry Smith 25591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRefineLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2560fef3a512SBarry Smith @*/ 2561d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRefineLevel(DM dm, PetscInt level) 2562d71ae5a4SJacob Faibussowitsch { 2563fef3a512SBarry Smith PetscFunctionBegin; 2564fef3a512SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2565fef3a512SBarry Smith dm->levelup = level; 25663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2567fef3a512SBarry Smith } 2568fef3a512SBarry Smith 2569d410b0cfSMatthew G. Knepley /*@ 2570bb7acecfSBarry Smith DMExtrude - Extrude a `DM` object from a surface 2571d410b0cfSMatthew G. Knepley 257220f4b53cSBarry Smith Collective 2573d410b0cfSMatthew G. Knepley 2574f1a722f8SMatthew G. Knepley Input Parameters: 2575bb7acecfSBarry Smith + dm - the `DM` object 2576d410b0cfSMatthew G. Knepley - layers - the number of extruded cell layers 2577d410b0cfSMatthew G. Knepley 2578d410b0cfSMatthew G. Knepley Output Parameter: 257920f4b53cSBarry Smith . dme - the extruded `DM`, or `NULL` 2580d410b0cfSMatthew G. Knepley 2581d410b0cfSMatthew G. Knepley Level: developer 2582d410b0cfSMatthew G. Knepley 258320f4b53cSBarry Smith Note: 258420f4b53cSBarry Smith If no extrusion was done, the return value is `NULL` 258520f4b53cSBarry Smith 25861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()` 2587d410b0cfSMatthew G. Knepley @*/ 2588d71ae5a4SJacob Faibussowitsch PetscErrorCode DMExtrude(DM dm, PetscInt layers, DM *dme) 2589d71ae5a4SJacob Faibussowitsch { 2590d410b0cfSMatthew G. Knepley PetscFunctionBegin; 2591d410b0cfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2592dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, extrude, layers, dme); 2593d410b0cfSMatthew G. Knepley if (*dme) { 2594d410b0cfSMatthew G. Knepley (*dme)->ops->creatematrix = dm->ops->creatematrix; 25959566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dme)); 2596d410b0cfSMatthew G. Knepley (*dme)->ctx = dm->ctx; 25979566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dme, dm->mattype)); 2598d410b0cfSMatthew G. Knepley } 25993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2600d410b0cfSMatthew G. Knepley } 2601d410b0cfSMatthew G. Knepley 2602d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2603d71ae5a4SJacob Faibussowitsch { 2604ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2605ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26064f572ea9SToby Isaac PetscAssertPointer(tdm, 2); 2607ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 26083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2609ca3d3a14SMatthew G. Knepley } 2610ca3d3a14SMatthew G. Knepley 2611d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2612d71ae5a4SJacob Faibussowitsch { 2613ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2614ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26154f572ea9SToby Isaac PetscAssertPointer(tv, 2); 2616ca3d3a14SMatthew G. Knepley *tv = dm->transform; 26173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2618ca3d3a14SMatthew G. Knepley } 2619ca3d3a14SMatthew G. Knepley 2620ca3d3a14SMatthew G. Knepley /*@ 2621bb7acecfSBarry Smith DMHasBasisTransform - Whether the `DM` employs a basis transformation from functions in global vectors to functions in local vectors 2622ca3d3a14SMatthew G. Knepley 2623ca3d3a14SMatthew G. Knepley Input Parameter: 262420f4b53cSBarry Smith . dm - The `DM` 2625ca3d3a14SMatthew G. Knepley 2626ca3d3a14SMatthew G. Knepley Output Parameter: 262720f4b53cSBarry Smith . flg - `PETSC_TRUE` if a basis transformation should be done 2628ca3d3a14SMatthew G. Knepley 2629ca3d3a14SMatthew G. Knepley Level: developer 2630ca3d3a14SMatthew G. Knepley 26311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPlexGlobalToLocalBasis()`, `DMPlexLocalToGlobalBasis()`, `DMPlexCreateBasisRotation()` 2632ca3d3a14SMatthew G. Knepley @*/ 2633d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2634d71ae5a4SJacob Faibussowitsch { 2635ca3d3a14SMatthew G. Knepley Vec tv; 2636ca3d3a14SMatthew G. Knepley 2637ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2638ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26394f572ea9SToby Isaac PetscAssertPointer(flg, 2); 26409566063dSJacob Faibussowitsch PetscCall(DMGetBasisTransformVec_Internal(dm, &tv)); 2641ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 26423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2643ca3d3a14SMatthew G. Knepley } 2644ca3d3a14SMatthew G. Knepley 2645d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2646d71ae5a4SJacob Faibussowitsch { 2647ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2648ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2649ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2650ca3d3a14SMatthew G. Knepley 2651ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 26529566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 26539566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 26549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 26559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 26569566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->transformDM)); 26579566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm->transformDM, &ts)); 26589566063dSJacob Faibussowitsch PetscCall(PetscSectionSetNumFields(ts, Nf)); 26599566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(ts, pStart, pEnd)); 2660ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26619566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(s, f, &Nc)); 2662ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2663ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2664ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 26659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &dof)); 2666ca3d3a14SMatthew G. Knepley if (!dof) continue; 26679566063dSJacob Faibussowitsch PetscCall(PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim))); 26689566063dSJacob Faibussowitsch PetscCall(PetscSectionAddDof(ts, p, PetscSqr(cdim))); 2669ca3d3a14SMatthew G. Knepley } 2670ca3d3a14SMatthew G. Knepley } 26719566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(ts)); 26729566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dm->transformDM, &dm->transform)); 26739566063dSJacob Faibussowitsch PetscCall(VecGetArray(dm->transform, &ta)); 2674ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2675ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26769566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(ts, p, f, &dof)); 2677ca3d3a14SMatthew G. Knepley if (dof) { 2678ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2679ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2680ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2681ca3d3a14SMatthew G. Knepley 2682ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 26839566063dSJacob Faibussowitsch PetscCall((*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx)); 26849566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *)&tva)); 26859566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tva, A, PetscSqr(cdim))); 2686ca3d3a14SMatthew G. Knepley } 2687ca3d3a14SMatthew G. Knepley } 2688ca3d3a14SMatthew G. Knepley } 26899566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(dm->transform, &ta)); 26903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2691ca3d3a14SMatthew G. Knepley } 2692ca3d3a14SMatthew G. Knepley 2693d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2694d71ae5a4SJacob Faibussowitsch { 2695ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2696ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2697ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2698ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2699ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2700ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2701ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 27029566063dSJacob Faibussowitsch if (newdm->transformSetUp) PetscCall(DMConstructBasisTransform_Internal(newdm)); 27033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2704ca3d3a14SMatthew G. Knepley } 2705ca3d3a14SMatthew G. Knepley 2706bb9467b5SJed Brown /*@C 2707bb7acecfSBarry Smith DMGlobalToLocalHookAdd - adds a callback to be run when `DMGlobalToLocal()` is called 2708baf369e7SPeter Brune 270920f4b53cSBarry Smith Logically Collective 2710baf369e7SPeter Brune 27114165533cSJose E. Roman Input Parameters: 2712bb7acecfSBarry Smith + dm - the `DM` 2713bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMGlobalToLocalBegin()` 2714bb7acecfSBarry Smith . endhook - function to run after `DMGlobalToLocalEnd()` has completed 271520f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2716baf369e7SPeter Brune 271720f4b53cSBarry Smith Calling sequence of `beginhook`: 2718a4e35b19SJacob Faibussowitsch + dm - global `DM` 2719baf369e7SPeter Brune . g - global vector 2720baf369e7SPeter Brune . mode - mode 2721baf369e7SPeter Brune . l - local vector 2722baf369e7SPeter Brune - ctx - optional user-defined function context 2723baf369e7SPeter Brune 272420f4b53cSBarry Smith Calling sequence of `endhook`: 2725a4e35b19SJacob Faibussowitsch + dm - global `DM` 2726a4e35b19SJacob Faibussowitsch . g - global vector 2727a4e35b19SJacob Faibussowitsch . mode - mode 2728a4e35b19SJacob Faibussowitsch . l - local vector 2729baf369e7SPeter Brune - ctx - optional user-defined function context 2730baf369e7SPeter Brune 2731baf369e7SPeter Brune Level: advanced 2732baf369e7SPeter Brune 2733bb7acecfSBarry Smith Note: 2734bb7acecfSBarry 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. 2735bb7acecfSBarry Smith 27361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocal()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2737baf369e7SPeter Brune @*/ 2738a4e35b19SJacob 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) 2739d71ae5a4SJacob Faibussowitsch { 2740baf369e7SPeter Brune DMGlobalToLocalHookLink link, *p; 2741baf369e7SPeter Brune 2742baf369e7SPeter Brune PetscFunctionBegin; 2743baf369e7SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2744baf369e7SPeter Brune for (p = &dm->gtolhook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 27459566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2746baf369e7SPeter Brune link->beginhook = beginhook; 2747baf369e7SPeter Brune link->endhook = endhook; 2748baf369e7SPeter Brune link->ctx = ctx; 27490298fd71SBarry Smith link->next = NULL; 2750baf369e7SPeter Brune *p = link; 27513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2752baf369e7SPeter Brune } 2753baf369e7SPeter Brune 2754d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 2755d71ae5a4SJacob Faibussowitsch { 27564c274da1SToby Isaac Mat cMat; 275779769bd5SJed Brown Vec cVec, cBias; 27584c274da1SToby Isaac PetscSection section, cSec; 27594c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 27604c274da1SToby Isaac 27614c274da1SToby Isaac PetscFunctionBegin; 2762a4e35b19SJacob Faibussowitsch (void)g; 2763a4e35b19SJacob Faibussowitsch (void)ctx; 27644c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 27659566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, &cBias)); 27664c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 27675db9a05bSToby Isaac PetscInt nRows; 27685db9a05bSToby Isaac 27699566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 27703ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 27719566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 27729566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 27739566063dSJacob Faibussowitsch PetscCall(MatMult(cMat, l, cVec)); 27749566063dSJacob Faibussowitsch if (cBias) PetscCall(VecAXPY(cVec, 1., cBias)); 27759566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 27764c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 27779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 27784c274da1SToby Isaac if (dof) { 27794c274da1SToby Isaac PetscScalar *vals; 27809566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(cVec, cSec, p, &vals)); 27819566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(l, section, p, vals, INSERT_ALL_VALUES)); 27824c274da1SToby Isaac } 27834c274da1SToby Isaac } 27849566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 27854c274da1SToby Isaac } 27863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27874c274da1SToby Isaac } 27884c274da1SToby Isaac 278947c6ae99SBarry Smith /*@ 279001729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 279101729b5cSPatrick Sanan 279220f4b53cSBarry Smith Neighbor-wise Collective 279301729b5cSPatrick Sanan 279401729b5cSPatrick Sanan Input Parameters: 2795bb7acecfSBarry Smith + dm - the `DM` object 279601729b5cSPatrick Sanan . g - the global vector 2797bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 279801729b5cSPatrick Sanan - l - the local vector 279901729b5cSPatrick Sanan 280020f4b53cSBarry Smith Level: beginner 280120f4b53cSBarry Smith 280201729b5cSPatrick Sanan Notes: 2803bb7acecfSBarry Smith The communication involved in this update can be overlapped with computation by instead using 2804bb7acecfSBarry Smith `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. 2805bb7acecfSBarry Smith 2806bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 280701729b5cSPatrick Sanan 28081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocalHookAdd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, 280960225df5SJacob Faibussowitsch `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, 2810bb7acecfSBarry Smith `DMGlobalToLocalBegin()` `DMGlobalToLocalEnd()` 281101729b5cSPatrick Sanan @*/ 2812d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocal(DM dm, Vec g, InsertMode mode, Vec l) 2813d71ae5a4SJacob Faibussowitsch { 281401729b5cSPatrick Sanan PetscFunctionBegin; 28159566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, g, mode, l)); 28169566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, g, mode, l)); 28173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 281801729b5cSPatrick Sanan } 281901729b5cSPatrick Sanan 282001729b5cSPatrick Sanan /*@ 282147c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 282247c6ae99SBarry Smith 282320f4b53cSBarry Smith Neighbor-wise Collective 282447c6ae99SBarry Smith 282547c6ae99SBarry Smith Input Parameters: 2826bb7acecfSBarry Smith + dm - the `DM` object 282747c6ae99SBarry Smith . g - the global vector 2828bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 282947c6ae99SBarry Smith - l - the local vector 283047c6ae99SBarry Smith 283101729b5cSPatrick Sanan Level: intermediate 283247c6ae99SBarry Smith 2833bb7acecfSBarry Smith Notes: 2834bb7acecfSBarry Smith The operation is completed with `DMGlobalToLocalEnd()` 2835bb7acecfSBarry Smith 2836bb7acecfSBarry Smith One can perform local computations between the `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to overlap communication and computation 2837bb7acecfSBarry Smith 2838bb7acecfSBarry Smith `DMGlobalToLocal()` is a short form of `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` 2839bb7acecfSBarry Smith 2840bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 2841bb7acecfSBarry Smith 284260225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 284347c6ae99SBarry Smith @*/ 2844d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 2845d71ae5a4SJacob Faibussowitsch { 28467128ae9fSMatthew G Knepley PetscSF sf; 2847baf369e7SPeter Brune DMGlobalToLocalHookLink link; 284847c6ae99SBarry Smith 284947c6ae99SBarry Smith PetscFunctionBegin; 2850171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2851baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 28521baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, g, mode, l, link->ctx)); 2853baf369e7SPeter Brune } 28549566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28557128ae9fSMatthew G Knepley if (sf) { 2856ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2857ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2858d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 28597128ae9fSMatthew G Knepley 28607a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28619566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28629566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28639566063dSJacob Faibussowitsch PetscCall(PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE)); 28649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28659566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28667128ae9fSMatthew G Knepley } else { 2867fa1e479aSStefano Zampini PetscUseTypeMethod(dm, globaltolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 28687128ae9fSMatthew G Knepley } 28693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 287047c6ae99SBarry Smith } 287147c6ae99SBarry Smith 287247c6ae99SBarry Smith /*@ 287347c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 287447c6ae99SBarry Smith 287520f4b53cSBarry Smith Neighbor-wise Collective 287647c6ae99SBarry Smith 287747c6ae99SBarry Smith Input Parameters: 2878bb7acecfSBarry Smith + dm - the `DM` object 287947c6ae99SBarry Smith . g - the global vector 2880bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 288147c6ae99SBarry Smith - l - the local vector 288247c6ae99SBarry Smith 288301729b5cSPatrick Sanan Level: intermediate 288447c6ae99SBarry Smith 2885bb7acecfSBarry Smith Note: 2886bb7acecfSBarry Smith See `DMGlobalToLocalBegin()` for details. 2887bb7acecfSBarry Smith 288860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 288947c6ae99SBarry Smith @*/ 2890d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 2891d71ae5a4SJacob Faibussowitsch { 28927128ae9fSMatthew G Knepley PetscSF sf; 2893ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2894ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2895ca3d3a14SMatthew G. Knepley PetscBool transform; 2896baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2897d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 289847c6ae99SBarry Smith 289947c6ae99SBarry Smith PetscFunctionBegin; 2900171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29019566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 29029566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 29037128ae9fSMatthew G Knepley if (sf) { 29047a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 29057128ae9fSMatthew G Knepley 29069566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 29079566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 29089566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray, MPI_REPLACE)); 29099566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 29109566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 29119566063dSJacob Faibussowitsch if (transform) PetscCall(DMPlexGlobalToLocalBasis(dm, l)); 29127128ae9fSMatthew G Knepley } else { 2913fa1e479aSStefano Zampini PetscUseTypeMethod(dm, globaltolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 29147128ae9fSMatthew G Knepley } 29159566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalHook_Constraints(dm, g, mode, l, NULL)); 2916baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 29179566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 2918baf369e7SPeter Brune } 29193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 292047c6ae99SBarry Smith } 292147c6ae99SBarry Smith 2922d4d07f1eSToby Isaac /*@C 2923d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2924d4d07f1eSToby Isaac 292520f4b53cSBarry Smith Logically Collective 2926d4d07f1eSToby Isaac 29274165533cSJose E. Roman Input Parameters: 2928bb7acecfSBarry Smith + dm - the `DM` 2929bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMLocalToGlobalBegin()` 2930bb7acecfSBarry Smith . endhook - function to run after `DMLocalToGlobalEnd()` has completed 293120f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2932d4d07f1eSToby Isaac 293320f4b53cSBarry Smith Calling sequence of `beginhook`: 2934a4e35b19SJacob Faibussowitsch + global - global `DM` 2935d4d07f1eSToby Isaac . l - local vector 2936d4d07f1eSToby Isaac . mode - mode 2937d4d07f1eSToby Isaac . g - global vector 2938d4d07f1eSToby Isaac - ctx - optional user-defined function context 2939d4d07f1eSToby Isaac 294020f4b53cSBarry Smith Calling sequence of `endhook`: 2941bb7acecfSBarry Smith + global - global `DM` 2942d4d07f1eSToby Isaac . l - local vector 2943d4d07f1eSToby Isaac . mode - mode 2944d4d07f1eSToby Isaac . g - global vector 2945d4d07f1eSToby Isaac - ctx - optional user-defined function context 2946d4d07f1eSToby Isaac 2947d4d07f1eSToby Isaac Level: advanced 2948d4d07f1eSToby Isaac 29491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMRefineHookAdd()`, `DMGlobalToLocalHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2950d4d07f1eSToby Isaac @*/ 2951a4e35b19SJacob 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) 2952d71ae5a4SJacob Faibussowitsch { 2953d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, *p; 2954d4d07f1eSToby Isaac 2955d4d07f1eSToby Isaac PetscFunctionBegin; 2956d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2957d4d07f1eSToby Isaac for (p = &dm->ltoghook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 29589566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2959d4d07f1eSToby Isaac link->beginhook = beginhook; 2960d4d07f1eSToby Isaac link->endhook = endhook; 2961d4d07f1eSToby Isaac link->ctx = ctx; 2962d4d07f1eSToby Isaac link->next = NULL; 2963d4d07f1eSToby Isaac *p = link; 29643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2965d4d07f1eSToby Isaac } 2966d4d07f1eSToby Isaac 2967d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 2968d71ae5a4SJacob Faibussowitsch { 29694c274da1SToby Isaac PetscFunctionBegin; 2970a4e35b19SJacob Faibussowitsch (void)g; 2971a4e35b19SJacob Faibussowitsch (void)ctx; 29724c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29732b6b7d09SToby Isaac if (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES) { 29742b6b7d09SToby Isaac Mat cMat; 29752b6b7d09SToby Isaac Vec cVec; 29765db9a05bSToby Isaac PetscInt nRows; 29772b6b7d09SToby Isaac PetscSection section, cSec; 29782b6b7d09SToby Isaac PetscInt pStart, pEnd, p, dof; 29792b6b7d09SToby Isaac 29802b6b7d09SToby Isaac PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, NULL)); 29812b6b7d09SToby Isaac if (!cMat) PetscFunctionReturn(PETSC_SUCCESS); 29825db9a05bSToby Isaac 29839566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 29843ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 29859566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 29869566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 29879566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 29884c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 29899566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 29904c274da1SToby Isaac if (dof) { 29914c274da1SToby Isaac PetscInt d; 29924c274da1SToby Isaac PetscScalar *vals; 29939566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(l, section, p, &vals)); 29949566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(cVec, cSec, p, vals, mode)); 29954c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 29964c274da1SToby Isaac * we just extracted */ 2997ad540459SPierre Jolivet for (d = 0; d < dof; d++) vals[d] = 0.; 29984c274da1SToby Isaac } 29994c274da1SToby Isaac } 30009566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd(cMat, cVec, l, l)); 30019566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 30024c274da1SToby Isaac } 30033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30044c274da1SToby Isaac } 300501729b5cSPatrick Sanan /*@ 300601729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 300701729b5cSPatrick Sanan 300820f4b53cSBarry Smith Neighbor-wise Collective 300901729b5cSPatrick Sanan 301001729b5cSPatrick Sanan Input Parameters: 3011bb7acecfSBarry Smith + dm - the `DM` object 301201729b5cSPatrick Sanan . l - the local vector 3013bb7acecfSBarry 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. 301401729b5cSPatrick Sanan - g - the global vector 301501729b5cSPatrick Sanan 301620f4b53cSBarry Smith Level: beginner 301720f4b53cSBarry Smith 301801729b5cSPatrick Sanan Notes: 301901729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 3020bb7acecfSBarry Smith `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. 302101729b5cSPatrick Sanan 3022bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 3023bb7acecfSBarry Smith 3024bb7acecfSBarry 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. 3025bb7acecfSBarry Smith 3026bb7acecfSBarry Smith Use `DMLocalToGlobalHookAdd()` to add additional operations that are performed on the data during the update process 302701729b5cSPatrick Sanan 30281cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalHookAdd()`, `DMGlobaToLocallHookAdd()` 302901729b5cSPatrick Sanan @*/ 3030d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobal(DM dm, Vec l, InsertMode mode, Vec g) 3031d71ae5a4SJacob Faibussowitsch { 303201729b5cSPatrick Sanan PetscFunctionBegin; 30339566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, l, mode, g)); 30349566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, l, mode, g)); 30353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 303601729b5cSPatrick Sanan } 30374c274da1SToby Isaac 303847c6ae99SBarry Smith /*@ 303901729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 30409a42bb27SBarry Smith 304120f4b53cSBarry Smith Neighbor-wise Collective 30429a42bb27SBarry Smith 30439a42bb27SBarry Smith Input Parameters: 3044bb7acecfSBarry Smith + dm - the `DM` object 3045f6813fd5SJed Brown . l - the local vector 3046aa624791SPierre 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. 30471eb28f2eSBarry Smith - g - the global vector 30489a42bb27SBarry Smith 304920f4b53cSBarry Smith Level: intermediate 305020f4b53cSBarry Smith 305195452b02SPatrick Sanan Notes: 3052bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 3053bb7acecfSBarry Smith 3054bb7acecfSBarry 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. 3055bb7acecfSBarry Smith 3056bb7acecfSBarry Smith Use `DMLocalToGlobalEnd()` to complete the communication process. 3057bb7acecfSBarry Smith 3058bb7acecfSBarry Smith `DMLocalToGlobal()` is a short form of `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()` 3059bb7acecfSBarry Smith 3060bb7acecfSBarry Smith `DMLocalToGlobalHookAdd()` may be used to provide additional operations that are performed during the update process. 30619a42bb27SBarry Smith 30621cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()` 30639a42bb27SBarry Smith @*/ 3064d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBegin(DM dm, Vec l, InsertMode mode, Vec g) 3065d71ae5a4SJacob Faibussowitsch { 30667128ae9fSMatthew G Knepley PetscSF sf; 306784330215SMatthew G. Knepley PetscSection s, gs; 3068d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3069ca3d3a14SMatthew G. Knepley Vec tmpl; 3070ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3071ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3072fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 3073d0295fc0SJunchao Zhang PetscMemType lmtype = PETSC_MEMTYPE_HOST, gmtype = PETSC_MEMTYPE_HOST; 30749a42bb27SBarry Smith 30759a42bb27SBarry Smith PetscFunctionBegin; 3076171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3077d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 30781baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, l, mode, g, link->ctx)); 3079d4d07f1eSToby Isaac } 30809566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalHook_Constraints(dm, l, mode, g, NULL)); 30819566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 30829566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 30837128ae9fSMatthew G Knepley switch (mode) { 30847128ae9fSMatthew G Knepley case INSERT_VALUES: 30857128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 3086d71ae5a4SJacob Faibussowitsch case INSERT_BC_VALUES: 3087d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3088d71ae5a4SJacob Faibussowitsch break; 30897128ae9fSMatthew G Knepley case ADD_VALUES: 30907128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 3091d71ae5a4SJacob Faibussowitsch case ADD_BC_VALUES: 3092d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3093d71ae5a4SJacob Faibussowitsch break; 3094d71ae5a4SJacob Faibussowitsch default: 3095d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 30967128ae9fSMatthew G Knepley } 3097ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 30989566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3099ca3d3a14SMatthew G. Knepley if (transform) { 31009566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 31019566063dSJacob Faibussowitsch PetscCall(VecCopy(l, tmpl)); 31029566063dSJacob Faibussowitsch PetscCall(DMPlexLocalToGlobalBasis(dm, tmpl)); 31039566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3104fa88e482SJed Brown } else if (isInsert) { 31059566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(l, &lArray)); 3106fa88e482SJed Brown } else { 31079566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, &lmtype)); 3108fa88e482SJed Brown l_inplace = PETSC_TRUE; 3109ca3d3a14SMatthew G. Knepley } 3110fa88e482SJed Brown if (s && isInsert) { 31119566063dSJacob Faibussowitsch PetscCall(VecGetArray(g, &gArray)); 3112fa88e482SJed Brown } else { 31139566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, &gmtype)); 3114fa88e482SJed Brown g_inplace = PETSC_TRUE; 3115fa88e482SJed Brown } 3116ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 31179566063dSJacob Faibussowitsch PetscCall(PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM)); 311884330215SMatthew G. Knepley } else if (s && isInsert) { 311984330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 312084330215SMatthew G. Knepley 31219566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 31229566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 31239566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g, &gStart, NULL)); 312484330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3125b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 312684330215SMatthew G. Knepley 31279566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 31289566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(gs, p, &gdof)); 31299566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 31309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(gs, p, &gcdof)); 31319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(s, p, &off)); 31329566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(gs, p, &goff)); 3133b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 313403442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 31357a8be351SBarry 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); 3136b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 3137b3b16f48SMatthew G. Knepley if (!gcdof) { 313884330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff - gStart + d] = lArray[off + d]; 3139b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 3140b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 314184330215SMatthew G. Knepley const PetscInt *cdofs; 314284330215SMatthew G. Knepley PetscInt cind = 0; 314384330215SMatthew G. Knepley 31449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(s, p, &cdofs)); 3145b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 31469371c9d4SSatish Balay if ((cind < cdof) && (d == cdofs[cind])) { 31479371c9d4SSatish Balay ++cind; 31489371c9d4SSatish Balay continue; 31499371c9d4SSatish Balay } 3150b3b16f48SMatthew G. Knepley gArray[goff - gStart + e++] = lArray[off + d]; 315184330215SMatthew G. Knepley } 31527a8be351SBarry 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); 315384330215SMatthew G. Knepley } 3154ca3d3a14SMatthew G. Knepley } 3155fa88e482SJed Brown if (g_inplace) { 31569566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 3157fa88e482SJed Brown } else { 31589566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(g, &gArray)); 3159fa88e482SJed Brown } 3160ca3d3a14SMatthew G. Knepley if (transform) { 31619566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31629566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3163fa88e482SJed Brown } else if (l_inplace) { 31649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3165ca3d3a14SMatthew G. Knepley } else { 31669566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(l, &lArray)); 3167ca3d3a14SMatthew G. Knepley } 31687128ae9fSMatthew G Knepley } else { 3169fa1e479aSStefano Zampini PetscUseTypeMethod(dm, localtoglobalbegin, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g); 31707128ae9fSMatthew G Knepley } 31713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31729a42bb27SBarry Smith } 31739a42bb27SBarry Smith 31749a42bb27SBarry Smith /*@ 31759a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 317647c6ae99SBarry Smith 317720f4b53cSBarry Smith Neighbor-wise Collective 317847c6ae99SBarry Smith 317947c6ae99SBarry Smith Input Parameters: 3180bb7acecfSBarry Smith + dm - the `DM` object 3181f6813fd5SJed Brown . l - the local vector 3182bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 3183f6813fd5SJed Brown - g - the global vector 318447c6ae99SBarry Smith 318501729b5cSPatrick Sanan Level: intermediate 318647c6ae99SBarry Smith 3187bb7acecfSBarry Smith Note: 3188bb7acecfSBarry Smith See `DMLocalToGlobalBegin()` for full details 3189bb7acecfSBarry Smith 319060225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()` 319147c6ae99SBarry Smith @*/ 3192d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEnd(DM dm, Vec l, InsertMode mode, Vec g) 3193d71ae5a4SJacob Faibussowitsch { 31947128ae9fSMatthew G Knepley PetscSF sf; 319584330215SMatthew G. Knepley PetscSection s; 3196d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3197ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 319847c6ae99SBarry Smith 319947c6ae99SBarry Smith PetscFunctionBegin; 3200171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32019566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 32029566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 32037128ae9fSMatthew G Knepley switch (mode) { 32047128ae9fSMatthew G Knepley case INSERT_VALUES: 3205d71ae5a4SJacob Faibussowitsch case INSERT_ALL_VALUES: 3206d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3207d71ae5a4SJacob Faibussowitsch break; 32087128ae9fSMatthew G Knepley case ADD_VALUES: 3209d71ae5a4SJacob Faibussowitsch case ADD_ALL_VALUES: 3210d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3211d71ae5a4SJacob Faibussowitsch break; 3212d71ae5a4SJacob Faibussowitsch default: 3213d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 32147128ae9fSMatthew G Knepley } 321584330215SMatthew G. Knepley if (sf && !isInsert) { 3216ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3217ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3218ca3d3a14SMatthew G. Knepley Vec tmpl; 321984330215SMatthew G. Knepley 32209566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3221ca3d3a14SMatthew G. Knepley if (transform) { 32229566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 32239566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3224ca3d3a14SMatthew G. Knepley } else { 32259566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, NULL)); 3226ca3d3a14SMatthew G. Knepley } 32279566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, NULL)); 32289566063dSJacob Faibussowitsch PetscCall(PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM)); 3229ca3d3a14SMatthew G. Knepley if (transform) { 32309566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 32319566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3232ca3d3a14SMatthew G. Knepley } else { 32339566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3234ca3d3a14SMatthew G. Knepley } 32359566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 323684330215SMatthew G. Knepley } else if (s && isInsert) { 32377128ae9fSMatthew G Knepley } else { 3238fa1e479aSStefano Zampini PetscUseTypeMethod(dm, localtoglobalend, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g); 32397128ae9fSMatthew G Knepley } 3240d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 32419566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 3242d4d07f1eSToby Isaac } 32433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 324447c6ae99SBarry Smith } 324547c6ae99SBarry Smith 3246f089877aSRichard Tran Mills /*@ 3247a4e35b19SJacob Faibussowitsch DMLocalToLocalBegin - Begins the process of mapping values from a local vector (that include 3248a4e35b19SJacob Faibussowitsch ghost points that contain irrelevant values) to another local vector where the ghost points 3249a4e35b19SJacob Faibussowitsch in the second are set correctly from values on other MPI ranks. 3250f089877aSRichard Tran Mills 325120f4b53cSBarry Smith Neighbor-wise Collective 3252f089877aSRichard Tran Mills 3253f089877aSRichard Tran Mills Input Parameters: 3254bb7acecfSBarry Smith + dm - the `DM` object 3255bc0a1609SRichard Tran Mills . g - the original local vector 3256bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3257f089877aSRichard Tran Mills 3258bc0a1609SRichard Tran Mills Output Parameter: 3259bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3260f089877aSRichard Tran Mills 3261f089877aSRichard Tran Mills Level: intermediate 3262f089877aSRichard Tran Mills 326373ff1848SBarry Smith Note: 3264a4e35b19SJacob Faibussowitsch Must be followed by `DMLocalToLocalEnd()`. 3265a4e35b19SJacob Faibussowitsch 326660225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3267f089877aSRichard Tran Mills @*/ 3268d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 3269d71ae5a4SJacob Faibussowitsch { 3270f089877aSRichard Tran Mills PetscFunctionBegin; 3271f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32729f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 32739f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 32749f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 32753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3276f089877aSRichard Tran Mills } 3277f089877aSRichard Tran Mills 3278f089877aSRichard Tran Mills /*@ 3279bb7acecfSBarry Smith DMLocalToLocalEnd - Maps from a local vector to another local vector where the ghost 3280bb7acecfSBarry Smith points in the second are set correctly. Must be preceded by `DMLocalToLocalBegin()`. 3281f089877aSRichard Tran Mills 328220f4b53cSBarry Smith Neighbor-wise Collective 3283f089877aSRichard Tran Mills 3284f089877aSRichard Tran Mills Input Parameters: 328560225df5SJacob Faibussowitsch + dm - the `DM` object 3286bc0a1609SRichard Tran Mills . g - the original local vector 3287bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3288f089877aSRichard Tran Mills 3289bc0a1609SRichard Tran Mills Output Parameter: 3290bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3291f089877aSRichard Tran Mills 3292f089877aSRichard Tran Mills Level: intermediate 3293f089877aSRichard Tran Mills 329460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3295f089877aSRichard Tran Mills @*/ 3296d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 3297d71ae5a4SJacob Faibussowitsch { 3298f089877aSRichard Tran Mills PetscFunctionBegin; 3299f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 33009f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 33019f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 33029f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 33033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3304f089877aSRichard Tran Mills } 3305f089877aSRichard Tran Mills 330647c6ae99SBarry Smith /*@ 3307bb7acecfSBarry Smith DMCoarsen - Coarsens a `DM` object using a standard, non-adaptive coarsening of the underlying mesh 330847c6ae99SBarry Smith 330920f4b53cSBarry Smith Collective 331047c6ae99SBarry Smith 3311d8d19677SJose E. Roman Input Parameters: 3312bb7acecfSBarry Smith + dm - the `DM` object 331320f4b53cSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 331447c6ae99SBarry Smith 331547c6ae99SBarry Smith Output Parameter: 3316bb7acecfSBarry Smith . dmc - the coarsened `DM` 331747c6ae99SBarry Smith 331847c6ae99SBarry Smith Level: developer 331947c6ae99SBarry Smith 332073ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateDomainDecomposition()`, 332173ff1848SBarry Smith `DMCoarsenHookAdd()`, `DMCoarsenHookRemove()` 332247c6ae99SBarry Smith @*/ 3323d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 3324d71ae5a4SJacob Faibussowitsch { 3325b17ce1afSJed Brown DMCoarsenHookLink link; 332647c6ae99SBarry Smith 332747c6ae99SBarry Smith PetscFunctionBegin; 3328171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 33299566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Coarsen, dm, 0, 0, 0)); 3330dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsen, comm, dmc); 3331b9d85ea2SLisandro Dalcin if (*dmc) { 3332a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 33339566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm, *dmc)); 333443842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 33359566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmc)); 3336644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 33370598a293SJed Brown (*dmc)->levelup = dm->levelup; 3338656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 33399566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmc, dm->mattype)); 3340b17ce1afSJed Brown for (link = dm->coarsenhook; link; link = link->next) { 33419566063dSJacob Faibussowitsch if (link->coarsenhook) PetscCall((*link->coarsenhook)(dm, *dmc, link->ctx)); 3342b17ce1afSJed Brown } 3343b9d85ea2SLisandro Dalcin } 33449566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Coarsen, dm, 0, 0, 0)); 33457a8be351SBarry Smith PetscCheck(*dmc, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 33463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3347b17ce1afSJed Brown } 3348b17ce1afSJed Brown 3349bb9467b5SJed Brown /*@C 3350b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3351b17ce1afSJed Brown 335220f4b53cSBarry Smith Logically Collective; No Fortran Support 3353b17ce1afSJed Brown 33544165533cSJose E. Roman Input Parameters: 3355bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3356b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3357bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels (called once per `SNESSolve()`) 335820f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3359b17ce1afSJed Brown 336020f4b53cSBarry Smith Calling sequence of `coarsenhook`: 3361bb7acecfSBarry Smith + fine - fine level `DM` 3362bb7acecfSBarry Smith . coarse - coarse level `DM` to restrict problem to 3363b17ce1afSJed Brown - ctx - optional user-defined function context 3364b17ce1afSJed Brown 336520f4b53cSBarry Smith Calling sequence of `restricthook`: 3366bb7acecfSBarry Smith + fine - fine level `DM` 3367bb7acecfSBarry Smith . mrestrict - matrix restricting a fine-level solution to the coarse grid, usually the transpose of the interpolation 3368c833c3b5SJed Brown . rscale - scaling vector for restriction 3369c833c3b5SJed Brown . inject - matrix restricting by injection 3370b17ce1afSJed Brown . coarse - coarse level DM to update 3371b17ce1afSJed Brown - ctx - optional user-defined function context 3372b17ce1afSJed Brown 3373b17ce1afSJed Brown Level: advanced 3374b17ce1afSJed Brown 3375b17ce1afSJed Brown Notes: 3376bb7acecfSBarry 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`. 3377b17ce1afSJed Brown 3378b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3379b17ce1afSJed Brown 3380b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3381bb7acecfSBarry Smith extract the finest level information from its context (instead of from the `SNES`). 3382b17ce1afSJed Brown 3383bb7acecfSBarry Smith The hooks are automatically called by `DMRestrict()` 3384bb7acecfSBarry Smith 33851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3386b17ce1afSJed Brown @*/ 3387a4e35b19SJacob 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) 3388d71ae5a4SJacob Faibussowitsch { 3389b17ce1afSJed Brown DMCoarsenHookLink link, *p; 3390b17ce1afSJed Brown 3391b17ce1afSJed Brown PetscFunctionBegin; 3392b17ce1afSJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 33931e3d8eccSJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 33943ba16761SJacob Faibussowitsch if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 33951e3d8eccSJed Brown } 33969566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3397b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3398b17ce1afSJed Brown link->restricthook = restricthook; 3399b17ce1afSJed Brown link->ctx = ctx; 34000298fd71SBarry Smith link->next = NULL; 3401b17ce1afSJed Brown *p = link; 34023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3403b17ce1afSJed Brown } 3404b17ce1afSJed Brown 3405dc822a44SJed Brown /*@C 3406bb7acecfSBarry Smith DMCoarsenHookRemove - remove a callback set with `DMCoarsenHookAdd()` 3407dc822a44SJed Brown 340820f4b53cSBarry Smith Logically Collective; No Fortran Support 3409dc822a44SJed Brown 34104165533cSJose E. Roman Input Parameters: 3411bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3412dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3413bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels 341420f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3415dc822a44SJed Brown 3416dc822a44SJed Brown Level: advanced 3417dc822a44SJed Brown 341873ff1848SBarry Smith Notes: 341973ff1848SBarry Smith This function does nothing if the `coarsenhook` is not in the list. 342073ff1848SBarry Smith 342173ff1848SBarry Smith See `DMCoarsenHookAdd()` for the calling sequence of `coarsenhook` and `restricthook` 3422dc822a44SJed Brown 34231cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3424dc822a44SJed Brown @*/ 3425d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHookRemove(DM fine, PetscErrorCode (*coarsenhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, Mat, Vec, Mat, DM, void *), void *ctx) 3426d71ae5a4SJacob Faibussowitsch { 3427dc822a44SJed Brown DMCoarsenHookLink link, *p; 3428dc822a44SJed Brown 3429dc822a44SJed Brown PetscFunctionBegin; 3430dc822a44SJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 3431dc822a44SJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3432dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3433dc822a44SJed Brown link = *p; 3434dc822a44SJed Brown *p = link->next; 34359566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3436dc822a44SJed Brown break; 3437dc822a44SJed Brown } 3438dc822a44SJed Brown } 34393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3440dc822a44SJed Brown } 3441dc822a44SJed Brown 3442b17ce1afSJed Brown /*@ 3443bb7acecfSBarry Smith DMRestrict - restricts user-defined problem data to a coarser `DM` by running hooks registered by `DMCoarsenHookAdd()` 3444b17ce1afSJed Brown 3445b17ce1afSJed Brown Collective if any hooks are 3446b17ce1afSJed Brown 34474165533cSJose E. Roman Input Parameters: 3448bb7acecfSBarry Smith + fine - finer `DM` from which the data is obtained 3449bb7acecfSBarry Smith . restrct - restriction matrix, apply using `MatRestrict()`, usually the transpose of the interpolation 3450e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3451bb7acecfSBarry Smith . inject - injection matrix, also use `MatRestrict()` 345220f4b53cSBarry Smith - coarse - coarser `DM` to update 3453b17ce1afSJed Brown 3454b17ce1afSJed Brown Level: developer 3455b17ce1afSJed Brown 345673ff1848SBarry Smith Developer Note: 3457bb7acecfSBarry Smith Though this routine is called `DMRestrict()` the hooks are added with `DMCoarsenHookAdd()`, a consistent terminology would be better 3458bb7acecfSBarry Smith 34591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `MatRestrict()`, `DMInterpolate()`, `DMRefineHookAdd()` 3460b17ce1afSJed Brown @*/ 3461d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestrict(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse) 3462d71ae5a4SJacob Faibussowitsch { 3463b17ce1afSJed Brown DMCoarsenHookLink link; 3464b17ce1afSJed Brown 3465b17ce1afSJed Brown PetscFunctionBegin; 3466b17ce1afSJed Brown for (link = fine->coarsenhook; link; link = link->next) { 34671baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(fine, restrct, rscale, inject, coarse, link->ctx)); 3468b17ce1afSJed Brown } 34693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 347047c6ae99SBarry Smith } 347147c6ae99SBarry Smith 3472bb9467b5SJed Brown /*@C 347373ff1848SBarry Smith DMSubDomainHookAdd - adds a callback to be run when restricting a problem to subdomain `DM`s with `DMCreateDomainDecomposition()` 34745dbd56e3SPeter Brune 347520f4b53cSBarry Smith Logically Collective; No Fortran Support 34765dbd56e3SPeter Brune 34774165533cSJose E. Roman Input Parameters: 3478bb7acecfSBarry Smith + global - global `DM` 3479bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 34805dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 348120f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 34825dbd56e3SPeter Brune 348320f4b53cSBarry Smith Calling sequence of `ddhook`: 3484bb7acecfSBarry Smith + global - global `DM` 348573ff1848SBarry Smith . block - subdomain `DM` 3486ec4806b8SPeter Brune - ctx - optional user-defined function context 3487ec4806b8SPeter Brune 348820f4b53cSBarry Smith Calling sequence of `restricthook`: 3489bb7acecfSBarry Smith + global - global `DM` 349073ff1848SBarry Smith . out - scatter to the outer (with ghost and overlap points) sub vector 349173ff1848SBarry Smith . in - scatter to sub vector values only owned locally 349273ff1848SBarry Smith . block - subdomain `DM` 34935dbd56e3SPeter Brune - ctx - optional user-defined function context 34945dbd56e3SPeter Brune 34955dbd56e3SPeter Brune Level: advanced 34965dbd56e3SPeter Brune 34975dbd56e3SPeter Brune Notes: 349873ff1848SBarry Smith This function can be used if auxiliary data needs to be set up on subdomain `DM`s. 34995dbd56e3SPeter Brune 35005dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 35015dbd56e3SPeter Brune 35025dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3503bb7acecfSBarry Smith extract the global information from its context (instead of from the `SNES`). 35045dbd56e3SPeter Brune 350573ff1848SBarry Smith Developer Note: 350673ff1848SBarry Smith It is unclear what "block solve" means within the definition of `restricthook` 350773ff1848SBarry Smith 350873ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()`, `DMCreateDomainDecomposition()` 35095dbd56e3SPeter Brune @*/ 3510a4e35b19SJacob 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) 3511d71ae5a4SJacob Faibussowitsch { 3512be081cd6SPeter Brune DMSubDomainHookLink link, *p; 35135dbd56e3SPeter Brune 35145dbd56e3SPeter Brune PetscFunctionBegin; 35155dbd56e3SPeter Brune PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3516b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 35173ba16761SJacob Faibussowitsch if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 3518b3a6b972SJed Brown } 35199566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 35205dbd56e3SPeter Brune link->restricthook = restricthook; 3521be081cd6SPeter Brune link->ddhook = ddhook; 35225dbd56e3SPeter Brune link->ctx = ctx; 35230298fd71SBarry Smith link->next = NULL; 35245dbd56e3SPeter Brune *p = link; 35253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35265dbd56e3SPeter Brune } 35275dbd56e3SPeter Brune 3528b3a6b972SJed Brown /*@C 352973ff1848SBarry Smith DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to subdomain `DM`s with `DMCreateDomainDecomposition()` 3530b3a6b972SJed Brown 353120f4b53cSBarry Smith Logically Collective; No Fortran Support 3532b3a6b972SJed Brown 35334165533cSJose E. Roman Input Parameters: 3534bb7acecfSBarry Smith + global - global `DM` 3535bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 3536b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 353720f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3538b3a6b972SJed Brown 3539b3a6b972SJed Brown Level: advanced 3540b3a6b972SJed Brown 354173ff1848SBarry Smith Note: 354273ff1848SBarry Smith See `DMSubDomainHookAdd()` for the calling sequences of `ddhook` and `restricthook` 354373ff1848SBarry Smith 354473ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()`, 354573ff1848SBarry Smith `DMCreateDomainDecomposition()` 3546b3a6b972SJed Brown @*/ 3547d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookRemove(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3548d71ae5a4SJacob Faibussowitsch { 3549b3a6b972SJed Brown DMSubDomainHookLink link, *p; 3550b3a6b972SJed Brown 3551b3a6b972SJed Brown PetscFunctionBegin; 3552b3a6b972SJed Brown PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3553b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3554b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3555b3a6b972SJed Brown link = *p; 3556b3a6b972SJed Brown *p = link->next; 35579566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3558b3a6b972SJed Brown break; 3559b3a6b972SJed Brown } 3560b3a6b972SJed Brown } 35613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3562b3a6b972SJed Brown } 3563b3a6b972SJed Brown 35645dbd56e3SPeter Brune /*@ 356573ff1848SBarry Smith DMSubDomainRestrict - restricts user-defined problem data to a subdomain `DM` by running hooks registered by `DMSubDomainHookAdd()` 35665dbd56e3SPeter Brune 35675dbd56e3SPeter Brune Collective if any hooks are 35685dbd56e3SPeter Brune 35694165533cSJose E. Roman Input Parameters: 3570a4e35b19SJacob Faibussowitsch + global - The global `DM` to use as a base 3571a4e35b19SJacob Faibussowitsch . oscatter - The scatter from domain global vector filling subdomain global vector with overlap 3572a4e35b19SJacob Faibussowitsch . gscatter - The scatter from domain global vector filling subdomain local vector with ghosts 3573a4e35b19SJacob Faibussowitsch - subdm - The subdomain `DM` to update 35745dbd56e3SPeter Brune 35755dbd56e3SPeter Brune Level: developer 35765dbd56e3SPeter Brune 357773ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `MatRestrict()`, `DMCreateDomainDecomposition()` 35785dbd56e3SPeter Brune @*/ 3579d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainRestrict(DM global, VecScatter oscatter, VecScatter gscatter, DM subdm) 3580d71ae5a4SJacob Faibussowitsch { 3581be081cd6SPeter Brune DMSubDomainHookLink link; 35825dbd56e3SPeter Brune 35835dbd56e3SPeter Brune PetscFunctionBegin; 3584be081cd6SPeter Brune for (link = global->subdomainhook; link; link = link->next) { 35851baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(global, oscatter, gscatter, subdm, link->ctx)); 35865dbd56e3SPeter Brune } 35873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35885dbd56e3SPeter Brune } 35895dbd56e3SPeter Brune 35905fe1f584SPeter Brune /*@ 3591bb7acecfSBarry Smith DMGetCoarsenLevel - Gets the number of coarsenings that have generated this `DM`. 35925fe1f584SPeter Brune 35935fe1f584SPeter Brune Not Collective 35945fe1f584SPeter Brune 35955fe1f584SPeter Brune Input Parameter: 3596bb7acecfSBarry Smith . dm - the `DM` object 35975fe1f584SPeter Brune 35985fe1f584SPeter Brune Output Parameter: 35996a7d9d85SPeter Brune . level - number of coarsenings 36005fe1f584SPeter Brune 36015fe1f584SPeter Brune Level: developer 36025fe1f584SPeter Brune 36031cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMSetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 36045fe1f584SPeter Brune @*/ 3605d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarsenLevel(DM dm, PetscInt *level) 3606d71ae5a4SJacob Faibussowitsch { 36075fe1f584SPeter Brune PetscFunctionBegin; 36085fe1f584SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36094f572ea9SToby Isaac PetscAssertPointer(level, 2); 36105fe1f584SPeter Brune *level = dm->leveldown; 36113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36125fe1f584SPeter Brune } 36135fe1f584SPeter Brune 36149a64c4a8SMatthew G. Knepley /*@ 3615bb7acecfSBarry Smith DMSetCoarsenLevel - Sets the number of coarsenings that have generated this `DM`. 36169a64c4a8SMatthew G. Knepley 361720f4b53cSBarry Smith Collective 36189a64c4a8SMatthew G. Knepley 36199a64c4a8SMatthew G. Knepley Input Parameters: 3620bb7acecfSBarry Smith + dm - the `DM` object 36219a64c4a8SMatthew G. Knepley - level - number of coarsenings 36229a64c4a8SMatthew G. Knepley 36239a64c4a8SMatthew G. Knepley Level: developer 36249a64c4a8SMatthew G. Knepley 3625bb7acecfSBarry Smith Note: 3626bb7acecfSBarry Smith This is rarely used directly, the information is automatically set when a `DM` is created with `DMCoarsen()` 3627bb7acecfSBarry Smith 362842747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 36299a64c4a8SMatthew G. Knepley @*/ 3630d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarsenLevel(DM dm, PetscInt level) 3631d71ae5a4SJacob Faibussowitsch { 36329a64c4a8SMatthew G. Knepley PetscFunctionBegin; 36339a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36349a64c4a8SMatthew G. Knepley dm->leveldown = level; 36353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36369a64c4a8SMatthew G. Knepley } 36379a64c4a8SMatthew G. Knepley 3638cc4c1da9SBarry Smith /*@ 3639bb7acecfSBarry Smith DMRefineHierarchy - Refines a `DM` object, all levels at once 364047c6ae99SBarry Smith 364120f4b53cSBarry Smith Collective 364247c6ae99SBarry Smith 3643d8d19677SJose E. Roman Input Parameters: 3644bb7acecfSBarry Smith + dm - the `DM` object 364547c6ae99SBarry Smith - nlevels - the number of levels of refinement 364647c6ae99SBarry Smith 364747c6ae99SBarry Smith Output Parameter: 3648bb7acecfSBarry Smith . dmf - the refined `DM` hierarchy 364947c6ae99SBarry Smith 365047c6ae99SBarry Smith Level: developer 365147c6ae99SBarry Smith 36521cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMCoarsenHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 365347c6ae99SBarry Smith @*/ 3654d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHierarchy(DM dm, PetscInt nlevels, DM dmf[]) 3655d71ae5a4SJacob Faibussowitsch { 365647c6ae99SBarry Smith PetscFunctionBegin; 3657171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36587a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36593ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 36604f572ea9SToby Isaac PetscAssertPointer(dmf, 3); 3661213acdd3SPierre Jolivet if (dm->ops->refine && !dm->ops->refinehierarchy) { 366247c6ae99SBarry Smith PetscInt i; 366347c6ae99SBarry Smith 36649566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0])); 366548a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i])); 3666213acdd3SPierre Jolivet } else PetscUseTypeMethod(dm, refinehierarchy, nlevels, dmf); 36673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 366847c6ae99SBarry Smith } 366947c6ae99SBarry Smith 3670cc4c1da9SBarry Smith /*@ 3671bb7acecfSBarry Smith DMCoarsenHierarchy - Coarsens a `DM` object, all levels at once 367247c6ae99SBarry Smith 367320f4b53cSBarry Smith Collective 367447c6ae99SBarry Smith 3675d8d19677SJose E. Roman Input Parameters: 3676bb7acecfSBarry Smith + dm - the `DM` object 367747c6ae99SBarry Smith - nlevels - the number of levels of coarsening 367847c6ae99SBarry Smith 367947c6ae99SBarry Smith Output Parameter: 3680bb7acecfSBarry Smith . dmc - the coarsened `DM` hierarchy 368147c6ae99SBarry Smith 368247c6ae99SBarry Smith Level: developer 368347c6ae99SBarry Smith 36841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMRefineHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 368547c6ae99SBarry Smith @*/ 3686d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 3687d71ae5a4SJacob Faibussowitsch { 368847c6ae99SBarry Smith PetscFunctionBegin; 3689171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36907a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36913ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 36924f572ea9SToby Isaac PetscAssertPointer(dmc, 3); 3693213acdd3SPierre Jolivet if (dm->ops->coarsen && !dm->ops->coarsenhierarchy) { 369447c6ae99SBarry Smith PetscInt i; 369547c6ae99SBarry Smith 36969566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0])); 369748a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i])); 3698213acdd3SPierre Jolivet } else PetscUseTypeMethod(dm, coarsenhierarchy, nlevels, dmc); 36993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 370047c6ae99SBarry Smith } 370147c6ae99SBarry Smith 37021a266240SBarry Smith /*@C 3703bb7acecfSBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the `DM` is destroyed 37041a266240SBarry Smith 3705bb7acecfSBarry Smith Logically Collective if the function is collective 37061a266240SBarry Smith 37071a266240SBarry Smith Input Parameters: 3708bb7acecfSBarry Smith + dm - the `DM` object 370949abdd8aSBarry Smith - destroy - the destroy function, see `PetscCtxDestroyFn` for the calling sequence 37101a266240SBarry Smith 37111a266240SBarry Smith Level: intermediate 37121a266240SBarry Smith 371349abdd8aSBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, 371449abdd8aSBarry Smith `DMGetApplicationContext()`, `PetscCtxDestroyFn` 3715f07f9ceaSJed Brown @*/ 371649abdd8aSBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm, PetscCtxDestroyFn *destroy) 3717d71ae5a4SJacob Faibussowitsch { 37181a266240SBarry Smith PetscFunctionBegin; 3719171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37201a266240SBarry Smith dm->ctxdestroy = destroy; 37213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37221a266240SBarry Smith } 37231a266240SBarry Smith 3724b07ff414SBarry Smith /*@ 3725bb7acecfSBarry Smith DMSetApplicationContext - Set a user context into a `DM` object 372647c6ae99SBarry Smith 372747c6ae99SBarry Smith Not Collective 372847c6ae99SBarry Smith 372947c6ae99SBarry Smith Input Parameters: 3730bb7acecfSBarry Smith + dm - the `DM` object 373147c6ae99SBarry Smith - ctx - the user context 373247c6ae99SBarry Smith 373347c6ae99SBarry Smith Level: intermediate 373447c6ae99SBarry Smith 3735e33b3f0fSStefano Zampini Notes: 373635cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3737e33b3f0fSStefano Zampini In a multilevel solver, the user context is shared by all the `DM` in the hierarchy; it is thus not advisable 3738e33b3f0fSStefano Zampini to store objects that represent discretized quantities inside the context. 3739bb7acecfSBarry Smith 374060225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 374147c6ae99SBarry Smith @*/ 3742d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContext(DM dm, void *ctx) 3743d71ae5a4SJacob Faibussowitsch { 374447c6ae99SBarry Smith PetscFunctionBegin; 3745171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 374647c6ae99SBarry Smith dm->ctx = ctx; 37473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 374847c6ae99SBarry Smith } 374947c6ae99SBarry Smith 375047c6ae99SBarry Smith /*@ 3751bb7acecfSBarry Smith DMGetApplicationContext - Gets a user context from a `DM` object 375247c6ae99SBarry Smith 375347c6ae99SBarry Smith Not Collective 375447c6ae99SBarry Smith 375547c6ae99SBarry Smith Input Parameter: 3756bb7acecfSBarry Smith . dm - the `DM` object 375747c6ae99SBarry Smith 375847c6ae99SBarry Smith Output Parameter: 375947c6ae99SBarry Smith . ctx - the user context 376047c6ae99SBarry Smith 376147c6ae99SBarry Smith Level: intermediate 376247c6ae99SBarry Smith 3763bb7acecfSBarry Smith Note: 376435cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3765bb7acecfSBarry Smith 376642747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 376747c6ae99SBarry Smith @*/ 3768d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetApplicationContext(DM dm, void *ctx) 3769d71ae5a4SJacob Faibussowitsch { 377047c6ae99SBarry Smith PetscFunctionBegin; 3771171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37721b2093e4SBarry Smith *(void **)ctx = dm->ctx; 37733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 377447c6ae99SBarry Smith } 377547c6ae99SBarry Smith 377608da532bSDmitry Karpeev /*@C 3777bb7acecfSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for `SNESVI`. 377808da532bSDmitry Karpeev 377920f4b53cSBarry Smith Logically Collective 378008da532bSDmitry Karpeev 3781d8d19677SJose E. Roman Input Parameters: 378208da532bSDmitry Karpeev + dm - the DM object 378320f4b53cSBarry Smith - f - the function that computes variable bounds used by SNESVI (use `NULL` to cancel a previous function that was set) 378408da532bSDmitry Karpeev 378508da532bSDmitry Karpeev Level: intermediate 378608da532bSDmitry Karpeev 37871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()`, 3788db781477SPatrick Sanan `DMSetJacobian()` 378908da532bSDmitry Karpeev @*/ 3790d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVariableBounds(DM dm, PetscErrorCode (*f)(DM, Vec, Vec)) 3791d71ae5a4SJacob Faibussowitsch { 379208da532bSDmitry Karpeev PetscFunctionBegin; 37935a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 379408da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 37953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 379608da532bSDmitry Karpeev } 379708da532bSDmitry Karpeev 379808da532bSDmitry Karpeev /*@ 3799bb7acecfSBarry Smith DMHasVariableBounds - does the `DM` object have a variable bounds function? 380008da532bSDmitry Karpeev 380108da532bSDmitry Karpeev Not Collective 380208da532bSDmitry Karpeev 380308da532bSDmitry Karpeev Input Parameter: 3804bb7acecfSBarry Smith . dm - the `DM` object to destroy 380508da532bSDmitry Karpeev 380608da532bSDmitry Karpeev Output Parameter: 3807bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the variable bounds function exists 380808da532bSDmitry Karpeev 380908da532bSDmitry Karpeev Level: developer 381008da532bSDmitry Karpeev 38111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 381208da532bSDmitry Karpeev @*/ 3813d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasVariableBounds(DM dm, PetscBool *flg) 3814d71ae5a4SJacob Faibussowitsch { 381508da532bSDmitry Karpeev PetscFunctionBegin; 38165a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38174f572ea9SToby Isaac PetscAssertPointer(flg, 2); 381808da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 38193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 382008da532bSDmitry Karpeev } 382108da532bSDmitry Karpeev 3822cc4c1da9SBarry Smith /*@ 3823bb7acecfSBarry Smith DMComputeVariableBounds - compute variable bounds used by `SNESVI`. 382408da532bSDmitry Karpeev 382520f4b53cSBarry Smith Logically Collective 382608da532bSDmitry Karpeev 3827f899ff85SJose E. Roman Input Parameter: 3828bb7acecfSBarry Smith . dm - the `DM` object 382908da532bSDmitry Karpeev 383060225df5SJacob Faibussowitsch Output Parameters: 383108da532bSDmitry Karpeev + xl - lower bound 383208da532bSDmitry Karpeev - xu - upper bound 383308da532bSDmitry Karpeev 3834907376e6SBarry Smith Level: advanced 3835907376e6SBarry Smith 383620f4b53cSBarry Smith Note: 383795452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 383808da532bSDmitry Karpeev 38391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 384008da532bSDmitry Karpeev @*/ 3841d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 3842d71ae5a4SJacob Faibussowitsch { 384308da532bSDmitry Karpeev PetscFunctionBegin; 38445a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 384508da532bSDmitry Karpeev PetscValidHeaderSpecific(xl, VEC_CLASSID, 2); 38465a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu, VEC_CLASSID, 3); 3847dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, computevariablebounds, xl, xu); 38483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 384908da532bSDmitry Karpeev } 385008da532bSDmitry Karpeev 3851b0ae01b7SPeter Brune /*@ 3852bb7acecfSBarry Smith DMHasColoring - does the `DM` object have a method of providing a coloring? 3853b0ae01b7SPeter Brune 3854b0ae01b7SPeter Brune Not Collective 3855b0ae01b7SPeter Brune 3856b0ae01b7SPeter Brune Input Parameter: 3857b0ae01b7SPeter Brune . dm - the DM object 3858b0ae01b7SPeter Brune 3859b0ae01b7SPeter Brune Output Parameter: 3860bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateColoring()`. 3861b0ae01b7SPeter Brune 3862b0ae01b7SPeter Brune Level: developer 3863b0ae01b7SPeter Brune 38641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateColoring()` 3865b0ae01b7SPeter Brune @*/ 3866d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasColoring(DM dm, PetscBool *flg) 3867d71ae5a4SJacob Faibussowitsch { 3868b0ae01b7SPeter Brune PetscFunctionBegin; 38695a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38704f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3871b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 38723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3873b0ae01b7SPeter Brune } 3874b0ae01b7SPeter Brune 38753ad4599aSBarry Smith /*@ 3876bb7acecfSBarry Smith DMHasCreateRestriction - does the `DM` object have a method of providing a restriction? 38773ad4599aSBarry Smith 38783ad4599aSBarry Smith Not Collective 38793ad4599aSBarry Smith 38803ad4599aSBarry Smith Input Parameter: 3881bb7acecfSBarry Smith . dm - the `DM` object 38823ad4599aSBarry Smith 38833ad4599aSBarry Smith Output Parameter: 3884bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateRestriction()`. 38853ad4599aSBarry Smith 38863ad4599aSBarry Smith Level: developer 38873ad4599aSBarry Smith 38881cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateRestriction()`, `DMHasCreateInterpolation()`, `DMHasCreateInjection()` 38893ad4599aSBarry Smith @*/ 3890d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateRestriction(DM dm, PetscBool *flg) 3891d71ae5a4SJacob Faibussowitsch { 38923ad4599aSBarry Smith PetscFunctionBegin; 38935a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38944f572ea9SToby Isaac PetscAssertPointer(flg, 2); 38953ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 38963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38973ad4599aSBarry Smith } 38983ad4599aSBarry Smith 3899a7058e45SLawrence Mitchell /*@ 3900bb7acecfSBarry Smith DMHasCreateInjection - does the `DM` object have a method of providing an injection? 3901a7058e45SLawrence Mitchell 3902a7058e45SLawrence Mitchell Not Collective 3903a7058e45SLawrence Mitchell 3904a7058e45SLawrence Mitchell Input Parameter: 3905bb7acecfSBarry Smith . dm - the `DM` object 3906a7058e45SLawrence Mitchell 3907a7058e45SLawrence Mitchell Output Parameter: 3908bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateInjection()`. 3909a7058e45SLawrence Mitchell 3910a7058e45SLawrence Mitchell Level: developer 3911a7058e45SLawrence Mitchell 39121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateInjection()`, `DMHasCreateRestriction()`, `DMHasCreateInterpolation()` 3913a7058e45SLawrence Mitchell @*/ 3914d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateInjection(DM dm, PetscBool *flg) 3915d71ae5a4SJacob Faibussowitsch { 3916a7058e45SLawrence Mitchell PetscFunctionBegin; 39175a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39184f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3919dbbe0bcdSBarry Smith if (dm->ops->hascreateinjection) PetscUseTypeMethod(dm, hascreateinjection, flg); 3920ad540459SPierre Jolivet else *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 39213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3922a7058e45SLawrence Mitchell } 3923a7058e45SLawrence Mitchell 39240298fd71SBarry Smith PetscFunctionList DMList = NULL; 3925264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3926264ace61SBarry Smith 3927cc4c1da9SBarry Smith /*@ 3928bb7acecfSBarry Smith DMSetType - Builds a `DM`, for a particular `DM` implementation. 3929264ace61SBarry Smith 393020f4b53cSBarry Smith Collective 3931264ace61SBarry Smith 3932264ace61SBarry Smith Input Parameters: 3933bb7acecfSBarry Smith + dm - The `DM` object 3934bb7acecfSBarry Smith - method - The name of the `DMType`, for example `DMDA`, `DMPLEX` 3935264ace61SBarry Smith 3936264ace61SBarry Smith Options Database Key: 3937bb7acecfSBarry Smith . -dm_type <type> - Sets the `DM` type; use -help for a list of available types 3938264ace61SBarry Smith 3939264ace61SBarry Smith Level: intermediate 3940264ace61SBarry Smith 3941bb7acecfSBarry Smith Note: 39420462cc06SPierre Jolivet Of the `DM` is constructed by directly calling a function to construct a particular `DM`, for example, `DMDACreate2d()` or `DMPlexCreateBoxMesh()` 3943bb7acecfSBarry Smith 39441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMGetType()`, `DMCreate()`, `DMDACreate2d()` 3945264ace61SBarry Smith @*/ 3946d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetType(DM dm, DMType method) 3947d71ae5a4SJacob Faibussowitsch { 3948264ace61SBarry Smith PetscErrorCode (*r)(DM); 3949264ace61SBarry Smith PetscBool match; 3950264ace61SBarry Smith 3951264ace61SBarry Smith PetscFunctionBegin; 3952264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, method, &match)); 39543ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 3955264ace61SBarry Smith 39569566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 39579566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(DMList, method, &r)); 39587a8be351SBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3959264ace61SBarry Smith 3960dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, destroy); 39619566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops, sizeof(*dm->ops))); 39629566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)dm, method)); 39639566063dSJacob Faibussowitsch PetscCall((*r)(dm)); 39643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3965264ace61SBarry Smith } 3966264ace61SBarry Smith 3967cc4c1da9SBarry Smith /*@ 3968bb7acecfSBarry Smith DMGetType - Gets the `DM` type name (as a string) from the `DM`. 3969264ace61SBarry Smith 3970264ace61SBarry Smith Not Collective 3971264ace61SBarry Smith 3972264ace61SBarry Smith Input Parameter: 3973bb7acecfSBarry Smith . dm - The `DM` 3974264ace61SBarry Smith 3975264ace61SBarry Smith Output Parameter: 3976bb7acecfSBarry Smith . type - The `DMType` name 3977264ace61SBarry Smith 3978264ace61SBarry Smith Level: intermediate 3979264ace61SBarry Smith 39801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMSetType()`, `DMCreate()` 3981264ace61SBarry Smith @*/ 3982d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetType(DM dm, DMType *type) 3983d71ae5a4SJacob Faibussowitsch { 3984264ace61SBarry Smith PetscFunctionBegin; 3985264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39864f572ea9SToby Isaac PetscAssertPointer(type, 2); 39879566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 3988264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 39893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3990264ace61SBarry Smith } 3991264ace61SBarry Smith 39925d83a8b1SBarry Smith /*@ 3993bb7acecfSBarry Smith DMConvert - Converts a `DM` to another `DM`, either of the same or different type. 399467a56275SMatthew G Knepley 399520f4b53cSBarry Smith Collective 399667a56275SMatthew G Knepley 399767a56275SMatthew G Knepley Input Parameters: 3998bb7acecfSBarry Smith + dm - the `DM` 3999bb7acecfSBarry Smith - newtype - new `DM` type (use "same" for the same type) 400067a56275SMatthew G Knepley 400167a56275SMatthew G Knepley Output Parameter: 4002bb7acecfSBarry Smith . M - pointer to new `DM` 400367a56275SMatthew G Knepley 400420f4b53cSBarry Smith Level: intermediate 400520f4b53cSBarry Smith 400673ff1848SBarry Smith Note: 4007bb7acecfSBarry Smith Cannot be used to convert a sequential `DM` to a parallel or a parallel to sequential, 4008bb7acecfSBarry Smith the MPI communicator of the generated `DM` is always the same as the communicator 4009bb7acecfSBarry Smith of the input `DM`. 401067a56275SMatthew G Knepley 40111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetType()`, `DMCreate()`, `DMClone()` 401267a56275SMatthew G Knepley @*/ 4013d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 4014d71ae5a4SJacob Faibussowitsch { 401567a56275SMatthew G Knepley DM B; 401667a56275SMatthew G Knepley char convname[256]; 4017c067b6caSMatthew G. Knepley PetscBool sametype /*, issame */; 401867a56275SMatthew G Knepley 401967a56275SMatthew G Knepley PetscFunctionBegin; 402067a56275SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 402167a56275SMatthew G Knepley PetscValidType(dm, 1); 40224f572ea9SToby Isaac PetscAssertPointer(M, 3); 40239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, newtype, &sametype)); 40249566063dSJacob Faibussowitsch /* PetscCall(PetscStrcmp(newtype, "same", &issame)); */ 4025c067b6caSMatthew G. Knepley if (sametype) { 4026c067b6caSMatthew G. Knepley *M = dm; 40279566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 40283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4029c067b6caSMatthew G. Knepley } else { 40300298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM *) = NULL; 403167a56275SMatthew G Knepley 403267a56275SMatthew G Knepley /* 403367a56275SMatthew G Knepley Order of precedence: 403467a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 403567a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 403667a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 403767a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 403867a56275SMatthew G Knepley 5) Use a really basic converter. 403967a56275SMatthew G Knepley */ 404067a56275SMatthew G Knepley 404167a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 40429566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40439566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40449566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40459566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40469566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40479566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)dm, convname, &conv)); 404867a56275SMatthew G Knepley if (conv) goto foundconv; 404967a56275SMatthew G Knepley 405067a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 40519566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &B)); 40529566063dSJacob Faibussowitsch PetscCall(DMSetType(B, newtype)); 40539566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40549566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40559566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40569566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40579566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40589566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 405967a56275SMatthew G Knepley if (conv) { 40609566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 406167a56275SMatthew G Knepley goto foundconv; 406267a56275SMatthew G Knepley } 406367a56275SMatthew G Knepley 406467a56275SMatthew G Knepley #if 0 406567a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 406667a56275SMatthew G Knepley conv = B->ops->convertfrom; 40679566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 406867a56275SMatthew G Knepley if (conv) goto foundconv; 406967a56275SMatthew G Knepley 407067a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 407167a56275SMatthew G Knepley if (dm->ops->convert) { 407267a56275SMatthew G Knepley conv = dm->ops->convert; 407367a56275SMatthew G Knepley } 407467a56275SMatthew G Knepley if (conv) goto foundconv; 407567a56275SMatthew G Knepley #endif 407667a56275SMatthew G Knepley 407767a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 407898921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject)dm)->type_name, newtype); 407967a56275SMatthew G Knepley 408067a56275SMatthew G Knepley foundconv: 40819566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Convert, dm, 0, 0, 0)); 40829566063dSJacob Faibussowitsch PetscCall((*conv)(dm, newtype, M)); 408312fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 408490b157c4SStefano Zampini { 40854fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 40866858538eSMatthew G. Knepley 40874fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 40884fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*M, maxCell, Lstart, L)); 4089c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 40909566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->vectype)); 40919566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*M)->vectype)); 40929566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->mattype)); 40939566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*M)->mattype)); 409412fa691eSMatthew G. Knepley } 40959566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Convert, dm, 0, 0, 0)); 409667a56275SMatthew G Knepley } 40979566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 40983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 409967a56275SMatthew G Knepley } 4100264ace61SBarry Smith 4101264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 4102264ace61SBarry Smith 4103264ace61SBarry Smith /*@C 4104bb7acecfSBarry Smith DMRegister - Adds a new `DM` type implementation 41051c84c290SBarry Smith 4106cc4c1da9SBarry Smith Not Collective, No Fortran Support 41071c84c290SBarry Smith 41081c84c290SBarry Smith Input Parameters: 410920f4b53cSBarry Smith + sname - The name of a new user-defined creation routine 411020f4b53cSBarry Smith - function - The creation routine itself 411120f4b53cSBarry Smith 411220f4b53cSBarry Smith Level: advanced 41131c84c290SBarry Smith 411473ff1848SBarry Smith Note: 411520f4b53cSBarry Smith `DMRegister()` may be called multiple times to add several user-defined `DM`s 41161c84c290SBarry Smith 411760225df5SJacob Faibussowitsch Example Usage: 41181c84c290SBarry Smith .vb 4119bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 41201c84c290SBarry Smith .ve 41211c84c290SBarry Smith 412220f4b53cSBarry Smith Then, your `DM` type can be chosen with the procedural interface via 41231c84c290SBarry Smith .vb 41241c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 41251c84c290SBarry Smith DMSetType(DM,"my_da"); 41261c84c290SBarry Smith .ve 41271c84c290SBarry Smith or at runtime via the option 41281c84c290SBarry Smith .vb 41291c84c290SBarry Smith -da_type my_da 41301c84c290SBarry Smith .ve 4131264ace61SBarry Smith 41321cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMSetType()`, `DMRegisterAll()`, `DMRegisterDestroy()` 4133264ace61SBarry Smith @*/ 4134d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRegister(const char sname[], PetscErrorCode (*function)(DM)) 4135d71ae5a4SJacob Faibussowitsch { 4136264ace61SBarry Smith PetscFunctionBegin; 41379566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 41389566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&DMList, sname, function)); 41393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4140264ace61SBarry Smith } 4141264ace61SBarry Smith 4142ffeef943SBarry Smith /*@ 4143bb7acecfSBarry Smith DMLoad - Loads a DM that has been stored in binary with `DMView()`. 4144b859378eSBarry Smith 414520f4b53cSBarry Smith Collective 4146b859378eSBarry Smith 4147b859378eSBarry Smith Input Parameters: 4148bb7acecfSBarry Smith + newdm - the newly loaded `DM`, this needs to have been created with `DMCreate()` or 4149bb7acecfSBarry Smith some related function before a call to `DMLoad()`. 4150bb7acecfSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or 4151bb7acecfSBarry Smith `PETSCVIEWERHDF5` file viewer, obtained from `PetscViewerHDF5Open()` 4152b859378eSBarry Smith 4153b859378eSBarry Smith Level: intermediate 4154b859378eSBarry Smith 4155b859378eSBarry Smith Notes: 415655849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4157b859378eSBarry Smith 4158bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` format, one can save multiple `DMPLEX` 4159bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 4160bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 4161cd7e8a5eSksagiyam 41621cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewerBinaryOpen()`, `DMView()`, `MatLoad()`, `VecLoad()` 4163b859378eSBarry Smith @*/ 4164d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4165d71ae5a4SJacob Faibussowitsch { 41669331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4167b859378eSBarry Smith 4168b859378eSBarry Smith PetscFunctionBegin; 4169b859378eSBarry Smith PetscValidHeaderSpecific(newdm, DM_CLASSID, 1); 4170b859378eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 41719566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckReadable(viewer)); 41729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 41739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 41749566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Load, viewer, 0, 0, 0)); 41759331c7a4SMatthew G. Knepley if (isbinary) { 41769331c7a4SMatthew G. Knepley PetscInt classid; 41779331c7a4SMatthew G. Knepley char type[256]; 4178b859378eSBarry Smith 41799566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 4180835f2295SStefano Zampini PetscCheck(classid == DM_FILE_CLASSID, PetscObjectComm((PetscObject)newdm), PETSC_ERR_ARG_WRONG, "Not DM next in file, classid found %" PetscInt_FMT, classid); 41819566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 41829566063dSJacob Faibussowitsch PetscCall(DMSetType(newdm, type)); 4183dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41849331c7a4SMatthew G. Knepley } else if (ishdf5) { 4185dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41869331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 41879566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Load, viewer, 0, 0, 0)); 41883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4189b859378eSBarry Smith } 4190b859378eSBarry Smith 41914ee01570SBarry Smith /* FEM Support */ 41927da65231SMatthew G Knepley 41932ecf6ec3SMatthew G. Knepley PetscErrorCode DMPrintCellIndices(PetscInt c, const char name[], PetscInt len, const PetscInt x[]) 41942ecf6ec3SMatthew G. Knepley { 41952ecf6ec3SMatthew G. Knepley PetscInt f; 41962ecf6ec3SMatthew G. Knepley 41972ecf6ec3SMatthew G. Knepley PetscFunctionBegin; 41982ecf6ec3SMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41992ecf6ec3SMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %" PetscInt_FMT " |\n", x[f])); 42002ecf6ec3SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 42012ecf6ec3SMatthew G. Knepley } 42022ecf6ec3SMatthew G. Knepley 4203d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4204d71ae5a4SJacob Faibussowitsch { 42051d47ebbbSSatish Balay PetscInt f; 42061b30c384SMatthew G Knepley 42077da65231SMatthew G Knepley PetscFunctionBegin; 420863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 420948a46eb9SPierre Jolivet for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]))); 42103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42117da65231SMatthew G Knepley } 42127da65231SMatthew G Knepley 42135962854dSMatthew G. Knepley PetscErrorCode DMPrintCellVectorReal(PetscInt c, const char name[], PetscInt len, const PetscReal x[]) 42145962854dSMatthew G. Knepley { 42155962854dSMatthew G. Knepley PetscInt f; 42165962854dSMatthew G. Knepley 42175962854dSMatthew G. Knepley PetscFunctionBegin; 42185962854dSMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 42195962854dSMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)x[f])); 42205962854dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 42215962854dSMatthew G. Knepley } 42225962854dSMatthew G. Knepley 4223d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4224d71ae5a4SJacob Faibussowitsch { 42251b30c384SMatthew G Knepley PetscInt f, g; 42267da65231SMatthew G Knepley 42277da65231SMatthew G Knepley PetscFunctionBegin; 422863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 42291d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 42309566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |")); 423148a46eb9SPierre Jolivet for (g = 0; g < cols; ++g) PetscCall(PetscPrintf(PETSC_COMM_SELF, " % 9.5g", (double)PetscRealPart(A[f * cols + g]))); 42329566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |\n")); 42337da65231SMatthew G Knepley } 42343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42357da65231SMatthew G Knepley } 4236e7c4fc90SDmitry Karpeev 4237d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4238d71ae5a4SJacob Faibussowitsch { 42390c5b8624SToby Isaac PetscInt localSize, bs; 42400c5b8624SToby Isaac PetscMPIInt size; 42410c5b8624SToby Isaac Vec x, xglob; 42420c5b8624SToby Isaac const PetscScalar *xarray; 4243e759306cSMatthew G. Knepley 4244e759306cSMatthew G. Knepley PetscFunctionBegin; 42459566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 42469566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &x)); 42479566063dSJacob Faibussowitsch PetscCall(VecCopy(X, x)); 424893ec0da9SPierre Jolivet PetscCall(VecFilter(x, tol)); 42499566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "%s:\n", name)); 42500c5b8624SToby Isaac if (size > 1) { 42519566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(x, &localSize)); 42529566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xarray)); 42539566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(x, &bs)); 42549566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm), bs, localSize, PETSC_DETERMINE, xarray, &xglob)); 42550c5b8624SToby Isaac } else { 42560c5b8624SToby Isaac xglob = x; 42570c5b8624SToby Isaac } 42589566063dSJacob Faibussowitsch PetscCall(VecView(xglob, PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)dm)))); 42590c5b8624SToby Isaac if (size > 1) { 42609566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xglob)); 42619566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xarray)); 42620c5b8624SToby Isaac } 42639566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 42643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4265e759306cSMatthew G. Knepley } 4266e759306cSMatthew G. Knepley 426788ed4aceSMatthew G Knepley /*@ 4268bb7acecfSBarry Smith DMGetLocalSection - Get the `PetscSection` encoding the local data layout for the `DM`. 426988ed4aceSMatthew G Knepley 427088ed4aceSMatthew G Knepley Input Parameter: 4271bb7acecfSBarry Smith . dm - The `DM` 427288ed4aceSMatthew G Knepley 427388ed4aceSMatthew G Knepley Output Parameter: 4274bb7acecfSBarry Smith . section - The `PetscSection` 427588ed4aceSMatthew G Knepley 427620f4b53cSBarry Smith Options Database Key: 4277bb7acecfSBarry Smith . -dm_petscsection_view - View the section created by the `DM` 4278e5893cccSMatthew G. Knepley 427988ed4aceSMatthew G Knepley Level: intermediate 428088ed4aceSMatthew G Knepley 4281bb7acecfSBarry Smith Note: 4282bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 428388ed4aceSMatthew G Knepley 42841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetGlobalSection()` 428588ed4aceSMatthew G Knepley @*/ 4286d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 4287d71ae5a4SJacob Faibussowitsch { 428888ed4aceSMatthew G Knepley PetscFunctionBegin; 428988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 42904f572ea9SToby Isaac PetscAssertPointer(section, 2); 42911bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4292e5e52638SMatthew G. Knepley PetscInt d; 4293e5e52638SMatthew G. Knepley 429445480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 429545480ffeSMatthew G. Knepley PetscObject obj = (PetscObject)dm; 429645480ffeSMatthew G. Knepley PetscViewer viewer; 429745480ffeSMatthew G. Knepley PetscViewerFormat format; 429845480ffeSMatthew G. Knepley PetscBool flg; 429945480ffeSMatthew G. Knepley 4300648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg)); 43019566063dSJacob Faibussowitsch if (flg) PetscCall(PetscViewerPushFormat(viewer, format)); 430245480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 43039566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(dm->probs[d].ds)); 43049566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDSView(dm->probs[d].ds, viewer)); 430545480ffeSMatthew G. Knepley } 430645480ffeSMatthew G. Knepley if (flg) { 43079566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 43089566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 4309648c30bcSBarry Smith PetscCall(PetscViewerDestroy(&viewer)); 431045480ffeSMatthew G. Knepley } 431145480ffeSMatthew G. Knepley } 4312dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalsection); 43139566063dSJacob Faibussowitsch if (dm->localSection) PetscCall(PetscObjectViewFromOptions((PetscObject)dm->localSection, NULL, "-dm_petscsection_view")); 43142f0f8703SMatthew G. Knepley } 43151bb6d2a8SBarry Smith *section = dm->localSection; 43163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 431788ed4aceSMatthew G Knepley } 431888ed4aceSMatthew G Knepley 431988ed4aceSMatthew G Knepley /*@ 4320bb7acecfSBarry Smith DMSetLocalSection - Set the `PetscSection` encoding the local data layout for the `DM`. 432188ed4aceSMatthew G Knepley 432288ed4aceSMatthew G Knepley Input Parameters: 4323bb7acecfSBarry Smith + dm - The `DM` 4324bb7acecfSBarry Smith - section - The `PetscSection` 432588ed4aceSMatthew G Knepley 432688ed4aceSMatthew G Knepley Level: intermediate 432788ed4aceSMatthew G Knepley 4328bb7acecfSBarry Smith Note: 4329bb7acecfSBarry Smith Any existing Section will be destroyed 433088ed4aceSMatthew G Knepley 43311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscSection`, `DMGetLocalSection()`, `DMSetGlobalSection()` 433288ed4aceSMatthew G Knepley @*/ 4333d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 4334d71ae5a4SJacob Faibussowitsch { 4335c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4336af122d2aSMatthew G Knepley PetscInt f; 433788ed4aceSMatthew G Knepley 433888ed4aceSMatthew G Knepley PetscFunctionBegin; 433988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4340b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 43419566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 43429566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->localSection)); 43431bb6d2a8SBarry Smith dm->localSection = section; 43449566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(dm->localSection, &numFields)); 4345af122d2aSMatthew G Knepley if (numFields) { 43469566063dSJacob Faibussowitsch PetscCall(DMSetNumFields(dm, numFields)); 4347af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43480f21e855SMatthew G. Knepley PetscObject disc; 4349af122d2aSMatthew G Knepley const char *name; 4350af122d2aSMatthew G Knepley 43519566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(dm->localSection, f, &name)); 43529566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, &disc)); 43539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName(disc, name)); 4354af122d2aSMatthew G Knepley } 4355af122d2aSMatthew G Knepley } 435650350c8eSStefano Zampini /* The global section and the SectionSF will be rebuilt 435750350c8eSStefano Zampini in the next call to DMGetGlobalSection() and DMGetSectionSF(). */ 43589566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 435950350c8eSStefano Zampini PetscCall(PetscSFDestroy(&dm->sectionSF)); 436052947b74SStefano Zampini PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 436150350c8eSStefano Zampini 436250350c8eSStefano Zampini /* Clear scratch vectors */ 436350350c8eSStefano Zampini PetscCall(DMClearGlobalVectors(dm)); 436450350c8eSStefano Zampini PetscCall(DMClearLocalVectors(dm)); 436550350c8eSStefano Zampini PetscCall(DMClearNamedGlobalVectors(dm)); 436650350c8eSStefano Zampini PetscCall(DMClearNamedLocalVectors(dm)); 43673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 436888ed4aceSMatthew G Knepley } 436988ed4aceSMatthew G Knepley 4370adc21957SMatthew G. Knepley /*@C 4371d8b4a066SPierre Jolivet DMCreateSectionPermutation - Create a permutation of the `PetscSection` chart and optionally a block structure. 4372adc21957SMatthew G. Knepley 4373adc21957SMatthew G. Knepley Input Parameter: 4374adc21957SMatthew G. Knepley . dm - The `DM` 4375adc21957SMatthew G. Knepley 43769cde84edSJose E. Roman Output Parameters: 4377adc21957SMatthew G. Knepley + perm - A permutation of the mesh points in the chart 4378b6971eaeSBarry Smith - blockStarts - A high bit is set for the point that begins every block, or `NULL` for default blocking 4379adc21957SMatthew G. Knepley 4380adc21957SMatthew G. Knepley Level: developer 4381adc21957SMatthew G. Knepley 4382adc21957SMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `PetscSection`, `DMGetLocalSection()`, `DMGetGlobalSection()` 4383adc21957SMatthew G. Knepley @*/ 4384adc21957SMatthew G. Knepley PetscErrorCode DMCreateSectionPermutation(DM dm, IS *perm, PetscBT *blockStarts) 4385adc21957SMatthew G. Knepley { 4386adc21957SMatthew G. Knepley PetscFunctionBegin; 4387adc21957SMatthew G. Knepley *perm = NULL; 4388adc21957SMatthew G. Knepley *blockStarts = NULL; 4389adc21957SMatthew G. Knepley PetscTryTypeMethod(dm, createsectionpermutation, perm, blockStarts); 4390adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 4391adc21957SMatthew G. Knepley } 4392adc21957SMatthew G. Knepley 43939435951eSToby Isaac /*@ 4394bb7acecfSBarry Smith DMGetDefaultConstraints - Get the `PetscSection` and `Mat` that specify the local constraint interpolation. See `DMSetDefaultConstraints()` for a description of the purpose of constraint interpolation. 43959435951eSToby Isaac 439620f4b53cSBarry Smith not Collective 4397e228b242SToby Isaac 43989435951eSToby Isaac Input Parameter: 4399bb7acecfSBarry Smith . dm - The `DM` 44009435951eSToby Isaac 4401d8d19677SJose E. Roman Output Parameters: 440220f4b53cSBarry 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. 440320f4b53cSBarry 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. 440479769bd5SJed Brown - bias - Vector containing bias to be added to constrained dofs 44059435951eSToby Isaac 44069435951eSToby Isaac Level: advanced 44079435951eSToby Isaac 4408bb7acecfSBarry Smith Note: 4409bb7acecfSBarry Smith This gets borrowed references, so the user should not destroy the `PetscSection`, `Mat`, or `Vec`. 44109435951eSToby Isaac 44111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDefaultConstraints()` 44129435951eSToby Isaac @*/ 4413d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat, Vec *bias) 4414d71ae5a4SJacob Faibussowitsch { 44159435951eSToby Isaac PetscFunctionBegin; 44169435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4417dbbe0bcdSBarry Smith if (!dm->defaultConstraint.section && !dm->defaultConstraint.mat && dm->ops->createdefaultconstraints) PetscUseTypeMethod(dm, createdefaultconstraints); 44183b8ba7d1SJed Brown if (section) *section = dm->defaultConstraint.section; 44193b8ba7d1SJed Brown if (mat) *mat = dm->defaultConstraint.mat; 442079769bd5SJed Brown if (bias) *bias = dm->defaultConstraint.bias; 44213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44229435951eSToby Isaac } 44239435951eSToby Isaac 44249435951eSToby Isaac /*@ 4425bb7acecfSBarry Smith DMSetDefaultConstraints - Set the `PetscSection` and `Mat` that specify the local constraint interpolation. 44269435951eSToby Isaac 442720f4b53cSBarry Smith Collective 4428e228b242SToby Isaac 44299435951eSToby Isaac Input Parameters: 4430bb7acecfSBarry Smith + dm - The `DM` 4431bb7acecfSBarry 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). 443220f4b53cSBarry 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). 443320f4b53cSBarry 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). 44349435951eSToby Isaac 44359435951eSToby Isaac Level: advanced 44369435951eSToby Isaac 443720f4b53cSBarry Smith Notes: 443820f4b53cSBarry 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()`. 443920f4b53cSBarry Smith 444020f4b53cSBarry 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. 444120f4b53cSBarry Smith 4442bb7acecfSBarry Smith This increments the references of the `PetscSection`, `Mat`, and `Vec`, so they user can destroy them. 44439435951eSToby Isaac 44441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDefaultConstraints()` 44459435951eSToby Isaac @*/ 4446d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat, Vec bias) 4447d71ae5a4SJacob Faibussowitsch { 4448e228b242SToby Isaac PetscMPIInt result; 44499435951eSToby Isaac 44509435951eSToby Isaac PetscFunctionBegin; 44519435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4452e228b242SToby Isaac if (section) { 4453e228b242SToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 44549566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)section), &result)); 44557a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint section must have local communicator"); 4456e228b242SToby Isaac } 4457e228b242SToby Isaac if (mat) { 4458e228b242SToby Isaac PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 44599566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)mat), &result)); 44607a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint matrix must have local communicator"); 4461e228b242SToby Isaac } 446279769bd5SJed Brown if (bias) { 446379769bd5SJed Brown PetscValidHeaderSpecific(bias, VEC_CLASSID, 4); 44649566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)bias), &result)); 446579769bd5SJed Brown PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint bias must have local communicator"); 446679769bd5SJed Brown } 44679566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 44689566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->defaultConstraint.section)); 44693b8ba7d1SJed Brown dm->defaultConstraint.section = section; 44709566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 44719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dm->defaultConstraint.mat)); 44723b8ba7d1SJed Brown dm->defaultConstraint.mat = mat; 44739566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)bias)); 44749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dm->defaultConstraint.bias)); 447579769bd5SJed Brown dm->defaultConstraint.bias = bias; 44763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44779435951eSToby Isaac } 44789435951eSToby Isaac 4479497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4480507e4973SMatthew G. Knepley /* 4481bb7acecfSBarry Smith DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. Generates and error if they are not consistent. 4482507e4973SMatthew G. Knepley 4483507e4973SMatthew G. Knepley Input Parameters: 4484bb7acecfSBarry Smith + dm - The `DM` 4485bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4486bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 4487507e4973SMatthew G. Knepley 4488507e4973SMatthew G. Knepley Level: intermediate 4489507e4973SMatthew G. Knepley 44901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()` 4491507e4973SMatthew G. Knepley */ 4492d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4493d71ae5a4SJacob Faibussowitsch { 4494507e4973SMatthew G. Knepley MPI_Comm comm; 4495507e4973SMatthew G. Knepley PetscLayout layout; 4496507e4973SMatthew G. Knepley const PetscInt *ranges; 4497507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4498507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4499507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4500507e4973SMatthew G. Knepley 4501507e4973SMatthew G. Knepley PetscFunctionBegin; 45029566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4503507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 45059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 45069566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(globalSection, &pStart, &pEnd)); 45079566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(globalSection, &nroots)); 45089566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &layout)); 45099566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(layout, 1)); 45109566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(layout, nroots)); 45119566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(layout)); 45129566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRanges(layout, &ranges)); 4513507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4514f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4515507e4973SMatthew G. Knepley 45169566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(localSection, p, &dof)); 45179566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(localSection, p, &off)); 45189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(localSection, p, &cdof)); 45199566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(globalSection, p, &gdof)); 45209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(globalSection, p, &gcdof)); 45219566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(globalSection, p, &goff)); 4522507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 45239371c9d4SSatish Balay if ((gdof < 0 ? -(gdof + 1) : gdof) != dof) { 45249371c9d4SSatish 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)); 45259371c9d4SSatish Balay valid = PETSC_FALSE; 45269371c9d4SSatish Balay } 45279371c9d4SSatish Balay if (gcdof && (gcdof != cdof)) { 45289371c9d4SSatish 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)); 45299371c9d4SSatish Balay valid = PETSC_FALSE; 45309371c9d4SSatish Balay } 4531507e4973SMatthew G. Knepley if (gdof < 0) { 4532507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof + 1) - gcdof : gdof - gcdof; 4533507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4534507e4973SMatthew G. Knepley PetscInt offset = -(goff + 1) + d, r; 4535507e4973SMatthew G. Knepley 45369566063dSJacob Faibussowitsch PetscCall(PetscFindInt(offset, size + 1, ranges, &r)); 4537507e4973SMatthew G. Knepley if (r < 0) r = -(r + 2); 45389371c9d4SSatish Balay if ((r < 0) || (r >= size)) { 45399371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Point %" PetscInt_FMT " mapped to invalid process %" PetscInt_FMT " (%" PetscInt_FMT ", %" PetscInt_FMT ")\n", rank, p, r, gdof, goff)); 45409371c9d4SSatish Balay valid = PETSC_FALSE; 45419371c9d4SSatish Balay break; 45429371c9d4SSatish Balay } 4543507e4973SMatthew G. Knepley } 4544507e4973SMatthew G. Knepley } 4545507e4973SMatthew G. Knepley } 45469566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&layout)); 45479566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 4548462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm)); 4549507e4973SMatthew G. Knepley if (!gvalid) { 45509566063dSJacob Faibussowitsch PetscCall(DMView(dm, NULL)); 4551507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4552507e4973SMatthew G. Knepley } 45533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4554507e4973SMatthew G. Knepley } 4555f741bcd2SMatthew G. Knepley #endif 4556507e4973SMatthew G. Knepley 455790df3356SJames Wright PetscErrorCode DMGetIsoperiodicPointSF_Internal(DM dm, PetscSF *sf) 45586725e60dSJed Brown { 45596725e60dSJed Brown PetscErrorCode (*f)(DM, PetscSF *); 45604d86920dSPierre Jolivet 45616725e60dSJed Brown PetscFunctionBegin; 45626725e60dSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45634f572ea9SToby Isaac PetscAssertPointer(sf, 2); 45645f06a3ddSJed Brown PetscCall(PetscObjectQueryFunction((PetscObject)dm, "DMGetIsoperiodicPointSF_C", &f)); 45656725e60dSJed Brown if (f) PetscCall(f(dm, sf)); 45666725e60dSJed Brown else *sf = dm->sf; 45673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45686725e60dSJed Brown } 45696725e60dSJed Brown 457088ed4aceSMatthew G Knepley /*@ 4571bb7acecfSBarry Smith DMGetGlobalSection - Get the `PetscSection` encoding the global data layout for the `DM`. 457288ed4aceSMatthew G Knepley 457320f4b53cSBarry Smith Collective 45748b1ab98fSJed Brown 457588ed4aceSMatthew G Knepley Input Parameter: 4576bb7acecfSBarry Smith . dm - The `DM` 457788ed4aceSMatthew G Knepley 457888ed4aceSMatthew G Knepley Output Parameter: 4579bb7acecfSBarry Smith . section - The `PetscSection` 458088ed4aceSMatthew G Knepley 458188ed4aceSMatthew G Knepley Level: intermediate 458288ed4aceSMatthew G Knepley 4583bb7acecfSBarry Smith Note: 4584bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 458588ed4aceSMatthew G Knepley 45861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetLocalSection()` 458788ed4aceSMatthew G Knepley @*/ 4588d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 4589d71ae5a4SJacob Faibussowitsch { 459088ed4aceSMatthew G Knepley PetscFunctionBegin; 459188ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45924f572ea9SToby Isaac PetscAssertPointer(section, 2); 45931bb6d2a8SBarry Smith if (!dm->globalSection) { 4594fd59a867SMatthew G. Knepley PetscSection s; 45956725e60dSJed Brown PetscSF sf; 4596fd59a867SMatthew G. Knepley 45979566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 45987a8be351SBarry Smith PetscCheck(s, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 45997a8be351SBarry Smith PetscCheck(dm->sf, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 46005f06a3ddSJed Brown PetscCall(DMGetIsoperiodicPointSF_Internal(dm, &sf)); 4601eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionCreateGlobalSection(s, sf, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &dm->globalSection)); 46029566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&dm->map)); 46039566063dSJacob Faibussowitsch PetscCall(PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map)); 46049566063dSJacob Faibussowitsch PetscCall(PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view")); 460588ed4aceSMatthew G Knepley } 46061bb6d2a8SBarry Smith *section = dm->globalSection; 46073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 460888ed4aceSMatthew G Knepley } 460988ed4aceSMatthew G Knepley 4610b21d0597SMatthew G Knepley /*@ 4611bb7acecfSBarry Smith DMSetGlobalSection - Set the `PetscSection` encoding the global data layout for the `DM`. 4612b21d0597SMatthew G Knepley 4613b21d0597SMatthew G Knepley Input Parameters: 4614bb7acecfSBarry Smith + dm - The `DM` 46152fe279fdSBarry Smith - section - The PetscSection, or `NULL` 4616b21d0597SMatthew G Knepley 4617b21d0597SMatthew G Knepley Level: intermediate 4618b21d0597SMatthew G Knepley 4619bb7acecfSBarry Smith Note: 4620bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4621b21d0597SMatthew G Knepley 46221cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetGlobalSection()`, `DMSetLocalSection()` 4623b21d0597SMatthew G Knepley @*/ 4624d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 4625d71ae5a4SJacob Faibussowitsch { 4626b21d0597SMatthew G Knepley PetscFunctionBegin; 4627b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46285080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 46299566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 46309566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 46311bb6d2a8SBarry Smith dm->globalSection = section; 4632497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 46339566063dSJacob Faibussowitsch if (section) PetscCall(DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section)); 4634507e4973SMatthew G. Knepley #endif 463550350c8eSStefano Zampini /* Clear global scratch vectors and sectionSF */ 463650350c8eSStefano Zampini PetscCall(PetscSFDestroy(&dm->sectionSF)); 463752947b74SStefano Zampini PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 463850350c8eSStefano Zampini PetscCall(DMClearGlobalVectors(dm)); 463950350c8eSStefano Zampini PetscCall(DMClearNamedGlobalVectors(dm)); 46403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4641b21d0597SMatthew G Knepley } 4642b21d0597SMatthew G Knepley 464388ed4aceSMatthew G Knepley /*@ 4644bb7acecfSBarry Smith DMGetSectionSF - Get the `PetscSF` encoding the parallel dof overlap for the `DM`. If it has not been set, 4645bb7acecfSBarry Smith it is created from the default `PetscSection` layouts in the `DM`. 464688ed4aceSMatthew G Knepley 464788ed4aceSMatthew G Knepley Input Parameter: 4648bb7acecfSBarry Smith . dm - The `DM` 464988ed4aceSMatthew G Knepley 465088ed4aceSMatthew G Knepley Output Parameter: 4651bb7acecfSBarry Smith . sf - The `PetscSF` 465288ed4aceSMatthew G Knepley 465388ed4aceSMatthew G Knepley Level: intermediate 465488ed4aceSMatthew G Knepley 4655bb7acecfSBarry Smith Note: 4656bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 465788ed4aceSMatthew G Knepley 46581cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetSectionSF()`, `DMCreateSectionSF()` 465988ed4aceSMatthew G Knepley @*/ 4660d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 4661d71ae5a4SJacob Faibussowitsch { 466288ed4aceSMatthew G Knepley PetscInt nroots; 466388ed4aceSMatthew G Knepley 466488ed4aceSMatthew G Knepley PetscFunctionBegin; 466588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46664f572ea9SToby Isaac PetscAssertPointer(sf, 2); 466748a46eb9SPierre Jolivet if (!dm->sectionSF) PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 46689566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL)); 466988ed4aceSMatthew G Knepley if (nroots < 0) { 467088ed4aceSMatthew G Knepley PetscSection section, gSection; 467188ed4aceSMatthew G Knepley 46729566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 467331ea6d37SMatthew G Knepley if (section) { 46749566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gSection)); 46759566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSF(dm, section, gSection)); 467631ea6d37SMatthew G Knepley } else { 46770298fd71SBarry Smith *sf = NULL; 46783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 467931ea6d37SMatthew G Knepley } 468088ed4aceSMatthew G Knepley } 46811bb6d2a8SBarry Smith *sf = dm->sectionSF; 46823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 468388ed4aceSMatthew G Knepley } 468488ed4aceSMatthew G Knepley 468588ed4aceSMatthew G Knepley /*@ 4686bb7acecfSBarry Smith DMSetSectionSF - Set the `PetscSF` encoding the parallel dof overlap for the `DM` 468788ed4aceSMatthew G Knepley 468888ed4aceSMatthew G Knepley Input Parameters: 4689bb7acecfSBarry Smith + dm - The `DM` 4690bb7acecfSBarry Smith - sf - The `PetscSF` 469188ed4aceSMatthew G Knepley 469288ed4aceSMatthew G Knepley Level: intermediate 469388ed4aceSMatthew G Knepley 4694bb7acecfSBarry Smith Note: 4695bb7acecfSBarry Smith Any previous `PetscSF` is destroyed 469688ed4aceSMatthew G Knepley 46971cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMCreateSectionSF()` 469888ed4aceSMatthew G Knepley @*/ 4699d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 4700d71ae5a4SJacob Faibussowitsch { 470188ed4aceSMatthew G Knepley PetscFunctionBegin; 470288ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4703b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47049566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47059566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sectionSF)); 47061bb6d2a8SBarry Smith dm->sectionSF = sf; 47073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 470888ed4aceSMatthew G Knepley } 470988ed4aceSMatthew G Knepley 4710cc4c1da9SBarry Smith /*@ 4711bb7acecfSBarry Smith DMCreateSectionSF - Create the `PetscSF` encoding the parallel dof overlap for the `DM` based upon the `PetscSection`s 471288ed4aceSMatthew G Knepley describing the data layout. 471388ed4aceSMatthew G Knepley 471488ed4aceSMatthew G Knepley Input Parameters: 4715bb7acecfSBarry Smith + dm - The `DM` 4716bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4717bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 471888ed4aceSMatthew G Knepley 47191bb6d2a8SBarry Smith Level: developer 47201bb6d2a8SBarry Smith 4721bb7acecfSBarry Smith Note: 4722bb7acecfSBarry Smith One usually uses `DMGetSectionSF()` to obtain the `PetscSF` 4723bb7acecfSBarry Smith 472473ff1848SBarry Smith Developer Note: 4725bb7acecfSBarry Smith Since this routine has for arguments the two sections from the `DM` and puts the resulting `PetscSF` 4726bb7acecfSBarry Smith directly into the `DM`, perhaps this function should not take the local and global sections as 4727b6971eaeSBarry Smith input and should just obtain them from the `DM`? Plus PETSc creation functions return the thing 4728b6971eaeSBarry Smith they create, this returns nothing 47291bb6d2a8SBarry Smith 47301cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMGetLocalSection()`, `DMGetGlobalSection()` 473188ed4aceSMatthew G Knepley @*/ 4732d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 4733d71ae5a4SJacob Faibussowitsch { 473488ed4aceSMatthew G Knepley PetscFunctionBegin; 473588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47369566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection)); 47373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 473888ed4aceSMatthew G Knepley } 4739af122d2aSMatthew G Knepley 4740b21d0597SMatthew G Knepley /*@ 4741bb7acecfSBarry Smith DMGetPointSF - Get the `PetscSF` encoding the parallel section point overlap for the `DM`. 4742bb7acecfSBarry Smith 4743bb7acecfSBarry Smith Not collective but the resulting `PetscSF` is collective 4744b21d0597SMatthew G Knepley 4745b21d0597SMatthew G Knepley Input Parameter: 4746bb7acecfSBarry Smith . dm - The `DM` 4747b21d0597SMatthew G Knepley 4748b21d0597SMatthew G Knepley Output Parameter: 4749bb7acecfSBarry Smith . sf - The `PetscSF` 4750b21d0597SMatthew G Knepley 4751b21d0597SMatthew G Knepley Level: intermediate 4752b21d0597SMatthew G Knepley 4753bb7acecfSBarry Smith Note: 4754bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 4755b21d0597SMatthew G Knepley 47561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4757b21d0597SMatthew G Knepley @*/ 4758d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 4759d71ae5a4SJacob Faibussowitsch { 4760b21d0597SMatthew G Knepley PetscFunctionBegin; 4761b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47624f572ea9SToby Isaac PetscAssertPointer(sf, 2); 4763b21d0597SMatthew G Knepley *sf = dm->sf; 47643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4765b21d0597SMatthew G Knepley } 4766b21d0597SMatthew G Knepley 4767057b4bcdSMatthew G Knepley /*@ 4768bb7acecfSBarry Smith DMSetPointSF - Set the `PetscSF` encoding the parallel section point overlap for the `DM`. 4769bb7acecfSBarry Smith 477020f4b53cSBarry Smith Collective 4771057b4bcdSMatthew G Knepley 4772057b4bcdSMatthew G Knepley Input Parameters: 4773bb7acecfSBarry Smith + dm - The `DM` 4774bb7acecfSBarry Smith - sf - The `PetscSF` 4775057b4bcdSMatthew G Knepley 4776057b4bcdSMatthew G Knepley Level: intermediate 4777057b4bcdSMatthew G Knepley 47781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4779057b4bcdSMatthew G Knepley @*/ 4780d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 4781d71ae5a4SJacob Faibussowitsch { 4782057b4bcdSMatthew G Knepley PetscFunctionBegin; 4783057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4784b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47859566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47869566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sf)); 4787057b4bcdSMatthew G Knepley dm->sf = sf; 47883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4789057b4bcdSMatthew G Knepley } 4790057b4bcdSMatthew G Knepley 47914f37162bSMatthew G. Knepley /*@ 4792bb7acecfSBarry Smith DMGetNaturalSF - Get the `PetscSF` encoding the map back to the original mesh ordering 47934f37162bSMatthew G. Knepley 47944f37162bSMatthew G. Knepley Input Parameter: 4795bb7acecfSBarry Smith . dm - The `DM` 47964f37162bSMatthew G. Knepley 47974f37162bSMatthew G. Knepley Output Parameter: 4798bb7acecfSBarry Smith . sf - The `PetscSF` 47994f37162bSMatthew G. Knepley 48004f37162bSMatthew G. Knepley Level: intermediate 48014f37162bSMatthew G. Knepley 4802bb7acecfSBarry Smith Note: 4803bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 48044f37162bSMatthew G. Knepley 48051cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 48064f37162bSMatthew G. Knepley @*/ 4807d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 4808d71ae5a4SJacob Faibussowitsch { 48094f37162bSMatthew G. Knepley PetscFunctionBegin; 48104f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48114f572ea9SToby Isaac PetscAssertPointer(sf, 2); 48124f37162bSMatthew G. Knepley *sf = dm->sfNatural; 48133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48144f37162bSMatthew G. Knepley } 48154f37162bSMatthew G. Knepley 48164f37162bSMatthew G. Knepley /*@ 48174f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 48184f37162bSMatthew G. Knepley 48194f37162bSMatthew G. Knepley Input Parameters: 48204f37162bSMatthew G. Knepley + dm - The DM 48214f37162bSMatthew G. Knepley - sf - The PetscSF 48224f37162bSMatthew G. Knepley 48234f37162bSMatthew G. Knepley Level: intermediate 48244f37162bSMatthew G. Knepley 48251cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 48264f37162bSMatthew G. Knepley @*/ 4827d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 4828d71ae5a4SJacob Faibussowitsch { 48294f37162bSMatthew G. Knepley PetscFunctionBegin; 48304f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48314f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 48329566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 48339566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sfNatural)); 48344f37162bSMatthew G. Knepley dm->sfNatural = sf; 48353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48364f37162bSMatthew G. Knepley } 48374f37162bSMatthew G. Knepley 4838d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 4839d71ae5a4SJacob Faibussowitsch { 484034aa8a36SMatthew G. Knepley PetscClassId id; 484134aa8a36SMatthew G. Knepley 484234aa8a36SMatthew G. Knepley PetscFunctionBegin; 48439566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 484434aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 48459566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 484634aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 48479566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE)); 484817c1d62eSMatthew G. Knepley } else { 48499566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 485034aa8a36SMatthew G. Knepley } 48513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 485234aa8a36SMatthew G. Knepley } 485334aa8a36SMatthew G. Knepley 4854d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 4855d71ae5a4SJacob Faibussowitsch { 485644a7f3ddSMatthew G. Knepley RegionField *tmpr; 485744a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 485844a7f3ddSMatthew G. Knepley 485944a7f3ddSMatthew G. Knepley PetscFunctionBegin; 48603ba16761SJacob Faibussowitsch if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS); 48619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NfNew, &tmpr)); 486244a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 48639371c9d4SSatish Balay for (f = Nf; f < NfNew; ++f) { 48649371c9d4SSatish Balay tmpr[f].disc = NULL; 48659371c9d4SSatish Balay tmpr[f].label = NULL; 48669371c9d4SSatish Balay tmpr[f].avoidTensor = PETSC_FALSE; 48679371c9d4SSatish Balay } 48689566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 486944a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 487044a7f3ddSMatthew G. Knepley dm->fields = tmpr; 48713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 487244a7f3ddSMatthew G. Knepley } 487344a7f3ddSMatthew G. Knepley 487444a7f3ddSMatthew G. Knepley /*@ 487520f4b53cSBarry Smith DMClearFields - Remove all fields from the `DM` 487644a7f3ddSMatthew G. Knepley 487720f4b53cSBarry Smith Logically Collective 487844a7f3ddSMatthew G. Knepley 487944a7f3ddSMatthew G. Knepley Input Parameter: 488020f4b53cSBarry Smith . dm - The `DM` 488144a7f3ddSMatthew G. Knepley 488244a7f3ddSMatthew G. Knepley Level: intermediate 488344a7f3ddSMatthew G. Knepley 48841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetNumFields()`, `DMSetField()` 488544a7f3ddSMatthew G. Knepley @*/ 4886d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearFields(DM dm) 4887d71ae5a4SJacob Faibussowitsch { 488844a7f3ddSMatthew G. Knepley PetscInt f; 488944a7f3ddSMatthew G. Knepley 489044a7f3ddSMatthew G. Knepley PetscFunctionBegin; 489144a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 489244a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 48939566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 48949566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 489544a7f3ddSMatthew G. Knepley } 48969566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 489744a7f3ddSMatthew G. Knepley dm->fields = NULL; 489844a7f3ddSMatthew G. Knepley dm->Nf = 0; 48993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 490044a7f3ddSMatthew G. Knepley } 490144a7f3ddSMatthew G. Knepley 4902689b5837SMatthew G. Knepley /*@ 490320f4b53cSBarry Smith DMGetNumFields - Get the number of fields in the `DM` 4904689b5837SMatthew G. Knepley 490520f4b53cSBarry Smith Not Collective 4906689b5837SMatthew G. Knepley 4907689b5837SMatthew G. Knepley Input Parameter: 490820f4b53cSBarry Smith . dm - The `DM` 4909689b5837SMatthew G. Knepley 4910689b5837SMatthew G. Knepley Output Parameter: 491160225df5SJacob Faibussowitsch . numFields - The number of fields 4912689b5837SMatthew G. Knepley 4913689b5837SMatthew G. Knepley Level: intermediate 4914689b5837SMatthew G. Knepley 49151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNumFields()`, `DMSetField()` 4916689b5837SMatthew G. Knepley @*/ 4917d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 4918d71ae5a4SJacob Faibussowitsch { 49190f21e855SMatthew G. Knepley PetscFunctionBegin; 49200f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49214f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 492244a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 49233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4924af122d2aSMatthew G Knepley } 4925af122d2aSMatthew G Knepley 4926689b5837SMatthew G. Knepley /*@ 492720f4b53cSBarry Smith DMSetNumFields - Set the number of fields in the `DM` 4928689b5837SMatthew G. Knepley 492920f4b53cSBarry Smith Logically Collective 4930689b5837SMatthew G. Knepley 4931689b5837SMatthew G. Knepley Input Parameters: 493220f4b53cSBarry Smith + dm - The `DM` 493360225df5SJacob Faibussowitsch - numFields - The number of fields 4934689b5837SMatthew G. Knepley 4935689b5837SMatthew G. Knepley Level: intermediate 4936689b5837SMatthew G. Knepley 49371cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetField()` 4938689b5837SMatthew G. Knepley @*/ 4939d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4940d71ae5a4SJacob Faibussowitsch { 49410f21e855SMatthew G. Knepley PetscInt Nf, f; 4942af122d2aSMatthew G Knepley 4943af122d2aSMatthew G Knepley PetscFunctionBegin; 4944af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49459566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 49460f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 49470f21e855SMatthew G. Knepley PetscContainer obj; 49480f21e855SMatthew G. Knepley 49499566063dSJacob Faibussowitsch PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)dm), &obj)); 49509566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject)obj)); 49519566063dSJacob Faibussowitsch PetscCall(PetscContainerDestroy(&obj)); 4952af122d2aSMatthew G Knepley } 49533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4954af122d2aSMatthew G Knepley } 4955af122d2aSMatthew G Knepley 4956c1929be8SMatthew G. Knepley /*@ 4957bb7acecfSBarry Smith DMGetField - Return the `DMLabel` and discretization object for a given `DM` field 4958c1929be8SMatthew G. Knepley 495920f4b53cSBarry Smith Not Collective 4960c1929be8SMatthew G. Knepley 4961c1929be8SMatthew G. Knepley Input Parameters: 4962bb7acecfSBarry Smith + dm - The `DM` 4963c1929be8SMatthew G. Knepley - f - The field number 4964c1929be8SMatthew G. Knepley 496544a7f3ddSMatthew G. Knepley Output Parameters: 496620f4b53cSBarry Smith + label - The label indicating the support of the field, or `NULL` for the entire mesh (pass in `NULL` if not needed) 496720f4b53cSBarry Smith - disc - The discretization object (pass in `NULL` if not needed) 4968c1929be8SMatthew G. Knepley 496944a7f3ddSMatthew G. Knepley Level: intermediate 4970c1929be8SMatthew G. Knepley 49711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()` 4972c1929be8SMatthew G. Knepley @*/ 4973d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *disc) 4974d71ae5a4SJacob Faibussowitsch { 4975af122d2aSMatthew G Knepley PetscFunctionBegin; 4976af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49774f572ea9SToby Isaac PetscAssertPointer(disc, 4); 49787a8be351SBarry 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); 497944a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 4980bb7acecfSBarry Smith if (disc) *disc = dm->fields[f].disc; 49813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4982decb47aaSMatthew G. Knepley } 4983decb47aaSMatthew G. Knepley 4984083401c6SMatthew G. Knepley /* Does not clear the DS */ 4985d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4986d71ae5a4SJacob Faibussowitsch { 4987083401c6SMatthew G. Knepley PetscFunctionBegin; 49889566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, f + 1)); 49899566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 49909566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 4991083401c6SMatthew G. Knepley dm->fields[f].label = label; 4992bb7acecfSBarry Smith dm->fields[f].disc = disc; 49939566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 4994835f2295SStefano Zampini PetscCall(PetscObjectReference(disc)); 49953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4996083401c6SMatthew G. Knepley } 4997083401c6SMatthew G. Knepley 4998ffeef943SBarry Smith /*@ 4999bb7acecfSBarry Smith DMSetField - Set the discretization object for a given `DM` field. Usually one would call `DMAddField()` which automatically handles 5000bb7acecfSBarry Smith the field numbering. 5001c1929be8SMatthew G. Knepley 500220f4b53cSBarry Smith Logically Collective 5003c1929be8SMatthew G. Knepley 5004c1929be8SMatthew G. Knepley Input Parameters: 5005bb7acecfSBarry Smith + dm - The `DM` 5006c1929be8SMatthew G. Knepley . f - The field number 500720f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 5008bb7acecfSBarry Smith - disc - The discretization object 5009c1929be8SMatthew G. Knepley 501044a7f3ddSMatthew G. Knepley Level: intermediate 5011c1929be8SMatthew G. Knepley 50121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()` 5013c1929be8SMatthew G. Knepley @*/ 5014d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject disc) 5015d71ae5a4SJacob Faibussowitsch { 5016decb47aaSMatthew G. Knepley PetscFunctionBegin; 5017decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5018e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 5019bb7acecfSBarry Smith PetscValidHeader(disc, 4); 50207a8be351SBarry Smith PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f); 5021bb7acecfSBarry Smith PetscCall(DMSetField_Internal(dm, f, label, disc)); 5022bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, f, disc)); 50239566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 50243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 502544a7f3ddSMatthew G. Knepley } 502644a7f3ddSMatthew G. Knepley 5027ffeef943SBarry Smith /*@ 5028bb7acecfSBarry 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) 5029bb7acecfSBarry Smith and a discretization object that defines the function space associated with those points. 503044a7f3ddSMatthew G. Knepley 503120f4b53cSBarry Smith Logically Collective 503244a7f3ddSMatthew G. Knepley 503344a7f3ddSMatthew G. Knepley Input Parameters: 5034bb7acecfSBarry Smith + dm - The `DM` 503520f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 5036bb7acecfSBarry Smith - disc - The discretization object 503744a7f3ddSMatthew G. Knepley 503844a7f3ddSMatthew G. Knepley Level: intermediate 503944a7f3ddSMatthew G. Knepley 5040bb7acecfSBarry Smith Notes: 5041bb7acecfSBarry Smith The label already exists or will be added to the `DM` with `DMSetLabel()`. 5042bb7acecfSBarry Smith 5043da81f932SPierre Jolivet For example, a piecewise continuous pressure field can be defined by coefficients at the cell centers of a mesh and piecewise constant functions 5044bb7acecfSBarry 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 5045bb7acecfSBarry Smith geometry entities, a `DMLabel` indicating a subset of those geometric entities, and a discretization object, such as a `PetscFE`. 5046bb7acecfSBarry Smith 50471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLabel()`, `DMSetField()`, `DMGetField()`, `PetscFE` 504844a7f3ddSMatthew G. Knepley @*/ 5049d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject disc) 5050d71ae5a4SJacob Faibussowitsch { 505144a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 505244a7f3ddSMatthew G. Knepley 505344a7f3ddSMatthew G. Knepley PetscFunctionBegin; 505444a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5055064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5056bb7acecfSBarry Smith PetscValidHeader(disc, 3); 50579566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, Nf + 1)); 505844a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 5059bb7acecfSBarry Smith dm->fields[Nf].disc = disc; 50609566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5061835f2295SStefano Zampini PetscCall(PetscObjectReference(disc)); 5062bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, Nf, disc)); 50639566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 50643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5065af122d2aSMatthew G Knepley } 50666636e97aSMatthew G Knepley 5067e5e52638SMatthew G. Knepley /*@ 5068e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 5069e0b68406SMatthew Knepley 507020f4b53cSBarry Smith Logically Collective 5071e0b68406SMatthew Knepley 5072e0b68406SMatthew Knepley Input Parameters: 5073bb7acecfSBarry Smith + dm - The `DM` 5074e0b68406SMatthew Knepley . f - The field index 5075bb7acecfSBarry Smith - avoidTensor - `PETSC_TRUE` to skip defining the field on tensor cells 5076e0b68406SMatthew Knepley 5077e0b68406SMatthew Knepley Level: intermediate 5078e0b68406SMatthew Knepley 50791cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5080e0b68406SMatthew Knepley @*/ 5081d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5082d71ae5a4SJacob Faibussowitsch { 5083e0b68406SMatthew Knepley PetscFunctionBegin; 508463a3b9bcSJacob 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); 5085e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 50863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5087e0b68406SMatthew Knepley } 5088e0b68406SMatthew Knepley 5089e0b68406SMatthew Knepley /*@ 5090e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5091e0b68406SMatthew Knepley 509220f4b53cSBarry Smith Not Collective 5093e0b68406SMatthew Knepley 5094e0b68406SMatthew Knepley Input Parameters: 5095bb7acecfSBarry Smith + dm - The `DM` 5096e0b68406SMatthew Knepley - f - The field index 5097e0b68406SMatthew Knepley 5098e0b68406SMatthew Knepley Output Parameter: 5099e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5100e0b68406SMatthew Knepley 5101e0b68406SMatthew Knepley Level: intermediate 5102e0b68406SMatthew Knepley 510360225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()`, `DMGetField()`, `DMSetFieldAvoidTensor()` 5104e0b68406SMatthew Knepley @*/ 5105d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5106d71ae5a4SJacob Faibussowitsch { 5107e0b68406SMatthew Knepley PetscFunctionBegin; 510863a3b9bcSJacob 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); 5109e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 51103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5111e0b68406SMatthew Knepley } 5112e0b68406SMatthew Knepley 5113e0b68406SMatthew Knepley /*@ 5114bb7acecfSBarry Smith DMCopyFields - Copy the discretizations for the `DM` into another `DM` 5115e5e52638SMatthew G. Knepley 511620f4b53cSBarry Smith Collective 5117e5e52638SMatthew G. Knepley 5118bb4b53efSMatthew G. Knepley Input Parameters: 5119bb4b53efSMatthew G. Knepley + dm - The `DM` 5120bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit 5121bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit 5122e5e52638SMatthew G. Knepley 5123e5e52638SMatthew G. Knepley Output Parameter: 5124bb7acecfSBarry Smith . newdm - The `DM` 5125e5e52638SMatthew G. Knepley 5126e5e52638SMatthew G. Knepley Level: advanced 5127e5e52638SMatthew G. Knepley 51281cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetField()`, `DMSetField()`, `DMAddField()`, `DMCopyDS()`, `DMGetDS()`, `DMGetCellDS()` 5129e5e52638SMatthew G. Knepley @*/ 5130bb4b53efSMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, PetscInt minDegree, PetscInt maxDegree, DM newdm) 5131d71ae5a4SJacob Faibussowitsch { 5132e5e52638SMatthew G. Knepley PetscInt Nf, f; 5133e5e52638SMatthew G. Knepley 5134e5e52638SMatthew G. Knepley PetscFunctionBegin; 51353ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 51369566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51379566063dSJacob Faibussowitsch PetscCall(DMClearFields(newdm)); 5138e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5139e5e52638SMatthew G. Knepley DMLabel label; 5140e5e52638SMatthew G. Knepley PetscObject field; 5141bb4b53efSMatthew G. Knepley PetscClassId id; 514234aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5143e5e52638SMatthew G. Knepley 51449566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, &label, &field)); 5145bb4b53efSMatthew G. Knepley PetscCall(PetscObjectGetClassId(field, &id)); 5146bb4b53efSMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5147bb4b53efSMatthew G. Knepley PetscFE newfe; 5148bb4b53efSMatthew G. Knepley 5149bb4b53efSMatthew G. Knepley PetscCall(PetscFELimitDegree((PetscFE)field, minDegree, maxDegree, &newfe)); 5150bb4b53efSMatthew G. Knepley PetscCall(DMSetField(newdm, f, label, (PetscObject)newfe)); 5151bb4b53efSMatthew G. Knepley PetscCall(PetscFEDestroy(&newfe)); 5152bb4b53efSMatthew G. Knepley } else { 51539566063dSJacob Faibussowitsch PetscCall(DMSetField(newdm, f, label, field)); 5154bb4b53efSMatthew G. Knepley } 51559566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, f, &useCone, &useClosure)); 51569566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(newdm, f, useCone, useClosure)); 515734aa8a36SMatthew G. Knepley } 51583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 515934aa8a36SMatthew G. Knepley } 516034aa8a36SMatthew G. Knepley 516134aa8a36SMatthew G. Knepley /*@ 516234aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 516334aa8a36SMatthew G. Knepley 516420f4b53cSBarry Smith Not Collective 516534aa8a36SMatthew G. Knepley 516634aa8a36SMatthew G. Knepley Input Parameters: 516720f4b53cSBarry Smith + dm - The `DM` object 516820f4b53cSBarry Smith - f - The field number, or `PETSC_DEFAULT` for the default adjacency 516934aa8a36SMatthew G. Knepley 5170d8d19677SJose E. Roman Output Parameters: 517134aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 517234aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 517334aa8a36SMatthew G. Knepley 517434aa8a36SMatthew G. Knepley Level: developer 517534aa8a36SMatthew G. Knepley 517620f4b53cSBarry Smith Notes: 517720f4b53cSBarry Smith .vb 517820f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 517920f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 518020f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 518120f4b53cSBarry Smith .ve 518220f4b53cSBarry Smith Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 518320f4b53cSBarry Smith 51841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetAdjacency()`, `DMGetField()`, `DMSetField()` 518534aa8a36SMatthew G. Knepley @*/ 5186d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 5187d71ae5a4SJacob Faibussowitsch { 518834aa8a36SMatthew G. Knepley PetscFunctionBegin; 518934aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 51904f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 3); 51914f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 4); 519234aa8a36SMatthew G. Knepley if (f < 0) { 519334aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 519434aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 519534aa8a36SMatthew G. Knepley } else { 519634aa8a36SMatthew G. Knepley PetscInt Nf; 519734aa8a36SMatthew G. Knepley 51989566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51997a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 520034aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 520134aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 520234aa8a36SMatthew G. Knepley } 52033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 520434aa8a36SMatthew G. Knepley } 520534aa8a36SMatthew G. Knepley 520634aa8a36SMatthew G. Knepley /*@ 520734aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 520834aa8a36SMatthew G. Knepley 520920f4b53cSBarry Smith Not Collective 521034aa8a36SMatthew G. Knepley 521134aa8a36SMatthew G. Knepley Input Parameters: 521220f4b53cSBarry Smith + dm - The `DM` object 521334aa8a36SMatthew G. Knepley . f - The field number 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`, `DMGetAdjacency()`, `DMGetField()`, `DMSetField()` 522834aa8a36SMatthew G. Knepley @*/ 5229d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 5230d71ae5a4SJacob Faibussowitsch { 523134aa8a36SMatthew G. Knepley PetscFunctionBegin; 523234aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 523334aa8a36SMatthew G. Knepley if (f < 0) { 523434aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 523534aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 523634aa8a36SMatthew G. Knepley } else { 523734aa8a36SMatthew G. Knepley PetscInt Nf; 523834aa8a36SMatthew G. Knepley 52399566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 52407a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 524134aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 524234aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5243e5e52638SMatthew G. Knepley } 52443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5245e5e52638SMatthew G. Knepley } 5246e5e52638SMatthew G. Knepley 5247b0441da4SMatthew G. Knepley /*@ 5248b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5249b0441da4SMatthew G. Knepley 5250b0441da4SMatthew G. Knepley Not collective 5251b0441da4SMatthew G. Knepley 5252f899ff85SJose E. Roman Input Parameter: 525320f4b53cSBarry Smith . dm - The `DM` object 5254b0441da4SMatthew G. Knepley 5255d8d19677SJose E. Roman Output Parameters: 5256b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5257b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5258b0441da4SMatthew G. Knepley 5259b0441da4SMatthew G. Knepley Level: developer 5260b0441da4SMatthew G. Knepley 526120f4b53cSBarry Smith Notes: 526220f4b53cSBarry Smith .vb 526320f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 526420f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 526520f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 526620f4b53cSBarry Smith .ve 526720f4b53cSBarry Smith 52681cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5269b0441da4SMatthew G. Knepley @*/ 5270d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5271d71ae5a4SJacob Faibussowitsch { 5272b0441da4SMatthew G. Knepley PetscInt Nf; 5273b0441da4SMatthew G. Knepley 5274b0441da4SMatthew G. Knepley PetscFunctionBegin; 5275b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52764f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 2); 52774f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 3); 52789566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5279b0441da4SMatthew G. Knepley if (!Nf) { 52809566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5281b0441da4SMatthew G. Knepley } else { 52829566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, 0, useCone, useClosure)); 5283b0441da4SMatthew G. Knepley } 52843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5285b0441da4SMatthew G. Knepley } 5286b0441da4SMatthew G. Knepley 5287b0441da4SMatthew G. Knepley /*@ 5288b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5289b0441da4SMatthew G. Knepley 529020f4b53cSBarry Smith Not Collective 5291b0441da4SMatthew G. Knepley 5292b0441da4SMatthew G. Knepley Input Parameters: 529320f4b53cSBarry Smith + dm - The `DM` object 5294b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5295b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5296b0441da4SMatthew G. Knepley 5297b0441da4SMatthew G. Knepley Level: developer 5298b0441da4SMatthew G. Knepley 529920f4b53cSBarry Smith Notes: 530020f4b53cSBarry Smith .vb 530120f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 530220f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 530320f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 530420f4b53cSBarry Smith .ve 530520f4b53cSBarry Smith 53061cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5307b0441da4SMatthew G. Knepley @*/ 5308d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5309d71ae5a4SJacob Faibussowitsch { 5310b0441da4SMatthew G. Knepley PetscInt Nf; 5311b0441da4SMatthew G. Knepley 5312b0441da4SMatthew G. Knepley PetscFunctionBegin; 5313b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 53149566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5315b0441da4SMatthew G. Knepley if (!Nf) { 53169566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5317b0441da4SMatthew G. Knepley } else { 53189566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, 0, useCone, useClosure)); 5319e5e52638SMatthew G. Knepley } 53203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5321e5e52638SMatthew G. Knepley } 5322e5e52638SMatthew G. Knepley 5323d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompleteBCLabels_Internal(DM dm) 5324d71ae5a4SJacob Faibussowitsch { 5325799db056SMatthew G. Knepley DM plex; 5326799db056SMatthew G. Knepley DMLabel *labels, *glabels; 5327799db056SMatthew G. Knepley const char **names; 5328799db056SMatthew G. Knepley char *sendNames, *recvNames; 5329799db056SMatthew G. Knepley PetscInt Nds, s, maxLabels = 0, maxLen = 0, gmaxLen, Nl = 0, gNl, l, gl, m; 5330799db056SMatthew G. Knepley size_t len; 5331799db056SMatthew G. Knepley MPI_Comm comm; 5332799db056SMatthew G. Knepley PetscMPIInt rank, size, p, *counts, *displs; 5333783e2ec8SMatthew G. Knepley 5334783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5335799db056SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5336799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 5337799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5338799db056SMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 5339799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5340799db056SMatthew G. Knepley PetscDS dsBC; 5341799db056SMatthew G. Knepley PetscInt numBd; 5342799db056SMatthew G. Knepley 534307218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5344799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5345799db056SMatthew G. Knepley maxLabels += numBd; 5346799db056SMatthew G. Knepley } 5347799db056SMatthew G. Knepley PetscCall(PetscCalloc1(maxLabels, &labels)); 5348799db056SMatthew G. Knepley /* Get list of labels to be completed */ 5349799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5350799db056SMatthew G. Knepley PetscDS dsBC; 5351799db056SMatthew G. Knepley PetscInt numBd, bd; 5352799db056SMatthew G. Knepley 535307218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5354799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5355799db056SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5356799db056SMatthew G. Knepley DMLabel label; 5357799db056SMatthew G. Knepley PetscInt field; 5358799db056SMatthew G. Knepley PetscObject obj; 5359799db056SMatthew G. Knepley PetscClassId id; 5360799db056SMatthew G. Knepley 5361799db056SMatthew G. Knepley PetscCall(PetscDSGetBoundary(dsBC, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 53629566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, field, NULL, &obj)); 53639566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(obj, &id)); 5364fa74d514SMatthew G. Knepley if (id != PETSCFE_CLASSID || !label) continue; 53659371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 53669371c9d4SSatish Balay if (labels[l] == label) break; 5367799db056SMatthew G. Knepley if (l == Nl) labels[Nl++] = label; 5368783e2ec8SMatthew G. Knepley } 5369799db056SMatthew G. Knepley } 5370799db056SMatthew G. Knepley /* Get label names */ 5371799db056SMatthew G. Knepley PetscCall(PetscMalloc1(Nl, &names)); 5372799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscObjectGetName((PetscObject)labels[l], &names[l])); 53739371c9d4SSatish Balay for (l = 0; l < Nl; ++l) { 53749371c9d4SSatish Balay PetscCall(PetscStrlen(names[l], &len)); 53759371c9d4SSatish Balay maxLen = PetscMax(maxLen, (PetscInt)len + 2); 53769371c9d4SSatish Balay } 5377799db056SMatthew G. Knepley PetscCall(PetscFree(labels)); 5378462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&maxLen, &gmaxLen, 1, MPIU_INT, MPI_MAX, comm)); 5379799db056SMatthew G. Knepley PetscCall(PetscCalloc1(Nl * gmaxLen, &sendNames)); 5380c6a7a370SJeremy L Thompson for (l = 0; l < Nl; ++l) PetscCall(PetscStrncpy(&sendNames[gmaxLen * l], names[l], gmaxLen)); 5381799db056SMatthew G. Knepley PetscCall(PetscFree(names)); 5382799db056SMatthew G. Knepley /* Put all names on all processes */ 5383799db056SMatthew G. Knepley PetscCall(PetscCalloc2(size, &counts, size + 1, &displs)); 5384799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgather(&Nl, 1, MPI_INT, counts, 1, MPI_INT, comm)); 5385799db056SMatthew G. Knepley for (p = 0; p < size; ++p) displs[p + 1] = displs[p] + counts[p]; 5386799db056SMatthew G. Knepley gNl = displs[size]; 53879371c9d4SSatish Balay for (p = 0; p < size; ++p) { 53889371c9d4SSatish Balay counts[p] *= gmaxLen; 53899371c9d4SSatish Balay displs[p] *= gmaxLen; 53909371c9d4SSatish Balay } 5391799db056SMatthew G. Knepley PetscCall(PetscCalloc2(gNl * gmaxLen, &recvNames, gNl, &glabels)); 5392799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgatherv(sendNames, counts[rank], MPI_CHAR, recvNames, counts, displs, MPI_CHAR, comm)); 5393799db056SMatthew G. Knepley PetscCall(PetscFree2(counts, displs)); 5394799db056SMatthew G. Knepley PetscCall(PetscFree(sendNames)); 5395799db056SMatthew G. Knepley for (l = 0, gl = 0; l < gNl; ++l) { 5396799db056SMatthew G. Knepley PetscCall(DMGetLabel(dm, &recvNames[l * gmaxLen], &glabels[gl])); 5397799db056SMatthew G. Knepley PetscCheck(glabels[gl], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Label %s missing on rank %d", &recvNames[l * gmaxLen], rank); 53989371c9d4SSatish Balay for (m = 0; m < gl; ++m) 53995d6b2bfcSJames Wright if (glabels[m] == glabels[gl]) goto next_label; 54009566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 5401799db056SMatthew G. Knepley PetscCall(DMPlexLabelComplete(plex, glabels[gl])); 54029566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5403799db056SMatthew G. Knepley ++gl; 54045d6b2bfcSJames Wright next_label: 54055d6b2bfcSJames Wright continue; 5406783e2ec8SMatthew G. Knepley } 5407799db056SMatthew G. Knepley PetscCall(PetscFree2(recvNames, glabels)); 54083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5409783e2ec8SMatthew G. Knepley } 5410783e2ec8SMatthew G. Knepley 5411d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5412d71ae5a4SJacob Faibussowitsch { 5413e5e52638SMatthew G. Knepley DMSpace *tmpd; 5414e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5415e5e52638SMatthew G. Knepley 5416e5e52638SMatthew G. Knepley PetscFunctionBegin; 54173ba16761SJacob Faibussowitsch if (Nds >= NdsNew) PetscFunctionReturn(PETSC_SUCCESS); 54189566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NdsNew, &tmpd)); 5419e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 54209371c9d4SSatish Balay for (s = Nds; s < NdsNew; ++s) { 54219371c9d4SSatish Balay tmpd[s].ds = NULL; 54229371c9d4SSatish Balay tmpd[s].label = NULL; 54239371c9d4SSatish Balay tmpd[s].fields = NULL; 54249371c9d4SSatish Balay } 54259566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5426e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5427e5e52638SMatthew G. Knepley dm->probs = tmpd; 54283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5429e5e52638SMatthew G. Knepley } 5430e5e52638SMatthew G. Knepley 5431e5e52638SMatthew G. Knepley /*@ 543220f4b53cSBarry Smith DMGetNumDS - Get the number of discrete systems in the `DM` 5433e5e52638SMatthew G. Knepley 543420f4b53cSBarry Smith Not Collective 5435e5e52638SMatthew G. Knepley 5436e5e52638SMatthew G. Knepley Input Parameter: 543720f4b53cSBarry Smith . dm - The `DM` 5438e5e52638SMatthew G. Knepley 5439e5e52638SMatthew G. Knepley Output Parameter: 544020f4b53cSBarry Smith . Nds - The number of `PetscDS` objects 5441e5e52638SMatthew G. Knepley 5442e5e52638SMatthew G. Knepley Level: intermediate 5443e5e52638SMatthew G. Knepley 54441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMGetCellDS()` 5445e5e52638SMatthew G. Knepley @*/ 5446d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5447d71ae5a4SJacob Faibussowitsch { 5448e5e52638SMatthew G. Knepley PetscFunctionBegin; 5449e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54504f572ea9SToby Isaac PetscAssertPointer(Nds, 2); 5451e5e52638SMatthew G. Knepley *Nds = dm->Nds; 54523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5453e5e52638SMatthew G. Knepley } 5454e5e52638SMatthew G. Knepley 5455e5e52638SMatthew G. Knepley /*@ 545620f4b53cSBarry Smith DMClearDS - Remove all discrete systems from the `DM` 5457e5e52638SMatthew G. Knepley 545820f4b53cSBarry Smith Logically Collective 5459e5e52638SMatthew G. Knepley 5460e5e52638SMatthew G. Knepley Input Parameter: 546120f4b53cSBarry Smith . dm - The `DM` 5462e5e52638SMatthew G. Knepley 5463e5e52638SMatthew G. Knepley Level: intermediate 5464e5e52638SMatthew G. Knepley 54651cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumDS()`, `DMGetDS()`, `DMSetField()` 5466e5e52638SMatthew G. Knepley @*/ 5467d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearDS(DM dm) 5468d71ae5a4SJacob Faibussowitsch { 5469e5e52638SMatthew G. Knepley PetscInt s; 5470e5e52638SMatthew G. Knepley 5471e5e52638SMatthew G. Knepley PetscFunctionBegin; 5472e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5473e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 54749566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 547507218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 54769566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[s].label)); 54779566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[s].fields)); 5478e5e52638SMatthew G. Knepley } 54799566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5480e5e52638SMatthew G. Knepley dm->probs = NULL; 5481e5e52638SMatthew G. Knepley dm->Nds = 0; 54823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5483e5e52638SMatthew G. Knepley } 5484e5e52638SMatthew G. Knepley 5485e5e52638SMatthew G. Knepley /*@ 548620f4b53cSBarry Smith DMGetDS - Get the default `PetscDS` 5487e5e52638SMatthew G. Knepley 548820f4b53cSBarry Smith Not Collective 5489e5e52638SMatthew G. Knepley 5490e5e52638SMatthew G. Knepley Input Parameter: 549120f4b53cSBarry Smith . dm - The `DM` 5492e5e52638SMatthew G. Knepley 5493e5e52638SMatthew G. Knepley Output Parameter: 549407218a29SMatthew G. Knepley . ds - The default `PetscDS` 5495e5e52638SMatthew G. Knepley 5496e5e52638SMatthew G. Knepley Level: intermediate 5497e5e52638SMatthew G. Knepley 54981cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCellDS()`, `DMGetRegionDS()` 5499e5e52638SMatthew G. Knepley @*/ 550007218a29SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *ds) 5501d71ae5a4SJacob Faibussowitsch { 5502e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5503e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55044f572ea9SToby Isaac PetscAssertPointer(ds, 2); 550507218a29SMatthew G. Knepley PetscCheck(dm->Nds > 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Need to call DMCreateDS() before calling DMGetDS()"); 550607218a29SMatthew G. Knepley *ds = dm->probs[0].ds; 55073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5508e5e52638SMatthew G. Knepley } 5509e5e52638SMatthew G. Knepley 5510e5e52638SMatthew G. Knepley /*@ 551120f4b53cSBarry Smith DMGetCellDS - Get the `PetscDS` defined on a given cell 5512e5e52638SMatthew G. Knepley 551320f4b53cSBarry Smith Not Collective 5514e5e52638SMatthew G. Knepley 5515e5e52638SMatthew G. Knepley Input Parameters: 551620f4b53cSBarry Smith + dm - The `DM` 551720f4b53cSBarry Smith - point - Cell for the `PetscDS` 5518e5e52638SMatthew G. Knepley 551907218a29SMatthew G. Knepley Output Parameters: 552007218a29SMatthew G. Knepley + ds - The `PetscDS` defined on the given cell 552107218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or NULL if the same ds 5522e5e52638SMatthew G. Knepley 5523e5e52638SMatthew G. Knepley Level: developer 5524e5e52638SMatthew G. Knepley 55251cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMSetRegionDS()` 5526e5e52638SMatthew G. Knepley @*/ 552707218a29SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *ds, PetscDS *dsIn) 5528d71ae5a4SJacob Faibussowitsch { 552907218a29SMatthew G. Knepley PetscDS dsDef = NULL; 5530e5e52638SMatthew G. Knepley PetscInt s; 5531e5e52638SMatthew G. Knepley 5532e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5533e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55344f572ea9SToby Isaac if (ds) PetscAssertPointer(ds, 3); 55354f572ea9SToby Isaac if (dsIn) PetscAssertPointer(dsIn, 4); 553663a3b9bcSJacob Faibussowitsch PetscCheck(point >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %" PetscInt_FMT, point); 553707218a29SMatthew G. Knepley if (ds) *ds = NULL; 553807218a29SMatthew G. Knepley if (dsIn) *dsIn = NULL; 5539e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5540e5e52638SMatthew G. Knepley PetscInt val; 5541e5e52638SMatthew G. Knepley 55429371c9d4SSatish Balay if (!dm->probs[s].label) { 554307218a29SMatthew G. Knepley dsDef = dm->probs[s].ds; 55449371c9d4SSatish Balay } else { 55459566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dm->probs[s].label, point, &val)); 55469371c9d4SSatish Balay if (val >= 0) { 554707218a29SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 554807218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 55499371c9d4SSatish Balay break; 55509371c9d4SSatish Balay } 5551e5e52638SMatthew G. Knepley } 5552e5e52638SMatthew G. Knepley } 555307218a29SMatthew G. Knepley if (ds && !*ds) *ds = dsDef; 55543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5555e5e52638SMatthew G. Knepley } 5556e5e52638SMatthew G. Knepley 5557e5e52638SMatthew G. Knepley /*@ 555820f4b53cSBarry Smith DMGetRegionDS - Get the `PetscDS` for a given mesh region, defined by a `DMLabel` 5559e5e52638SMatthew G. Knepley 556020f4b53cSBarry Smith Not Collective 5561e5e52638SMatthew G. Knepley 5562e5e52638SMatthew G. Knepley Input Parameters: 556320f4b53cSBarry Smith + dm - The `DM` 556420f4b53cSBarry Smith - label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 5565e5e52638SMatthew G. Knepley 5566b3cf3223SMatthew G. Knepley Output Parameters: 556720f4b53cSBarry Smith + fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 556807218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 556907218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5570e5e52638SMatthew G. Knepley 5571e5e52638SMatthew G. Knepley Level: advanced 5572e5e52638SMatthew G. Knepley 557320f4b53cSBarry Smith Note: 557420f4b53cSBarry Smith If a non-`NULL` label is given, but there is no `PetscDS` on that specific label, 557520f4b53cSBarry Smith the `PetscDS` for the full domain (if present) is returned. Returns with 557607218a29SMatthew G. Knepley fields = `NULL` and ds = `NULL` if there is no `PetscDS` for the full domain. 557720f4b53cSBarry Smith 55781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5579e5e52638SMatthew G. Knepley @*/ 558007218a29SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5581d71ae5a4SJacob Faibussowitsch { 5582e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5583e5e52638SMatthew G. Knepley 5584e5e52638SMatthew G. Knepley PetscFunctionBegin; 5585e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5586e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 55879371c9d4SSatish Balay if (fields) { 55884f572ea9SToby Isaac PetscAssertPointer(fields, 3); 55899371c9d4SSatish Balay *fields = NULL; 55909371c9d4SSatish Balay } 55919371c9d4SSatish Balay if (ds) { 55924f572ea9SToby Isaac PetscAssertPointer(ds, 4); 55939371c9d4SSatish Balay *ds = NULL; 55949371c9d4SSatish Balay } 559507218a29SMatthew G. Knepley if (dsIn) { 55964f572ea9SToby Isaac PetscAssertPointer(dsIn, 5); 559707218a29SMatthew G. Knepley *dsIn = NULL; 559807218a29SMatthew G. Knepley } 5599e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5600154ca461SJed Brown if (dm->probs[s].label == label || !dm->probs[s].label) { 5601b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5602b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 560307218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 56043ba16761SJacob Faibussowitsch if (dm->probs[s].label) PetscFunctionReturn(PETSC_SUCCESS); 5605b3cf3223SMatthew G. Knepley } 5606e5e52638SMatthew G. Knepley } 56073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5608e5e52638SMatthew G. Knepley } 5609e5e52638SMatthew G. Knepley 5610e5e52638SMatthew G. Knepley /*@ 5611bb7acecfSBarry Smith DMSetRegionDS - Set the `PetscDS` for a given mesh region, defined by a `DMLabel` 5612083401c6SMatthew G. Knepley 561320f4b53cSBarry Smith Collective 5614083401c6SMatthew G. Knepley 5615083401c6SMatthew G. Knepley Input Parameters: 5616bb7acecfSBarry Smith + dm - The `DM` 561720f4b53cSBarry Smith . label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 561807218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` for all fields 561907218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region 562007218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5621083401c6SMatthew G. Knepley 562220f4b53cSBarry Smith Level: advanced 562320f4b53cSBarry Smith 5624bb7acecfSBarry Smith Note: 5625bb7acecfSBarry 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, 5626083401c6SMatthew G. Knepley the fields argument is ignored. 5627083401c6SMatthew G. Knepley 56281cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionNumDS()`, `DMGetDS()`, `DMGetCellDS()` 5629083401c6SMatthew G. Knepley @*/ 563007218a29SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5631d71ae5a4SJacob Faibussowitsch { 5632083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5633083401c6SMatthew G. Knepley 5634083401c6SMatthew G. Knepley PetscFunctionBegin; 5635083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5636083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 563707218a29SMatthew G. Knepley if (fields) PetscValidHeaderSpecific(fields, IS_CLASSID, 3); 5638064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 563907218a29SMatthew G. Knepley if (dsIn) PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 5); 5640083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5641083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 56429566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 564307218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 5644083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 564507218a29SMatthew G. Knepley dm->probs[s].dsIn = dsIn; 56463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5647083401c6SMatthew G. Knepley } 5648083401c6SMatthew G. Knepley } 56499566063dSJacob Faibussowitsch PetscCall(DMDSEnlarge_Static(dm, Nds + 1)); 56509566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 56519566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 56529566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 565307218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 5654083401c6SMatthew G. Knepley if (!label) { 5655083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5656083401c6SMatthew G. Knepley for (s = Nds - 1; s >= 0; --s) dm->probs[s + 1] = dm->probs[s]; 5657083401c6SMatthew G. Knepley Nds = 0; 5658083401c6SMatthew G. Knepley } 5659083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5660083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5661083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 566207218a29SMatthew G. Knepley dm->probs[Nds].dsIn = dsIn; 56633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5664083401c6SMatthew G. Knepley } 5665083401c6SMatthew G. Knepley 5666083401c6SMatthew G. Knepley /*@ 566720f4b53cSBarry Smith DMGetRegionNumDS - Get the `PetscDS` for a given mesh region, defined by the region number 5668e5e52638SMatthew G. Knepley 566920f4b53cSBarry Smith Not Collective 5670e5e52638SMatthew G. Knepley 5671e5e52638SMatthew G. Knepley Input Parameters: 567220f4b53cSBarry Smith + dm - The `DM` 5673e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5674e5e52638SMatthew G. Knepley 5675e5e52638SMatthew G. Knepley Output Parameters: 567620f4b53cSBarry Smith + label - The region label, or `NULL` 567720f4b53cSBarry Smith . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 567807218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 567907218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5680e5e52638SMatthew G. Knepley 5681e5e52638SMatthew G. Knepley Level: advanced 5682e5e52638SMatthew G. Knepley 56831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5684e5e52638SMatthew G. Knepley @*/ 568507218a29SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5686d71ae5a4SJacob Faibussowitsch { 5687e5e52638SMatthew G. Knepley PetscInt Nds; 5688e5e52638SMatthew G. Knepley 5689e5e52638SMatthew G. Knepley PetscFunctionBegin; 5690e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56919566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 569263a3b9bcSJacob 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); 5693e5e52638SMatthew G. Knepley if (label) { 56944f572ea9SToby Isaac PetscAssertPointer(label, 3); 5695e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5696e5e52638SMatthew G. Knepley } 5697b3cf3223SMatthew G. Knepley if (fields) { 56984f572ea9SToby Isaac PetscAssertPointer(fields, 4); 5699b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5700b3cf3223SMatthew G. Knepley } 5701e5e52638SMatthew G. Knepley if (ds) { 57024f572ea9SToby Isaac PetscAssertPointer(ds, 5); 5703e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5704e5e52638SMatthew G. Knepley } 570507218a29SMatthew G. Knepley if (dsIn) { 57064f572ea9SToby Isaac PetscAssertPointer(dsIn, 6); 570707218a29SMatthew G. Knepley *dsIn = dm->probs[num].dsIn; 570807218a29SMatthew G. Knepley } 57093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5710e5e52638SMatthew G. Knepley } 5711e5e52638SMatthew G. Knepley 5712e5e52638SMatthew G. Knepley /*@ 571320f4b53cSBarry Smith DMSetRegionNumDS - Set 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` 5719083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 572020f4b53cSBarry Smith . label - The region label, or `NULL` 572107218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` to prevent setting 572207218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` to prevent setting 572307218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5724e5e52638SMatthew G. Knepley 5725e5e52638SMatthew G. Knepley Level: advanced 5726e5e52638SMatthew G. Knepley 57271cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5728e5e52638SMatthew G. Knepley @*/ 572907218a29SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5730d71ae5a4SJacob Faibussowitsch { 5731083401c6SMatthew G. Knepley PetscInt Nds; 5732e5e52638SMatthew G. Knepley 5733e5e52638SMatthew G. Knepley PetscFunctionBegin; 5734e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5735ad540459SPierre Jolivet if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 57369566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 573763a3b9bcSJacob 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); 57389566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 57399566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[num].label)); 5740083401c6SMatthew G. Knepley dm->probs[num].label = label; 5741083401c6SMatthew G. Knepley if (fields) { 5742083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 57439566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 57449566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[num].fields)); 5745083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5746e5e52638SMatthew G. Knepley } 5747083401c6SMatthew G. Knepley if (ds) { 5748083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 57499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 57509566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[num].ds)); 5751083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5752083401c6SMatthew G. Knepley } 575307218a29SMatthew G. Knepley if (dsIn) { 575407218a29SMatthew G. Knepley PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 6); 575507218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 575607218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[num].dsIn)); 575707218a29SMatthew G. Knepley dm->probs[num].dsIn = dsIn; 575807218a29SMatthew G. Knepley } 57593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5760e5e52638SMatthew G. Knepley } 5761e5e52638SMatthew G. Knepley 5762e5e52638SMatthew G. Knepley /*@ 576320f4b53cSBarry Smith DMFindRegionNum - Find the region number for a given `PetscDS`, or -1 if it is not found. 57641d3af9e0SMatthew G. Knepley 576520f4b53cSBarry Smith Not Collective 57661d3af9e0SMatthew G. Knepley 57671d3af9e0SMatthew G. Knepley Input Parameters: 576820f4b53cSBarry Smith + dm - The `DM` 576920f4b53cSBarry Smith - ds - The `PetscDS` defined on the given region 57701d3af9e0SMatthew G. Knepley 57711d3af9e0SMatthew G. Knepley Output Parameter: 57721d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 57731d3af9e0SMatthew G. Knepley 57741d3af9e0SMatthew G. Knepley Level: advanced 57751d3af9e0SMatthew G. Knepley 57761cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 57771d3af9e0SMatthew G. Knepley @*/ 5778d71ae5a4SJacob Faibussowitsch PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 5779d71ae5a4SJacob Faibussowitsch { 57801d3af9e0SMatthew G. Knepley PetscInt Nds, n; 57811d3af9e0SMatthew G. Knepley 57821d3af9e0SMatthew G. Knepley PetscFunctionBegin; 57831d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57841d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 57854f572ea9SToby Isaac PetscAssertPointer(num, 3); 57869566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 57879371c9d4SSatish Balay for (n = 0; n < Nds; ++n) 57889371c9d4SSatish Balay if (ds == dm->probs[n].ds) break; 57891d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 57901d3af9e0SMatthew G. Knepley else *num = n; 57913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57921d3af9e0SMatthew G. Knepley } 57931d3af9e0SMatthew G. Knepley 5794cc4c1da9SBarry Smith /*@ 5795bb7acecfSBarry Smith DMCreateFEDefault - Create a `PetscFE` based on the celltype for the mesh 57962df84da0SMatthew G. Knepley 579720f4b53cSBarry Smith Not Collective 57982df84da0SMatthew G. Knepley 5799f1a722f8SMatthew G. Knepley Input Parameters: 5800bb7acecfSBarry Smith + dm - The `DM` 58012df84da0SMatthew G. Knepley . Nc - The number of components for the field 580220f4b53cSBarry Smith . prefix - The options prefix for the output `PetscFE`, or `NULL` 5803bb7acecfSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 58042df84da0SMatthew G. Knepley 58052df84da0SMatthew G. Knepley Output Parameter: 5806bb7acecfSBarry Smith . fem - The `PetscFE` 58072df84da0SMatthew G. Knepley 580820f4b53cSBarry Smith Level: intermediate 580920f4b53cSBarry Smith 5810bb7acecfSBarry Smith Note: 5811bb7acecfSBarry Smith This is a convenience method that just calls `PetscFECreateByCell()` underneath. 58122df84da0SMatthew G. Knepley 58131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscFECreateByCell()`, `DMAddField()`, `DMCreateDS()`, `DMGetCellDS()`, `DMGetRegionDS()` 58142df84da0SMatthew G. Knepley @*/ 5815d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFEDefault(DM dm, PetscInt Nc, const char prefix[], PetscInt qorder, PetscFE *fem) 5816d71ae5a4SJacob Faibussowitsch { 58172df84da0SMatthew G. Knepley DMPolytopeType ct; 58182df84da0SMatthew G. Knepley PetscInt dim, cStart; 58192df84da0SMatthew G. Knepley 58202df84da0SMatthew G. Knepley PetscFunctionBegin; 58212df84da0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58222df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 2); 58234f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 3); 58242df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, qorder, 4); 58254f572ea9SToby Isaac PetscAssertPointer(fem, 5); 58269566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 58279566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 58289566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 58299566063dSJacob Faibussowitsch PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, Nc, ct, prefix, qorder, fem)); 58303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58312df84da0SMatthew G. Knepley } 58322df84da0SMatthew G. Knepley 58331d3af9e0SMatthew G. Knepley /*@ 5834bb7acecfSBarry Smith DMCreateDS - Create the discrete systems for the `DM` based upon the fields added to the `DM` 5835e5e52638SMatthew G. Knepley 583620f4b53cSBarry Smith Collective 5837e5e52638SMatthew G. Knepley 5838e5e52638SMatthew G. Knepley Input Parameter: 5839bb7acecfSBarry Smith . dm - The `DM` 5840e5e52638SMatthew G. Knepley 584120f4b53cSBarry Smith Options Database Key: 5842bb7acecfSBarry Smith . -dm_petscds_view - View all the `PetscDS` objects in this `DM` 584345480ffeSMatthew G. Knepley 584420f4b53cSBarry Smith Level: intermediate 584520f4b53cSBarry Smith 58461cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetField`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 5847e5e52638SMatthew G. Knepley @*/ 5848d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDS(DM dm) 5849d71ae5a4SJacob Faibussowitsch { 5850e5e52638SMatthew G. Knepley MPI_Comm comm; 5851083401c6SMatthew G. Knepley PetscDS dsDef; 5852083401c6SMatthew G. Knepley DMLabel *labelSet; 5853f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5854f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5855e5e52638SMatthew G. Knepley 5856e5e52638SMatthew G. Knepley PetscFunctionBegin; 5857e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58583ba16761SJacob Faibussowitsch if (!dm->fields) PetscFunctionReturn(PETSC_SUCCESS); 58599566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 58609566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dE)); 5861083401c6SMatthew G. Knepley /* Determine how many regions we have */ 58629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &labelSet)); 5863083401c6SMatthew G. Knepley Nl = 0; 5864083401c6SMatthew G. Knepley Ndef = 0; 5865083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5866083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5867083401c6SMatthew G. Knepley PetscInt l; 5868083401c6SMatthew G. Knepley 5869f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5870f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5871f918ec44SMatthew G. Knepley { 5872f918ec44SMatthew G. Knepley PetscClassId id; 5873f918ec44SMatthew G. Knepley 58749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(dm->fields[f].disc, &id)); 5875f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5876f918ec44SMatthew G. Knepley Ceed ceed; 5877f918ec44SMatthew G. Knepley 58789566063dSJacob Faibussowitsch PetscCall(DMGetCeed(dm, &ceed)); 58799566063dSJacob Faibussowitsch PetscCall(PetscFESetCeed((PetscFE)dm->fields[f].disc, ceed)); 5880f918ec44SMatthew G. Knepley } 5881f918ec44SMatthew G. Knepley } 5882f918ec44SMatthew G. Knepley #endif 58839371c9d4SSatish Balay if (!label) { 58849371c9d4SSatish Balay ++Ndef; 58859371c9d4SSatish Balay continue; 58869371c9d4SSatish Balay } 58879371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 58889371c9d4SSatish Balay if (label == labelSet[l]) break; 5889083401c6SMatthew G. Knepley if (l < Nl) continue; 5890083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5891083401c6SMatthew G. Knepley } 5892083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 589307218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 5894083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5895b3cf3223SMatthew G. Knepley IS fields; 5896b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5897b3cf3223SMatthew G. Knepley 58989371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58999371c9d4SSatish Balay if (!dm->fields[f].label) ++nf; 59007a8be351SBarry Smith PetscCheck(nf, comm, PETSC_ERR_PLIB, "All fields have labels, but we are trying to create a default DS"); 59019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 59029371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59039371c9d4SSatish Balay if (!dm->fields[f].label) fld[nf++] = f; 59049566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 59059566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 59069566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 59079566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 590888f0c812SMatthew G. Knepley 59099566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 591007218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, NULL, fields, dsDef, NULL)); 59119566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 59129566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 59132df9ee95SMatthew G. Knepley } 591407218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 59159566063dSJacob Faibussowitsch if (dsDef) PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 5916083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5917083401c6SMatthew G. Knepley if (Ndef && Nl) { 59180122748bSMatthew G. Knepley DM plex; 5919083401c6SMatthew G. Knepley DMLabel cellLabel; 5920083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5921083401c6SMatthew G. Knepley PetscInt *fields; 5922083401c6SMatthew G. Knepley const PetscInt *cells; 5923083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 59240122748bSMatthew G. Knepley 59259566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 59269566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(plex, &depth)); 59279566063dSJacob Faibussowitsch PetscCall(DMGetStratumIS(plex, "dim", depth, &allcellIS)); 59289566063dSJacob Faibussowitsch if (!allcellIS) PetscCall(DMGetStratumIS(plex, "depth", depth, &allcellIS)); 59295fedec97SMatthew G. Knepley /* TODO This looks like it only works for one label */ 5930083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5931083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5932083401c6SMatthew G. Knepley IS pointIS; 5933083401c6SMatthew G. Knepley 59349566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 59359566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, 1, &pointIS)); 59369566063dSJacob Faibussowitsch PetscCall(ISDifference(allcellIS, pointIS, &defcellIS)); 59379566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointIS)); 5938083401c6SMatthew G. Knepley } 59399566063dSJacob Faibussowitsch PetscCall(ISDestroy(&allcellIS)); 5940083401c6SMatthew G. Knepley 59419566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel)); 59429566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(defcellIS, &n)); 59439566063dSJacob Faibussowitsch PetscCall(ISGetIndices(defcellIS, &cells)); 59449566063dSJacob Faibussowitsch for (c = 0; c < n; ++c) PetscCall(DMLabelSetValue(cellLabel, cells[c], 1)); 59459566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(defcellIS, &cells)); 59469566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 59479566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(plex, cellLabel)); 5948083401c6SMatthew G. Knepley 59499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Ndef, &fields)); 59509371c9d4SSatish Balay for (f = 0; f < Nf; ++f) 59519371c9d4SSatish Balay if (!dm->fields[f].label) fields[nf++] = f; 59529566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fieldIS)); 59539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fieldIS, "dm_fields_")); 59549566063dSJacob Faibussowitsch PetscCall(ISSetType(fieldIS, ISGENERAL)); 59559566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER)); 5956083401c6SMatthew G. Knepley 59579566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 595807218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, cellLabel, fieldIS, dsDef, NULL)); 59599566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 59609566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&cellLabel)); 59619566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 59629566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fieldIS)); 59639566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5964083401c6SMatthew G. Knepley } 5965083401c6SMatthew G. Knepley /* Create label DSes 5966083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5967083401c6SMatthew G. Knepley */ 5968083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5969083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5970083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 597107218a29SMatthew G. Knepley PetscDS ds, dsIn = NULL; 5972083401c6SMatthew G. Knepley IS fields; 5973083401c6SMatthew G. Knepley PetscInt *fld, nf; 5974083401c6SMatthew G. Knepley 59759566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 59769371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59779371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 59789566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 59799371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59809371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 59819566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 59829566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 59839566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 59849566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 59859566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(ds, dE)); 5986083401c6SMatthew G. Knepley { 5987083401c6SMatthew G. Knepley DMPolytopeType ct; 5988083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 59895fedec97SMatthew G. Knepley PetscBool isCohesiveLocal = PETSC_FALSE, isCohesive; 59900122748bSMatthew G. Knepley 59919566063dSJacob Faibussowitsch PetscCall(DMLabelGetBounds(label, &lStart, &lEnd)); 5992665f567fSMatthew G. Knepley if (lStart >= 0) { 59939566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, lStart, &ct)); 5994412e9a14SMatthew G. Knepley switch (ct) { 5995412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5996412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5997412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5998d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5999d71ae5a4SJacob Faibussowitsch isCohesiveLocal = PETSC_TRUE; 6000d71ae5a4SJacob Faibussowitsch break; 6001d71ae5a4SJacob Faibussowitsch default: 6002d71ae5a4SJacob Faibussowitsch break; 6003412e9a14SMatthew G. Knepley } 6004665f567fSMatthew G. Knepley } 6005462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&isCohesiveLocal, &isCohesive, 1, MPIU_BOOL, MPI_LOR, comm)); 600607218a29SMatthew G. Knepley if (isCohesive) { 600707218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsIn)); 600807218a29SMatthew G. Knepley PetscCall(PetscDSSetCoordinateDimension(dsIn, dE)); 600907218a29SMatthew G. Knepley } 60105fedec97SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) { 60115fedec97SMatthew G. Knepley if (label == dm->fields[f].label || !dm->fields[f].label) { 60125fedec97SMatthew G. Knepley if (label == dm->fields[f].label) { 60139566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, nf, NULL)); 60149566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(ds, nf, isCohesive)); 601507218a29SMatthew G. Knepley if (dsIn) { 601607218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, nf, NULL)); 601707218a29SMatthew G. Knepley PetscCall(PetscDSSetCohesive(dsIn, nf, isCohesive)); 601807218a29SMatthew G. Knepley } 60195fedec97SMatthew G. Knepley } 60205fedec97SMatthew G. Knepley ++nf; 60215fedec97SMatthew G. Knepley } 60225fedec97SMatthew G. Knepley } 6023e5e52638SMatthew G. Knepley } 602407218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, ds, dsIn)); 602507218a29SMatthew G. Knepley PetscCall(ISDestroy(&fields)); 60269566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 602707218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsIn)); 6028e5e52638SMatthew G. Knepley } 60299566063dSJacob Faibussowitsch PetscCall(PetscFree(labelSet)); 6030e5e52638SMatthew G. Knepley /* Set fields in DSes */ 6031083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 6032083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 603307218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 6034083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 6035083401c6SMatthew G. Knepley const PetscInt *fld; 60365fedec97SMatthew G. Knepley PetscInt nf, dsnf; 60375fedec97SMatthew G. Knepley PetscBool isCohesive; 6038e5e52638SMatthew G. Knepley 60399566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsnf)); 60409566063dSJacob Faibussowitsch PetscCall(PetscDSIsCohesive(ds, &isCohesive)); 60419566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(fields, &nf)); 60429566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fields, &fld)); 6043083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 6044083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 60455fedec97SMatthew G. Knepley PetscBool isCohesiveField; 6046e5e52638SMatthew G. Knepley PetscClassId id; 6047e5e52638SMatthew G. Knepley 60485fedec97SMatthew G. Knepley /* Handle DS with no fields */ 60499566063dSJacob Faibussowitsch if (dsnf) PetscCall(PetscDSGetCohesive(ds, f, &isCohesiveField)); 60505fedec97SMatthew G. Knepley /* If this is a cohesive cell, then regular fields need the lower dimensional discretization */ 605107218a29SMatthew G. Knepley if (isCohesive) { 605207218a29SMatthew G. Knepley if (!isCohesiveField) { 605307218a29SMatthew G. Knepley PetscObject bdDisc; 605407218a29SMatthew G. Knepley 605507218a29SMatthew G. Knepley PetscCall(PetscFEGetHeightSubspace((PetscFE)disc, 1, (PetscFE *)&bdDisc)); 605607218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, bdDisc)); 605707218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 605807218a29SMatthew G. Knepley } else { 60599566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, f, disc)); 606007218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 606107218a29SMatthew G. Knepley } 606207218a29SMatthew G. Knepley } else { 606307218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, disc)); 606407218a29SMatthew G. Knepley } 6065083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 60669566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 6067e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 6068e5e52638SMatthew G. Knepley } 60699566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fields, &fld)); 6070e5e52638SMatthew G. Knepley } 6071f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 60729566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)dm)->prefix, "-dm_ds_jet_degree", &k, &flg)); 6073f9244615SMatthew G. Knepley if (flg) { 60743b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 60753b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 607607218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 60773b4aee56SMatthew G. Knepley PetscInt Nf, f; 60783b4aee56SMatthew G. Knepley 60799566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 608007218a29SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 608107218a29SMatthew G. Knepley PetscCall(PetscDSSetJetDegree(ds, f, k)); 608207218a29SMatthew G. Knepley if (dsIn) PetscCall(PetscDSSetJetDegree(dsIn, f, k)); 608307218a29SMatthew G. Knepley } 60843b4aee56SMatthew G. Knepley } 6085f9244615SMatthew G. Knepley } 6086e5e52638SMatthew G. Knepley /* Setup DSes */ 6087e5e52638SMatthew G. Knepley if (doSetup) { 608807218a29SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 6089cf1363e4SMatthew G. Knepley if (dm->setfromoptionscalled) { 6090cf1363e4SMatthew G. Knepley PetscCall(PetscDSSetFromOptions(dm->probs[s].ds)); 6091cf1363e4SMatthew G. Knepley if (dm->probs[s].dsIn) PetscCall(PetscDSSetFromOptions(dm->probs[s].dsIn)); 6092cf1363e4SMatthew G. Knepley } 609307218a29SMatthew G. Knepley PetscCall(PetscDSSetUp(dm->probs[s].ds)); 609407218a29SMatthew G. Knepley if (dm->probs[s].dsIn) PetscCall(PetscDSSetUp(dm->probs[s].dsIn)); 609507218a29SMatthew G. Knepley } 6096e5e52638SMatthew G. Knepley } 60973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6098e5e52638SMatthew G. Knepley } 6099e5e52638SMatthew G. Knepley 6100e5e52638SMatthew G. Knepley /*@ 6101d2b2dc1eSMatthew G. Knepley DMUseTensorOrder - Use a tensor product closure ordering for the default section 6102d2b2dc1eSMatthew G. Knepley 6103d2b2dc1eSMatthew G. Knepley Input Parameters: 6104d2b2dc1eSMatthew G. Knepley + dm - The DM 6105d2b2dc1eSMatthew G. Knepley - tensor - Flag for tensor order 6106d2b2dc1eSMatthew G. Knepley 6107d2b2dc1eSMatthew G. Knepley Level: developer 6108d2b2dc1eSMatthew G. Knepley 6109d2b2dc1eSMatthew G. Knepley .seealso: `DMPlexSetClosurePermutationTensor()`, `PetscSectionResetClosurePermutation()` 6110d2b2dc1eSMatthew G. Knepley @*/ 6111d2b2dc1eSMatthew G. Knepley PetscErrorCode DMUseTensorOrder(DM dm, PetscBool tensor) 6112d2b2dc1eSMatthew G. Knepley { 6113d2b2dc1eSMatthew G. Knepley PetscInt Nf; 6114d2b2dc1eSMatthew G. Knepley PetscBool reorder = PETSC_TRUE, isPlex; 6115d2b2dc1eSMatthew G. Knepley 6116d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 6117d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMPLEX, &isPlex)); 6118d2b2dc1eSMatthew G. Knepley PetscCall(DMGetNumFields(dm, &Nf)); 6119d2b2dc1eSMatthew G. Knepley for (PetscInt f = 0; f < Nf; ++f) { 6120d2b2dc1eSMatthew G. Knepley PetscObject obj; 6121d2b2dc1eSMatthew G. Knepley PetscClassId id; 6122d2b2dc1eSMatthew G. Knepley 6123d2b2dc1eSMatthew G. Knepley PetscCall(DMGetField(dm, f, NULL, &obj)); 6124d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 6125d2b2dc1eSMatthew G. Knepley if (id == PETSCFE_CLASSID) { 6126d2b2dc1eSMatthew G. Knepley PetscSpace sp; 6127d2b2dc1eSMatthew G. Knepley PetscBool tensor; 6128d2b2dc1eSMatthew G. Knepley 6129d2b2dc1eSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace((PetscFE)obj, &sp)); 6130d2b2dc1eSMatthew G. Knepley PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 6131d2b2dc1eSMatthew G. Knepley reorder = reorder && tensor ? PETSC_TRUE : PETSC_FALSE; 6132d2b2dc1eSMatthew G. Knepley } else reorder = PETSC_FALSE; 6133d2b2dc1eSMatthew G. Knepley } 6134d2b2dc1eSMatthew G. Knepley if (tensor) { 6135d2b2dc1eSMatthew G. Knepley if (reorder && isPlex) PetscCall(DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, NULL)); 6136d2b2dc1eSMatthew G. Knepley } else { 6137d2b2dc1eSMatthew G. Knepley PetscSection s; 6138d2b2dc1eSMatthew G. Knepley 6139d2b2dc1eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm, &s)); 6140d2b2dc1eSMatthew G. Knepley if (s) PetscCall(PetscSectionResetClosurePermutation(s)); 6141d2b2dc1eSMatthew G. Knepley } 6142d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 6143d2b2dc1eSMatthew G. Knepley } 6144d2b2dc1eSMatthew G. Knepley 6145d2b2dc1eSMatthew G. Knepley /*@ 6146bb7acecfSBarry Smith DMComputeExactSolution - Compute the exact solution for a given `DM`, using the `PetscDS` information. 61477f96f943SMatthew G. Knepley 614820f4b53cSBarry Smith Collective 6149f2cacb80SMatthew G. Knepley 61507f96f943SMatthew G. Knepley Input Parameters: 6151bb7acecfSBarry Smith + dm - The `DM` 61527f96f943SMatthew G. Knepley - time - The time 61537f96f943SMatthew G. Knepley 61547f96f943SMatthew G. Knepley Output Parameters: 615520f4b53cSBarry Smith + u - The vector will be filled with exact solution values, or `NULL` 615620f4b53cSBarry Smith - u_t - The vector will be filled with the time derivative of exact solution values, or `NULL` 615720f4b53cSBarry Smith 615820f4b53cSBarry Smith Level: developer 61597f96f943SMatthew G. Knepley 6160bb7acecfSBarry Smith Note: 6161bb7acecfSBarry Smith The user must call `PetscDSSetExactSolution()` before using this routine 61627f96f943SMatthew G. Knepley 61631cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscDSSetExactSolution()` 61647f96f943SMatthew G. Knepley @*/ 6165d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 6166d71ae5a4SJacob Faibussowitsch { 61677f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 61687f96f943SMatthew G. Knepley void **ectxs; 6169f60fa741SMatthew G. Knepley Vec locu, locu_t; 61707f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 61717f96f943SMatthew G. Knepley 61727f96f943SMatthew G. Knepley PetscFunctionBegin; 6173f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6174f60fa741SMatthew G. Knepley if (u) { 6175f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 6176f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu)); 6177f60fa741SMatthew G. Knepley PetscCall(VecSet(locu, 0.)); 6178f60fa741SMatthew G. Knepley } 6179f60fa741SMatthew G. Knepley if (u_t) { 6180f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 6181f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu_t)); 6182f60fa741SMatthew G. Knepley PetscCall(VecSet(locu_t, 0.)); 6183f60fa741SMatthew G. Knepley } 61849566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 61859566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exacts, Nf, &ectxs)); 61869566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 61877f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 61887f96f943SMatthew G. Knepley PetscDS ds; 61897f96f943SMatthew G. Knepley DMLabel label; 61907f96f943SMatthew G. Knepley IS fieldIS; 61917f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 61927f96f943SMatthew G. Knepley PetscInt dsNf, f; 61937f96f943SMatthew G. Knepley 619407218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 61959566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 61969566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fieldIS, &fields)); 61979566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 61989566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6199f2cacb80SMatthew G. Knepley if (u) { 6200f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolution(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6201f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu)); 6202f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu)); 62037f96f943SMatthew G. Knepley } 6204f2cacb80SMatthew G. Knepley if (u_t) { 62059566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 62069566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6207f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6208f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6209f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6210f2cacb80SMatthew G. Knepley } 62119566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 6212f2cacb80SMatthew G. Knepley } 6213f2cacb80SMatthew G. Knepley if (u) { 62149566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution")); 62159566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u, "exact_")); 6216f2cacb80SMatthew G. Knepley } 6217f2cacb80SMatthew G. Knepley if (u_t) { 62189566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution Time Derivative")); 62199566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u_t, "exact_t_")); 6220f2cacb80SMatthew G. Knepley } 62219566063dSJacob Faibussowitsch PetscCall(PetscFree2(exacts, ectxs)); 6222f60fa741SMatthew G. Knepley if (u) { 6223f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu, INSERT_ALL_VALUES, u)); 6224f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu, INSERT_ALL_VALUES, u)); 6225f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu)); 6226f60fa741SMatthew G. Knepley } 6227f60fa741SMatthew G. Knepley if (u_t) { 6228f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6229f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6230f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu_t)); 6231f60fa741SMatthew G. Knepley } 62323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62337f96f943SMatthew G. Knepley } 62347f96f943SMatthew G. Knepley 6235bb4b53efSMatthew G. Knepley static PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscInt minDegree, PetscInt maxDegree, PetscDS ds, PetscDS dsIn) 6236d71ae5a4SJacob Faibussowitsch { 623707218a29SMatthew G. Knepley PetscDS dsNew, dsInNew = NULL; 623845480ffeSMatthew G. Knepley 623945480ffeSMatthew G. Knepley PetscFunctionBegin; 62409566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)ds), &dsNew)); 6241bb4b53efSMatthew G. Knepley PetscCall(PetscDSCopy(ds, minDegree, maxDegree, dm, dsNew)); 624207218a29SMatthew G. Knepley if (dsIn) { 624307218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)dsIn), &dsInNew)); 6244bb4b53efSMatthew G. Knepley PetscCall(PetscDSCopy(dsIn, minDegree, maxDegree, dm, dsInNew)); 624545480ffeSMatthew G. Knepley } 624607218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, dsNew, dsInNew)); 62479566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsNew)); 624807218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsInNew)); 62493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 625045480ffeSMatthew G. Knepley } 625145480ffeSMatthew G. Knepley 62527f96f943SMatthew G. Knepley /*@ 6253bb7acecfSBarry Smith DMCopyDS - Copy the discrete systems for the `DM` into another `DM` 6254e5e52638SMatthew G. Knepley 625520f4b53cSBarry Smith Collective 6256e5e52638SMatthew G. Knepley 6257bb4b53efSMatthew G. Knepley Input Parameters: 6258bb4b53efSMatthew G. Knepley + dm - The `DM` 6259bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit 6260bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit 6261e5e52638SMatthew G. Knepley 6262e5e52638SMatthew G. Knepley Output Parameter: 6263bb7acecfSBarry Smith . newdm - The `DM` 6264e5e52638SMatthew G. Knepley 6265e5e52638SMatthew G. Knepley Level: advanced 6266e5e52638SMatthew G. Knepley 62671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 6268e5e52638SMatthew G. Knepley @*/ 6269bb4b53efSMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, PetscInt minDegree, PetscInt maxDegree, DM newdm) 6270d71ae5a4SJacob Faibussowitsch { 6271e5e52638SMatthew G. Knepley PetscInt Nds, s; 6272e5e52638SMatthew G. Knepley 6273e5e52638SMatthew G. Knepley PetscFunctionBegin; 62743ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 62759566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 62769566063dSJacob Faibussowitsch PetscCall(DMClearDS(newdm)); 6277e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6278e5e52638SMatthew G. Knepley DMLabel label; 6279b3cf3223SMatthew G. Knepley IS fields; 628007218a29SMatthew G. Knepley PetscDS ds, dsIn, newds; 6281783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6282e5e52638SMatthew G. Knepley 628307218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fields, &ds, &dsIn)); 6284b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 6285bb4b53efSMatthew G. Knepley PetscCall(DMTransferDS_Internal(newdm, label, fields, minDegree, maxDegree, ds, dsIn)); 6286d5b43468SJose E. Roman /* Complete new labels in the new DS */ 628707218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(newdm, label, NULL, &newds, NULL)); 62889566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumBoundary(newds, &Nbd)); 6289783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6290b8025e53SMatthew G. Knepley PetscWeakForm wf; 629145480ffeSMatthew G. Knepley DMLabel label; 6292783e2ec8SMatthew G. Knepley PetscInt field; 6293783e2ec8SMatthew G. Knepley 62949566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 62959566063dSJacob Faibussowitsch PetscCall(PetscWeakFormReplaceLabel(wf, label)); 6296783e2ec8SMatthew G. Knepley } 6297e5e52638SMatthew G. Knepley } 6298799db056SMatthew G. Knepley PetscCall(DMCompleteBCLabels_Internal(newdm)); 62993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6300e5e52638SMatthew G. Knepley } 6301e5e52638SMatthew G. Knepley 6302e5e52638SMatthew G. Knepley /*@ 6303bb7acecfSBarry Smith DMCopyDisc - Copy the fields and discrete systems for the `DM` into another `DM` 6304e5e52638SMatthew G. Knepley 630520f4b53cSBarry Smith Collective 6306e5e52638SMatthew G. Knepley 6307e5e52638SMatthew G. Knepley Input Parameter: 6308bb7acecfSBarry Smith . dm - The `DM` 6309e5e52638SMatthew G. Knepley 6310e5e52638SMatthew G. Knepley Output Parameter: 6311bb7acecfSBarry Smith . newdm - The `DM` 6312e5e52638SMatthew G. Knepley 6313e5e52638SMatthew G. Knepley Level: advanced 6314e5e52638SMatthew G. Knepley 631573ff1848SBarry Smith Developer Note: 6316bb7acecfSBarry Smith Really ugly name, nothing in PETSc is called a `Disc` plus it is an ugly abbreviation 6317bb7acecfSBarry Smith 63181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMCopyDS()` 6319e5e52638SMatthew G. Knepley @*/ 6320d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6321d71ae5a4SJacob Faibussowitsch { 6322e5e52638SMatthew G. Knepley PetscFunctionBegin; 6323bb4b53efSMatthew G. Knepley PetscCall(DMCopyFields(dm, PETSC_DETERMINE, PETSC_DETERMINE, newdm)); 6324bb4b53efSMatthew G. Knepley PetscCall(DMCopyDS(dm, PETSC_DETERMINE, PETSC_DETERMINE, newdm)); 63253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6326e5e52638SMatthew G. Knepley } 6327e5e52638SMatthew G. Knepley 6328c73cfb54SMatthew G. Knepley /*@ 6329bb7acecfSBarry Smith DMGetDimension - Return the topological dimension of the `DM` 6330c73cfb54SMatthew G. Knepley 633120f4b53cSBarry Smith Not Collective 6332c73cfb54SMatthew G. Knepley 6333c73cfb54SMatthew G. Knepley Input Parameter: 6334bb7acecfSBarry Smith . dm - The `DM` 6335c73cfb54SMatthew G. Knepley 6336c73cfb54SMatthew G. Knepley Output Parameter: 6337c73cfb54SMatthew G. Knepley . dim - The topological dimension 6338c73cfb54SMatthew G. Knepley 6339c73cfb54SMatthew G. Knepley Level: beginner 6340c73cfb54SMatthew G. Knepley 63411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDimension()`, `DMCreate()` 6342c73cfb54SMatthew G. Knepley @*/ 6343d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6344d71ae5a4SJacob Faibussowitsch { 6345c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6346c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63474f572ea9SToby Isaac PetscAssertPointer(dim, 2); 6348c73cfb54SMatthew G. Knepley *dim = dm->dim; 63493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6350c73cfb54SMatthew G. Knepley } 6351c73cfb54SMatthew G. Knepley 6352c73cfb54SMatthew G. Knepley /*@ 6353bb7acecfSBarry Smith DMSetDimension - Set the topological dimension of the `DM` 6354c73cfb54SMatthew G. Knepley 635520f4b53cSBarry Smith Collective 6356c73cfb54SMatthew G. Knepley 6357c73cfb54SMatthew G. Knepley Input Parameters: 6358bb7acecfSBarry Smith + dm - The `DM` 6359c73cfb54SMatthew G. Knepley - dim - The topological dimension 6360c73cfb54SMatthew G. Knepley 6361c73cfb54SMatthew G. Knepley Level: beginner 6362c73cfb54SMatthew G. Knepley 63631cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDimension()`, `DMCreate()` 6364c73cfb54SMatthew G. Knepley @*/ 6365d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6366d71ae5a4SJacob Faibussowitsch { 6367e5e52638SMatthew G. Knepley PetscDS ds; 636845480ffeSMatthew G. Knepley PetscInt Nds, n; 6369f17e8794SMatthew G. Knepley 6370c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6371c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6372c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6373c73cfb54SMatthew G. Knepley dm->dim = dim; 6374d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 63759566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 637645480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 637707218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds, NULL)); 63789566063dSJacob Faibussowitsch if (ds->dimEmbed < 0) PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 637945480ffeSMatthew G. Knepley } 6380d17bd122SMatthew G. Knepley } 63813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6382c73cfb54SMatthew G. Knepley } 6383c73cfb54SMatthew G. Knepley 6384793f3fe5SMatthew G. Knepley /*@ 6385793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6386793f3fe5SMatthew G. Knepley 638720f4b53cSBarry Smith Collective 6388793f3fe5SMatthew G. Knepley 6389793f3fe5SMatthew G. Knepley Input Parameters: 6390bb7acecfSBarry Smith + dm - the `DM` 6391793f3fe5SMatthew G. Knepley - dim - the dimension 6392793f3fe5SMatthew G. Knepley 6393793f3fe5SMatthew G. Knepley Output Parameters: 6394793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6395aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6396793f3fe5SMatthew G. Knepley 639720f4b53cSBarry Smith Level: intermediate 639820f4b53cSBarry Smith 6399793f3fe5SMatthew G. Knepley Note: 6400793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6401a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6402793f3fe5SMatthew G. Knepley then the interval is empty. 6403793f3fe5SMatthew G. Knepley 64041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPLEX`, `DMPlexGetDepthStratum()`, `DMPlexGetHeightStratum()` 6405793f3fe5SMatthew G. Knepley @*/ 6406d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6407d71ae5a4SJacob Faibussowitsch { 6408793f3fe5SMatthew G. Knepley PetscInt d; 6409793f3fe5SMatthew G. Knepley 6410793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6411793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64129566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &d)); 64137a8be351SBarry Smith PetscCheck((dim >= 0) && (dim <= d), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %" PetscInt_FMT, dim); 6414dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getdimpoints, dim, pStart, pEnd); 64153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6416793f3fe5SMatthew G. Knepley } 6417793f3fe5SMatthew G. Knepley 64186636e97aSMatthew G Knepley /*@ 6419bb7acecfSBarry Smith DMGetOutputDM - Retrieve the `DM` associated with the layout for output 6420f4d763aaSMatthew G. Knepley 642120f4b53cSBarry Smith Collective 64228f700142SStefano Zampini 6423f4d763aaSMatthew G. Knepley Input Parameter: 6424bb7acecfSBarry Smith . dm - The original `DM` 6425f4d763aaSMatthew G. Knepley 6426f4d763aaSMatthew G. Knepley Output Parameter: 6427bb7acecfSBarry Smith . odm - The `DM` which provides the layout for output 6428f4d763aaSMatthew G. Knepley 6429f4d763aaSMatthew G. Knepley Level: intermediate 6430f4d763aaSMatthew G. Knepley 6431bb7acecfSBarry Smith Note: 6432bb7acecfSBarry Smith In some situations the vector obtained with `DMCreateGlobalVector()` excludes points for degrees of freedom that are associated with fixed (Dirichelet) boundary 6433bb7acecfSBarry 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 6434bb7acecfSBarry Smith locations for those dof so that they can be output to a file or other viewer along with the unconstrained dof. 6435bb7acecfSBarry Smith 64361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()`, `DMGetGlobalSection()`, `DMCreateGlobalVector()`, `PetscSectionHasConstraints()`, `DMSetGlobalSection()` 6437f4d763aaSMatthew G. Knepley @*/ 6438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 6439d71ae5a4SJacob Faibussowitsch { 6440c26acbdeSMatthew G. Knepley PetscSection section; 6441eb9d3e4dSMatthew G. Knepley IS perm; 6442eb9d3e4dSMatthew G. Knepley PetscBool hasConstraints, newDM, gnewDM; 644392a26154SJames Wright PetscInt num_face_sfs = 0; 644414f150ffSMatthew G. Knepley 644514f150ffSMatthew G. Knepley PetscFunctionBegin; 644614f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64474f572ea9SToby Isaac PetscAssertPointer(odm, 2); 64489566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 64499566063dSJacob Faibussowitsch PetscCall(PetscSectionHasConstraints(section, &hasConstraints)); 6450eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionGetPermutation(section, &perm)); 645192a26154SJames Wright PetscCall(DMPlexGetIsoperiodicFaceSF(dm, &num_face_sfs, NULL)); 645292a26154SJames Wright newDM = hasConstraints || perm || (num_face_sfs > 0) ? PETSC_TRUE : PETSC_FALSE; 6453462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&newDM, &gnewDM, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)dm))); 6454eb9d3e4dSMatthew G. Knepley if (!gnewDM) { 6455c26acbdeSMatthew G. Knepley *odm = dm; 64563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6457c26acbdeSMatthew G. Knepley } 645814f150ffSMatthew G. Knepley if (!dm->dmBC) { 6459c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 646092a26154SJames Wright PetscSF sf, sfNatural; 6461eb9d3e4dSMatthew G. Knepley PetscBool usePerm = dm->ignorePermOutput ? PETSC_FALSE : PETSC_TRUE; 646214f150ffSMatthew G. Knepley 64639566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->dmBC)); 64649566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, dm->dmBC)); 64659566063dSJacob Faibussowitsch PetscCall(PetscSectionClone(section, &newSection)); 64669566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm->dmBC, newSection)); 64679566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&newSection)); 646892a26154SJames Wright PetscCall(DMGetNaturalSF(dm, &sfNatural)); 646992a26154SJames Wright PetscCall(DMSetNaturalSF(dm->dmBC, sfNatural)); 64709566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm->dmBC, &sf)); 6471eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionCreateGlobalSection(section, sf, usePerm, PETSC_TRUE, PETSC_FALSE, &gsection)); 64729566063dSJacob Faibussowitsch PetscCall(DMSetGlobalSection(dm->dmBC, gsection)); 64739566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&gsection)); 647414f150ffSMatthew G. Knepley } 647514f150ffSMatthew G. Knepley *odm = dm->dmBC; 64763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 647714f150ffSMatthew G. Knepley } 6478f4d763aaSMatthew G. Knepley 6479f4d763aaSMatthew G. Knepley /*@ 6480cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 6481f4d763aaSMatthew G. Knepley 6482f4d763aaSMatthew G. Knepley Input Parameter: 6483bb7acecfSBarry Smith . dm - The original `DM` 6484f4d763aaSMatthew G. Knepley 6485cdb7a50dSMatthew G. Knepley Output Parameters: 6486cdb7a50dSMatthew G. Knepley + num - The output sequence number 6487cdb7a50dSMatthew G. Knepley - val - The output sequence value 6488f4d763aaSMatthew G. Knepley 6489f4d763aaSMatthew G. Knepley Level: intermediate 6490f4d763aaSMatthew G. Knepley 6491bb7acecfSBarry Smith Note: 6492bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6493bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6494bb7acecfSBarry Smith 649573ff1848SBarry Smith Developer Note: 6496bb7acecfSBarry Smith The `DM` serves as a convenient place to store the current iteration value. The iteration is not 6497bb7acecfSBarry Smith not directly related to the `DM`. 6498f4d763aaSMatthew G. Knepley 64991cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6500f4d763aaSMatthew G. Knepley @*/ 6501d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 6502d71ae5a4SJacob Faibussowitsch { 6503f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6504f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65059371c9d4SSatish Balay if (num) { 65064f572ea9SToby Isaac PetscAssertPointer(num, 2); 65079371c9d4SSatish Balay *num = dm->outputSequenceNum; 65089371c9d4SSatish Balay } 65099371c9d4SSatish Balay if (val) { 65104f572ea9SToby Isaac PetscAssertPointer(val, 3); 65119371c9d4SSatish Balay *val = dm->outputSequenceVal; 65129371c9d4SSatish Balay } 65133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6514f4d763aaSMatthew G. Knepley } 6515f4d763aaSMatthew G. Knepley 6516f4d763aaSMatthew G. Knepley /*@ 6517cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 6518f4d763aaSMatthew G. Knepley 6519f4d763aaSMatthew G. Knepley Input Parameters: 6520bb7acecfSBarry Smith + dm - The original `DM` 6521cdb7a50dSMatthew G. Knepley . num - The output sequence number 6522cdb7a50dSMatthew G. Knepley - val - The output sequence value 6523f4d763aaSMatthew G. Knepley 6524f4d763aaSMatthew G. Knepley Level: intermediate 6525f4d763aaSMatthew G. Knepley 6526bb7acecfSBarry Smith Note: 6527bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6528bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6529f4d763aaSMatthew G. Knepley 65301cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6531f4d763aaSMatthew G. Knepley @*/ 6532d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 6533d71ae5a4SJacob Faibussowitsch { 6534f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6535f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6536f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 6537cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 65383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6539cdb7a50dSMatthew G. Knepley } 6540cdb7a50dSMatthew G. Knepley 65415d83a8b1SBarry Smith /*@ 6542bb7acecfSBarry Smith DMOutputSequenceLoad - Retrieve the sequence value from a `PetscViewer` 6543cdb7a50dSMatthew G. Knepley 6544cdb7a50dSMatthew G. Knepley Input Parameters: 6545bb7acecfSBarry Smith + dm - The original `DM` 6546b2033f5dSMatthew G. Knepley . viewer - The `PetscViewer` to get it from 6547cdb7a50dSMatthew G. Knepley . name - The sequence name 6548cdb7a50dSMatthew G. Knepley - num - The output sequence number 6549cdb7a50dSMatthew G. Knepley 6550cdb7a50dSMatthew G. Knepley Output Parameter: 6551cdb7a50dSMatthew G. Knepley . val - The output sequence value 6552cdb7a50dSMatthew G. Knepley 6553cdb7a50dSMatthew G. Knepley Level: intermediate 6554cdb7a50dSMatthew G. Knepley 6555bb7acecfSBarry Smith Note: 6556bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6557bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6558bb7acecfSBarry Smith 655973ff1848SBarry Smith Developer Note: 6560bb7acecfSBarry Smith It is unclear at the user API level why a `DM` is needed as input 6561cdb7a50dSMatthew G. Knepley 65621cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6563cdb7a50dSMatthew G. Knepley @*/ 6564b2033f5dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char name[], PetscInt num, PetscReal *val) 6565d71ae5a4SJacob Faibussowitsch { 6566cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 6567cdb7a50dSMatthew G. Knepley 6568cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 6569cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6570cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6571b2033f5dSMatthew G. Knepley PetscAssertPointer(name, 3); 65724f572ea9SToby Isaac PetscAssertPointer(val, 5); 65739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6574cdb7a50dSMatthew G. Knepley if (ishdf5) { 6575cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6576cdb7a50dSMatthew G. Knepley PetscScalar value; 6577cdb7a50dSMatthew G. Knepley 65789566063dSJacob Faibussowitsch PetscCall(DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer)); 65794aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 6580cdb7a50dSMatthew G. Knepley #endif 6581cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 65823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6583f4d763aaSMatthew G. Knepley } 65848e4ac7eaSMatthew G. Knepley 65858e4ac7eaSMatthew G. Knepley /*@ 6586b2033f5dSMatthew G. Knepley DMGetOutputSequenceLength - Retrieve the number of sequence values from a `PetscViewer` 6587b2033f5dSMatthew G. Knepley 6588b2033f5dSMatthew G. Knepley Input Parameters: 6589b2033f5dSMatthew G. Knepley + dm - The original `DM` 6590b2033f5dSMatthew G. Knepley . viewer - The `PetscViewer` to get it from 6591b2033f5dSMatthew G. Knepley - name - The sequence name 6592b2033f5dSMatthew G. Knepley 6593b2033f5dSMatthew G. Knepley Output Parameter: 6594b2033f5dSMatthew G. Knepley . len - The length of the output sequence 6595b2033f5dSMatthew G. Knepley 6596b2033f5dSMatthew G. Knepley Level: intermediate 6597b2033f5dSMatthew G. Knepley 6598b2033f5dSMatthew G. Knepley Note: 6599b2033f5dSMatthew G. Knepley This is intended for output that should appear in sequence, for instance 6600b2033f5dSMatthew G. Knepley a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6601b2033f5dSMatthew G. Knepley 6602b2033f5dSMatthew G. Knepley Developer Note: 6603b2033f5dSMatthew G. Knepley It is unclear at the user API level why a `DM` is needed as input 6604b2033f5dSMatthew G. Knepley 6605b2033f5dSMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6606b2033f5dSMatthew G. Knepley @*/ 6607b2033f5dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceLength(DM dm, PetscViewer viewer, const char name[], PetscInt *len) 6608b2033f5dSMatthew G. Knepley { 6609b2033f5dSMatthew G. Knepley PetscBool ishdf5; 6610b2033f5dSMatthew G. Knepley 6611b2033f5dSMatthew G. Knepley PetscFunctionBegin; 6612b2033f5dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6613b2033f5dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6614b2033f5dSMatthew G. Knepley PetscAssertPointer(name, 3); 6615b2033f5dSMatthew G. Knepley PetscAssertPointer(len, 4); 6616b2033f5dSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6617b2033f5dSMatthew G. Knepley if (ishdf5) { 6618b2033f5dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6619b2033f5dSMatthew G. Knepley PetscCall(DMSequenceGetLength_HDF5_Internal(dm, name, len, viewer)); 6620b2033f5dSMatthew G. Knepley #endif 6621b2033f5dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 6622b2033f5dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 6623b2033f5dSMatthew G. Knepley } 6624b2033f5dSMatthew G. Knepley 6625b2033f5dSMatthew G. Knepley /*@ 6626bb7acecfSBarry Smith DMGetUseNatural - Get the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 66278e4ac7eaSMatthew G. Knepley 662820f4b53cSBarry Smith Not Collective 66298e4ac7eaSMatthew G. Knepley 66308e4ac7eaSMatthew G. Knepley Input Parameter: 6631bb7acecfSBarry Smith . dm - The `DM` 66328e4ac7eaSMatthew G. Knepley 66338e4ac7eaSMatthew G. Knepley Output Parameter: 6634bb7acecfSBarry Smith . useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 66358e4ac7eaSMatthew G. Knepley 66368e4ac7eaSMatthew G. Knepley Level: beginner 66378e4ac7eaSMatthew G. Knepley 66381cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetUseNatural()`, `DMCreate()` 66398e4ac7eaSMatthew G. Knepley @*/ 6640d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 6641d71ae5a4SJacob Faibussowitsch { 66428e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 66438e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66444f572ea9SToby Isaac PetscAssertPointer(useNatural, 2); 66458e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 66463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66478e4ac7eaSMatthew G. Knepley } 66488e4ac7eaSMatthew G. Knepley 66498e4ac7eaSMatthew G. Knepley /*@ 6650bb7acecfSBarry Smith DMSetUseNatural - Set the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 66518e4ac7eaSMatthew G. Knepley 665220f4b53cSBarry Smith Collective 66538e4ac7eaSMatthew G. Knepley 66548e4ac7eaSMatthew G. Knepley Input Parameters: 6655bb7acecfSBarry Smith + dm - The `DM` 6656bb7acecfSBarry Smith - useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 66578e4ac7eaSMatthew G. Knepley 665873ff1848SBarry Smith Level: beginner 665973ff1848SBarry Smith 6660bb7acecfSBarry Smith Note: 6661bb7acecfSBarry Smith This also causes the map to be build after `DMCreateSubDM()` and `DMCreateSuperDM()` 66625d3b26e6SMatthew G. Knepley 66631cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetUseNatural()`, `DMCreate()`, `DMPlexDistribute()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 66648e4ac7eaSMatthew G. Knepley @*/ 6665d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 6666d71ae5a4SJacob Faibussowitsch { 66678e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 66688e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66698833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 66708e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 66713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66728e4ac7eaSMatthew G. Knepley } 6673c58f1c22SToby Isaac 6674cc4c1da9SBarry Smith /*@ 6675bb7acecfSBarry Smith DMCreateLabel - Create a label of the given name if it does not already exist in the `DM` 6676c58f1c22SToby Isaac 6677c58f1c22SToby Isaac Not Collective 6678c58f1c22SToby Isaac 6679c58f1c22SToby Isaac Input Parameters: 6680bb7acecfSBarry Smith + dm - The `DM` object 6681c58f1c22SToby Isaac - name - The label name 6682c58f1c22SToby Isaac 6683c58f1c22SToby Isaac Level: intermediate 6684c58f1c22SToby Isaac 66851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6686c58f1c22SToby Isaac @*/ 6687d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabel(DM dm, const char name[]) 6688d71ae5a4SJacob Faibussowitsch { 66895d80c0bfSVaclav Hapla PetscBool flg; 66905d80c0bfSVaclav Hapla DMLabel label; 6691c58f1c22SToby Isaac 6692c58f1c22SToby Isaac PetscFunctionBegin; 6693c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66944f572ea9SToby Isaac PetscAssertPointer(name, 2); 66959566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 6696c58f1c22SToby Isaac if (!flg) { 66979566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 66989566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 66999566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 6700c58f1c22SToby Isaac } 67013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6702c58f1c22SToby Isaac } 6703c58f1c22SToby Isaac 6704cc4c1da9SBarry Smith /*@ 6705bb7acecfSBarry 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. 67060fdc7489SMatthew Knepley 67070fdc7489SMatthew Knepley Not Collective 67080fdc7489SMatthew Knepley 67090fdc7489SMatthew Knepley Input Parameters: 6710bb7acecfSBarry Smith + dm - The `DM` object 67110fdc7489SMatthew Knepley . l - The index for the label 67120fdc7489SMatthew Knepley - name - The label name 67130fdc7489SMatthew Knepley 67140fdc7489SMatthew Knepley Level: intermediate 67150fdc7489SMatthew Knepley 67161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateLabel()`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 67170fdc7489SMatthew Knepley @*/ 6718d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 6719d71ae5a4SJacob Faibussowitsch { 67200fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 67210fdc7489SMatthew Knepley DMLabel label; 67220fdc7489SMatthew Knepley PetscInt Nl, m; 67230fdc7489SMatthew Knepley PetscBool flg, match; 67240fdc7489SMatthew Knepley const char *lname; 67250fdc7489SMatthew Knepley 67260fdc7489SMatthew Knepley PetscFunctionBegin; 67270fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67284f572ea9SToby Isaac PetscAssertPointer(name, 3); 67299566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 67300fdc7489SMatthew Knepley if (!flg) { 67319566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 67329566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 67339566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 67340fdc7489SMatthew Knepley } 67359566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 673663a3b9bcSJacob Faibussowitsch PetscCheck(l < Nl, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", l, Nl); 67370fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 67389566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)orig->label, &lname)); 67399566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &match)); 67400fdc7489SMatthew Knepley if (match) break; 67410fdc7489SMatthew Knepley } 67423ba16761SJacob Faibussowitsch if (m == l) PetscFunctionReturn(PETSC_SUCCESS); 67430fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 67440fdc7489SMatthew Knepley else prev->next = orig->next; 67450fdc7489SMatthew Knepley if (!l) { 67460fdc7489SMatthew Knepley orig->next = dm->labels; 67470fdc7489SMatthew Knepley dm->labels = orig; 67480fdc7489SMatthew Knepley } else { 6749fbccb6d4SPierre Jolivet for (m = 0, prev = dm->labels; m < l - 1; ++m, prev = prev->next); 67500fdc7489SMatthew Knepley orig->next = prev->next; 67510fdc7489SMatthew Knepley prev->next = orig; 67520fdc7489SMatthew Knepley } 67533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 67540fdc7489SMatthew Knepley } 67550fdc7489SMatthew Knepley 6756cc4c1da9SBarry Smith /*@ 6757bb7acecfSBarry Smith DMGetLabelValue - Get the value in a `DMLabel` for the given point, with -1 as the default 6758c58f1c22SToby Isaac 6759c58f1c22SToby Isaac Not Collective 6760c58f1c22SToby Isaac 6761c58f1c22SToby Isaac Input Parameters: 6762bb7acecfSBarry Smith + dm - The `DM` object 6763c58f1c22SToby Isaac . name - The label name 6764c58f1c22SToby Isaac - point - The mesh point 6765c58f1c22SToby Isaac 6766c58f1c22SToby Isaac Output Parameter: 6767c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 6768c58f1c22SToby Isaac 6769c58f1c22SToby Isaac Level: beginner 6770c58f1c22SToby Isaac 67711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6772c58f1c22SToby Isaac @*/ 6773d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 6774d71ae5a4SJacob Faibussowitsch { 6775c58f1c22SToby Isaac DMLabel label; 6776c58f1c22SToby Isaac 6777c58f1c22SToby Isaac PetscFunctionBegin; 6778c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67794f572ea9SToby Isaac PetscAssertPointer(name, 2); 67809566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 67817a8be351SBarry Smith PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 67829566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, point, value)); 67833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6784c58f1c22SToby Isaac } 6785c58f1c22SToby Isaac 6786cc4c1da9SBarry Smith /*@ 6787bb7acecfSBarry Smith DMSetLabelValue - Add a point to a `DMLabel` with given value 6788c58f1c22SToby Isaac 6789c58f1c22SToby Isaac Not Collective 6790c58f1c22SToby Isaac 6791c58f1c22SToby Isaac Input Parameters: 6792bb7acecfSBarry Smith + dm - The `DM` object 6793c58f1c22SToby Isaac . name - The label name 6794c58f1c22SToby Isaac . point - The mesh point 6795c58f1c22SToby Isaac - value - The label value for this point 6796c58f1c22SToby Isaac 6797c58f1c22SToby Isaac Output Parameter: 6798c58f1c22SToby Isaac 6799c58f1c22SToby Isaac Level: beginner 6800c58f1c22SToby Isaac 68011cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelSetValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6802c58f1c22SToby Isaac @*/ 6803d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6804d71ae5a4SJacob Faibussowitsch { 6805c58f1c22SToby Isaac DMLabel label; 6806c58f1c22SToby Isaac 6807c58f1c22SToby Isaac PetscFunctionBegin; 6808c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68094f572ea9SToby Isaac PetscAssertPointer(name, 2); 68109566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6811c58f1c22SToby Isaac if (!label) { 68129566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 68139566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6814c58f1c22SToby Isaac } 68159566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, point, value)); 68163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6817c58f1c22SToby Isaac } 6818c58f1c22SToby Isaac 6819cc4c1da9SBarry Smith /*@ 6820bb7acecfSBarry Smith DMClearLabelValue - Remove a point from a `DMLabel` with given value 6821c58f1c22SToby Isaac 6822c58f1c22SToby Isaac Not Collective 6823c58f1c22SToby Isaac 6824c58f1c22SToby Isaac Input Parameters: 6825bb7acecfSBarry Smith + dm - The `DM` object 6826c58f1c22SToby Isaac . name - The label name 6827c58f1c22SToby Isaac . point - The mesh point 6828c58f1c22SToby Isaac - value - The label value for this point 6829c58f1c22SToby Isaac 6830c58f1c22SToby Isaac Level: beginner 6831c58f1c22SToby Isaac 68321cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelClearValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6833c58f1c22SToby Isaac @*/ 6834d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6835d71ae5a4SJacob Faibussowitsch { 6836c58f1c22SToby Isaac DMLabel label; 6837c58f1c22SToby Isaac 6838c58f1c22SToby Isaac PetscFunctionBegin; 6839c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68404f572ea9SToby Isaac PetscAssertPointer(name, 2); 68419566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 68423ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68439566063dSJacob Faibussowitsch PetscCall(DMLabelClearValue(label, point, value)); 68443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6845c58f1c22SToby Isaac } 6846c58f1c22SToby Isaac 6847cc4c1da9SBarry Smith /*@ 6848bb7acecfSBarry Smith DMGetLabelSize - Get the value of `DMLabelGetNumValues()` of a `DMLabel` in the `DM` 6849c58f1c22SToby Isaac 6850c58f1c22SToby Isaac Not Collective 6851c58f1c22SToby Isaac 6852c58f1c22SToby Isaac Input Parameters: 6853bb7acecfSBarry Smith + dm - The `DM` object 6854c58f1c22SToby Isaac - name - The label name 6855c58f1c22SToby Isaac 6856c58f1c22SToby Isaac Output Parameter: 6857c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 6858c58f1c22SToby Isaac 6859c58f1c22SToby Isaac Level: beginner 6860c58f1c22SToby Isaac 686173ff1848SBarry Smith Developer Note: 6862bb7acecfSBarry Smith This should be renamed to something like `DMGetLabelNumValues()` or removed. 6863bb7acecfSBarry Smith 68641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetNumValues()`, `DMSetLabelValue()`, `DMGetLabel()` 6865c58f1c22SToby Isaac @*/ 6866d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 6867d71ae5a4SJacob Faibussowitsch { 6868c58f1c22SToby Isaac DMLabel label; 6869c58f1c22SToby Isaac 6870c58f1c22SToby Isaac PetscFunctionBegin; 6871c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68724f572ea9SToby Isaac PetscAssertPointer(name, 2); 68734f572ea9SToby Isaac PetscAssertPointer(size, 3); 68749566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6875c58f1c22SToby Isaac *size = 0; 68763ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68779566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, size)); 68783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6879c58f1c22SToby Isaac } 6880c58f1c22SToby Isaac 6881cc4c1da9SBarry Smith /*@ 6882bb7acecfSBarry Smith DMGetLabelIdIS - Get the `DMLabelGetValueIS()` from a `DMLabel` in the `DM` 6883c58f1c22SToby Isaac 6884c58f1c22SToby Isaac Not Collective 6885c58f1c22SToby Isaac 6886c58f1c22SToby Isaac Input Parameters: 688760225df5SJacob Faibussowitsch + dm - The `DM` object 6888c58f1c22SToby Isaac - name - The label name 6889c58f1c22SToby Isaac 6890c58f1c22SToby Isaac Output Parameter: 689120f4b53cSBarry Smith . ids - The integer ids, or `NULL` if the label does not exist 6892c58f1c22SToby Isaac 6893c58f1c22SToby Isaac Level: beginner 6894c58f1c22SToby Isaac 68951cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValueIS()`, `DMGetLabelSize()` 6896c58f1c22SToby Isaac @*/ 6897d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 6898d71ae5a4SJacob Faibussowitsch { 6899c58f1c22SToby Isaac DMLabel label; 6900c58f1c22SToby Isaac 6901c58f1c22SToby Isaac PetscFunctionBegin; 6902c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69034f572ea9SToby Isaac PetscAssertPointer(name, 2); 69044f572ea9SToby Isaac PetscAssertPointer(ids, 3); 69059566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6906c58f1c22SToby Isaac *ids = NULL; 6907dab2e251SBlaise Bourdin if (label) { 69089566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, ids)); 6909dab2e251SBlaise Bourdin } else { 6910dab2e251SBlaise Bourdin /* returning an empty IS */ 69119566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 0, NULL, PETSC_USE_POINTER, ids)); 6912dab2e251SBlaise Bourdin } 69133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6914c58f1c22SToby Isaac } 6915c58f1c22SToby Isaac 6916cc4c1da9SBarry Smith /*@ 6917c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 6918c58f1c22SToby Isaac 6919c58f1c22SToby Isaac Not Collective 6920c58f1c22SToby Isaac 6921c58f1c22SToby Isaac Input Parameters: 6922bb7acecfSBarry Smith + dm - The `DM` object 6923b6971eaeSBarry Smith . name - The label name of the stratum 6924c58f1c22SToby Isaac - value - The stratum value 6925c58f1c22SToby Isaac 6926c58f1c22SToby Isaac Output Parameter: 6927bb7acecfSBarry Smith . size - The number of points, also called the stratum size 6928c58f1c22SToby Isaac 6929c58f1c22SToby Isaac Level: beginner 6930c58f1c22SToby Isaac 69311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumSize()`, `DMGetLabelSize()`, `DMGetLabelIds()` 6932c58f1c22SToby Isaac @*/ 6933d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 6934d71ae5a4SJacob Faibussowitsch { 6935c58f1c22SToby Isaac DMLabel label; 6936c58f1c22SToby Isaac 6937c58f1c22SToby Isaac PetscFunctionBegin; 6938c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69394f572ea9SToby Isaac PetscAssertPointer(name, 2); 69404f572ea9SToby Isaac PetscAssertPointer(size, 4); 69419566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6942c58f1c22SToby Isaac *size = 0; 69433ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69449566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, value, size)); 69453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6946c58f1c22SToby Isaac } 6947c58f1c22SToby Isaac 6948cc4c1da9SBarry Smith /*@ 6949c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 6950c58f1c22SToby Isaac 6951c58f1c22SToby Isaac Not Collective 6952c58f1c22SToby Isaac 6953c58f1c22SToby Isaac Input Parameters: 6954bb7acecfSBarry Smith + dm - The `DM` object 6955c58f1c22SToby Isaac . name - The label name 6956c58f1c22SToby Isaac - value - The stratum value 6957c58f1c22SToby Isaac 6958c58f1c22SToby Isaac Output Parameter: 695920f4b53cSBarry Smith . points - The stratum points, or `NULL` if the label does not exist or does not have that value 6960c58f1c22SToby Isaac 6961c58f1c22SToby Isaac Level: beginner 6962c58f1c22SToby Isaac 69631cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumIS()`, `DMGetStratumSize()` 6964c58f1c22SToby Isaac @*/ 6965d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 6966d71ae5a4SJacob Faibussowitsch { 6967c58f1c22SToby Isaac DMLabel label; 6968c58f1c22SToby Isaac 6969c58f1c22SToby Isaac PetscFunctionBegin; 6970c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69714f572ea9SToby Isaac PetscAssertPointer(name, 2); 69724f572ea9SToby Isaac PetscAssertPointer(points, 4); 69739566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6974c58f1c22SToby Isaac *points = NULL; 69753ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69769566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, value, points)); 69773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6978c58f1c22SToby Isaac } 6979c58f1c22SToby Isaac 6980cc4c1da9SBarry Smith /*@ 69819044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 69824de306b1SToby Isaac 69834de306b1SToby Isaac Not Collective 69844de306b1SToby Isaac 69854de306b1SToby Isaac Input Parameters: 6986bb7acecfSBarry Smith + dm - The `DM` object 69874de306b1SToby Isaac . name - The label name 69884de306b1SToby Isaac . value - The stratum value 69894de306b1SToby Isaac - points - The stratum points 69904de306b1SToby Isaac 69914de306b1SToby Isaac Level: beginner 69924de306b1SToby Isaac 69931cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMClearLabelStratum()`, `DMLabelClearStratum()`, `DMLabelSetStratumIS()`, `DMGetStratumSize()` 69944de306b1SToby Isaac @*/ 6995d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 6996d71ae5a4SJacob Faibussowitsch { 69974de306b1SToby Isaac DMLabel label; 69984de306b1SToby Isaac 69994de306b1SToby Isaac PetscFunctionBegin; 70004de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70014f572ea9SToby Isaac PetscAssertPointer(name, 2); 7002292bffcbSToby Isaac PetscValidHeaderSpecific(points, IS_CLASSID, 4); 70039566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 70043ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 70059566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, points)); 70063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 70074de306b1SToby Isaac } 70084de306b1SToby Isaac 7009cc4c1da9SBarry Smith /*@ 7010bb7acecfSBarry Smith DMClearLabelStratum - Remove all points from a stratum from a `DMLabel` 7011c58f1c22SToby Isaac 7012c58f1c22SToby Isaac Not Collective 7013c58f1c22SToby Isaac 7014c58f1c22SToby Isaac Input Parameters: 7015bb7acecfSBarry Smith + dm - The `DM` object 7016c58f1c22SToby Isaac . name - The label name 7017c58f1c22SToby Isaac - value - The label value for this point 7018c58f1c22SToby Isaac 7019c58f1c22SToby Isaac Output Parameter: 7020c58f1c22SToby Isaac 7021c58f1c22SToby Isaac Level: beginner 7022c58f1c22SToby Isaac 70231cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMLabelClearStratum()`, `DMSetLabelValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 7024c58f1c22SToby Isaac @*/ 7025d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 7026d71ae5a4SJacob Faibussowitsch { 7027c58f1c22SToby Isaac DMLabel label; 7028c58f1c22SToby Isaac 7029c58f1c22SToby Isaac PetscFunctionBegin; 7030c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70314f572ea9SToby Isaac PetscAssertPointer(name, 2); 70329566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 70333ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 70349566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 70353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7036c58f1c22SToby Isaac } 7037c58f1c22SToby Isaac 7038c58f1c22SToby Isaac /*@ 7039bb7acecfSBarry Smith DMGetNumLabels - Return the number of labels defined by on the `DM` 7040c58f1c22SToby Isaac 7041c58f1c22SToby Isaac Not Collective 7042c58f1c22SToby Isaac 7043c58f1c22SToby Isaac Input Parameter: 7044bb7acecfSBarry Smith . dm - The `DM` object 7045c58f1c22SToby Isaac 7046c58f1c22SToby Isaac Output Parameter: 7047c58f1c22SToby Isaac . numLabels - the number of Labels 7048c58f1c22SToby Isaac 7049c58f1c22SToby Isaac Level: intermediate 7050c58f1c22SToby Isaac 70511cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabelName()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7052c58f1c22SToby Isaac @*/ 7053d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7054d71ae5a4SJacob Faibussowitsch { 70555d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7056c58f1c22SToby Isaac PetscInt n = 0; 7057c58f1c22SToby Isaac 7058c58f1c22SToby Isaac PetscFunctionBegin; 7059c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70604f572ea9SToby Isaac PetscAssertPointer(numLabels, 2); 70619371c9d4SSatish Balay while (next) { 70629371c9d4SSatish Balay ++n; 70639371c9d4SSatish Balay next = next->next; 70649371c9d4SSatish Balay } 7065c58f1c22SToby Isaac *numLabels = n; 70663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7067c58f1c22SToby Isaac } 7068c58f1c22SToby Isaac 7069cc4c1da9SBarry Smith /*@ 7070c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7071c58f1c22SToby Isaac 7072c58f1c22SToby Isaac Not Collective 7073c58f1c22SToby Isaac 7074c58f1c22SToby Isaac Input Parameters: 7075bb7acecfSBarry Smith + dm - The `DM` object 7076c58f1c22SToby Isaac - n - the label number 7077c58f1c22SToby Isaac 7078c58f1c22SToby Isaac Output Parameter: 7079c58f1c22SToby Isaac . name - the label name 7080c58f1c22SToby Isaac 7081c58f1c22SToby Isaac Level: intermediate 7082c58f1c22SToby Isaac 708373ff1848SBarry Smith Developer Note: 7084bb7acecfSBarry Smith Some of the functions that appropriate on labels using their number have the suffix ByNum, others do not. 7085bb7acecfSBarry Smith 70861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7087c58f1c22SToby Isaac @*/ 7088cc4c1da9SBarry Smith PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char *name[]) 7089d71ae5a4SJacob Faibussowitsch { 70905d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7091c58f1c22SToby Isaac PetscInt l = 0; 7092c58f1c22SToby Isaac 7093c58f1c22SToby Isaac PetscFunctionBegin; 7094c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70954f572ea9SToby Isaac PetscAssertPointer(name, 3); 7096c58f1c22SToby Isaac while (next) { 7097c58f1c22SToby Isaac if (l == n) { 70989566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, name)); 70993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7100c58f1c22SToby Isaac } 7101c58f1c22SToby Isaac ++l; 7102c58f1c22SToby Isaac next = next->next; 7103c58f1c22SToby Isaac } 710463a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7105c58f1c22SToby Isaac } 7106c58f1c22SToby Isaac 7107cc4c1da9SBarry Smith /*@ 7108bb7acecfSBarry Smith DMHasLabel - Determine whether the `DM` has a label of a given name 7109c58f1c22SToby Isaac 7110c58f1c22SToby Isaac Not Collective 7111c58f1c22SToby Isaac 7112c58f1c22SToby Isaac Input Parameters: 7113bb7acecfSBarry Smith + dm - The `DM` object 7114c58f1c22SToby Isaac - name - The label name 7115c58f1c22SToby Isaac 7116c58f1c22SToby Isaac Output Parameter: 7117bb7acecfSBarry Smith . hasLabel - `PETSC_TRUE` if the label is present 7118c58f1c22SToby Isaac 7119c58f1c22SToby Isaac Level: intermediate 7120c58f1c22SToby Isaac 71211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabel()`, `DMGetLabelByNum()`, `DMCreateLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7122c58f1c22SToby Isaac @*/ 7123d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7124d71ae5a4SJacob Faibussowitsch { 71255d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7126d67d17b1SMatthew G. Knepley const char *lname; 7127c58f1c22SToby Isaac 7128c58f1c22SToby Isaac PetscFunctionBegin; 7129c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71304f572ea9SToby Isaac PetscAssertPointer(name, 2); 71314f572ea9SToby Isaac PetscAssertPointer(hasLabel, 3); 7132c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7133c58f1c22SToby Isaac while (next) { 71349566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 71359566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, hasLabel)); 7136c58f1c22SToby Isaac if (*hasLabel) break; 7137c58f1c22SToby Isaac next = next->next; 7138c58f1c22SToby Isaac } 71393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7140c58f1c22SToby Isaac } 7141c58f1c22SToby Isaac 7142a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7143cc4c1da9SBarry Smith /*@ 714420f4b53cSBarry Smith DMGetLabel - Return the label of a given name, or `NULL`, from a `DM` 7145c58f1c22SToby Isaac 7146c58f1c22SToby Isaac Not Collective 7147c58f1c22SToby Isaac 7148c58f1c22SToby Isaac Input Parameters: 7149bb7acecfSBarry Smith + dm - The `DM` object 7150c58f1c22SToby Isaac - name - The label name 7151c58f1c22SToby Isaac 7152c58f1c22SToby Isaac Output Parameter: 715320f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent 7154c58f1c22SToby Isaac 7155bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7156bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7157bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7158bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7159bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7160bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7161bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 71626d7c9049SMatthew G. Knepley 7163c58f1c22SToby Isaac Level: intermediate 7164c58f1c22SToby Isaac 716560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMHasLabel()`, `DMGetLabelByNum()`, `DMAddLabel()`, `DMCreateLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 7166c58f1c22SToby Isaac @*/ 7167d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7168d71ae5a4SJacob Faibussowitsch { 71695d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7170c58f1c22SToby Isaac PetscBool hasLabel; 7171d67d17b1SMatthew G. Knepley const char *lname; 7172c58f1c22SToby Isaac 7173c58f1c22SToby Isaac PetscFunctionBegin; 7174c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71754f572ea9SToby Isaac PetscAssertPointer(name, 2); 71764f572ea9SToby Isaac PetscAssertPointer(label, 3); 7177c58f1c22SToby Isaac *label = NULL; 7178c58f1c22SToby Isaac while (next) { 71799566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 71809566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7181c58f1c22SToby Isaac if (hasLabel) { 7182c58f1c22SToby Isaac *label = next->label; 7183c58f1c22SToby Isaac break; 7184c58f1c22SToby Isaac } 7185c58f1c22SToby Isaac next = next->next; 7186c58f1c22SToby Isaac } 71873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7188c58f1c22SToby Isaac } 7189c58f1c22SToby Isaac 7190cc4c1da9SBarry Smith /*@ 7191bb7acecfSBarry Smith DMGetLabelByNum - Return the nth label on a `DM` 7192c58f1c22SToby Isaac 7193c58f1c22SToby Isaac Not Collective 7194c58f1c22SToby Isaac 7195c58f1c22SToby Isaac Input Parameters: 7196bb7acecfSBarry Smith + dm - The `DM` object 7197c58f1c22SToby Isaac - n - the label number 7198c58f1c22SToby Isaac 7199c58f1c22SToby Isaac Output Parameter: 7200c58f1c22SToby Isaac . label - the label 7201c58f1c22SToby Isaac 7202c58f1c22SToby Isaac Level: intermediate 7203c58f1c22SToby Isaac 72041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7205c58f1c22SToby Isaac @*/ 7206d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7207d71ae5a4SJacob Faibussowitsch { 72085d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7209c58f1c22SToby Isaac PetscInt l = 0; 7210c58f1c22SToby Isaac 7211c58f1c22SToby Isaac PetscFunctionBegin; 7212c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72134f572ea9SToby Isaac PetscAssertPointer(label, 3); 7214c58f1c22SToby Isaac while (next) { 7215c58f1c22SToby Isaac if (l == n) { 7216c58f1c22SToby Isaac *label = next->label; 72173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7218c58f1c22SToby Isaac } 7219c58f1c22SToby Isaac ++l; 7220c58f1c22SToby Isaac next = next->next; 7221c58f1c22SToby Isaac } 722263a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7223c58f1c22SToby Isaac } 7224c58f1c22SToby Isaac 7225cc4c1da9SBarry Smith /*@ 7226bb7acecfSBarry Smith DMAddLabel - Add the label to this `DM` 7227c58f1c22SToby Isaac 7228c58f1c22SToby Isaac Not Collective 7229c58f1c22SToby Isaac 7230c58f1c22SToby Isaac Input Parameters: 7231bb7acecfSBarry Smith + dm - The `DM` object 7232bb7acecfSBarry Smith - label - The `DMLabel` 7233c58f1c22SToby Isaac 7234c58f1c22SToby Isaac Level: developer 7235c58f1c22SToby Isaac 723660225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7237c58f1c22SToby Isaac @*/ 7238d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7239d71ae5a4SJacob Faibussowitsch { 72405d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7241c58f1c22SToby Isaac PetscBool hasLabel; 7242d67d17b1SMatthew G. Knepley const char *lname; 72435d80c0bfSVaclav Hapla PetscBool flg; 7244c58f1c22SToby Isaac 7245c58f1c22SToby Isaac PetscFunctionBegin; 7246c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 72489566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, lname, &hasLabel)); 72497a8be351SBarry Smith PetscCheck(!hasLabel, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 72509566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(1, &tmpLabel)); 7251c58f1c22SToby Isaac tmpLabel->label = label; 7252c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 72535d80c0bfSVaclav Hapla for (p = &dm->labels; (l = *p); p = &l->next) { } 72545d80c0bfSVaclav Hapla *p = tmpLabel; 72559566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 72569566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 72575d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 72589566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 7259ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 72603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7261c58f1c22SToby Isaac } 7262c58f1c22SToby Isaac 7263a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7264cc4c1da9SBarry Smith /*@ 72654a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 72664a7ee7d0SMatthew G. Knepley 72674a7ee7d0SMatthew G. Knepley Not Collective 72684a7ee7d0SMatthew G. Knepley 72694a7ee7d0SMatthew G. Knepley Input Parameters: 7270bb7acecfSBarry Smith + dm - The `DM` object 7271bb7acecfSBarry Smith - label - The `DMLabel`, having the same name, to substitute 72724a7ee7d0SMatthew G. Knepley 7273bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7274bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7275bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7276bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7277bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7278bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7279bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 72804a7ee7d0SMatthew G. Knepley 72814a7ee7d0SMatthew G. Knepley Level: intermediate 72824a7ee7d0SMatthew G. Knepley 72831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 72844a7ee7d0SMatthew G. Knepley @*/ 7285d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabel(DM dm, DMLabel label) 7286d71ae5a4SJacob Faibussowitsch { 72874a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 72884a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 72894a7ee7d0SMatthew G. Knepley const char *name, *lname; 72904a7ee7d0SMatthew G. Knepley 72914a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 72924a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72934a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 72949566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 72954a7ee7d0SMatthew G. Knepley while (next) { 72969566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 72979566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 72984a7ee7d0SMatthew G. Knepley if (hasLabel) { 72999566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 73009566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 73014a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 73029566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 73034a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 73049566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 73054a7ee7d0SMatthew G. Knepley next->label = label; 73064a7ee7d0SMatthew G. Knepley break; 73074a7ee7d0SMatthew G. Knepley } 73084a7ee7d0SMatthew G. Knepley next = next->next; 73094a7ee7d0SMatthew G. Knepley } 73103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 73114a7ee7d0SMatthew G. Knepley } 73124a7ee7d0SMatthew G. Knepley 7313cc4c1da9SBarry Smith /*@ 7314bb7acecfSBarry Smith DMRemoveLabel - Remove the label given by name from this `DM` 7315c58f1c22SToby Isaac 7316c58f1c22SToby Isaac Not Collective 7317c58f1c22SToby Isaac 7318c58f1c22SToby Isaac Input Parameters: 7319bb7acecfSBarry Smith + dm - The `DM` object 7320c58f1c22SToby Isaac - name - The label name 7321c58f1c22SToby Isaac 7322c58f1c22SToby Isaac Output Parameter: 732320f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent. Pass in `NULL` to call `DMLabelDestroy()` on the label, otherwise the 7324bb7acecfSBarry Smith caller is responsible for calling `DMLabelDestroy()`. 7325c58f1c22SToby Isaac 7326c58f1c22SToby Isaac Level: developer 7327c58f1c22SToby Isaac 73281cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabelBySelf()` 7329c58f1c22SToby Isaac @*/ 7330d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7331d71ae5a4SJacob Faibussowitsch { 733295d578d6SVaclav Hapla DMLabelLink link, *pnext; 7333c58f1c22SToby Isaac PetscBool hasLabel; 7334d67d17b1SMatthew G. Knepley const char *lname; 7335c58f1c22SToby Isaac 7336c58f1c22SToby Isaac PetscFunctionBegin; 7337c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73384f572ea9SToby Isaac PetscAssertPointer(name, 2); 7339e5472504SVaclav Hapla if (label) { 73404f572ea9SToby Isaac PetscAssertPointer(label, 3); 7341c58f1c22SToby Isaac *label = NULL; 7342e5472504SVaclav Hapla } 73435d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 73449566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)link->label, &lname)); 73459566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7346c58f1c22SToby Isaac if (hasLabel) { 734795d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 73489566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &hasLabel)); 734995d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 73509566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &hasLabel)); 7351ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 735295d578d6SVaclav Hapla if (label) *label = link->label; 73539566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&link->label)); 73549566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7355c58f1c22SToby Isaac break; 7356c58f1c22SToby Isaac } 7357c58f1c22SToby Isaac } 73583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7359c58f1c22SToby Isaac } 7360c58f1c22SToby Isaac 7361306894acSVaclav Hapla /*@ 7362bb7acecfSBarry Smith DMRemoveLabelBySelf - Remove the label from this `DM` 7363306894acSVaclav Hapla 7364306894acSVaclav Hapla Not Collective 7365306894acSVaclav Hapla 7366306894acSVaclav Hapla Input Parameters: 7367bb7acecfSBarry Smith + dm - The `DM` object 7368bb7acecfSBarry Smith . label - The `DMLabel` to be removed from the `DM` 736920f4b53cSBarry Smith - failNotFound - Should it fail if the label is not found in the `DM`? 7370306894acSVaclav Hapla 7371306894acSVaclav Hapla Level: developer 7372306894acSVaclav Hapla 7373bb7acecfSBarry Smith Note: 7374306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7375bb7acecfSBarry Smith If the `DM` has an exclusive reference to the label, the label gets destroyed and 7376306894acSVaclav Hapla *label nullified. 7377306894acSVaclav Hapla 73781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()` `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabel()` 7379306894acSVaclav Hapla @*/ 7380d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7381d71ae5a4SJacob Faibussowitsch { 738243e45a93SVaclav Hapla DMLabelLink link, *pnext; 7383306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7384306894acSVaclav Hapla 7385306894acSVaclav Hapla PetscFunctionBegin; 7386306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73874f572ea9SToby Isaac PetscAssertPointer(label, 2); 73883ba16761SJacob Faibussowitsch if (!*label && !failNotFound) PetscFunctionReturn(PETSC_SUCCESS); 7389306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7390306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm, failNotFound, 3); 73915d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 739243e45a93SVaclav Hapla if (*label == link->label) { 7393306894acSVaclav Hapla hasLabel = PETSC_TRUE; 739443e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7395306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7396ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 739743e45a93SVaclav Hapla if (((PetscObject)link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 73989566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&link->label)); 73999566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7400306894acSVaclav Hapla break; 7401306894acSVaclav Hapla } 7402306894acSVaclav Hapla } 74037a8be351SBarry Smith PetscCheck(hasLabel || !failNotFound, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 74043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7405306894acSVaclav Hapla } 7406306894acSVaclav Hapla 7407cc4c1da9SBarry Smith /*@ 7408c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7409c58f1c22SToby Isaac 7410c58f1c22SToby Isaac Not Collective 7411c58f1c22SToby Isaac 7412c58f1c22SToby Isaac Input Parameters: 7413bb7acecfSBarry Smith + dm - The `DM` object 7414c58f1c22SToby Isaac - name - The label name 7415c58f1c22SToby Isaac 7416c58f1c22SToby Isaac Output Parameter: 7417c58f1c22SToby Isaac . output - The flag for output 7418c58f1c22SToby Isaac 7419c58f1c22SToby Isaac Level: developer 7420c58f1c22SToby Isaac 74211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMSetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7422c58f1c22SToby Isaac @*/ 7423d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7424d71ae5a4SJacob Faibussowitsch { 74255d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7426d67d17b1SMatthew G. Knepley const char *lname; 7427c58f1c22SToby Isaac 7428c58f1c22SToby Isaac PetscFunctionBegin; 7429c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 74304f572ea9SToby Isaac PetscAssertPointer(name, 2); 74314f572ea9SToby Isaac PetscAssertPointer(output, 3); 7432c58f1c22SToby Isaac while (next) { 7433c58f1c22SToby Isaac PetscBool flg; 7434c58f1c22SToby Isaac 74359566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 74369566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 74379371c9d4SSatish Balay if (flg) { 74389371c9d4SSatish Balay *output = next->output; 74393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74409371c9d4SSatish Balay } 7441c58f1c22SToby Isaac next = next->next; 7442c58f1c22SToby Isaac } 744398921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7444c58f1c22SToby Isaac } 7445c58f1c22SToby Isaac 7446cc4c1da9SBarry Smith /*@ 7447bb7acecfSBarry Smith DMSetLabelOutput - Set if a given label should be saved to a `PetscViewer` in calls to `DMView()` 7448c58f1c22SToby Isaac 7449c58f1c22SToby Isaac Not Collective 7450c58f1c22SToby Isaac 7451c58f1c22SToby Isaac Input Parameters: 7452bb7acecfSBarry Smith + dm - The `DM` object 7453c58f1c22SToby Isaac . name - The label name 7454bb7acecfSBarry Smith - output - `PETSC_TRUE` to save the label to the viewer 7455c58f1c22SToby Isaac 7456c58f1c22SToby Isaac Level: developer 7457c58f1c22SToby Isaac 74581cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetOutputFlag()`, `DMGetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7459c58f1c22SToby Isaac @*/ 7460d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7461d71ae5a4SJacob Faibussowitsch { 74625d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7463d67d17b1SMatthew G. Knepley const char *lname; 7464c58f1c22SToby Isaac 7465c58f1c22SToby Isaac PetscFunctionBegin; 7466c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 74674f572ea9SToby Isaac PetscAssertPointer(name, 2); 7468c58f1c22SToby Isaac while (next) { 7469c58f1c22SToby Isaac PetscBool flg; 7470c58f1c22SToby Isaac 74719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 74729566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 74739371c9d4SSatish Balay if (flg) { 74749371c9d4SSatish Balay next->output = output; 74753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74769371c9d4SSatish Balay } 7477c58f1c22SToby Isaac next = next->next; 7478c58f1c22SToby Isaac } 747998921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7480c58f1c22SToby Isaac } 7481c58f1c22SToby Isaac 7482c58f1c22SToby Isaac /*@ 7483bb7acecfSBarry Smith DMCopyLabels - Copy labels from one `DM` mesh to another `DM` with a superset of the points 7484c58f1c22SToby Isaac 748520f4b53cSBarry Smith Collective 7486c58f1c22SToby Isaac 7487d8d19677SJose E. Roman Input Parameters: 7488bb7acecfSBarry Smith + dmA - The `DM` object with initial labels 7489bb7acecfSBarry Smith . dmB - The `DM` object to which labels are copied 7490bb7acecfSBarry Smith . mode - Copy labels by pointers (`PETSC_OWN_POINTER`) or duplicate them (`PETSC_COPY_VALUES`) 7491bb7acecfSBarry Smith . all - Copy all labels including "depth", "dim", and "celltype" (`PETSC_TRUE`) which are otherwise ignored (`PETSC_FALSE`) 7492bb7acecfSBarry Smith - emode - How to behave when a `DMLabel` in the source and destination `DM`s with the same name is encountered (see `DMCopyLabelsMode`) 7493c58f1c22SToby Isaac 7494c58f1c22SToby Isaac Level: intermediate 7495c58f1c22SToby Isaac 7496bb7acecfSBarry Smith Note: 74972cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 7498c58f1c22SToby Isaac 74991cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode` 7500c58f1c22SToby Isaac @*/ 7501d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 7502d71ae5a4SJacob Faibussowitsch { 75032cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 7504c58f1c22SToby Isaac const char *name; 7505c58f1c22SToby Isaac PetscBool flg; 75065d80c0bfSVaclav Hapla DMLabelLink link; 7507c58f1c22SToby Isaac 75085d80c0bfSVaclav Hapla PetscFunctionBegin; 75095d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 75105d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 75115d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode, 3); 75125d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 75137a8be351SBarry Smith PetscCheck(mode != PETSC_USE_POINTER, PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 75143ba16761SJacob Faibussowitsch if (dmA == dmB) PetscFunctionReturn(PETSC_SUCCESS); 75155d80c0bfSVaclav Hapla for (link = dmA->labels; link; link = link->next) { 75165d80c0bfSVaclav Hapla label = link->label; 75179566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 75185d80c0bfSVaclav Hapla if (!all) { 75199566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &flg)); 7520c58f1c22SToby Isaac if (flg) continue; 75219566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "dim", &flg)); 75227d5acc75SStefano Zampini if (flg) continue; 75239566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &flg)); 7524ba2698f1SMatthew G. Knepley if (flg) continue; 75255d80c0bfSVaclav Hapla } 75269566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmB, name, &labelOld)); 75272cbb9b06SVaclav Hapla if (labelOld) { 75282cbb9b06SVaclav Hapla switch (emode) { 7529d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_KEEP: 7530d71ae5a4SJacob Faibussowitsch continue; 7531d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_REPLACE: 7532d71ae5a4SJacob Faibussowitsch PetscCall(DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE)); 7533d71ae5a4SJacob Faibussowitsch break; 7534d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_FAIL: 7535d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 7536d71ae5a4SJacob Faibussowitsch default: 7537d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", (int)emode); 75382cbb9b06SVaclav Hapla } 75392cbb9b06SVaclav Hapla } 75405d80c0bfSVaclav Hapla if (mode == PETSC_COPY_VALUES) { 75419566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, &labelNew)); 75425d80c0bfSVaclav Hapla } else { 75435d80c0bfSVaclav Hapla labelNew = label; 75445d80c0bfSVaclav Hapla } 75459566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmB, labelNew)); 75469566063dSJacob Faibussowitsch if (mode == PETSC_COPY_VALUES) PetscCall(DMLabelDestroy(&labelNew)); 7547c58f1c22SToby Isaac } 75483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7549c58f1c22SToby Isaac } 7550461a15a0SLisandro Dalcin 7551609dae6eSVaclav Hapla /*@C 7552b4028c23SStefano Zampini DMCompareLabels - Compare labels between two `DM` objects 7553609dae6eSVaclav Hapla 755420f4b53cSBarry Smith Collective; No Fortran Support 7555609dae6eSVaclav Hapla 7556609dae6eSVaclav Hapla Input Parameters: 7557bb7acecfSBarry Smith + dm0 - First `DM` object 7558bb7acecfSBarry Smith - dm1 - Second `DM` object 7559609dae6eSVaclav Hapla 7560a4e35b19SJacob Faibussowitsch Output Parameters: 75615efe38ccSVaclav Hapla + equal - (Optional) Flag whether labels of dm0 and dm1 are the same 756220f4b53cSBarry Smith - message - (Optional) Message describing the difference, or `NULL` if there is no difference 7563609dae6eSVaclav Hapla 7564609dae6eSVaclav Hapla Level: intermediate 7565609dae6eSVaclav Hapla 7566609dae6eSVaclav Hapla Notes: 7567bb7acecfSBarry Smith The output flag equal will be the same on all processes. 7568bb7acecfSBarry Smith 756920f4b53cSBarry Smith If equal is passed as `NULL` and difference is found, an error is thrown on all processes. 7570bb7acecfSBarry Smith 757120f4b53cSBarry Smith Make sure to pass equal is `NULL` on all processes or none of them. 7572609dae6eSVaclav Hapla 75735efe38ccSVaclav Hapla The output message is set independently on each rank. 7574bb7acecfSBarry Smith 7575bb7acecfSBarry Smith message must be freed with `PetscFree()` 7576bb7acecfSBarry Smith 757720f4b53cSBarry Smith If message is passed as `NULL` and a difference is found, the difference description is printed to stderr in synchronized manner. 7578bb7acecfSBarry Smith 757920f4b53cSBarry Smith Make sure to pass message as `NULL` on all processes or no processes. 7580609dae6eSVaclav Hapla 7581609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 7582bb7acecfSBarry Smith `DMLabelCompare()` is used to compare each pair of labels with the same name. 7583609dae6eSVaclav Hapla 7584cc4c1da9SBarry Smith Developer Note: 7585cc4c1da9SBarry Smith Can automatically generate the Fortran stub because `message` must be freed with `PetscFree()` 7586cc4c1da9SBarry Smith 75871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode`, `DMLabelCompare()` 7588609dae6eSVaclav Hapla @*/ 7589d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *equal, char **message) 7590d71ae5a4SJacob Faibussowitsch { 75915efe38ccSVaclav Hapla PetscInt n, i; 7592609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 75935efe38ccSVaclav Hapla PetscBool eq; 7594609dae6eSVaclav Hapla MPI_Comm comm; 75955efe38ccSVaclav Hapla PetscMPIInt rank; 7596609dae6eSVaclav Hapla 7597609dae6eSVaclav Hapla PetscFunctionBegin; 7598609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0, DM_CLASSID, 1); 7599609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1, DM_CLASSID, 2); 7600609dae6eSVaclav Hapla PetscCheckSameComm(dm0, 1, dm1, 2); 76014f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 3); 76024f572ea9SToby Isaac if (message) PetscAssertPointer(message, 4); 76039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm0, &comm)); 76049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 76055efe38ccSVaclav Hapla { 76065efe38ccSVaclav Hapla PetscInt n1; 76075efe38ccSVaclav Hapla 76089566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm0, &n)); 76099566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm1, &n1)); 76105efe38ccSVaclav Hapla eq = (PetscBool)(n == n1); 761148a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %" PetscInt_FMT " != %" PetscInt_FMT " = Number of labels in dm1", n, n1)); 7612462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 76135efe38ccSVaclav Hapla if (!eq) goto finish; 76145efe38ccSVaclav Hapla } 76155efe38ccSVaclav Hapla for (i = 0; i < n; i++) { 7616609dae6eSVaclav Hapla DMLabel l0, l1; 7617609dae6eSVaclav Hapla const char *name; 7618609dae6eSVaclav Hapla char *msgInner; 7619609dae6eSVaclav Hapla 7620609dae6eSVaclav Hapla /* Ignore label order */ 76219566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm0, i, &l0)); 76229566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name)); 76239566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm1, name, &l1)); 7624609dae6eSVaclav Hapla if (!l1) { 762563a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%" PetscInt_FMT " in dm0) not found in dm1", name, i)); 76265efe38ccSVaclav Hapla eq = PETSC_FALSE; 76275efe38ccSVaclav Hapla break; 7628609dae6eSVaclav Hapla } 76299566063dSJacob Faibussowitsch PetscCall(DMLabelCompare(comm, l0, l1, &eq, &msgInner)); 76309566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(msg, msgInner, sizeof(msg))); 76319566063dSJacob Faibussowitsch PetscCall(PetscFree(msgInner)); 76325efe38ccSVaclav Hapla if (!eq) break; 7633609dae6eSVaclav Hapla } 7634462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 7635609dae6eSVaclav Hapla finish: 76365efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 7637609dae6eSVaclav Hapla if (message) { 7638609dae6eSVaclav Hapla *message = NULL; 763948a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 76405efe38ccSVaclav Hapla } else { 764148a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 76429566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 76435efe38ccSVaclav Hapla } 76445efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 76455efe38ccSVaclav Hapla if (equal) *equal = eq; 76467a8be351SBarry Smith else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels are not the same in dm0 and dm1"); 76473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7648609dae6eSVaclav Hapla } 7649609dae6eSVaclav Hapla 7650d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 7651d71ae5a4SJacob Faibussowitsch { 7652461a15a0SLisandro Dalcin PetscFunctionBegin; 76534f572ea9SToby Isaac PetscAssertPointer(label, 2); 7654461a15a0SLisandro Dalcin if (!*label) { 76559566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 76569566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, label)); 7657461a15a0SLisandro Dalcin } 76589566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(*label, point, value)); 76593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7660461a15a0SLisandro Dalcin } 7661461a15a0SLisandro Dalcin 76620fdc7489SMatthew Knepley /* 76630fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 76640fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 76650fdc7489SMatthew Knepley (label, id) pair in the DM. 76660fdc7489SMatthew Knepley 76670fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 76680fdc7489SMatthew Knepley each label. 76690fdc7489SMatthew Knepley */ 7670d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 7671d71ae5a4SJacob Faibussowitsch { 76720fdc7489SMatthew Knepley DMUniversalLabel ul; 76730fdc7489SMatthew Knepley PetscBool *active; 76740fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 76750fdc7489SMatthew Knepley 76760fdc7489SMatthew Knepley PetscFunctionBegin; 76779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &ul)); 76789566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label)); 76799566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 76809566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nl, &active)); 76810fdc7489SMatthew Knepley ul->Nl = 0; 76820fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 76830fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 76840fdc7489SMatthew Knepley const char *name; 76850fdc7489SMatthew Knepley 76869566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 76879566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "depth", 6, &isdepth)); 76889566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "celltype", 9, &iscelltype)); 76890fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 76900fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 76910fdc7489SMatthew Knepley } 76929566063dSJacob 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)); 76930fdc7489SMatthew Knepley ul->Nv = 0; 76940fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 76950fdc7489SMatthew Knepley DMLabel label; 76960fdc7489SMatthew Knepley PetscInt nv; 76970fdc7489SMatthew Knepley const char *name; 76980fdc7489SMatthew Knepley 76990fdc7489SMatthew Knepley if (!active[l]) continue; 77009566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 77019566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 77029566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 77039566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &ul->names[m])); 77040fdc7489SMatthew Knepley ul->indices[m] = l; 77050fdc7489SMatthew Knepley ul->Nv += nv; 77060fdc7489SMatthew Knepley ul->offsets[m + 1] = nv; 77070fdc7489SMatthew Knepley ul->bits[m + 1] = PetscCeilReal(PetscLog2Real(nv + 1)); 77080fdc7489SMatthew Knepley ++m; 77090fdc7489SMatthew Knepley } 77100fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 77110fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l - 1] + ul->offsets[l]; 77120fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l - 1] + ul->bits[l]; 77130fdc7489SMatthew Knepley } 77140fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 77150fdc7489SMatthew Knepley PetscInt b; 77160fdc7489SMatthew Knepley 77170fdc7489SMatthew Knepley ul->masks[l] = 0; 77180fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l + 1]; ++b) ul->masks[l] |= 1 << b; 77190fdc7489SMatthew Knepley } 77209566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ul->Nv, &ul->values)); 77210fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 77220fdc7489SMatthew Knepley DMLabel label; 77230fdc7489SMatthew Knepley IS valueIS; 77240fdc7489SMatthew Knepley const PetscInt *varr; 77250fdc7489SMatthew Knepley PetscInt nv, v; 77260fdc7489SMatthew Knepley 77270fdc7489SMatthew Knepley if (!active[l]) continue; 77289566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 77299566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 77309566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &valueIS)); 77319566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &varr)); 7732ad540459SPierre Jolivet for (v = 0; v < nv; ++v) ul->values[ul->offsets[m] + v] = varr[v]; 77339566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(valueIS, &varr)); 77349566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valueIS)); 77359566063dSJacob Faibussowitsch PetscCall(PetscSortInt(nv, &ul->values[ul->offsets[m]])); 77360fdc7489SMatthew Knepley ++m; 77370fdc7489SMatthew Knepley } 77389566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 77390fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 77400fdc7489SMatthew Knepley PetscInt uval = 0; 77410fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 77420fdc7489SMatthew Knepley 77430fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 77440fdc7489SMatthew Knepley DMLabel label; 77450649b39aSStefano Zampini PetscInt val, defval, loc, nv; 77460fdc7489SMatthew Knepley 77470fdc7489SMatthew Knepley if (!active[l]) continue; 77489566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 77499566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &val)); 77509566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &defval)); 77519371c9d4SSatish Balay if (val == defval) { 77529371c9d4SSatish Balay ++m; 77539371c9d4SSatish Balay continue; 77549371c9d4SSatish Balay } 77550649b39aSStefano Zampini nv = ul->offsets[m + 1] - ul->offsets[m]; 77560fdc7489SMatthew Knepley marked = PETSC_TRUE; 77579566063dSJacob Faibussowitsch PetscCall(PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc)); 775863a3b9bcSJacob Faibussowitsch PetscCheck(loc >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %" PetscInt_FMT " not found in compression array", val); 77590fdc7489SMatthew Knepley uval += (loc + 1) << ul->bits[m]; 77600fdc7489SMatthew Knepley ++m; 77610fdc7489SMatthew Knepley } 77629566063dSJacob Faibussowitsch if (marked) PetscCall(DMLabelSetValue(ul->label, p, uval)); 77630fdc7489SMatthew Knepley } 77649566063dSJacob Faibussowitsch PetscCall(PetscFree(active)); 77650fdc7489SMatthew Knepley *universal = ul; 77663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77670fdc7489SMatthew Knepley } 77680fdc7489SMatthew Knepley 7769d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 7770d71ae5a4SJacob Faibussowitsch { 77710fdc7489SMatthew Knepley PetscInt l; 77720fdc7489SMatthew Knepley 77730fdc7489SMatthew Knepley PetscFunctionBegin; 77749566063dSJacob Faibussowitsch for (l = 0; l < (*universal)->Nl; ++l) PetscCall(PetscFree((*universal)->names[l])); 77759566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&(*universal)->label)); 77769566063dSJacob Faibussowitsch PetscCall(PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks)); 77779566063dSJacob Faibussowitsch PetscCall(PetscFree((*universal)->values)); 77789566063dSJacob Faibussowitsch PetscCall(PetscFree(*universal)); 77790fdc7489SMatthew Knepley *universal = NULL; 77803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77810fdc7489SMatthew Knepley } 77820fdc7489SMatthew Knepley 7783d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 7784d71ae5a4SJacob Faibussowitsch { 77850fdc7489SMatthew Knepley PetscFunctionBegin; 77864f572ea9SToby Isaac PetscAssertPointer(ulabel, 2); 77870fdc7489SMatthew Knepley *ulabel = ul->label; 77883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77890fdc7489SMatthew Knepley } 77900fdc7489SMatthew Knepley 7791d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 7792d71ae5a4SJacob Faibussowitsch { 77930fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 77940fdc7489SMatthew Knepley 77950fdc7489SMatthew Knepley PetscFunctionBegin; 7796064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 77970fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 77989566063dSJacob Faibussowitsch if (preserveOrder) PetscCall(DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l])); 77999566063dSJacob Faibussowitsch else PetscCall(DMCreateLabel(dm, ul->names[l])); 78000fdc7489SMatthew Knepley } 78010fdc7489SMatthew Knepley if (preserveOrder) { 78020fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 78030fdc7489SMatthew Knepley const char *name; 78040fdc7489SMatthew Knepley PetscBool match; 78050fdc7489SMatthew Knepley 78069566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, ul->indices[l], &name)); 78079566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, ul->names[l], &match)); 780863a3b9bcSJacob 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]); 78090fdc7489SMatthew Knepley } 78100fdc7489SMatthew Knepley } 78113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78120fdc7489SMatthew Knepley } 78130fdc7489SMatthew Knepley 7814d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 7815d71ae5a4SJacob Faibussowitsch { 78160fdc7489SMatthew Knepley PetscInt l; 78170fdc7489SMatthew Knepley 78180fdc7489SMatthew Knepley PetscFunctionBegin; 78190fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 78200fdc7489SMatthew Knepley DMLabel label; 78210fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 78220fdc7489SMatthew Knepley 78230fdc7489SMatthew Knepley if (lval) { 78249566063dSJacob Faibussowitsch if (useIndex) PetscCall(DMGetLabelByNum(dm, ul->indices[l], &label)); 78259566063dSJacob Faibussowitsch else PetscCall(DMGetLabel(dm, ul->names[l], &label)); 78269566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, p, ul->values[ul->offsets[l] + lval - 1])); 78270fdc7489SMatthew Knepley } 78280fdc7489SMatthew Knepley } 78293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78300fdc7489SMatthew Knepley } 7831a8fb8f29SToby Isaac 7832a8fb8f29SToby Isaac /*@ 7833bb7acecfSBarry Smith DMGetCoarseDM - Get the coarse `DM`from which this `DM` was obtained by refinement 7834bb7acecfSBarry Smith 783520f4b53cSBarry Smith Not Collective 7836a8fb8f29SToby Isaac 7837a8fb8f29SToby Isaac Input Parameter: 7838bb7acecfSBarry Smith . dm - The `DM` object 7839a8fb8f29SToby Isaac 7840a8fb8f29SToby Isaac Output Parameter: 7841bb7acecfSBarry Smith . cdm - The coarse `DM` 7842a8fb8f29SToby Isaac 7843a8fb8f29SToby Isaac Level: intermediate 7844a8fb8f29SToby Isaac 78451cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetCoarseDM()`, `DMCoarsen()` 7846a8fb8f29SToby Isaac @*/ 7847d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 7848d71ae5a4SJacob Faibussowitsch { 7849a8fb8f29SToby Isaac PetscFunctionBegin; 7850a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78514f572ea9SToby Isaac PetscAssertPointer(cdm, 2); 7852a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 78533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7854a8fb8f29SToby Isaac } 7855a8fb8f29SToby Isaac 7856a8fb8f29SToby Isaac /*@ 7857bb7acecfSBarry Smith DMSetCoarseDM - Set the coarse `DM` from which this `DM` was obtained by refinement 7858a8fb8f29SToby Isaac 7859a8fb8f29SToby Isaac Input Parameters: 7860bb7acecfSBarry Smith + dm - The `DM` object 7861bb7acecfSBarry Smith - cdm - The coarse `DM` 7862a8fb8f29SToby Isaac 7863a8fb8f29SToby Isaac Level: intermediate 7864a8fb8f29SToby Isaac 7865bb7acecfSBarry Smith Note: 7866bb7acecfSBarry Smith Normally this is set automatically by `DMRefine()` 7867bb7acecfSBarry Smith 78681cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCoarseDM()`, `DMCoarsen()`, `DMSetRefine()`, `DMSetFineDM()` 7869a8fb8f29SToby Isaac @*/ 7870d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 7871d71ae5a4SJacob Faibussowitsch { 7872a8fb8f29SToby Isaac PetscFunctionBegin; 7873a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7874a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 787589d734beSBarry Smith if (dm == cdm) cdm = NULL; 78769566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cdm)); 78779566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->coarseMesh)); 7878a8fb8f29SToby Isaac dm->coarseMesh = cdm; 78793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7880a8fb8f29SToby Isaac } 7881a8fb8f29SToby Isaac 788288bdff64SToby Isaac /*@ 7883bb7acecfSBarry Smith DMGetFineDM - Get the fine mesh from which this `DM` was obtained by coarsening 788488bdff64SToby Isaac 788588bdff64SToby Isaac Input Parameter: 7886bb7acecfSBarry Smith . dm - The `DM` object 788788bdff64SToby Isaac 788888bdff64SToby Isaac Output Parameter: 7889bb7acecfSBarry Smith . fdm - The fine `DM` 789088bdff64SToby Isaac 789188bdff64SToby Isaac Level: intermediate 789288bdff64SToby Isaac 78931cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetFineDM()`, `DMCoarsen()`, `DMRefine()` 789488bdff64SToby Isaac @*/ 7895d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 7896d71ae5a4SJacob Faibussowitsch { 789788bdff64SToby Isaac PetscFunctionBegin; 789888bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78994f572ea9SToby Isaac PetscAssertPointer(fdm, 2); 790088bdff64SToby Isaac *fdm = dm->fineMesh; 79013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 790288bdff64SToby Isaac } 790388bdff64SToby Isaac 790488bdff64SToby Isaac /*@ 7905bb7acecfSBarry Smith DMSetFineDM - Set the fine mesh from which this was obtained by coarsening 790688bdff64SToby Isaac 790788bdff64SToby Isaac Input Parameters: 7908bb7acecfSBarry Smith + dm - The `DM` object 7909bb7acecfSBarry Smith - fdm - The fine `DM` 791088bdff64SToby Isaac 7911bb7acecfSBarry Smith Level: developer 791288bdff64SToby Isaac 7913bb7acecfSBarry Smith Note: 7914bb7acecfSBarry Smith Normally this is set automatically by `DMCoarsen()` 7915bb7acecfSBarry Smith 79161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFineDM()`, `DMCoarsen()`, `DMRefine()` 791788bdff64SToby Isaac @*/ 7918d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFineDM(DM dm, DM fdm) 7919d71ae5a4SJacob Faibussowitsch { 792088bdff64SToby Isaac PetscFunctionBegin; 792188bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 792288bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 792389d734beSBarry Smith if (dm == fdm) fdm = NULL; 79249566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fdm)); 79259566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->fineMesh)); 792688bdff64SToby Isaac dm->fineMesh = fdm; 79273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 792888bdff64SToby Isaac } 792988bdff64SToby Isaac 7930a6ba4734SToby Isaac /*@C 7931bb7acecfSBarry Smith DMAddBoundary - Add a boundary condition to a model represented by a `DM` 7932a6ba4734SToby Isaac 793320f4b53cSBarry Smith Collective 7934783e2ec8SMatthew G. Knepley 7935a6ba4734SToby Isaac Input Parameters: 7936bb7acecfSBarry Smith + dm - The `DM`, with a `PetscDS` that matches the problem being constrained 7937bb7acecfSBarry Smith . type - The type of condition, e.g. `DM_BC_ESSENTIAL_ANALYTIC`, `DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann) 7938a6ba4734SToby Isaac . name - The BC name 793945480ffeSMatthew G. Knepley . label - The label defining constrained points 7940bb7acecfSBarry Smith . Nv - The number of `DMLabel` values for constrained points 794145480ffeSMatthew G. Knepley . values - An array of values for constrained points 7942a6ba4734SToby Isaac . field - The field to constrain 794345480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 7944a6ba4734SToby Isaac . comps - An array of constrained component numbers 7945a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 794656cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 7947a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 7948a6ba4734SToby Isaac 794945480ffeSMatthew G. Knepley Output Parameter: 795045480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 795145480ffeSMatthew G. Knepley 7952a6ba4734SToby Isaac Options Database Keys: 7953a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 7954a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 7955a6ba4734SToby Isaac 795620f4b53cSBarry Smith Level: intermediate 795720f4b53cSBarry Smith 7958bb7acecfSBarry Smith Notes: 7959fa74d514SMatthew G. Knepley If the `DM` is of type `DMPLEX` and the field is of type `PetscFE`, then this function completes the label using `DMPlexLabelComplete()`. 7960fa74d514SMatthew G. Knepley 7961aeebefc2SPierre 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\: 796273ff1848SBarry Smith .vb 796373ff1848SBarry Smith void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 796473ff1848SBarry Smith .ve 796556cf3b9cSMatthew G. Knepley 7966a4e35b19SJacob Faibussowitsch If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\: 796756cf3b9cSMatthew G. Knepley 796820f4b53cSBarry Smith .vb 796920f4b53cSBarry Smith void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 797020f4b53cSBarry Smith const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 797120f4b53cSBarry Smith const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 797220f4b53cSBarry Smith PetscReal time, const PetscReal x[], PetscScalar bcval[]) 797320f4b53cSBarry Smith .ve 797456cf3b9cSMatthew G. Knepley + dim - the spatial dimension 797556cf3b9cSMatthew G. Knepley . Nf - the number of fields 797656cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 797756cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 797856cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 797956cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 798056cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 798156cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 798256cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 798356cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 798456cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 798556cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 798656cf3b9cSMatthew G. Knepley . t - current time 798756cf3b9cSMatthew G. Knepley . x - coordinates of the current point 798856cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 798956cf3b9cSMatthew G. Knepley . constants - constant parameters 799056cf3b9cSMatthew G. Knepley - bcval - output values at the current point 799156cf3b9cSMatthew G. Knepley 79921cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DSGetBoundary()`, `PetscDSAddBoundary()` 7993a6ba4734SToby Isaac @*/ 7994d71ae5a4SJacob 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) 7995d71ae5a4SJacob Faibussowitsch { 7996e5e52638SMatthew G. Knepley PetscDS ds; 7997a6ba4734SToby Isaac 7998a6ba4734SToby Isaac PetscFunctionBegin; 7999a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8000783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 800145480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 800245480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 800345480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 800445480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 800501a5d20dSJed Brown PetscCheck(!dm->localSection, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot add boundary to DM after creating local section"); 80069566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 8007799db056SMatthew G. Knepley /* Complete label */ 8008799db056SMatthew G. Knepley if (label) { 8009799db056SMatthew G. Knepley PetscObject obj; 8010799db056SMatthew G. Knepley PetscClassId id; 8011799db056SMatthew G. Knepley 8012799db056SMatthew G. Knepley PetscCall(DMGetField(dm, field, NULL, &obj)); 8013799db056SMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 8014799db056SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 8015799db056SMatthew G. Knepley DM plex; 8016799db056SMatthew G. Knepley 8017799db056SMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 8018799db056SMatthew G. Knepley if (plex) PetscCall(DMPlexLabelComplete(plex, label)); 8019799db056SMatthew G. Knepley PetscCall(DMDestroy(&plex)); 8020799db056SMatthew G. Knepley } 8021799db056SMatthew G. Knepley } 80229566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd)); 80233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8024a6ba4734SToby Isaac } 8025a6ba4734SToby Isaac 802645480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 8027d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPopulateBoundary(DM dm) 8028d71ae5a4SJacob Faibussowitsch { 8029e5e52638SMatthew G. Knepley PetscDS ds; 8030dff059c6SToby Isaac DMBoundary *lastnext; 8031e6f8dbb6SToby Isaac DSBoundary dsbound; 8032e6f8dbb6SToby Isaac 8033e6f8dbb6SToby Isaac PetscFunctionBegin; 80349566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 8035e5e52638SMatthew G. Knepley dsbound = ds->boundary; 803647a1f5adSToby Isaac if (dm->boundary) { 803747a1f5adSToby Isaac DMBoundary next = dm->boundary; 803847a1f5adSToby Isaac 803947a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 80403ba16761SJacob Faibussowitsch if (next->dsboundary == dsbound) PetscFunctionReturn(PETSC_SUCCESS); 804147a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 804247a1f5adSToby Isaac while (next) { 804347a1f5adSToby Isaac DMBoundary b = next; 804447a1f5adSToby Isaac 804547a1f5adSToby Isaac next = b->next; 80469566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 8047a6ba4734SToby Isaac } 804847a1f5adSToby Isaac dm->boundary = NULL; 8049a6ba4734SToby Isaac } 805047a1f5adSToby Isaac 8051f4f49eeaSPierre Jolivet lastnext = &dm->boundary; 8052e6f8dbb6SToby Isaac while (dsbound) { 8053e6f8dbb6SToby Isaac DMBoundary dmbound; 8054e6f8dbb6SToby Isaac 80559566063dSJacob Faibussowitsch PetscCall(PetscNew(&dmbound)); 8056e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 805745480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 805847a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8059dff059c6SToby Isaac *lastnext = dmbound; 8060f4f49eeaSPierre Jolivet lastnext = &dmbound->next; 8061dff059c6SToby Isaac dsbound = dsbound->next; 8062a6ba4734SToby Isaac } 80633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8064a6ba4734SToby Isaac } 8065a6ba4734SToby Isaac 8066bb7acecfSBarry Smith /* TODO: missing manual page */ 8067d71ae5a4SJacob Faibussowitsch PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8068d71ae5a4SJacob Faibussowitsch { 8069b95f2879SToby Isaac DMBoundary b; 8070a6ba4734SToby Isaac 8071a6ba4734SToby Isaac PetscFunctionBegin; 8072a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 80734f572ea9SToby Isaac PetscAssertPointer(isBd, 3); 8074a6ba4734SToby Isaac *isBd = PETSC_FALSE; 80759566063dSJacob Faibussowitsch PetscCall(DMPopulateBoundary(dm)); 8076b95f2879SToby Isaac b = dm->boundary; 807757508eceSPierre Jolivet while (b && !*isBd) { 8078e6f8dbb6SToby Isaac DMLabel label = b->label; 8079e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 8080a6ba4734SToby Isaac PetscInt i; 8081a6ba4734SToby Isaac 808245480ffeSMatthew G. Knepley if (label) { 808357508eceSPierre Jolivet for (i = 0; i < dsb->Nv && !*isBd; ++i) PetscCall(DMLabelStratumHasPoint(label, dsb->values[i], point, isBd)); 8084a6ba4734SToby Isaac } 8085a6ba4734SToby Isaac b = b->next; 8086a6ba4734SToby Isaac } 80873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8088a6ba4734SToby Isaac } 80894d6f44ffSToby Isaac 80904d6f44ffSToby Isaac /*@C 8091bb7acecfSBarry Smith DMProjectFunction - This projects the given function into the function space provided by a `DM`, putting the coefficients in a global vector. 8092a6e0b375SMatthew G. Knepley 809320f4b53cSBarry Smith Collective 80944d6f44ffSToby Isaac 80954d6f44ffSToby Isaac Input Parameters: 8096bb7acecfSBarry Smith + dm - The `DM` 80970709b2feSToby Isaac . time - The time 80984d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 80994d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 81004d6f44ffSToby Isaac - mode - The insertion mode for values 81014d6f44ffSToby Isaac 81024d6f44ffSToby Isaac Output Parameter: 81034d6f44ffSToby Isaac . X - vector 81044d6f44ffSToby Isaac 810520f4b53cSBarry Smith Calling sequence of `funcs`: 81064d6f44ffSToby Isaac + dim - The spatial dimension 81078ec8862eSJed Brown . time - The time at which to sample 81084d6f44ffSToby Isaac . x - The coordinates 810977b739a6SMatthew Knepley . Nc - The number of components 81104d6f44ffSToby Isaac . u - The output field values 81114d6f44ffSToby Isaac - ctx - optional user-defined function context 81124d6f44ffSToby Isaac 81134d6f44ffSToby Isaac Level: developer 81144d6f44ffSToby Isaac 8115bb7acecfSBarry Smith Developer Notes: 8116bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8117bb7acecfSBarry Smith 8118bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8119bb7acecfSBarry Smith 81201cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 81214d6f44ffSToby Isaac @*/ 8122a4e35b19SJacob 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) 8123d71ae5a4SJacob Faibussowitsch { 81244d6f44ffSToby Isaac Vec localX; 81254d6f44ffSToby Isaac 81264d6f44ffSToby Isaac PetscFunctionBegin; 81274d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8128708be2fdSJed Brown PetscCall(PetscLogEventBegin(DM_ProjectFunction, dm, X, 0, 0)); 81299566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8130f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 81319566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX)); 81329566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 81339566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 81349566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 8135708be2fdSJed Brown PetscCall(PetscLogEventEnd(DM_ProjectFunction, dm, X, 0, 0)); 81363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81374d6f44ffSToby Isaac } 81384d6f44ffSToby Isaac 8139a6e0b375SMatthew G. Knepley /*@C 8140bb7acecfSBarry Smith DMProjectFunctionLocal - This projects the given function into the function space provided by a `DM`, putting the coefficients in a local vector. 8141a6e0b375SMatthew G. Knepley 814220f4b53cSBarry Smith Not Collective 8143a6e0b375SMatthew G. Knepley 8144a6e0b375SMatthew G. Knepley Input Parameters: 8145bb7acecfSBarry Smith + dm - The `DM` 8146a6e0b375SMatthew G. Knepley . time - The time 8147a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8148a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8149a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8150a6e0b375SMatthew G. Knepley 8151a6e0b375SMatthew G. Knepley Output Parameter: 8152a6e0b375SMatthew G. Knepley . localX - vector 8153a6e0b375SMatthew G. Knepley 815420f4b53cSBarry Smith Calling sequence of `funcs`: 8155a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8156a4e35b19SJacob Faibussowitsch . time - The current timestep 8157a6e0b375SMatthew G. Knepley . x - The coordinates 815877b739a6SMatthew Knepley . Nc - The number of components 8159a6e0b375SMatthew G. Knepley . u - The output field values 8160a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8161a6e0b375SMatthew G. Knepley 8162a6e0b375SMatthew G. Knepley Level: developer 8163a6e0b375SMatthew G. Knepley 8164bb7acecfSBarry Smith Developer Notes: 8165bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8166bb7acecfSBarry Smith 8167bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8168bb7acecfSBarry Smith 81691cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8170a6e0b375SMatthew G. Knepley @*/ 8171a4e35b19SJacob 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) 8172d71ae5a4SJacob Faibussowitsch { 81734d6f44ffSToby Isaac PetscFunctionBegin; 81744d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8175064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 8176fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfunctionlocal, time, funcs, ctxs, mode, localX); 81773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81784d6f44ffSToby Isaac } 81794d6f44ffSToby Isaac 8180a6e0b375SMatthew G. Knepley /*@C 8181bb7acecfSBarry 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. 8182a6e0b375SMatthew G. Knepley 818320f4b53cSBarry Smith Collective 8184a6e0b375SMatthew G. Knepley 8185a6e0b375SMatthew G. Knepley Input Parameters: 8186bb7acecfSBarry Smith + dm - The `DM` 8187a6e0b375SMatthew G. Knepley . time - The time 8188a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8189a4e35b19SJacob Faibussowitsch . ids - The ids 8190a4e35b19SJacob Faibussowitsch . Nc - The number of components 8191a4e35b19SJacob Faibussowitsch . comps - The components 8192bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8193a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8194bb7acecfSBarry Smith . ctxs - Optional array of contexts to pass to each coordinate function. ctxs may be null. 8195a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8196a6e0b375SMatthew G. Knepley 8197a6e0b375SMatthew G. Knepley Output Parameter: 8198a6e0b375SMatthew G. Knepley . X - vector 8199a6e0b375SMatthew G. Knepley 820020f4b53cSBarry Smith Calling sequence of `funcs`: 8201a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8202a4e35b19SJacob Faibussowitsch . time - The current timestep 8203a6e0b375SMatthew G. Knepley . x - The coordinates 820477b739a6SMatthew Knepley . Nc - The number of components 8205a6e0b375SMatthew G. Knepley . u - The output field values 8206a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8207a6e0b375SMatthew G. Knepley 8208a6e0b375SMatthew G. Knepley Level: developer 8209a6e0b375SMatthew G. Knepley 8210bb7acecfSBarry Smith Developer Notes: 8211bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8212bb7acecfSBarry Smith 8213bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8214bb7acecfSBarry Smith 82151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabelLocal()`, `DMComputeL2Diff()` 8216a6e0b375SMatthew G. Knepley @*/ 8217a4e35b19SJacob 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) 8218d71ae5a4SJacob Faibussowitsch { 82192c53366bSMatthew G. Knepley Vec localX; 82202c53366bSMatthew G. Knepley 82212c53366bSMatthew G. Knepley PetscFunctionBegin; 82222c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 82239566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8224f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 82259566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 82269566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 82279566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 82289566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 82293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82302c53366bSMatthew G. Knepley } 82312c53366bSMatthew G. Knepley 8232a6e0b375SMatthew G. Knepley /*@C 8233bb7acecfSBarry 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. 8234a6e0b375SMatthew G. Knepley 823520f4b53cSBarry Smith Not Collective 8236a6e0b375SMatthew G. Knepley 8237a6e0b375SMatthew G. Knepley Input Parameters: 8238bb7acecfSBarry Smith + dm - The `DM` 8239a6e0b375SMatthew G. Knepley . time - The time 8240bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8241a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8242a4e35b19SJacob Faibussowitsch . ids - The ids 8243a4e35b19SJacob Faibussowitsch . Nc - The number of components 8244a4e35b19SJacob Faibussowitsch . comps - The components 8245a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8246a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8247a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8248a6e0b375SMatthew G. Knepley 8249a6e0b375SMatthew G. Knepley Output Parameter: 8250a6e0b375SMatthew G. Knepley . localX - vector 8251a6e0b375SMatthew G. Knepley 825220f4b53cSBarry Smith Calling sequence of `funcs`: 8253a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8254a4e35b19SJacob Faibussowitsch . time - The current time 8255a6e0b375SMatthew G. Knepley . x - The coordinates 825677b739a6SMatthew Knepley . Nc - The number of components 8257a6e0b375SMatthew G. Knepley . u - The output field values 8258a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8259a6e0b375SMatthew G. Knepley 8260a6e0b375SMatthew G. Knepley Level: developer 8261a6e0b375SMatthew G. Knepley 8262bb7acecfSBarry Smith Developer Notes: 8263bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8264bb7acecfSBarry Smith 8265bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8266bb7acecfSBarry Smith 82671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8268a6e0b375SMatthew G. Knepley @*/ 8269a4e35b19SJacob 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) 8270d71ae5a4SJacob Faibussowitsch { 82714d6f44ffSToby Isaac PetscFunctionBegin; 82724d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8273064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8274fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfunctionlabellocal, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX); 82753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82764d6f44ffSToby Isaac } 82772716604bSToby Isaac 8278a6e0b375SMatthew G. Knepley /*@C 8279bb7acecfSBarry 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. 8280a6e0b375SMatthew G. Knepley 828120f4b53cSBarry Smith Not Collective 8282a6e0b375SMatthew G. Knepley 8283a6e0b375SMatthew G. Knepley Input Parameters: 8284bb7acecfSBarry Smith + dm - The `DM` 8285a6e0b375SMatthew G. Knepley . time - The time 828620f4b53cSBarry Smith . localU - The input field vector; may be `NULL` if projection is defined purely by coordinates 8287a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8288a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8289a6e0b375SMatthew G. Knepley 8290a6e0b375SMatthew G. Knepley Output Parameter: 8291a6e0b375SMatthew G. Knepley . localX - The output vector 8292a6e0b375SMatthew G. Knepley 829320f4b53cSBarry Smith Calling sequence of `funcs`: 8294a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8295a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8296a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8297a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8298a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8299a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8300a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8301a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8302a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8303a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8304a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8305a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8306a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8307a6e0b375SMatthew G. Knepley . t - The current time 8308a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8309a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8310a6e0b375SMatthew G. Knepley . constants - The value of each constant 8311a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8312a6e0b375SMatthew G. Knepley 831373ff1848SBarry Smith Level: intermediate 831473ff1848SBarry Smith 8315bb7acecfSBarry Smith Note: 8316bb7acecfSBarry 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. 8317bb7acecfSBarry 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 8318bb7acecfSBarry 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 8319a6e0b375SMatthew 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. 8320a6e0b375SMatthew G. Knepley 8321bb7acecfSBarry Smith Developer Notes: 8322bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8323bb7acecfSBarry Smith 8324bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8325bb7acecfSBarry Smith 8326a4e35b19SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, 8327a4e35b19SJacob Faibussowitsch `DMProjectFunction()`, `DMComputeL2Diff()` 8328a6e0b375SMatthew G. Knepley @*/ 8329a4e35b19SJacob 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) 8330d71ae5a4SJacob Faibussowitsch { 83318c6c5593SMatthew G. Knepley PetscFunctionBegin; 83328c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8333eb8f539aSJed Brown if (localU) PetscValidHeaderSpecific(localU, VEC_CLASSID, 3); 83348c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 8335fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfieldlocal, time, localU, funcs, mode, localX); 83363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83378c6c5593SMatthew G. Knepley } 83388c6c5593SMatthew G. Knepley 8339a6e0b375SMatthew G. Knepley /*@C 8340a6e0b375SMatthew 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. 8341a6e0b375SMatthew G. Knepley 834220f4b53cSBarry Smith Not Collective 8343a6e0b375SMatthew G. Knepley 8344a6e0b375SMatthew G. Knepley Input Parameters: 8345bb7acecfSBarry Smith + dm - The `DM` 8346a6e0b375SMatthew G. Knepley . time - The time 8347bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8348a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8349a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8350bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 835120f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8352a6e0b375SMatthew G. Knepley . localU - The input field vector 8353a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8354a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8355a6e0b375SMatthew G. Knepley 8356a6e0b375SMatthew G. Knepley Output Parameter: 8357a6e0b375SMatthew G. Knepley . localX - The output vector 8358a6e0b375SMatthew G. Knepley 835920f4b53cSBarry Smith Calling sequence of `funcs`: 8360a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8361a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8362a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8363a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8364a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8365a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8366a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8367a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8368a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8369a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8370a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8371a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8372a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8373a6e0b375SMatthew G. Knepley . t - The current time 8374a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8375a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8376a6e0b375SMatthew G. Knepley . constants - The value of each constant 8377a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8378a6e0b375SMatthew G. Knepley 837973ff1848SBarry Smith Level: intermediate 838073ff1848SBarry Smith 8381bb7acecfSBarry Smith Note: 8382bb7acecfSBarry 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. 8383bb7acecfSBarry 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 8384bb7acecfSBarry 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 8385a6e0b375SMatthew 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. 8386a6e0b375SMatthew G. Knepley 8387bb7acecfSBarry Smith Developer Notes: 8388bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8389bb7acecfSBarry Smith 8390bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8391bb7acecfSBarry Smith 83921cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabel()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8393a6e0b375SMatthew G. Knepley @*/ 8394a4e35b19SJacob 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) 8395d71ae5a4SJacob Faibussowitsch { 83968c6c5593SMatthew G. Knepley PetscFunctionBegin; 83978c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8398064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8399064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8400fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfieldlabellocal, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX); 84013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 84028c6c5593SMatthew G. Knepley } 84038c6c5593SMatthew G. Knepley 84042716604bSToby Isaac /*@C 8405d29d7c6eSMatthew 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. 8406d29d7c6eSMatthew G. Knepley 840720f4b53cSBarry Smith Not Collective 8408d29d7c6eSMatthew G. Knepley 8409d29d7c6eSMatthew G. Knepley Input Parameters: 8410bb7acecfSBarry Smith + dm - The `DM` 8411d29d7c6eSMatthew G. Knepley . time - The time 8412bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8413d29d7c6eSMatthew G. Knepley . numIds - The number of label ids to use 8414d29d7c6eSMatthew G. Knepley . ids - The label ids to use for marking 8415bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 841620f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8417d29d7c6eSMatthew G. Knepley . U - The input field vector 8418d29d7c6eSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8419d29d7c6eSMatthew G. Knepley - mode - The insertion mode for values 8420d29d7c6eSMatthew G. Knepley 8421d29d7c6eSMatthew G. Knepley Output Parameter: 8422d29d7c6eSMatthew G. Knepley . X - The output vector 8423d29d7c6eSMatthew G. Knepley 842420f4b53cSBarry Smith Calling sequence of `funcs`: 8425d29d7c6eSMatthew G. Knepley + dim - The spatial dimension 8426d29d7c6eSMatthew G. Knepley . Nf - The number of input fields 8427d29d7c6eSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8428d29d7c6eSMatthew G. Knepley . uOff - The offset of each field in u[] 8429d29d7c6eSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8430d29d7c6eSMatthew G. Knepley . u - The field values at this point in space 8431d29d7c6eSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8432d29d7c6eSMatthew G. Knepley . u_x - The field derivatives at this point in space 8433d29d7c6eSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8434d29d7c6eSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8435d29d7c6eSMatthew G. Knepley . a - The auxiliary field values at this point in space 8436d29d7c6eSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8437d29d7c6eSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8438d29d7c6eSMatthew G. Knepley . t - The current time 8439d29d7c6eSMatthew G. Knepley . x - The coordinates of this point 8440d29d7c6eSMatthew G. Knepley . numConstants - The number of constants 8441d29d7c6eSMatthew G. Knepley . constants - The value of each constant 8442d29d7c6eSMatthew G. Knepley - f - The value of the function at this point in space 8443d29d7c6eSMatthew G. Knepley 844473ff1848SBarry Smith Level: intermediate 844573ff1848SBarry Smith 8446bb7acecfSBarry Smith Note: 8447bb7acecfSBarry 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. 8448bb7acecfSBarry 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 8449bb7acecfSBarry 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 8450d29d7c6eSMatthew 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. 8451d29d7c6eSMatthew G. Knepley 8452bb7acecfSBarry Smith Developer Notes: 8453bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8454bb7acecfSBarry Smith 8455bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8456bb7acecfSBarry Smith 84571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8458d29d7c6eSMatthew G. Knepley @*/ 8459a4e35b19SJacob 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) 8460d71ae5a4SJacob Faibussowitsch { 8461d29d7c6eSMatthew G. Knepley DM dmIn; 8462d29d7c6eSMatthew G. Knepley Vec localU, localX; 8463d29d7c6eSMatthew G. Knepley 8464d29d7c6eSMatthew G. Knepley PetscFunctionBegin; 8465d29d7c6eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8466d29d7c6eSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn)); 8467d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dmIn, &localU)); 8468d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &localX)); 8469f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 847072fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dmIn, U, mode, localU)); 847172fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dmIn, U, mode, localU)); 8472d29d7c6eSMatthew G. Knepley PetscCall(DMProjectFieldLabelLocal(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8473d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 8474d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 8475d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &localX)); 8476d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dmIn, &localU)); 84773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8478d29d7c6eSMatthew G. Knepley } 8479d29d7c6eSMatthew G. Knepley 8480d29d7c6eSMatthew G. Knepley /*@C 8481ece3a9fcSMatthew 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. 8482ece3a9fcSMatthew G. Knepley 848320f4b53cSBarry Smith Not Collective 8484ece3a9fcSMatthew G. Knepley 8485ece3a9fcSMatthew G. Knepley Input Parameters: 8486bb7acecfSBarry Smith + dm - The `DM` 8487ece3a9fcSMatthew G. Knepley . time - The time 8488bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain boundary to output 8489ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8490ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8491bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 849220f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8493ece3a9fcSMatthew G. Knepley . localU - The input field vector 8494ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8495ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8496ece3a9fcSMatthew G. Knepley 8497ece3a9fcSMatthew G. Knepley Output Parameter: 8498ece3a9fcSMatthew G. Knepley . localX - The output vector 8499ece3a9fcSMatthew G. Knepley 850020f4b53cSBarry Smith Calling sequence of `funcs`: 8501ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8502ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8503ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8504ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8505ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8506ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8507ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8508ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8509ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8510ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8511ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8512ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8513ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8514ece3a9fcSMatthew G. Knepley . t - The current time 8515ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8516ece3a9fcSMatthew G. Knepley . n - The face normal 8517ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8518ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8519ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8520ece3a9fcSMatthew G. Knepley 852173ff1848SBarry Smith Level: intermediate 852273ff1848SBarry Smith 8523ece3a9fcSMatthew G. Knepley Note: 8524bb7acecfSBarry 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. 8525bb7acecfSBarry 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 8526bb7acecfSBarry 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 8527ece3a9fcSMatthew 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. 8528ece3a9fcSMatthew G. Knepley 8529bb7acecfSBarry Smith Developer Notes: 8530bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8531bb7acecfSBarry Smith 8532bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8533bb7acecfSBarry Smith 85341cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8535ece3a9fcSMatthew G. Knepley @*/ 8536a4e35b19SJacob 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) 8537d71ae5a4SJacob Faibussowitsch { 8538ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8539ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8540064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8541064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8542fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectbdfieldlabellocal, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX); 85433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8544ece3a9fcSMatthew G. Knepley } 8545ece3a9fcSMatthew G. Knepley 8546ece3a9fcSMatthew G. Knepley /*@C 85472716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 85482716604bSToby Isaac 854920f4b53cSBarry Smith Collective 8550bb7acecfSBarry Smith 85512716604bSToby Isaac Input Parameters: 8552bb7acecfSBarry Smith + dm - The `DM` 85530709b2feSToby Isaac . time - The time 85542716604bSToby Isaac . funcs - The functions to evaluate for each field component 85552716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8556574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 85572716604bSToby Isaac 85582716604bSToby Isaac Output Parameter: 85592716604bSToby Isaac . diff - The diff ||u - u_h||_2 85602716604bSToby Isaac 85612716604bSToby Isaac Level: developer 85622716604bSToby Isaac 8563bb7acecfSBarry Smith Developer Notes: 8564bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8565bb7acecfSBarry Smith 8566bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8567bb7acecfSBarry Smith 85681cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 85692716604bSToby Isaac @*/ 8570d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 8571d71ae5a4SJacob Faibussowitsch { 85722716604bSToby Isaac PetscFunctionBegin; 85732716604bSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8574b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8575fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2diff, time, funcs, ctxs, X, diff); 85763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85772716604bSToby Isaac } 8578b698f381SToby Isaac 8579b698f381SToby Isaac /*@C 8580b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8581b698f381SToby Isaac 858220f4b53cSBarry Smith Collective 8583d083f849SBarry Smith 8584b698f381SToby Isaac Input Parameters: 8585bb7acecfSBarry Smith + dm - The `DM` 8586a4e35b19SJacob Faibussowitsch . time - The time 8587b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8588b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8589574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8590b698f381SToby Isaac - n - The vector to project along 8591b698f381SToby Isaac 8592b698f381SToby Isaac Output Parameter: 8593b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8594b698f381SToby Isaac 8595b698f381SToby Isaac Level: developer 8596b698f381SToby Isaac 8597bb7acecfSBarry Smith Developer Notes: 8598bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8599bb7acecfSBarry Smith 8600bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8601bb7acecfSBarry Smith 86021cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2Diff()`, `DMComputeL2FieldDiff()` 8603b698f381SToby Isaac @*/ 8604d71ae5a4SJacob 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) 8605d71ae5a4SJacob Faibussowitsch { 8606b698f381SToby Isaac PetscFunctionBegin; 8607b698f381SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8608b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8609fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2gradientdiff, time, funcs, ctxs, X, n, diff); 86103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8611b698f381SToby Isaac } 8612b698f381SToby Isaac 86132a16baeaSToby Isaac /*@C 86142a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 86152a16baeaSToby Isaac 861620f4b53cSBarry Smith Collective 8617d083f849SBarry Smith 86182a16baeaSToby Isaac Input Parameters: 8619bb7acecfSBarry Smith + dm - The `DM` 86202a16baeaSToby Isaac . time - The time 86212a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 86222a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8623574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 86242a16baeaSToby Isaac 86252a16baeaSToby Isaac Output Parameter: 86262a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 86272a16baeaSToby Isaac 86282a16baeaSToby Isaac Level: developer 86292a16baeaSToby Isaac 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 863542747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2GradientDiff()` 86362a16baeaSToby Isaac @*/ 8637d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 8638d71ae5a4SJacob Faibussowitsch { 86392a16baeaSToby Isaac PetscFunctionBegin; 86402a16baeaSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 86412a16baeaSToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8642fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2fielddiff, time, funcs, ctxs, X, diff); 86433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86442a16baeaSToby Isaac } 86452a16baeaSToby Isaac 8646df0b854cSToby Isaac /*@C 8647bb7acecfSBarry Smith DMGetNeighbors - Gets an array containing the MPI ranks of all the processes neighbors 8648502a2867SDave May 8649502a2867SDave May Not Collective 8650502a2867SDave May 8651502a2867SDave May Input Parameter: 8652bb7acecfSBarry Smith . dm - The `DM` 8653502a2867SDave May 86540a19bb7dSprj- Output Parameters: 86550a19bb7dSprj- + nranks - the number of neighbours 86560a19bb7dSprj- - ranks - the neighbors ranks 8657502a2867SDave May 86589bdbcad8SBarry Smith Level: beginner 86599bdbcad8SBarry Smith 8660bb7acecfSBarry Smith Note: 8661bb7acecfSBarry Smith Do not free the array, it is freed when the `DM` is destroyed. 8662502a2867SDave May 86631cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDAGetNeighbors()`, `PetscSFGetRootRanks()` 8664502a2867SDave May @*/ 8665d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNeighbors(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 8666d71ae5a4SJacob Faibussowitsch { 8667502a2867SDave May PetscFunctionBegin; 8668502a2867SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8669fa1e479aSStefano Zampini PetscUseTypeMethod(dm, getneighbors, nranks, ranks); 86703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8671502a2867SDave May } 8672502a2867SDave May 8673531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 8674531c7667SBarry Smith 8675531c7667SBarry Smith /* 8676531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 86772b6f951bSStefano Zampini This must be a different function because it requires DM which is not defined in the Mat library 8678531c7667SBarry Smith */ 867966976f2fSJacob Faibussowitsch static PetscErrorCode MatFDColoringApply_AIJDM(Mat J, MatFDColoring coloring, Vec x1, void *sctx) 8680d71ae5a4SJacob Faibussowitsch { 8681531c7667SBarry Smith PetscFunctionBegin; 8682531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8683531c7667SBarry Smith Vec x1local; 8684531c7667SBarry Smith DM dm; 86859566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 86867a8be351SBarry Smith PetscCheck(dm, PetscObjectComm((PetscObject)J), PETSC_ERR_ARG_INCOMP, "IS_COLORING_LOCAL requires a DM"); 86879566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &x1local)); 86889566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, x1, INSERT_VALUES, x1local)); 86899566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, x1, INSERT_VALUES, x1local)); 8690531c7667SBarry Smith x1 = x1local; 8691531c7667SBarry Smith } 86929566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply_AIJ(J, coloring, x1, sctx)); 8693531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8694531c7667SBarry Smith DM dm; 86959566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 86969566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &x1)); 8697531c7667SBarry Smith } 86983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8699531c7667SBarry Smith } 8700531c7667SBarry Smith 8701531c7667SBarry Smith /*@ 8702bb7acecfSBarry Smith MatFDColoringUseDM - allows a `MatFDColoring` object to use the `DM` associated with the matrix to compute a `IS_COLORING_LOCAL` coloring 8703531c7667SBarry Smith 8704a4e35b19SJacob Faibussowitsch Input Parameters: 8705a4e35b19SJacob Faibussowitsch + coloring - The matrix to get the `DM` from 8706a4e35b19SJacob Faibussowitsch - fdcoloring - the `MatFDColoring` object 8707531c7667SBarry Smith 87089bdbcad8SBarry Smith Level: advanced 87099bdbcad8SBarry Smith 871073ff1848SBarry Smith Developer Note: 871173ff1848SBarry Smith This routine exists because the PETSc `Mat` library does not know about the `DM` objects 8712531c7667SBarry Smith 87131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatFDColoring`, `MatFDColoringCreate()`, `ISColoringType` 8714531c7667SBarry Smith @*/ 8715d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringUseDM(Mat coloring, MatFDColoring fdcoloring) 8716d71ae5a4SJacob Faibussowitsch { 8717531c7667SBarry Smith PetscFunctionBegin; 8718531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 87193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8720531c7667SBarry Smith } 87218320bc6fSPatrick Sanan 87228320bc6fSPatrick Sanan /*@ 8723bb7acecfSBarry Smith DMGetCompatibility - determine if two `DM`s are compatible 87248320bc6fSPatrick Sanan 87258320bc6fSPatrick Sanan Collective 87268320bc6fSPatrick Sanan 87278320bc6fSPatrick Sanan Input Parameters: 8728bb7acecfSBarry Smith + dm1 - the first `DM` 8729bb7acecfSBarry Smith - dm2 - the second `DM` 87308320bc6fSPatrick Sanan 87318320bc6fSPatrick Sanan Output Parameters: 8732bb7acecfSBarry Smith + compatible - whether or not the two `DM`s are compatible 8733bb7acecfSBarry Smith - set - whether or not the compatible value was actually determined and set 87348320bc6fSPatrick Sanan 873520f4b53cSBarry Smith Level: advanced 873620f4b53cSBarry Smith 87378320bc6fSPatrick Sanan Notes: 8738bb7acecfSBarry Smith Two `DM`s are deemed compatible if they represent the same parallel decomposition 87393d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 87408320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 8741bb7acecfSBarry Smith Loosely speaking, compatible `DM`s represent the same domain and parallel 87423d862458SPatrick Sanan decomposition, but hold different data. 87438320bc6fSPatrick Sanan 87448320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 8745bb7acecfSBarry Smith over a pair of vectors obtained from different `DM`s. 87468320bc6fSPatrick Sanan 8747bb7acecfSBarry Smith For example, two `DMDA` objects are compatible if they have the same local 87488320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 87498320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 8750bb7acecfSBarry Smith either `DM` in bounds for a loop over vectors derived from either `DM`. 87518320bc6fSPatrick Sanan 8752bb7acecfSBarry Smith Consider the operation of summing data living on a 2-dof `DMDA` to data living 8753bb7acecfSBarry Smith on a 1-dof `DMDA`, which should be compatible, as in the following snippet. 87548320bc6fSPatrick Sanan .vb 87558320bc6fSPatrick Sanan ... 87569566063dSJacob Faibussowitsch PetscCall(DMGetCompatibility(da1,da2,&compatible,&set)); 87578320bc6fSPatrick Sanan if (set && compatible) { 87589566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1)); 87599566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2)); 87609566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL)); 87618320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 87628320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 87638320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 87648320bc6fSPatrick Sanan } 87658320bc6fSPatrick Sanan } 87669566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1)); 87679566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2)); 87688320bc6fSPatrick Sanan } else { 87698320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 87708320bc6fSPatrick Sanan } 87718320bc6fSPatrick Sanan ... 87728320bc6fSPatrick Sanan .ve 87738320bc6fSPatrick Sanan 8774bb7acecfSBarry Smith Checking compatibility might be expensive for a given implementation of `DM`, 87758320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 87768320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 87778320bc6fSPatrick Sanan always check the "set" output parameter. 87788320bc6fSPatrick Sanan 8779bb7acecfSBarry Smith A `DM` is always compatible with itself. 87808320bc6fSPatrick Sanan 8781bb7acecfSBarry Smith In the current implementation, `DM`s which live on "unequal" communicators 87828320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 87838320bc6fSPatrick Sanan incompatible. 87848320bc6fSPatrick Sanan 87858320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 8786bb7acecfSBarry Smith is required on each rank. However, in `DM` implementations which store all this 87878320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 87888320bc6fSPatrick Sanan 878973ff1848SBarry Smith Developer Note: 8790bb7acecfSBarry Smith Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B 87913d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 8792a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 8793bb7acecfSBarry Smith compatibility. It is left to `DM` implementers to ensure that symmetry is 87948320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 87953d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 8796bb7acecfSBarry Smith of other `DM` types and let *set = PETSC_FALSE if found. 87978320bc6fSPatrick Sanan 87981cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()` 87998320bc6fSPatrick Sanan @*/ 8800d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCompatibility(DM dm1, DM dm2, PetscBool *compatible, PetscBool *set) 8801d71ae5a4SJacob Faibussowitsch { 88028320bc6fSPatrick Sanan PetscMPIInt compareResult; 88038320bc6fSPatrick Sanan DMType type, type2; 88048320bc6fSPatrick Sanan PetscBool sameType; 88058320bc6fSPatrick Sanan 88068320bc6fSPatrick Sanan PetscFunctionBegin; 8807a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 88088320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 88098320bc6fSPatrick Sanan 88108320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 8811a5bc1bf3SBarry Smith if (dm1 == dm2) { 88128320bc6fSPatrick Sanan *set = PETSC_TRUE; 88138320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 88143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 88158320bc6fSPatrick Sanan } 88168320bc6fSPatrick Sanan 88178320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 88188320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 88198320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 88208320bc6fSPatrick Sanan determined by the implementation-specific logic */ 88219566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)dm1), PetscObjectComm((PetscObject)dm2), &compareResult)); 88228320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 88238320bc6fSPatrick Sanan *set = PETSC_TRUE; 88248320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 88253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 88268320bc6fSPatrick Sanan } 88278320bc6fSPatrick Sanan 88288320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 8829a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 8830dbbe0bcdSBarry Smith PetscUseTypeMethod(dm1, getcompatibility, dm2, compatible, set); 88313ba16761SJacob Faibussowitsch if (*set) PetscFunctionReturn(PETSC_SUCCESS); 88328320bc6fSPatrick Sanan } 88338320bc6fSPatrick Sanan 8834a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 88358320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 88369566063dSJacob Faibussowitsch PetscCall(DMGetType(dm1, &type)); 88379566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2, &type2)); 88389566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, type2, &sameType)); 88398320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 8840dbbe0bcdSBarry Smith PetscUseTypeMethod(dm2, getcompatibility, dm1, compatible, set); /* Note argument order */ 88418320bc6fSPatrick Sanan } else { 88428320bc6fSPatrick Sanan *set = PETSC_FALSE; 88438320bc6fSPatrick Sanan } 88443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 88458320bc6fSPatrick Sanan } 8846c0f0dcc3SMatthew G. Knepley 8847c0f0dcc3SMatthew G. Knepley /*@C 8848bb7acecfSBarry Smith DMMonitorSet - Sets an additional monitor function that is to be used after a solve to monitor discretization performance. 8849c0f0dcc3SMatthew G. Knepley 885020f4b53cSBarry Smith Logically Collective 8851c0f0dcc3SMatthew G. Knepley 8852c0f0dcc3SMatthew G. Knepley Input Parameters: 885360225df5SJacob Faibussowitsch + dm - the `DM` 8854c0f0dcc3SMatthew G. Knepley . f - the monitor function 885520f4b53cSBarry Smith . mctx - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired) 885649abdd8aSBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`), see `PetscCtxDestroyFn` for the calling sequence 8857c0f0dcc3SMatthew G. Knepley 885820f4b53cSBarry Smith Options Database Key: 885960225df5SJacob Faibussowitsch . -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `DMMonitorSet()`, but 8860c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 8861c0f0dcc3SMatthew G. Knepley 88629bdbcad8SBarry Smith Level: intermediate 88639bdbcad8SBarry Smith 8864bb7acecfSBarry Smith Note: 8865c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 8866bb7acecfSBarry Smith `DMMonitorSet()` multiple times or with `DMMonitorSetFromOptions()`; all will be called in the 8867c0f0dcc3SMatthew G. Knepley order in which they were set. 8868c0f0dcc3SMatthew G. Knepley 886973ff1848SBarry Smith Fortran Note: 8870bb7acecfSBarry Smith Only a single monitor function can be set for each `DM` object 8871bb7acecfSBarry Smith 887273ff1848SBarry Smith Developer Note: 8873bb7acecfSBarry Smith This API has a generic name but seems specific to a very particular aspect of the use of `DM` 8874c0f0dcc3SMatthew G. Knepley 887549abdd8aSBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorCancel()`, `DMMonitorSetFromOptions()`, `DMMonitor()`, `PetscCtxDestroyFn` 8876c0f0dcc3SMatthew G. Knepley @*/ 887749abdd8aSBarry Smith PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscCtxDestroyFn *monitordestroy) 8878d71ae5a4SJacob Faibussowitsch { 8879c0f0dcc3SMatthew G. Knepley PetscInt m; 8880c0f0dcc3SMatthew G. Knepley 8881c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8882c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8883c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 8884c0f0dcc3SMatthew G. Knepley PetscBool identical; 8885c0f0dcc3SMatthew G. Knepley 88869566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f, mctx, monitordestroy, (PetscErrorCode (*)(void))dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical)); 88873ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 8888c0f0dcc3SMatthew G. Knepley } 88897a8be351SBarry Smith PetscCheck(dm->numbermonitors < MAXDMMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 8890c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 8891c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 8892835f2295SStefano Zampini dm->monitorcontext[dm->numbermonitors++] = mctx; 88933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8894c0f0dcc3SMatthew G. Knepley } 8895c0f0dcc3SMatthew G. Knepley 8896c0f0dcc3SMatthew G. Knepley /*@ 8897bb7acecfSBarry Smith DMMonitorCancel - Clears all the monitor functions for a `DM` object. 8898c0f0dcc3SMatthew G. Knepley 889920f4b53cSBarry Smith Logically Collective 8900c0f0dcc3SMatthew G. Knepley 8901c0f0dcc3SMatthew G. Knepley Input Parameter: 8902c0f0dcc3SMatthew G. Knepley . dm - the DM 8903c0f0dcc3SMatthew G. Knepley 8904c0f0dcc3SMatthew G. Knepley Options Database Key: 8905c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 8906bb7acecfSBarry Smith into a code by calls to `DMonitorSet()`, but does not cancel those 8907c0f0dcc3SMatthew G. Knepley set via the options database 8908c0f0dcc3SMatthew G. Knepley 89099bdbcad8SBarry Smith Level: intermediate 89109bdbcad8SBarry Smith 8911bb7acecfSBarry Smith Note: 8912bb7acecfSBarry Smith There is no way to clear one specific monitor from a `DM` object. 8913c0f0dcc3SMatthew G. Knepley 89141cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8915c0f0dcc3SMatthew G. Knepley @*/ 8916d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorCancel(DM dm) 8917d71ae5a4SJacob Faibussowitsch { 8918c0f0dcc3SMatthew G. Knepley PetscInt m; 8919c0f0dcc3SMatthew G. Knepley 8920c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8921c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8922c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 89239566063dSJacob Faibussowitsch if (dm->monitordestroy[m]) PetscCall((*dm->monitordestroy[m])(&dm->monitorcontext[m])); 8924c0f0dcc3SMatthew G. Knepley } 8925c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 89263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8927c0f0dcc3SMatthew G. Knepley } 8928c0f0dcc3SMatthew G. Knepley 8929c0f0dcc3SMatthew G. Knepley /*@C 8930c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 8931c0f0dcc3SMatthew G. Knepley 893220f4b53cSBarry Smith Collective 8933c0f0dcc3SMatthew G. Knepley 8934c0f0dcc3SMatthew G. Knepley Input Parameters: 8935bb7acecfSBarry Smith + dm - `DM` object you wish to monitor 8936c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 8937c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 8938c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 893949abdd8aSBarry Smith . monitor - the monitor function, this must use a `PetscViewerFormat` as its context 8940bb7acecfSBarry 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 8941c0f0dcc3SMatthew G. Knepley 8942c0f0dcc3SMatthew G. Knepley Output Parameter: 8943c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 8944c0f0dcc3SMatthew G. Knepley 8945c0f0dcc3SMatthew G. Knepley Level: developer 8946c0f0dcc3SMatthew G. Knepley 8947648c30bcSBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscOptionsCreateViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 8948db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 894960225df5SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 8950db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 8951c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 8952db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 8953bb7acecfSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `DMMonitor()`, `DMMonitorSet()` 8954c0f0dcc3SMatthew G. Knepley @*/ 8955d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 8956d71ae5a4SJacob Faibussowitsch { 8957c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 8958c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 8959c0f0dcc3SMatthew G. Knepley 8960c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8961c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8962648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)dm), ((PetscObject)dm)->options, ((PetscObject)dm)->prefix, name, &viewer, &format, flg)); 8963c0f0dcc3SMatthew G. Knepley if (*flg) { 8964c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 8965c0f0dcc3SMatthew G. Knepley 89669566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 8967648c30bcSBarry Smith PetscCall(PetscViewerDestroy(&viewer)); 89689566063dSJacob Faibussowitsch if (monitorsetup) PetscCall((*monitorsetup)(dm, vf)); 8969835f2295SStefano Zampini PetscCall(DMMonitorSet(dm, monitor, vf, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy)); 8970c0f0dcc3SMatthew G. Knepley } 89713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8972c0f0dcc3SMatthew G. Knepley } 8973c0f0dcc3SMatthew G. Knepley 8974c0f0dcc3SMatthew G. Knepley /*@ 8975c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 8976c0f0dcc3SMatthew G. Knepley 897720f4b53cSBarry Smith Collective 8978c0f0dcc3SMatthew G. Knepley 89792fe279fdSBarry Smith Input Parameter: 8980bb7acecfSBarry Smith . dm - The `DM` 8981c0f0dcc3SMatthew G. Knepley 8982c0f0dcc3SMatthew G. Knepley Level: developer 8983c0f0dcc3SMatthew G. Knepley 898473ff1848SBarry Smith Developer Note: 8985a4e35b19SJacob Faibussowitsch Note should indicate when during the life of the `DM` the monitor is run. It appears to be 8986a4e35b19SJacob Faibussowitsch related to the discretization process seems rather specialized since some `DM` have no 8987a4e35b19SJacob Faibussowitsch concept of discretization. 8988bb7acecfSBarry Smith 89891cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()` 8990c0f0dcc3SMatthew G. Knepley @*/ 8991d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitor(DM dm) 8992d71ae5a4SJacob Faibussowitsch { 8993c0f0dcc3SMatthew G. Knepley PetscInt m; 8994c0f0dcc3SMatthew G. Knepley 8995c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 89963ba16761SJacob Faibussowitsch if (!dm) PetscFunctionReturn(PETSC_SUCCESS); 8997c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 899848a46eb9SPierre Jolivet for (m = 0; m < dm->numbermonitors; ++m) PetscCall((*dm->monitor[m])(dm, dm->monitorcontext[m])); 89993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9000c0f0dcc3SMatthew G. Knepley } 90012e4af2aeSMatthew G. Knepley 90022e4af2aeSMatthew G. Knepley /*@ 9003bb7acecfSBarry Smith DMComputeError - Computes the error assuming the user has provided the exact solution functions 90042e4af2aeSMatthew G. Knepley 900520f4b53cSBarry Smith Collective 90062e4af2aeSMatthew G. Knepley 90072e4af2aeSMatthew G. Knepley Input Parameters: 9008bb7acecfSBarry Smith + dm - The `DM` 90096b867d5aSJose E. Roman - sol - The solution vector 90102e4af2aeSMatthew G. Knepley 90116b867d5aSJose E. Roman Input/Output Parameter: 901220f4b53cSBarry Smith . errors - An array of length Nf, the number of fields, or `NULL` for no output; on output 90136b867d5aSJose E. Roman contains the error in each field 90146b867d5aSJose E. Roman 90156b867d5aSJose E. Roman Output Parameter: 901620f4b53cSBarry Smith . errorVec - A vector to hold the cellwise error (may be `NULL`) 901720f4b53cSBarry Smith 901820f4b53cSBarry Smith Level: developer 90192e4af2aeSMatthew G. Knepley 9020bb7acecfSBarry Smith Note: 9021bb7acecfSBarry Smith The exact solutions come from the `PetscDS` object, and the time comes from `DMGetOutputSequenceNumber()`. 90222e4af2aeSMatthew G. Knepley 90231cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMGetRegionNumDS()`, `PetscDSGetExactSolution()`, `DMGetOutputSequenceNumber()` 90242e4af2aeSMatthew G. Knepley @*/ 9025d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 9026d71ae5a4SJacob Faibussowitsch { 90272e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 90282e4af2aeSMatthew G. Knepley void **ctxs; 90292e4af2aeSMatthew G. Knepley PetscReal time; 90302e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 90312e4af2aeSMatthew G. Knepley 90322e4af2aeSMatthew G. Knepley PetscFunctionBegin; 90339566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 90349566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nf, &exactSol, Nf, &ctxs)); 90359566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 90362e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 90372e4af2aeSMatthew G. Knepley PetscDS ds; 90382e4af2aeSMatthew G. Knepley DMLabel label; 90392e4af2aeSMatthew G. Knepley IS fieldIS; 90402e4af2aeSMatthew G. Knepley const PetscInt *fields; 90412e4af2aeSMatthew G. Knepley PetscInt dsNf; 90422e4af2aeSMatthew G. Knepley 904307218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 90449566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 90459566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISGetIndices(fieldIS, &fields)); 90462e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 90472e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 90489566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field])); 90492e4af2aeSMatthew G. Knepley } 90509566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISRestoreIndices(fieldIS, &fields)); 90512e4af2aeSMatthew G. Knepley } 9052ad540459SPierre 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); 90539566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, NULL, &time)); 90549566063dSJacob Faibussowitsch if (errors) PetscCall(DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors)); 90552e4af2aeSMatthew G. Knepley if (errorVec) { 90562e4af2aeSMatthew G. Knepley DM edm; 90572e4af2aeSMatthew G. Knepley DMPolytopeType ct; 90582e4af2aeSMatthew G. Knepley PetscBool simplex; 90592e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 90602e4af2aeSMatthew G. Knepley 90619566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &edm)); 90629566063dSJacob Faibussowitsch PetscCall(DMGetDimension(edm, &dim)); 90639566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 90649566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 90652e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 90669566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 90672e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 90682e4af2aeSMatthew G. Knepley PetscFE fe, efe; 90692e4af2aeSMatthew G. Knepley PetscQuadrature q; 90702e4af2aeSMatthew G. Knepley const char *name; 90712e4af2aeSMatthew G. Knepley 90729566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, (PetscObject *)&fe)); 90739566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe)); 90749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 90759566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)efe, name)); 90769566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 90779566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(efe, q)); 90789566063dSJacob Faibussowitsch PetscCall(DMSetField(edm, f, NULL, (PetscObject)efe)); 90799566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&efe)); 90802e4af2aeSMatthew G. Knepley } 90819566063dSJacob Faibussowitsch PetscCall(DMCreateDS(edm)); 90822e4af2aeSMatthew G. Knepley 90839566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(edm, errorVec)); 90849566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*errorVec, "Error")); 90859566063dSJacob Faibussowitsch PetscCall(DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec)); 90869566063dSJacob Faibussowitsch PetscCall(DMDestroy(&edm)); 90872e4af2aeSMatthew G. Knepley } 90889566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, ctxs)); 90893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 90902e4af2aeSMatthew G. Knepley } 90919a2a23afSMatthew G. Knepley 90929a2a23afSMatthew G. Knepley /*@ 9093bb7acecfSBarry Smith DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this `DM` 90949a2a23afSMatthew G. Knepley 909520f4b53cSBarry Smith Not Collective 90969a2a23afSMatthew G. Knepley 90979a2a23afSMatthew G. Knepley Input Parameter: 9098bb7acecfSBarry Smith . dm - The `DM` 90999a2a23afSMatthew G. Knepley 91009a2a23afSMatthew G. Knepley Output Parameter: 9101a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 91029a2a23afSMatthew G. Knepley 91039a2a23afSMatthew G. Knepley Level: advanced 91049a2a23afSMatthew G. Knepley 9105e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMGetAuxiliaryVec()` 91069a2a23afSMatthew G. Knepley @*/ 9107d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 9108d71ae5a4SJacob Faibussowitsch { 91099a2a23afSMatthew G. Knepley PetscFunctionBegin; 91109a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 91119566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize(dm->auxData, numAux)); 91123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91139a2a23afSMatthew G. Knepley } 91149a2a23afSMatthew G. Knepley 91159a2a23afSMatthew G. Knepley /*@ 9116ac17215fSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value, and equation part 91179a2a23afSMatthew G. Knepley 911820f4b53cSBarry Smith Not Collective 91199a2a23afSMatthew G. Knepley 91209a2a23afSMatthew G. Knepley Input Parameters: 9121bb7acecfSBarry Smith + dm - The `DM` 9122bb7acecfSBarry Smith . label - The `DMLabel` 9123ac17215fSMatthew G. Knepley . value - The label value indicating the region 9124ac17215fSMatthew G. Knepley - part - The equation part, or 0 if unused 91259a2a23afSMatthew G. Knepley 91269a2a23afSMatthew G. Knepley Output Parameter: 9127bb7acecfSBarry Smith . aux - The `Vec` holding auxiliary field data 91289a2a23afSMatthew G. Knepley 91299bdbcad8SBarry Smith Level: advanced 91309bdbcad8SBarry Smith 9131bb7acecfSBarry Smith Note: 9132bb7acecfSBarry Smith If no auxiliary vector is found for this (label, value), (NULL, 0, 0) is checked as well. 913304c51a94SMatthew G. Knepley 9134e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryLabels()` 91359a2a23afSMatthew G. Knepley @*/ 9136d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec *aux) 9137d71ae5a4SJacob Faibussowitsch { 9138ac17215fSMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0, 0}; 913904c51a94SMatthew G. Knepley PetscBool has; 91409a2a23afSMatthew G. Knepley 91419a2a23afSMatthew G. Knepley PetscFunctionBegin; 91429a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 91439a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 91449a2a23afSMatthew G. Knepley key.label = label; 91459a2a23afSMatthew G. Knepley key.value = value; 9146ac17215fSMatthew G. Knepley key.part = part; 91479566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxHas(dm->auxData, key, &has)); 91489566063dSJacob Faibussowitsch if (has) PetscCall(PetscHMapAuxGet(dm->auxData, key, aux)); 91499566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxGet(dm->auxData, wild, aux)); 91503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91519a2a23afSMatthew G. Knepley } 91529a2a23afSMatthew G. Knepley 91539a2a23afSMatthew G. Knepley /*@ 9154bb7acecfSBarry Smith DMSetAuxiliaryVec - Set an auxiliary vector for region specified by the given label and value, and equation part 91559a2a23afSMatthew G. Knepley 915620f4b53cSBarry Smith Not Collective because auxiliary vectors are not parallel 91579a2a23afSMatthew G. Knepley 91589a2a23afSMatthew G. Knepley Input Parameters: 9159bb7acecfSBarry Smith + dm - The `DM` 9160bb7acecfSBarry Smith . label - The `DMLabel` 91619a2a23afSMatthew G. Knepley . value - The label value indicating the region 9162ac17215fSMatthew G. Knepley . part - The equation part, or 0 if unused 9163bb7acecfSBarry Smith - aux - The `Vec` holding auxiliary field data 91649a2a23afSMatthew G. Knepley 91659a2a23afSMatthew G. Knepley Level: advanced 91669a2a23afSMatthew G. Knepley 9167e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMCopyAuxiliaryVec()` 91689a2a23afSMatthew G. Knepley @*/ 9169d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec aux) 9170d71ae5a4SJacob Faibussowitsch { 91719a2a23afSMatthew G. Knepley Vec old; 91729a2a23afSMatthew G. Knepley PetscHashAuxKey key; 91739a2a23afSMatthew G. Knepley 91749a2a23afSMatthew G. Knepley PetscFunctionBegin; 91759a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 91769a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 91779a2a23afSMatthew G. Knepley key.label = label; 91789a2a23afSMatthew G. Knepley key.value = value; 9179ac17215fSMatthew G. Knepley key.part = part; 91809566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGet(dm->auxData, key, &old)); 91819566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)aux)); 91829566063dSJacob Faibussowitsch if (!aux) PetscCall(PetscHMapAuxDel(dm->auxData, key)); 91839566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxSet(dm->auxData, key, aux)); 9184d705d0eaSStefano Zampini PetscCall(VecDestroy(&old)); 91853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91869a2a23afSMatthew G. Knepley } 91879a2a23afSMatthew G. Knepley 9188cc4c1da9SBarry Smith /*@ 9189bb7acecfSBarry Smith DMGetAuxiliaryLabels - Get the labels, values, and parts for all auxiliary vectors in this `DM` 91909a2a23afSMatthew G. Knepley 919120f4b53cSBarry Smith Not Collective 91929a2a23afSMatthew G. Knepley 91939a2a23afSMatthew G. Knepley Input Parameter: 9194bb7acecfSBarry Smith . dm - The `DM` 91959a2a23afSMatthew G. Knepley 91969a2a23afSMatthew G. Knepley Output Parameters: 9197bb7acecfSBarry Smith + labels - The `DMLabel`s for each `Vec` 9198bb7acecfSBarry Smith . values - The label values for each `Vec` 9199bb7acecfSBarry Smith - parts - The equation parts for each `Vec` 92009a2a23afSMatthew G. Knepley 92019bdbcad8SBarry Smith Level: advanced 92029bdbcad8SBarry Smith 9203bb7acecfSBarry Smith Note: 9204bb7acecfSBarry Smith The arrays passed in must be at least as large as `DMGetNumAuxiliaryVec()`. 92059a2a23afSMatthew G. Knepley 9206e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMCopyAuxiliaryVec()` 92079a2a23afSMatthew G. Knepley @*/ 9208d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[], PetscInt parts[]) 9209d71ae5a4SJacob Faibussowitsch { 92109a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 92119a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 92129a2a23afSMatthew G. Knepley 92139a2a23afSMatthew G. Knepley PetscFunctionBegin; 92149a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 92154f572ea9SToby Isaac PetscAssertPointer(labels, 2); 92164f572ea9SToby Isaac PetscAssertPointer(values, 3); 92174f572ea9SToby Isaac PetscAssertPointer(parts, 4); 92189566063dSJacob Faibussowitsch PetscCall(DMGetNumAuxiliaryVec(dm, &n)); 92199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &keys)); 92209566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetKeys(dm->auxData, &off, keys)); 92219371c9d4SSatish Balay for (i = 0; i < n; ++i) { 92229371c9d4SSatish Balay labels[i] = keys[i].label; 92239371c9d4SSatish Balay values[i] = keys[i].value; 92249371c9d4SSatish Balay parts[i] = keys[i].part; 92259371c9d4SSatish Balay } 92269566063dSJacob Faibussowitsch PetscCall(PetscFree(keys)); 92273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92289a2a23afSMatthew G. Knepley } 92299a2a23afSMatthew G. Knepley 92309a2a23afSMatthew G. Knepley /*@ 9231bb7acecfSBarry Smith DMCopyAuxiliaryVec - Copy the auxiliary vector data on a `DM` to a new `DM` 92329a2a23afSMatthew G. Knepley 923320f4b53cSBarry Smith Not Collective 92349a2a23afSMatthew G. Knepley 92359a2a23afSMatthew G. Knepley Input Parameter: 9236bb7acecfSBarry Smith . dm - The `DM` 92379a2a23afSMatthew G. Knepley 92389a2a23afSMatthew G. Knepley Output Parameter: 9239bb7acecfSBarry Smith . dmNew - The new `DM`, now with the same auxiliary data 92409a2a23afSMatthew G. Knepley 92419a2a23afSMatthew G. Knepley Level: advanced 92429a2a23afSMatthew G. Knepley 9243bb7acecfSBarry Smith Note: 9244bb7acecfSBarry Smith This is a shallow copy of the auxiliary vectors 9245bb7acecfSBarry Smith 9246e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 92479a2a23afSMatthew G. Knepley @*/ 9248d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 9249d71ae5a4SJacob Faibussowitsch { 92509a2a23afSMatthew G. Knepley PetscFunctionBegin; 92519a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9252d705d0eaSStefano Zampini PetscValidHeaderSpecific(dmNew, DM_CLASSID, 2); 9253d705d0eaSStefano Zampini if (dm == dmNew) PetscFunctionReturn(PETSC_SUCCESS); 9254e4d5475eSStefano Zampini PetscCall(DMClearAuxiliaryVec(dmNew)); 9255e4d5475eSStefano Zampini 9256e4d5475eSStefano Zampini PetscCall(PetscHMapAuxDestroy(&dmNew->auxData)); 92579566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData)); 9258d705d0eaSStefano Zampini { 9259d705d0eaSStefano Zampini Vec *auxData; 9260d705d0eaSStefano Zampini PetscInt n, i, off = 0; 9261d705d0eaSStefano Zampini 9262d705d0eaSStefano Zampini PetscCall(PetscHMapAuxGetSize(dmNew->auxData, &n)); 9263d705d0eaSStefano Zampini PetscCall(PetscMalloc1(n, &auxData)); 9264d705d0eaSStefano Zampini PetscCall(PetscHMapAuxGetVals(dmNew->auxData, &off, auxData)); 9265d705d0eaSStefano Zampini for (i = 0; i < n; ++i) PetscCall(PetscObjectReference((PetscObject)auxData[i])); 9266d705d0eaSStefano Zampini PetscCall(PetscFree(auxData)); 9267e4d5475eSStefano Zampini } 9268e4d5475eSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 9269e4d5475eSStefano Zampini } 9270e4d5475eSStefano Zampini 9271e4d5475eSStefano Zampini /*@ 9272e4d5475eSStefano Zampini DMClearAuxiliaryVec - Destroys the auxiliary vector information and creates a new empty one 9273e4d5475eSStefano Zampini 9274e4d5475eSStefano Zampini Not Collective 9275e4d5475eSStefano Zampini 9276e4d5475eSStefano Zampini Input Parameter: 9277e4d5475eSStefano Zampini . dm - The `DM` 9278e4d5475eSStefano Zampini 9279e4d5475eSStefano Zampini Level: advanced 9280e4d5475eSStefano Zampini 9281e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMCopyAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 9282e4d5475eSStefano Zampini @*/ 9283e4d5475eSStefano Zampini PetscErrorCode DMClearAuxiliaryVec(DM dm) 9284e4d5475eSStefano Zampini { 9285e4d5475eSStefano Zampini Vec *auxData; 9286e4d5475eSStefano Zampini PetscInt n, i, off = 0; 9287e4d5475eSStefano Zampini 9288e4d5475eSStefano Zampini PetscFunctionBegin; 9289e4d5475eSStefano Zampini PetscCall(PetscHMapAuxGetSize(dm->auxData, &n)); 9290d705d0eaSStefano Zampini PetscCall(PetscMalloc1(n, &auxData)); 9291e4d5475eSStefano Zampini PetscCall(PetscHMapAuxGetVals(dm->auxData, &off, auxData)); 9292d705d0eaSStefano Zampini for (i = 0; i < n; ++i) PetscCall(VecDestroy(&auxData[i])); 9293d705d0eaSStefano Zampini PetscCall(PetscFree(auxData)); 9294e4d5475eSStefano Zampini PetscCall(PetscHMapAuxDestroy(&dm->auxData)); 9295e4d5475eSStefano Zampini PetscCall(PetscHMapAuxCreate(&dm->auxData)); 92963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92979a2a23afSMatthew G. Knepley } 9298b5a892a1SMatthew G. Knepley 9299cc4c1da9SBarry Smith /*@ 9300bb7acecfSBarry Smith DMPolytopeMatchOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9301b5a892a1SMatthew G. Knepley 930220f4b53cSBarry Smith Not Collective 9303b5a892a1SMatthew G. Knepley 9304b5a892a1SMatthew G. Knepley Input Parameters: 9305bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9306b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9307b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9308b5a892a1SMatthew G. Knepley 9309b5a892a1SMatthew G. Knepley Output Parameters: 9310bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9311b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9312b5a892a1SMatthew G. Knepley 9313b5a892a1SMatthew G. Knepley Level: advanced 9314b5a892a1SMatthew G. Knepley 9315bb7acecfSBarry Smith Note: 9316bb7acecfSBarry Smith An arrangement is a face order combined with an orientation for each face 9317bb7acecfSBarry Smith 931885036b15SMatthew G. Knepley Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangements(ct)`/2 to `DMPolytopeTypeGetNumArrangements(ct)`/2 9319bb7acecfSBarry Smith that labels each arrangement (face ordering plus orientation for each face). 9320bb7acecfSBarry Smith 9321bb7acecfSBarry Smith See `DMPolytopeMatchVertexOrientation()` to find a new vertex orientation that takes the source vertex arrangement to the target vertex arrangement 9322bb7acecfSBarry Smith 93231cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetVertexOrientation()` 9324b5a892a1SMatthew G. Knepley @*/ 9325d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9326d71ae5a4SJacob Faibussowitsch { 9327b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 932885036b15SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangements(ct) / 2; 9329b5a892a1SMatthew G. Knepley PetscInt o, c; 9330b5a892a1SMatthew G. Knepley 9331b5a892a1SMatthew G. Knepley PetscFunctionBegin; 93329371c9d4SSatish Balay if (!nO) { 93339371c9d4SSatish Balay *ornt = 0; 93349371c9d4SSatish Balay *found = PETSC_TRUE; 93353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 93369371c9d4SSatish Balay } 9337b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 933885036b15SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangement(ct, o); 9339b5a892a1SMatthew G. Knepley 93409371c9d4SSatish Balay for (c = 0; c < cS; ++c) 93419371c9d4SSatish Balay if (sourceCone[arr[c * 2]] != targetCone[c]) break; 93429371c9d4SSatish Balay if (c == cS) { 93439371c9d4SSatish Balay *ornt = o; 93449371c9d4SSatish Balay break; 93459371c9d4SSatish Balay } 9346b5a892a1SMatthew G. Knepley } 9347b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 93483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9349b5a892a1SMatthew G. Knepley } 9350b5a892a1SMatthew G. Knepley 9351cc4c1da9SBarry Smith /*@ 9352bb7acecfSBarry Smith DMPolytopeGetOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9353b5a892a1SMatthew G. Knepley 935420f4b53cSBarry Smith Not Collective 9355b5a892a1SMatthew G. Knepley 9356b5a892a1SMatthew G. Knepley Input Parameters: 9357bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9358b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9359b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9360b5a892a1SMatthew G. Knepley 93612fe279fdSBarry Smith Output Parameter: 9362bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9363b5a892a1SMatthew G. Knepley 9364b5a892a1SMatthew G. Knepley Level: advanced 9365b5a892a1SMatthew G. Knepley 9366bb7acecfSBarry Smith Note: 9367bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchOrientation()` except it will generate an error if no suitable orientation can be found. 9368bb7acecfSBarry Smith 936973ff1848SBarry Smith Developer Note: 9370bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchOrientation()` and error if none is found 9371bb7acecfSBarry Smith 93721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchOrientation()`, `DMPolytopeGetVertexOrientation()`, `DMPolytopeMatchVertexOrientation()` 9373b5a892a1SMatthew G. Knepley @*/ 9374d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9375d71ae5a4SJacob Faibussowitsch { 9376b5a892a1SMatthew G. Knepley PetscBool found; 9377b5a892a1SMatthew G. Knepley 9378b5a892a1SMatthew G. Knepley PetscFunctionBegin; 93799566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found)); 93807a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 93813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9382b5a892a1SMatthew G. Knepley } 9383b5a892a1SMatthew G. Knepley 9384cc4c1da9SBarry Smith /*@ 9385bb7acecfSBarry Smith DMPolytopeMatchVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9386b5a892a1SMatthew G. Knepley 938720f4b53cSBarry Smith Not Collective 9388b5a892a1SMatthew G. Knepley 9389b5a892a1SMatthew G. Knepley Input Parameters: 9390bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9391b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 9392b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 9393b5a892a1SMatthew G. Knepley 9394b5a892a1SMatthew G. Knepley Output Parameters: 9395bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9396b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9397b5a892a1SMatthew G. Knepley 9398b5a892a1SMatthew G. Knepley Level: advanced 9399b5a892a1SMatthew G. Knepley 940073ff1848SBarry Smith Notes: 9401bb7acecfSBarry Smith An arrangement is a vertex order 9402bb7acecfSBarry Smith 940385036b15SMatthew G. Knepley Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangements(ct)`/2 to `DMPolytopeTypeGetNumArrangements(ct)`/2 9404bb7acecfSBarry Smith that labels each arrangement (vertex ordering). 9405bb7acecfSBarry Smith 9406bb7acecfSBarry Smith See `DMPolytopeMatchOrientation()` to find a new face orientation that takes the source face arrangement to the target face arrangement 9407bb7acecfSBarry Smith 940885036b15SMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchOrientation()`, `DMPolytopeTypeGetNumVertices()`, `DMPolytopeTypeGetVertexArrangement()` 9409b5a892a1SMatthew G. Knepley @*/ 9410d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 9411d71ae5a4SJacob Faibussowitsch { 9412b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 941385036b15SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangements(ct) / 2; 9414b5a892a1SMatthew G. Knepley PetscInt o, c; 9415b5a892a1SMatthew G. Knepley 9416b5a892a1SMatthew G. Knepley PetscFunctionBegin; 94179371c9d4SSatish Balay if (!nO) { 94189371c9d4SSatish Balay *ornt = 0; 94199371c9d4SSatish Balay *found = PETSC_TRUE; 94203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 94219371c9d4SSatish Balay } 9422b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 942385036b15SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangement(ct, o); 9424b5a892a1SMatthew G. Knepley 94259371c9d4SSatish Balay for (c = 0; c < cS; ++c) 94269371c9d4SSatish Balay if (sourceVert[arr[c]] != targetVert[c]) break; 94279371c9d4SSatish Balay if (c == cS) { 94289371c9d4SSatish Balay *ornt = o; 94299371c9d4SSatish Balay break; 94309371c9d4SSatish Balay } 9431b5a892a1SMatthew G. Knepley } 9432b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 94333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9434b5a892a1SMatthew G. Knepley } 9435b5a892a1SMatthew G. Knepley 9436cc4c1da9SBarry Smith /*@ 9437bb7acecfSBarry Smith DMPolytopeGetVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9438b5a892a1SMatthew G. Knepley 943920f4b53cSBarry Smith Not Collective 9440b5a892a1SMatthew G. Knepley 9441b5a892a1SMatthew G. Knepley Input Parameters: 9442bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9443b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 9444b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 9445b5a892a1SMatthew G. Knepley 94462fe279fdSBarry Smith Output Parameter: 9447bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9448b5a892a1SMatthew G. Knepley 9449b5a892a1SMatthew G. Knepley Level: advanced 9450b5a892a1SMatthew G. Knepley 9451bb7acecfSBarry Smith Note: 9452bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchVertexOrientation()` except it errors if not orientation is possible. 9453bb7acecfSBarry Smith 945473ff1848SBarry Smith Developer Note: 9455bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchVertexOrientation()` and error if none is found 9456bb7acecfSBarry Smith 94571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetOrientation()` 9458b5a892a1SMatthew G. Knepley @*/ 9459d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9460d71ae5a4SJacob Faibussowitsch { 9461b5a892a1SMatthew G. Knepley PetscBool found; 9462b5a892a1SMatthew G. Knepley 9463b5a892a1SMatthew G. Knepley PetscFunctionBegin; 94649566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found)); 94657a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 94663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9467b5a892a1SMatthew G. Knepley } 9468012bc364SMatthew G. Knepley 9469cc4c1da9SBarry Smith /*@ 9470012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 9471012bc364SMatthew G. Knepley 947220f4b53cSBarry Smith Not Collective 9473012bc364SMatthew G. Knepley 9474012bc364SMatthew G. Knepley Input Parameters: 9475bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9476012bc364SMatthew G. Knepley - point - Coordinates of the point 9477012bc364SMatthew G. Knepley 94782fe279fdSBarry Smith Output Parameter: 9479012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 9480012bc364SMatthew G. Knepley 9481012bc364SMatthew G. Knepley Level: advanced 9482012bc364SMatthew G. Knepley 94831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMLocatePoints()` 9484012bc364SMatthew G. Knepley @*/ 9485d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 9486d71ae5a4SJacob Faibussowitsch { 9487012bc364SMatthew G. Knepley PetscReal sum = 0.0; 9488012bc364SMatthew G. Knepley PetscInt d; 9489012bc364SMatthew G. Knepley 9490012bc364SMatthew G. Knepley PetscFunctionBegin; 9491012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 9492012bc364SMatthew G. Knepley switch (ct) { 9493012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 9494012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 9495012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 94969371c9d4SSatish Balay if (point[d] < -1.0) { 94979371c9d4SSatish Balay *inside = PETSC_FALSE; 94989371c9d4SSatish Balay break; 94999371c9d4SSatish Balay } 9500012bc364SMatthew G. Knepley sum += point[d]; 9501012bc364SMatthew G. Knepley } 95029371c9d4SSatish Balay if (sum > PETSC_SMALL) { 95039371c9d4SSatish Balay *inside = PETSC_FALSE; 95049371c9d4SSatish Balay break; 95059371c9d4SSatish Balay } 9506012bc364SMatthew G. Knepley break; 9507012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 9508012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 9509012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 95109371c9d4SSatish Balay if (PetscAbsReal(point[d]) > 1. + PETSC_SMALL) { 95119371c9d4SSatish Balay *inside = PETSC_FALSE; 9512012bc364SMatthew G. Knepley break; 95139371c9d4SSatish Balay } 95149371c9d4SSatish Balay break; 9515d71ae5a4SJacob Faibussowitsch default: 9516d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 9517012bc364SMatthew G. Knepley } 95183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9519012bc364SMatthew G. Knepley } 9520adc21957SMatthew G. Knepley 9521adc21957SMatthew G. Knepley /*@ 9522adc21957SMatthew G. Knepley DMReorderSectionSetDefault - Set flag indicating whether the local section should be reordered by default 9523adc21957SMatthew G. Knepley 9524adc21957SMatthew G. Knepley Logically collective 9525adc21957SMatthew G. Knepley 9526adc21957SMatthew G. Knepley Input Parameters: 9527adc21957SMatthew G. Knepley + dm - The DM 9528adc21957SMatthew G. Knepley - reorder - Flag for reordering 9529adc21957SMatthew G. Knepley 9530adc21957SMatthew G. Knepley Level: intermediate 9531adc21957SMatthew G. Knepley 9532adc21957SMatthew G. Knepley .seealso: `DMReorderSectionGetDefault()` 9533adc21957SMatthew G. Knepley @*/ 9534adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionSetDefault(DM dm, DMReorderDefaultFlag reorder) 9535adc21957SMatthew G. Knepley { 9536adc21957SMatthew G. Knepley PetscFunctionBegin; 9537adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9538adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionSetDefault_C", (DM, DMReorderDefaultFlag), (dm, reorder)); 9539adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9540adc21957SMatthew G. Knepley } 9541adc21957SMatthew G. Knepley 9542adc21957SMatthew G. Knepley /*@ 9543adc21957SMatthew G. Knepley DMReorderSectionGetDefault - Get flag indicating whether the local section should be reordered by default 9544adc21957SMatthew G. Knepley 9545adc21957SMatthew G. Knepley Not collective 9546adc21957SMatthew G. Knepley 9547adc21957SMatthew G. Knepley Input Parameter: 9548adc21957SMatthew G. Knepley . dm - The DM 9549adc21957SMatthew G. Knepley 9550adc21957SMatthew G. Knepley Output Parameter: 9551adc21957SMatthew G. Knepley . reorder - Flag for reordering 9552adc21957SMatthew G. Knepley 9553adc21957SMatthew G. Knepley Level: intermediate 9554adc21957SMatthew G. Knepley 9555adc21957SMatthew G. Knepley .seealso: `DMReorderSetDefault()` 9556adc21957SMatthew G. Knepley @*/ 9557adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionGetDefault(DM dm, DMReorderDefaultFlag *reorder) 9558adc21957SMatthew G. Knepley { 9559adc21957SMatthew G. Knepley PetscFunctionBegin; 9560adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9561adc21957SMatthew G. Knepley PetscAssertPointer(reorder, 2); 9562adc21957SMatthew G. Knepley *reorder = DM_REORDER_DEFAULT_NOTSET; 9563adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionGetDefault_C", (DM, DMReorderDefaultFlag *), (dm, reorder)); 9564adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9565adc21957SMatthew G. Knepley } 9566adc21957SMatthew G. Knepley 9567cc4c1da9SBarry Smith /*@ 9568adc21957SMatthew G. Knepley DMReorderSectionSetType - Set the type of local section reordering 9569adc21957SMatthew G. Knepley 9570adc21957SMatthew G. Knepley Logically collective 9571adc21957SMatthew G. Knepley 9572adc21957SMatthew G. Knepley Input Parameters: 9573adc21957SMatthew G. Knepley + dm - The DM 9574adc21957SMatthew G. Knepley - reorder - The reordering method 9575adc21957SMatthew G. Knepley 9576adc21957SMatthew G. Knepley Level: intermediate 9577adc21957SMatthew G. Knepley 9578adc21957SMatthew G. Knepley .seealso: `DMReorderSectionGetType()`, `DMReorderSectionSetDefault()` 9579adc21957SMatthew G. Knepley @*/ 9580adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionSetType(DM dm, MatOrderingType reorder) 9581adc21957SMatthew G. Knepley { 9582adc21957SMatthew G. Knepley PetscFunctionBegin; 9583adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9584adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionSetType_C", (DM, MatOrderingType), (dm, reorder)); 9585adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9586adc21957SMatthew G. Knepley } 9587adc21957SMatthew G. Knepley 9588cc4c1da9SBarry Smith /*@ 9589adc21957SMatthew G. Knepley DMReorderSectionGetType - Get the reordering type for the local section 9590adc21957SMatthew G. Knepley 9591adc21957SMatthew G. Knepley Not collective 9592adc21957SMatthew G. Knepley 9593adc21957SMatthew G. Knepley Input Parameter: 9594adc21957SMatthew G. Knepley . dm - The DM 9595adc21957SMatthew G. Knepley 9596adc21957SMatthew G. Knepley Output Parameter: 9597adc21957SMatthew G. Knepley . reorder - The reordering method 9598adc21957SMatthew G. Knepley 9599adc21957SMatthew G. Knepley Level: intermediate 9600adc21957SMatthew G. Knepley 9601adc21957SMatthew G. Knepley .seealso: `DMReorderSetDefault()`, `DMReorderSectionGetDefault()` 9602adc21957SMatthew G. Knepley @*/ 9603adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionGetType(DM dm, MatOrderingType *reorder) 9604adc21957SMatthew G. Knepley { 9605adc21957SMatthew G. Knepley PetscFunctionBegin; 9606adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9607adc21957SMatthew G. Knepley PetscAssertPointer(reorder, 2); 9608adc21957SMatthew G. Knepley *reorder = NULL; 9609adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionGetType_C", (DM, MatOrderingType *), (dm, reorder)); 9610adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9611adc21957SMatthew G. Knepley } 9612