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> 6f19dbd58SToby Isaac #include <petscdmfield.h> 70c312b8eSJed Brown #include <petscsf.h> 82764a2aaSMatthew G. Knepley #include <petscds.h> 947c6ae99SBarry Smith 10f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 11f918ec44SMatthew G. Knepley #include <petscfeceed.h> 12f918ec44SMatthew G. Knepley #endif 13f918ec44SMatthew G. Knepley 14cea3dcb8SSatish Balay #if !defined(PETSC_HAVE_WINDOWS_COMPILERS) 15cea3dcb8SSatish Balay #include <petsc/private/valgrind/memcheck.h> 1600d952a4SJed Brown #endif 1700d952a4SJed Brown 18732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 19d67d17b1SMatthew G. Knepley PetscClassId DMLABEL_CLASSID; 205b8ffe73SMark Adams 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_AdaptInterpolator; 2167a56275SMatthew G Knepley 22ea78f98cSLisandro Dalcin const char *const DMBoundaryTypes[] = {"NONE", "GHOSTED", "MIRROR", "PERIODIC", "TWIST", "DMBoundaryType", "DM_BOUNDARY_", NULL}; 23d1b3049bSMatthew 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}; 249371c9d4SSatish Balay const char *const DMPolytopeTypes[] = {"vertex", "segment", "tensor_segment", "triangle", "quadrilateral", "tensor_quad", "tetrahedron", "hexahedron", "triangular_prism", "tensor_triangular_prism", "tensor_quadrilateral_prism", 259371c9d4SSatish Balay "pyramid", "FV_ghost_cell", "interior_ghost_cell", "unknown", "invalid", "DMPolytopeType", "DM_POLYTOPE_", NULL}; 262cbb9b06SVaclav Hapla const char *const DMCopyLabelsModes[] = {"replace", "keep", "fail", "DMCopyLabelsMode", "DM_COPY_LABELS_", NULL}; 2760c22052SBarry Smith 28a4121054SBarry Smith /*@ 29bb7acecfSBarry Smith DMCreate - Creates an empty `DM` object. `DM`s are the abstract objects in PETSc that mediate between meshes and discretizations and the 30bb7acecfSBarry Smith algebraic solvers, time integrators, and optimization algorithms. 31a4121054SBarry Smith 32d083f849SBarry Smith Collective 33a4121054SBarry Smith 34a4121054SBarry Smith Input Parameter: 35bb7acecfSBarry Smith . comm - The communicator for the `DM` object 36a4121054SBarry Smith 37a4121054SBarry Smith Output Parameter: 38bb7acecfSBarry Smith . dm - The `DM` object 39a4121054SBarry Smith 40a4121054SBarry Smith Level: beginner 41a4121054SBarry Smith 42bb7acecfSBarry Smith Notes: 43bb7acecfSBarry Smith See `DMType` for a brief summary of available `DM`. 44bb7acecfSBarry Smith 45bb7acecfSBarry Smith The type must then be set with `DMSetType()`. If you never call `DMSetType()` it will generate an 46bb7acecfSBarry Smith error when you try to use the dm. 47bb7acecfSBarry Smith 48bb7acecfSBarry Smith .seealso: `DMSetType()`, `DMType`, `DMDACreate()`, `DMDA`, `DMSLICED`, `DMCOMPOSITE`, `DMPLEX`, `DMMOAB`, `DMNETWORK` 49a4121054SBarry Smith @*/ 50d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreate(MPI_Comm comm, DM *dm) 51d71ae5a4SJacob Faibussowitsch { 52a4121054SBarry Smith DM v; 53e5e52638SMatthew G. Knepley PetscDS ds; 54a4121054SBarry Smith 55a4121054SBarry Smith PetscFunctionBegin; 561411c6eeSJed Brown PetscValidPointer(dm, 2); 570298fd71SBarry Smith *dm = NULL; 589566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 59a4121054SBarry Smith 609566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView)); 61e7c4fc90SDmitry Karpeev 6262e5d2d2SJDBetteridge ((PetscObject)v)->non_cyclic_references = &DMCountNonCyclicReferences; 6362e5d2d2SJDBetteridge 6449be4549SMatthew G. Knepley v->setupcalled = PETSC_FALSE; 6549be4549SMatthew G. Knepley v->setfromoptionscalled = PETSC_FALSE; 660298fd71SBarry Smith v->ltogmap = NULL; 67a4ea9b21SRichard Tran Mills v->bind_below = 0; 681411c6eeSJed Brown v->bs = 1; 69171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 709566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sf)); 719566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sectionSF)); 72c58f1c22SToby Isaac v->labels = NULL; 7334aa8a36SMatthew G. Knepley v->adjacency[0] = PETSC_FALSE; 7434aa8a36SMatthew G. Knepley v->adjacency[1] = PETSC_TRUE; 75c58f1c22SToby Isaac v->depthLabel = NULL; 76ba2698f1SMatthew G. Knepley v->celltypeLabel = NULL; 771bb6d2a8SBarry Smith v->localSection = NULL; 781bb6d2a8SBarry Smith v->globalSection = NULL; 793b8ba7d1SJed Brown v->defaultConstraint.section = NULL; 803b8ba7d1SJed Brown v->defaultConstraint.mat = NULL; 8179769bd5SJed Brown v->defaultConstraint.bias = NULL; 826858538eSMatthew G. Knepley v->coordinates[0].dim = PETSC_DEFAULT; 836858538eSMatthew G. Knepley v->coordinates[1].dim = PETSC_DEFAULT; 846858538eSMatthew G. Knepley v->sparseLocalize = PETSC_TRUE; 8596173672SStefano Zampini v->dim = PETSC_DETERMINE; 86435a35e8SMatthew G Knepley { 87435a35e8SMatthew G Knepley PetscInt i; 88435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 890298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 90f9d4088aSMatthew G. Knepley v->nearnullspaceConstructors[i] = NULL; 91435a35e8SMatthew G Knepley } 92435a35e8SMatthew G Knepley } 939566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 949566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(v, NULL, NULL, ds)); 959566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 969566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxCreate(&v->auxData)); 9714f150ffSMatthew G. Knepley v->dmBC = NULL; 98a8fb8f29SToby Isaac v->coarseMesh = NULL; 99f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 100cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 1019566063dSJacob Faibussowitsch PetscCall(DMSetVecType(v, VECSTANDARD)); 1029566063dSJacob Faibussowitsch PetscCall(DMSetMatType(v, MATAIJ)); 1034a7a4c06SLawrence Mitchell 1041411c6eeSJed Brown *dm = v; 105a4121054SBarry Smith PetscFunctionReturn(0); 106a4121054SBarry Smith } 107a4121054SBarry Smith 10838221697SMatthew G. Knepley /*@ 109bb7acecfSBarry Smith DMClone - Creates a `DM` object with the same topology as the original. 11038221697SMatthew G. Knepley 111d083f849SBarry Smith Collective 11238221697SMatthew G. Knepley 11338221697SMatthew G. Knepley Input Parameter: 114bb7acecfSBarry Smith . dm - The original `DM` object 11538221697SMatthew G. Knepley 11638221697SMatthew G. Knepley Output Parameter: 117bb7acecfSBarry Smith . newdm - The new `DM` object 11838221697SMatthew G. Knepley 11938221697SMatthew G. Knepley Level: beginner 12038221697SMatthew G. Knepley 1211cb8cacdSPatrick Sanan Notes: 122bb7acecfSBarry Smith For some `DM` implementations this is a shallow clone, the result of which may share (reference counted) information with its parent. For example, 123bb7acecfSBarry Smith `DMClone()` applied to a `DMPLEX` object will result in a new `DMPLEX` that shares the topology with the original `DMPLEX`. It does not 124bb7acecfSBarry Smith share the `PetscSection` of the original `DM`. 1251bb6d2a8SBarry Smith 126bb7acecfSBarry Smith The clone is considered set up if the original has been set up. 12789706ed2SPatrick Sanan 128bb7acecfSBarry Smith Use `DMConvert()` for a general way to create new `DM` from a given `DM` 129bb7acecfSBarry Smith 130bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMCreate()`, `DMSetType()`, `DMSetLocalSection()`, `DMSetGlobalSection()`, `DMPLEX`, `DMSetType()`, `DMConvert()` 1311bb6d2a8SBarry Smith 13238221697SMatthew G. Knepley @*/ 133d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClone(DM dm, DM *newdm) 134d71ae5a4SJacob Faibussowitsch { 13538221697SMatthew G. Knepley PetscSF sf; 13638221697SMatthew G. Knepley Vec coords; 13738221697SMatthew G. Knepley void *ctx; 1386858538eSMatthew G. Knepley PetscInt dim, cdim, i; 13938221697SMatthew G. Knepley 14038221697SMatthew G. Knepley PetscFunctionBegin; 14138221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14238221697SMatthew G. Knepley PetscValidPointer(newdm, 2); 1439566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), newdm)); 1449566063dSJacob Faibussowitsch PetscCall(DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE, DM_COPY_LABELS_FAIL)); 145ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 146ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 147c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 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)); 1606858538eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 1616858538eSMatthew G. Knepley if (dm->coordinates[i].dm) { 162be4c1c3eSMatthew G. Knepley DM ncdm; 163be4c1c3eSMatthew G. Knepley PetscSection cs; 1645a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 165be4c1c3eSMatthew G. Knepley 1666858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm->coordinates[i].dm, &cs)); 1679566063dSJacob Faibussowitsch if (cs) PetscCall(PetscSectionGetChart(cs, NULL, &pEnd)); 1689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&pEnd, &pEndMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 1695a0206caSToby Isaac if (pEndMax >= 0) { 1706858538eSMatthew G. Knepley PetscCall(DMClone(dm->coordinates[i].dm, &ncdm)); 1716858538eSMatthew G. Knepley PetscCall(DMCopyDisc(dm->coordinates[i].dm, ncdm)); 1729566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(ncdm, cs)); 1736858538eSMatthew G. Knepley if (i) PetscCall(DMSetCellCoordinateDM(*newdm, ncdm)); 1746858538eSMatthew G. Knepley else PetscCall(DMSetCoordinateDM(*newdm, ncdm)); 1759566063dSJacob Faibussowitsch PetscCall(DMDestroy(&ncdm)); 176be4c1c3eSMatthew G. Knepley } 177be4c1c3eSMatthew G. Knepley } 1786858538eSMatthew G. Knepley } 1799566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 1809566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateDim(*newdm, cdim)); 1819566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coords)); 18238221697SMatthew G. Knepley if (coords) { 1839566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(*newdm, coords)); 18438221697SMatthew G. Knepley } else { 1859566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm, &coords)); 1869566063dSJacob Faibussowitsch if (coords) PetscCall(DMSetCoordinates(*newdm, coords)); 18738221697SMatthew G. Knepley } 1886858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coords)); 1896858538eSMatthew G. Knepley if (coords) { 1906858538eSMatthew G. Knepley PetscCall(DMSetCellCoordinatesLocal(*newdm, coords)); 1916858538eSMatthew G. Knepley } else { 1926858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinates(dm, &coords)); 1936858538eSMatthew G. Knepley if (coords) PetscCall(DMSetCellCoordinates(*newdm, coords)); 1946858538eSMatthew G. Knepley } 19590b157c4SStefano Zampini { 1964fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 1976858538eSMatthew G. Knepley 1984fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 1994fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*newdm, maxCell, Lstart, L)); 200c6b900c6SMatthew G. Knepley } 20134aa8a36SMatthew G. Knepley { 20234aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 20334aa8a36SMatthew G. Knepley 2049566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure)); 2059566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure)); 20634aa8a36SMatthew G. Knepley } 20738221697SMatthew G. Knepley PetscFunctionReturn(0); 20838221697SMatthew G. Knepley } 20938221697SMatthew G. Knepley 2109a42bb27SBarry Smith /*@C 211bb7acecfSBarry Smith DMSetVecType - Sets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 2129a42bb27SBarry Smith 213d083f849SBarry Smith Logically Collective on da 2149a42bb27SBarry Smith 215147403d9SBarry Smith Input Parameters: 2169a42bb27SBarry Smith + da - initial distributed array 217bb7acecfSBarry Smith - ctype - the vector type, for example `VECSTANDARD`, `VECCUDA`, or `VECVIENNACL` 2189a42bb27SBarry Smith 2199a42bb27SBarry Smith Options Database: 220147403d9SBarry Smith . -dm_vec_type ctype - the type of vector to create 2219a42bb27SBarry Smith 2229a42bb27SBarry Smith Level: intermediate 2239a42bb27SBarry Smith 224bb7acecfSBarry Smith .seealso: `DMCreate()`, `DMDestroy()`, `DM`, `DMDAInterpolationType`, `VecType`, `DMGetVecType()`, `DMSetMatType()`, `DMGetMatType()`, 225bb7acecfSBarry Smith `VECSTANDARD`, `VECCUDA`, `VECVIENNACL`, `DMCreateLocalVector()`, `DMCreateGlobalVector()` 2269a42bb27SBarry Smith @*/ 227d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVecType(DM da, VecType ctype) 228d71ae5a4SJacob Faibussowitsch { 2299a42bb27SBarry Smith PetscFunctionBegin; 2309a42bb27SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 2319566063dSJacob Faibussowitsch PetscCall(PetscFree(da->vectype)); 2329566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype, (char **)&da->vectype)); 2339a42bb27SBarry Smith PetscFunctionReturn(0); 2349a42bb27SBarry Smith } 2359a42bb27SBarry Smith 236c0dedaeaSBarry Smith /*@C 237bb7acecfSBarry Smith DMGetVecType - Gets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 238c0dedaeaSBarry Smith 239d083f849SBarry Smith Logically Collective on da 240c0dedaeaSBarry Smith 241c0dedaeaSBarry Smith Input Parameter: 242c0dedaeaSBarry Smith . da - initial distributed array 243c0dedaeaSBarry Smith 244c0dedaeaSBarry Smith Output Parameter: 245c0dedaeaSBarry Smith . ctype - the vector type 246c0dedaeaSBarry Smith 247c0dedaeaSBarry Smith Level: intermediate 248c0dedaeaSBarry Smith 249db781477SPatrick Sanan .seealso: `DMCreate()`, `DMDestroy()`, `DM`, `DMDAInterpolationType`, `VecType`, `DMSetMatType()`, `DMGetMatType()`, `DMSetVecType()` 250c0dedaeaSBarry Smith @*/ 251d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetVecType(DM da, VecType *ctype) 252d71ae5a4SJacob Faibussowitsch { 253c0dedaeaSBarry Smith PetscFunctionBegin; 254c0dedaeaSBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 255c0dedaeaSBarry Smith *ctype = da->vectype; 256c0dedaeaSBarry Smith PetscFunctionReturn(0); 257c0dedaeaSBarry Smith } 258c0dedaeaSBarry Smith 2595f1ad066SMatthew G Knepley /*@ 260bb7acecfSBarry Smith VecGetDM - Gets the `DM` defining the data layout of the vector 2615f1ad066SMatthew G Knepley 2625f1ad066SMatthew G Knepley Not collective 2635f1ad066SMatthew G Knepley 2645f1ad066SMatthew G Knepley Input Parameter: 265bb7acecfSBarry Smith . v - The `Vec` 2665f1ad066SMatthew G Knepley 2675f1ad066SMatthew G Knepley Output Parameter: 268bb7acecfSBarry Smith . dm - The `DM` 2695f1ad066SMatthew G Knepley 2705f1ad066SMatthew G Knepley Level: intermediate 2715f1ad066SMatthew G Knepley 272bb7acecfSBarry Smith Note: 273bb7acecfSBarry Smith A `Vec` may not have a `DM` associated with it. 274bb7acecfSBarry Smith 275bb7acecfSBarry Smith .seealso: `DM`, `VecSetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 2765f1ad066SMatthew G Knepley @*/ 277d71ae5a4SJacob Faibussowitsch PetscErrorCode VecGetDM(Vec v, DM *dm) 278d71ae5a4SJacob Faibussowitsch { 2795f1ad066SMatthew G Knepley PetscFunctionBegin; 2805f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 2815f1ad066SMatthew G Knepley PetscValidPointer(dm, 2); 2829566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)v, "__PETSc_dm", (PetscObject *)dm)); 2835f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2845f1ad066SMatthew G Knepley } 2855f1ad066SMatthew G Knepley 2865f1ad066SMatthew G Knepley /*@ 287bb7acecfSBarry Smith VecSetDM - Sets the `DM` defining the data layout of the vector. 2885f1ad066SMatthew G Knepley 2895f1ad066SMatthew G Knepley Not collective 2905f1ad066SMatthew G Knepley 2915f1ad066SMatthew G Knepley Input Parameters: 292bb7acecfSBarry Smith + v - The `Vec` 293bb7acecfSBarry Smith - dm - The `DM` 2945f1ad066SMatthew G Knepley 295bb7acecfSBarry Smith Note: 296bb7acecfSBarry Smith This is rarely used, generally one uses `DMGetLocalVector()` or `DMGetGlobalVector()` to create a vector associated with a given `DM` 297d9805387SMatthew G. Knepley 298bb7acecfSBarry 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. 299bb7acecfSBarry Smith 300bb7acecfSBarry Smith Level: developer 3015f1ad066SMatthew G Knepley 302db781477SPatrick Sanan .seealso: `VecGetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 3035f1ad066SMatthew G Knepley @*/ 304d71ae5a4SJacob Faibussowitsch PetscErrorCode VecSetDM(Vec v, DM dm) 305d71ae5a4SJacob Faibussowitsch { 3065f1ad066SMatthew G Knepley PetscFunctionBegin; 3075f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 308d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 3099566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)v, "__PETSc_dm", (PetscObject)dm)); 3105f1ad066SMatthew G Knepley PetscFunctionReturn(0); 3115f1ad066SMatthew G Knepley } 3125f1ad066SMatthew G Knepley 313521d9a4cSLisandro Dalcin /*@C 314bb7acecfSBarry Smith DMSetISColoringType - Sets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 3158f1509bcSBarry Smith 316d083f849SBarry Smith Logically Collective on dm 3178f1509bcSBarry Smith 3188f1509bcSBarry Smith Input Parameters: 319bb7acecfSBarry Smith + dm - the `DM` context 3208f1509bcSBarry Smith - ctype - the matrix type 3218f1509bcSBarry Smith 3228f1509bcSBarry Smith Options Database: 3238f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3248f1509bcSBarry Smith 3258f1509bcSBarry Smith Level: intermediate 3268f1509bcSBarry Smith 327db781477SPatrick Sanan .seealso: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 328bb7acecfSBarry Smith `DMGetISColoringType()`, `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3298f1509bcSBarry Smith @*/ 330d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetISColoringType(DM dm, ISColoringType ctype) 331d71ae5a4SJacob Faibussowitsch { 3328f1509bcSBarry Smith PetscFunctionBegin; 3338f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3348f1509bcSBarry Smith dm->coloringtype = ctype; 3358f1509bcSBarry Smith PetscFunctionReturn(0); 3368f1509bcSBarry Smith } 3378f1509bcSBarry Smith 3388f1509bcSBarry Smith /*@C 339bb7acecfSBarry Smith DMGetISColoringType - Gets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 340521d9a4cSLisandro Dalcin 341d083f849SBarry Smith Logically Collective on dm 342521d9a4cSLisandro Dalcin 343521d9a4cSLisandro Dalcin Input Parameter: 344bb7acecfSBarry Smith . dm - the `DM` context 3458f1509bcSBarry Smith 3468f1509bcSBarry Smith Output Parameter: 3478f1509bcSBarry Smith . ctype - the matrix type 3488f1509bcSBarry Smith 3498f1509bcSBarry Smith Options Database: 3508f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3518f1509bcSBarry Smith 3528f1509bcSBarry Smith Level: intermediate 3538f1509bcSBarry Smith 354db781477SPatrick Sanan .seealso: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 355bb7acecfSBarry Smith `DMGetISColoringType()`, `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3568f1509bcSBarry Smith @*/ 357d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetISColoringType(DM dm, ISColoringType *ctype) 358d71ae5a4SJacob Faibussowitsch { 3598f1509bcSBarry Smith PetscFunctionBegin; 3608f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3618f1509bcSBarry Smith *ctype = dm->coloringtype; 3628f1509bcSBarry Smith PetscFunctionReturn(0); 3638f1509bcSBarry Smith } 3648f1509bcSBarry Smith 3658f1509bcSBarry Smith /*@C 366bb7acecfSBarry Smith DMSetMatType - Sets the type of matrix created with `DMCreateMatrix()` 3678f1509bcSBarry Smith 368d083f849SBarry Smith Logically Collective on dm 3698f1509bcSBarry Smith 3708f1509bcSBarry Smith Input Parameters: 371bb7acecfSBarry Smith + dm - the `DM` context 372bb7acecfSBarry Smith - ctype - the matrix type, for example `MATMPIAIJ` 373521d9a4cSLisandro Dalcin 374521d9a4cSLisandro Dalcin Options Database: 375bb7acecfSBarry Smith . -dm_mat_type ctype - the type of the matrix to create, for example mpiaij 376521d9a4cSLisandro Dalcin 377521d9a4cSLisandro Dalcin Level: intermediate 378521d9a4cSLisandro Dalcin 379bb7acecfSBarry Smith .seealso: `MatType`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, `DMSetMatType()`, `DMGetMatType()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()` 380521d9a4cSLisandro Dalcin @*/ 381d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatType(DM dm, MatType ctype) 382d71ae5a4SJacob Faibussowitsch { 383521d9a4cSLisandro Dalcin PetscFunctionBegin; 384521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3859566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->mattype)); 3869566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype, (char **)&dm->mattype)); 387521d9a4cSLisandro Dalcin PetscFunctionReturn(0); 388521d9a4cSLisandro Dalcin } 389521d9a4cSLisandro Dalcin 390c0dedaeaSBarry Smith /*@C 391bb7acecfSBarry Smith DMGetMatType - Gets the type of matrix created with `DMCreateMatrix()` 392c0dedaeaSBarry Smith 393d083f849SBarry Smith Logically Collective on dm 394c0dedaeaSBarry Smith 395c0dedaeaSBarry Smith Input Parameter: 396bb7acecfSBarry Smith . dm - the `DM` context 397c0dedaeaSBarry Smith 398c0dedaeaSBarry Smith Output Parameter: 399c0dedaeaSBarry Smith . ctype - the matrix type 400c0dedaeaSBarry Smith 401c0dedaeaSBarry Smith Level: intermediate 402c0dedaeaSBarry Smith 403db781477SPatrick Sanan .seealso: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMSetMatType()`, `DMSetMatType()`, `DMGetMatType()` 404c0dedaeaSBarry Smith @*/ 405d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetMatType(DM dm, MatType *ctype) 406d71ae5a4SJacob Faibussowitsch { 407c0dedaeaSBarry Smith PetscFunctionBegin; 408c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 409c0dedaeaSBarry Smith *ctype = dm->mattype; 410c0dedaeaSBarry Smith PetscFunctionReturn(0); 411c0dedaeaSBarry Smith } 412c0dedaeaSBarry Smith 413c688c046SMatthew G Knepley /*@ 414bb7acecfSBarry Smith MatGetDM - Gets the `DM` defining the data layout of the matrix 415c688c046SMatthew G Knepley 416c688c046SMatthew G Knepley Not collective 417c688c046SMatthew G Knepley 418c688c046SMatthew G Knepley Input Parameter: 419bb7acecfSBarry Smith . A - The `Mat` 420c688c046SMatthew G Knepley 421c688c046SMatthew G Knepley Output Parameter: 422bb7acecfSBarry Smith . dm - The `DM` 423c688c046SMatthew G Knepley 424c688c046SMatthew G Knepley Level: intermediate 425c688c046SMatthew G Knepley 426bb7acecfSBarry Smith Note: 427bb7acecfSBarry Smith A matrix may not have a `DM` associated with it 428bb7acecfSBarry Smith 429bb7acecfSBarry Smith Developer Note: 430bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with the `Mat` through a `PetscObjectCompose()` operation 4318f1509bcSBarry Smith 432db781477SPatrick Sanan .seealso: `MatSetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 433c688c046SMatthew G Knepley @*/ 434d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetDM(Mat A, DM *dm) 435d71ae5a4SJacob Faibussowitsch { 436c688c046SMatthew G Knepley PetscFunctionBegin; 437c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 438c688c046SMatthew G Knepley PetscValidPointer(dm, 2); 4399566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_dm", (PetscObject *)dm)); 440c688c046SMatthew G Knepley PetscFunctionReturn(0); 441c688c046SMatthew G Knepley } 442c688c046SMatthew G Knepley 443c688c046SMatthew G Knepley /*@ 444bb7acecfSBarry Smith MatSetDM - Sets the `DM` defining the data layout of the matrix 445c688c046SMatthew G Knepley 446c688c046SMatthew G Knepley Not collective 447c688c046SMatthew G Knepley 448c688c046SMatthew G Knepley Input Parameters: 449c688c046SMatthew G Knepley + A - The Mat 450c688c046SMatthew G Knepley - dm - The DM 451c688c046SMatthew G Knepley 452bb7acecfSBarry Smith Level: developer 453c688c046SMatthew G Knepley 454bb7acecfSBarry Smith Note: 455bb7acecfSBarry Smith This is rarely used in practice, rather `DMCreateMatrix()` is used to create a matrix associated with a particular `DM` 456bb7acecfSBarry Smith 457bb7acecfSBarry Smith Developer Note: 458bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with 459bb7acecfSBarry Smith the `Mat` through a `PetscObjectCompose()` operation 4608f1509bcSBarry Smith 461db781477SPatrick Sanan .seealso: `MatGetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 462c688c046SMatthew G Knepley @*/ 463d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetDM(Mat A, DM dm) 464d71ae5a4SJacob Faibussowitsch { 465c688c046SMatthew G Knepley PetscFunctionBegin; 466c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4678865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 4689566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_dm", (PetscObject)dm)); 469c688c046SMatthew G Knepley PetscFunctionReturn(0); 470c688c046SMatthew G Knepley } 471c688c046SMatthew G Knepley 4729a42bb27SBarry Smith /*@C 473bb7acecfSBarry Smith DMSetOptionsPrefix - Sets the prefix prepended to all option names when searching through the options database 4749a42bb27SBarry Smith 475d083f849SBarry Smith Logically Collective on dm 4769a42bb27SBarry Smith 477d8d19677SJose E. Roman Input Parameters: 478bb7acecfSBarry Smith + da - the `DM` context 479bb7acecfSBarry Smith - prefix - the prefix to prepend 4809a42bb27SBarry Smith 4819a42bb27SBarry Smith Notes: 4829a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 4839a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 4849a42bb27SBarry Smith 4859a42bb27SBarry Smith Level: advanced 4869a42bb27SBarry Smith 487bb7acecfSBarry Smith .seealso: `PetscObjectSetOptionsPrefix()`, `DMSetFromOptions()` 4889a42bb27SBarry Smith @*/ 489d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOptionsPrefix(DM dm, const char prefix[]) 490d71ae5a4SJacob Faibussowitsch { 4919a42bb27SBarry Smith PetscFunctionBegin; 4929a42bb27SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4939566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm, prefix)); 4941baa6e33SBarry Smith if (dm->sf) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sf, prefix)); 4951baa6e33SBarry Smith if (dm->sectionSF) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF, prefix)); 4969a42bb27SBarry Smith PetscFunctionReturn(0); 4979a42bb27SBarry Smith } 4989a42bb27SBarry Smith 49931697293SDave May /*@C 500bb7acecfSBarry Smith DMAppendOptionsPrefix - Appends an additional string to an already exising prefix used for searching for 501bb7acecfSBarry Smith `DM` options in the options database. 50231697293SDave May 503d083f849SBarry Smith Logically Collective on dm 50431697293SDave May 50531697293SDave May Input Parameters: 506bb7acecfSBarry Smith + dm - the `DM` context 507bb7acecfSBarry Smith - prefix - the string to append to the current prefix 50831697293SDave May 50931697293SDave May Notes: 510bb7acecfSBarry 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. 51131697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 51231697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 51331697293SDave May 51431697293SDave May Level: advanced 51531697293SDave May 516bb7acecfSBarry Smith .seealso: `DMSetOptionsPrefix()`, `DMGetOptionsPrefix()`, `PetscObjectAppendOptionsPrefix()`, `DMSetFromOptions()` 51731697293SDave May @*/ 518d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAppendOptionsPrefix(DM dm, const char prefix[]) 519d71ae5a4SJacob Faibussowitsch { 52031697293SDave May PetscFunctionBegin; 52131697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5229566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)dm, prefix)); 52331697293SDave May PetscFunctionReturn(0); 52431697293SDave May } 52531697293SDave May 52631697293SDave May /*@C 52731697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 528bb7acecfSBarry Smith DM options in the options database. 52931697293SDave May 53031697293SDave May Not Collective 53131697293SDave May 53231697293SDave May Input Parameters: 533bb7acecfSBarry Smith . dm - the `DM` context 53431697293SDave May 53531697293SDave May Output Parameters: 53631697293SDave May . prefix - pointer to the prefix string used is returned 53731697293SDave May 538bb7acecfSBarry Smith Fortran Note: 53995452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 54031697293SDave May sufficient length to hold the prefix. 54131697293SDave May 54231697293SDave May Level: advanced 54331697293SDave May 544bb7acecfSBarry Smith .seealso: `DMSetOptionsPrefix()`, `DMAppendOptionsPrefix()`, `DMSetFromOptions()` 54531697293SDave May @*/ 546d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOptionsPrefix(DM dm, const char *prefix[]) 547d71ae5a4SJacob Faibussowitsch { 54831697293SDave May PetscFunctionBegin; 54931697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5509566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, prefix)); 55131697293SDave May PetscFunctionReturn(0); 55231697293SDave May } 55331697293SDave May 55462e5d2d2SJDBetteridge static PetscErrorCode DMCountNonCyclicReferences_Internal(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 555d71ae5a4SJacob Faibussowitsch { 5566eb26441SStefano Zampini PetscInt refct = ((PetscObject)dm)->refct; 55788bdff64SToby Isaac 55888bdff64SToby Isaac PetscFunctionBegin; 559aab5bcd8SJed Brown *ncrefct = 0; 56088bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 56188bdff64SToby Isaac refct--; 56288bdff64SToby Isaac if (recurseCoarse) { 56388bdff64SToby Isaac PetscInt coarseCount; 56488bdff64SToby Isaac 56562e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE, &coarseCount)); 56688bdff64SToby Isaac refct += coarseCount; 56788bdff64SToby Isaac } 56888bdff64SToby Isaac } 56988bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 57088bdff64SToby Isaac refct--; 57188bdff64SToby Isaac if (recurseFine) { 57288bdff64SToby Isaac PetscInt fineCount; 57388bdff64SToby Isaac 57462e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->fineMesh, PETSC_FALSE, PETSC_TRUE, &fineCount)); 57588bdff64SToby Isaac refct += fineCount; 57688bdff64SToby Isaac } 57788bdff64SToby Isaac } 57888bdff64SToby Isaac *ncrefct = refct; 57988bdff64SToby Isaac PetscFunctionReturn(0); 58088bdff64SToby Isaac } 58188bdff64SToby Isaac 58262e5d2d2SJDBetteridge /* Generic wrapper for DMCountNonCyclicReferences_Internal() */ 58362e5d2d2SJDBetteridge PetscErrorCode DMCountNonCyclicReferences(PetscObject dm, PetscInt *ncrefct) 58462e5d2d2SJDBetteridge { 58562e5d2d2SJDBetteridge PetscFunctionBegin; 58662e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal((DM)dm, PETSC_TRUE, PETSC_TRUE, ncrefct)); 58762e5d2d2SJDBetteridge PetscFunctionReturn(0); 58862e5d2d2SJDBetteridge } 58962e5d2d2SJDBetteridge 590d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 591d71ae5a4SJacob Faibussowitsch { 5925d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 593354557abSToby Isaac 594354557abSToby Isaac PetscFunctionBegin; 595354557abSToby Isaac /* destroy the labels */ 596354557abSToby Isaac while (next) { 597354557abSToby Isaac DMLabelLink tmp = next->next; 598354557abSToby Isaac 5995d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 600ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 6019566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 6029566063dSJacob Faibussowitsch PetscCall(PetscFree(next)); 603354557abSToby Isaac next = tmp; 604354557abSToby Isaac } 6055d80c0bfSVaclav Hapla dm->labels = NULL; 606354557abSToby Isaac PetscFunctionReturn(0); 607354557abSToby Isaac } 608354557abSToby Isaac 609d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroyCoordinates_Private(DMCoordinates *c) 610d71ae5a4SJacob Faibussowitsch { 6116858538eSMatthew G. Knepley PetscFunctionBegin; 6126858538eSMatthew G. Knepley c->dim = PETSC_DEFAULT; 6136858538eSMatthew G. Knepley PetscCall(DMDestroy(&c->dm)); 6146858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->x)); 6156858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->xl)); 6166858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&c->field)); 6176858538eSMatthew G. Knepley PetscFunctionReturn(0); 6186858538eSMatthew G. Knepley } 6196858538eSMatthew G. Knepley 6201fb7b255SJunchao Zhang /*@C 621bb7acecfSBarry Smith DMDestroy - Destroys a `DM`. 62247c6ae99SBarry Smith 623d083f849SBarry Smith Collective on dm 62447c6ae99SBarry Smith 62547c6ae99SBarry Smith Input Parameter: 626bb7acecfSBarry Smith . dm - the `DM` object to destroy 62747c6ae99SBarry Smith 62847c6ae99SBarry Smith Level: developer 62947c6ae99SBarry Smith 630bb7acecfSBarry Smith .seealso: `DMCreate()`, `DMType`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 63147c6ae99SBarry Smith 63247c6ae99SBarry Smith @*/ 633d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroy(DM *dm) 634d71ae5a4SJacob Faibussowitsch { 6356eb26441SStefano Zampini PetscInt cnt; 636dfe15315SJed Brown DMNamedVecLink nlink, nnext; 63747c6ae99SBarry Smith 63847c6ae99SBarry Smith PetscFunctionBegin; 6396bf464f9SBarry Smith if (!*dm) PetscFunctionReturn(0); 6406bf464f9SBarry Smith PetscValidHeaderSpecific((*dm), DM_CLASSID, 1); 64187e657c6SBarry Smith 64288bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 64362e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(*dm, PETSC_TRUE, PETSC_TRUE, &cnt)); 64488bdff64SToby Isaac --((PetscObject)(*dm))->refct; 6459371c9d4SSatish Balay if (--cnt > 0) { 6469371c9d4SSatish Balay *dm = NULL; 6479371c9d4SSatish Balay PetscFunctionReturn(0); 6489371c9d4SSatish Balay } 6496bf464f9SBarry Smith if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 6506bf464f9SBarry Smith ((PetscObject)(*dm))->refct = 0; 6516eb26441SStefano Zampini 6529566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(*dm)); 6539566063dSJacob Faibussowitsch PetscCall(DMClearLocalVectors(*dm)); 6546eb26441SStefano Zampini 655f490541aSPeter Brune nnext = (*dm)->namedglobal; 6560298fd71SBarry Smith (*dm)->namedglobal = NULL; 657f490541aSPeter Brune for (nlink = nnext; nlink; nlink = nnext) { /* Destroy the named vectors */ 6582348bcf4SPeter Brune nnext = nlink->next; 6597a8be351SBarry Smith PetscCheck(nlink->status == DMVEC_STATUS_IN, ((PetscObject)*dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "DM still has Vec named '%s' checked out", nlink->name); 6609566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink->name)); 6619566063dSJacob Faibussowitsch PetscCall(VecDestroy(&nlink->X)); 6629566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink)); 6632348bcf4SPeter Brune } 664f490541aSPeter Brune nnext = (*dm)->namedlocal; 6650298fd71SBarry Smith (*dm)->namedlocal = NULL; 666f490541aSPeter Brune for (nlink = nnext; nlink; nlink = nnext) { /* Destroy the named local vectors */ 667f490541aSPeter Brune nnext = nlink->next; 6687a8be351SBarry Smith PetscCheck(nlink->status == DMVEC_STATUS_IN, ((PetscObject)*dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "DM still has Vec named '%s' checked out", nlink->name); 6699566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink->name)); 6709566063dSJacob Faibussowitsch PetscCall(VecDestroy(&nlink->X)); 6719566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink)); 672f490541aSPeter Brune } 6732348bcf4SPeter Brune 674b17ce1afSJed Brown /* Destroy the list of hooks */ 675c833c3b5SJed Brown { 676c833c3b5SJed Brown DMCoarsenHookLink link, next; 677b17ce1afSJed Brown for (link = (*dm)->coarsenhook; link; link = next) { 678b17ce1afSJed Brown next = link->next; 6799566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 680b17ce1afSJed Brown } 6810298fd71SBarry Smith (*dm)->coarsenhook = NULL; 682c833c3b5SJed Brown } 683c833c3b5SJed Brown { 684c833c3b5SJed Brown DMRefineHookLink link, next; 685c833c3b5SJed Brown for (link = (*dm)->refinehook; link; link = next) { 686c833c3b5SJed Brown next = link->next; 6879566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 688c833c3b5SJed Brown } 6890298fd71SBarry Smith (*dm)->refinehook = NULL; 690c833c3b5SJed Brown } 691be081cd6SPeter Brune { 692be081cd6SPeter Brune DMSubDomainHookLink link, next; 693be081cd6SPeter Brune for (link = (*dm)->subdomainhook; link; link = next) { 694be081cd6SPeter Brune next = link->next; 6959566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 696be081cd6SPeter Brune } 6970298fd71SBarry Smith (*dm)->subdomainhook = NULL; 698be081cd6SPeter Brune } 699baf369e7SPeter Brune { 700baf369e7SPeter Brune DMGlobalToLocalHookLink link, next; 701baf369e7SPeter Brune for (link = (*dm)->gtolhook; link; link = next) { 702baf369e7SPeter Brune next = link->next; 7039566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 704baf369e7SPeter Brune } 7050298fd71SBarry Smith (*dm)->gtolhook = NULL; 706baf369e7SPeter Brune } 707d4d07f1eSToby Isaac { 708d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, next; 709d4d07f1eSToby Isaac for (link = (*dm)->ltoghook; link; link = next) { 710d4d07f1eSToby Isaac next = link->next; 7119566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 712d4d07f1eSToby Isaac } 713d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 714d4d07f1eSToby Isaac } 715aa1993deSMatthew G Knepley /* Destroy the work arrays */ 716aa1993deSMatthew G Knepley { 717aa1993deSMatthew G Knepley DMWorkLink link, next; 7187a8be351SBarry Smith PetscCheck(!(*dm)->workout, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Work array still checked out"); 719aa1993deSMatthew G Knepley for (link = (*dm)->workin; link; link = next) { 720aa1993deSMatthew G Knepley next = link->next; 7219566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 7229566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 723aa1993deSMatthew G Knepley } 7240298fd71SBarry Smith (*dm)->workin = NULL; 725aa1993deSMatthew G Knepley } 726c58f1c22SToby Isaac /* destroy the labels */ 7279566063dSJacob Faibussowitsch PetscCall(DMDestroyLabelLinkList_Internal(*dm)); 728f4cdcedcSVaclav Hapla /* destroy the fields */ 7299566063dSJacob Faibussowitsch PetscCall(DMClearFields(*dm)); 730f4cdcedcSVaclav Hapla /* destroy the boundaries */ 731e6f8dbb6SToby Isaac { 732e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 733e6f8dbb6SToby Isaac while (next) { 734e6f8dbb6SToby Isaac DMBoundary b = next; 735e6f8dbb6SToby Isaac 736e6f8dbb6SToby Isaac next = b->next; 7379566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 738e6f8dbb6SToby Isaac } 739e6f8dbb6SToby Isaac } 740b17ce1afSJed Brown 7419566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmksp)); 7429566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmsnes)); 7439566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmts)); 74452536dc3SBarry Smith 74548a46eb9SPierre Jolivet if ((*dm)->ctx && (*dm)->ctxdestroy) PetscCall((*(*dm)->ctxdestroy)(&(*dm)->ctx)); 7469566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&(*dm)->fd)); 7479566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap)); 7489566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->vectype)); 7499566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->mattype)); 75088ed4aceSMatthew G Knepley 7519566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->localSection)); 7529566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->globalSection)); 7539566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&(*dm)->map)); 7549566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->defaultConstraint.section)); 7559566063dSJacob Faibussowitsch PetscCall(MatDestroy(&(*dm)->defaultConstraint.mat)); 7569566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sf)); 7579566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sectionSF)); 758736995cdSBlaise Bourdin if ((*dm)->useNatural) { 75948a46eb9SPierre Jolivet if ((*dm)->sfNatural) PetscCall(PetscSFDestroy(&(*dm)->sfNatural)); 7609566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)(*dm)->sfMigration)); 761736995cdSBlaise Bourdin } 7629a2a23afSMatthew G. Knepley { 7639a2a23afSMatthew G. Knepley Vec *auxData; 7649a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 7659a2a23afSMatthew G. Knepley 7669566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize((*dm)->auxData, &n)); 7679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &auxData)); 7689566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetVals((*dm)->auxData, &off, auxData)); 7699566063dSJacob Faibussowitsch for (i = 0; i < n; ++i) PetscCall(VecDestroy(&auxData[i])); 7709566063dSJacob Faibussowitsch PetscCall(PetscFree(auxData)); 7719566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&(*dm)->auxData)); 7729a2a23afSMatthew G. Knepley } 77348a46eb9SPierre Jolivet if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) PetscCall(DMSetFineDM((*dm)->coarseMesh, NULL)); 7746eb26441SStefano Zampini 7759566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->coarseMesh)); 77648a46eb9SPierre Jolivet if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) PetscCall(DMSetCoarseDM((*dm)->fineMesh, NULL)); 7779566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->fineMesh)); 7784fb89dddSMatthew G. Knepley PetscCall(PetscFree((*dm)->Lstart)); 7799566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->L)); 7809566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->maxCell)); 7816858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[0])); 7826858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[1])); 7839566063dSJacob Faibussowitsch if ((*dm)->transformDestroy) PetscCall((*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx)); 7849566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->transformDM)); 7859566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*dm)->transform)); 7866636e97aSMatthew G Knepley 7879566063dSJacob Faibussowitsch PetscCall(DMClearDS(*dm)); 7889566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->dmBC)); 789e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 7909566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*dm)); 791732e2eb9SMatthew G Knepley 79248a46eb9SPierre Jolivet if ((*dm)->ops->destroy) PetscCall((*(*dm)->ops->destroy)(*dm)); 7939566063dSJacob Faibussowitsch PetscCall(DMMonitorCancel(*dm)); 794f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 7959566063dSJacob Faibussowitsch PetscCallCEED(CeedElemRestrictionDestroy(&(*dm)->ceedERestrict)); 7969566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*dm)->ceed)); 797f918ec44SMatthew G. Knepley #endif 798435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 7999566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(dm)); 80047c6ae99SBarry Smith PetscFunctionReturn(0); 80147c6ae99SBarry Smith } 80247c6ae99SBarry Smith 803d7bf68aeSBarry Smith /*@ 804bb7acecfSBarry Smith DMSetUp - sets up the data structures inside a `DM` object 805d7bf68aeSBarry Smith 806d083f849SBarry Smith Collective on dm 807d7bf68aeSBarry Smith 808d7bf68aeSBarry Smith Input Parameter: 809bb7acecfSBarry Smith . dm - the `DM` object to setup 810d7bf68aeSBarry Smith 811bb7acecfSBarry Smith Level: intermediate 812d7bf68aeSBarry Smith 813bb7acecfSBarry Smith Note: 814bb7acecfSBarry Smith This is usually called after various parameter setting operations and `DMSetFromOptions()` are called on the `DM` 815bb7acecfSBarry Smith 816bb7acecfSBarry Smith .seealso: `DM`, `DMCreate()`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 817d7bf68aeSBarry Smith 818d7bf68aeSBarry Smith @*/ 819d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUp(DM dm) 820d71ae5a4SJacob Faibussowitsch { 821d7bf68aeSBarry Smith PetscFunctionBegin; 822171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8238387afaaSJed Brown if (dm->setupcalled) PetscFunctionReturn(0); 824dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setup); 8258387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 826d7bf68aeSBarry Smith PetscFunctionReturn(0); 827d7bf68aeSBarry Smith } 828d7bf68aeSBarry Smith 829d7bf68aeSBarry Smith /*@ 830bb7acecfSBarry Smith DMSetFromOptions - sets parameters in a `DM` from the options database 831d7bf68aeSBarry Smith 832d083f849SBarry Smith Collective on dm 833d7bf68aeSBarry Smith 834d7bf68aeSBarry Smith Input Parameter: 835bb7acecfSBarry Smith . dm - the `DM` object to set options for 836d7bf68aeSBarry Smith 837732e2eb9SMatthew G Knepley Options Database: 838bb7acecfSBarry Smith + -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 839bb7acecfSBarry Smith . -dm_vec_type <type> - type of vector to create inside `DM` 840bb7acecfSBarry Smith . -dm_mat_type <type> - type of matrix to create inside `DM` 841a4ea9b21SRichard Tran Mills . -dm_is_coloring_type - <global or local> 842bb7acecfSBarry 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` 843732e2eb9SMatthew G Knepley 8449318fe57SMatthew G. Knepley DMPLEX Specific creation options 8459318fe57SMatthew G. Knepley + -dm_plex_filename <str> - File containing a mesh 8469318fe57SMatthew G. Knepley . -dm_plex_boundary_filename <str> - File containing a mesh boundary 847cd7e8a5eSksagiyam . -dm_plex_name <str> - Name of the mesh in the file 848bb7acecfSBarry Smith . -dm_plex_shape <shape> - The domain shape, such as `DM_SHAPE_BOX`, `DM_SHAPE_SPHERE`, etc. 8499318fe57SMatthew G. Knepley . -dm_plex_cell <ct> - Cell shape 8509318fe57SMatthew G. Knepley . -dm_plex_reference_cell_domain <bool> - Use a reference cell domain 8519318fe57SMatthew G. Knepley . -dm_plex_dim <dim> - Set the topological dimension 852bb7acecfSBarry Smith . -dm_plex_simplex <bool> - `PETSC_TRUE` for simplex elements, `PETSC_FALSE` for tensor elements 853bb7acecfSBarry Smith . -dm_plex_interpolate <bool> - `PETSC_TRUE` turns on topological interpolation (creating edges and faces) 8549318fe57SMatthew G. Knepley . -dm_plex_scale <sc> - Scale factor for mesh coordinates 8559318fe57SMatthew G. Knepley . -dm_plex_box_faces <m,n,p> - Number of faces along each dimension 8569318fe57SMatthew G. Knepley . -dm_plex_box_lower <x,y,z> - Specify lower-left-bottom coordinates for the box 8579318fe57SMatthew G. Knepley . -dm_plex_box_upper <x,y,z> - Specify upper-right-top coordinates for the box 858bb7acecfSBarry Smith . -dm_plex_box_bd <bx,by,bz> - Specify the `DMBoundaryType `for each direction 8599318fe57SMatthew G. Knepley . -dm_plex_sphere_radius <r> - The sphere radius 8609318fe57SMatthew G. Knepley . -dm_plex_ball_radius <r> - Radius of the ball 8619318fe57SMatthew G. Knepley . -dm_plex_cylinder_bd <bz> - Boundary type in the z direction 8629318fe57SMatthew G. Knepley . -dm_plex_cylinder_num_wedges <n> - Number of wedges around the cylinder 863bdf63967SMatthew G. Knepley . -dm_plex_reorder <order> - Reorder the mesh using the specified algorithm 8649318fe57SMatthew G. Knepley . -dm_refine_pre <n> - The number of refinements before distribution 8659318fe57SMatthew G. Knepley . -dm_refine_uniform_pre <bool> - Flag for uniform refinement before distribution 8669318fe57SMatthew G. Knepley . -dm_refine_volume_limit_pre <v> - The maximum cell volume after refinement before distribution 8679318fe57SMatthew G. Knepley . -dm_refine <n> - The number of refinements after distribution 868bdf63967SMatthew G. Knepley . -dm_extrude <l> - Activate extrusion and specify the number of layers to extrude 869d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers 870d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding 871d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface 872d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction 873d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer 874909dfd52SMatthew G. Knepley . -dm_plex_create_fv_ghost_cells - Flag to create finite volume ghost cells on the boundary 875909dfd52SMatthew G. Knepley . -dm_plex_fv_ghost_cells_label <name> - Label name for ghost cells boundary 8769318fe57SMatthew G. Knepley . -dm_distribute <bool> - Flag to redistribute a mesh among processes 8779318fe57SMatthew G. Knepley . -dm_distribute_overlap <n> - The size of the overlap halo 8789318fe57SMatthew G. Knepley . -dm_plex_adj_cone <bool> - Set adjacency direction 8799318fe57SMatthew G. Knepley - -dm_plex_adj_closure <bool> - Set adjacency size 8809318fe57SMatthew G. Knepley 881384a6580SVaclav Hapla DMPLEX Specific Checks 882bb7acecfSBarry Smith + -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - `DMPlexCheckSymmetry()` 883bb7acecfSBarry Smith . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - `DMPlexCheckSkeleton()` 884bb7acecfSBarry 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()` 885bb7acecfSBarry Smith . -dm_plex_check_geometry - Check that cells have positive volume - `DMPlexCheckGeometry()` 886bb7acecfSBarry Smith . -dm_plex_check_pointsf - Check some necessary conditions for `PointSF` - `DMPlexCheckPointSF()` 887bb7acecfSBarry Smith . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - `DMPlexCheckInterfaceCones()` 888384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 889d7bf68aeSBarry Smith 89095eb5ee5SVaclav Hapla Level: intermediate 89195eb5ee5SVaclav Hapla 892bb7acecfSBarry Smith .seealso: `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 893bb7acecfSBarry Smith `DMPlexCheckSymmetry()`, `DMPlexCheckSkeleton()`, `DMPlexCheckFaces()`, `DMPlexCheckGeometry()`, `DMPlexCheckPointSF()`, `DMPlexCheckInterfaceCones()`, 894bb7acecfSBarry Smith `DMSetOptionsPrefix()`, `DM`, `DMType`, `DMPLEX`, `DMDA` 895d7bf68aeSBarry Smith 896d7bf68aeSBarry Smith @*/ 897d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFromOptions(DM dm) 898d71ae5a4SJacob Faibussowitsch { 8997781c08eSBarry Smith char typeName[256]; 900ca266f36SBarry Smith PetscBool flg; 901d7bf68aeSBarry Smith 902d7bf68aeSBarry Smith PetscFunctionBegin; 903171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90449be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 9059566063dSJacob Faibussowitsch if (dm->sf) PetscCall(PetscSFSetFromOptions(dm->sf)); 9069566063dSJacob Faibussowitsch if (dm->sectionSF) PetscCall(PetscSFSetFromOptions(dm->sectionSF)); 907d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)dm); 9089566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-dm_preallocate_only", "only preallocate matrix, but do not set column indices", "DMSetMatrixPreallocateOnly", dm->prealloc_only, &dm->prealloc_only, NULL)); 9099566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_vec_type", "Vector type used for created vectors", "DMSetVecType", VecList, dm->vectype, typeName, 256, &flg)); 9101baa6e33SBarry Smith if (flg) PetscCall(DMSetVecType(dm, typeName)); 9119566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_mat_type", "Matrix type used for created matrices", "DMSetMatType", MatList, dm->mattype ? dm->mattype : typeName, typeName, sizeof(typeName), &flg)); 9121baa6e33SBarry Smith if (flg) PetscCall(DMSetMatType(dm, typeName)); 9139566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-dm_is_coloring_type", "Global or local coloring of Jacobian", "DMSetISColoringType", ISColoringTypes, (PetscEnum)dm->coloringtype, (PetscEnum *)&dm->coloringtype, NULL)); 9149566063dSJacob 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)); 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(); 919d7bf68aeSBarry Smith PetscFunctionReturn(0); 920d7bf68aeSBarry Smith } 921d7bf68aeSBarry Smith 922fc9bc008SSatish Balay /*@C 923bb7acecfSBarry Smith DMViewFromOptions - View a `DM` in a particular way based on a request in the options database 924fe2efc57SMark 925bb7acecfSBarry Smith Collective on dm 926fe2efc57SMark 927fe2efc57SMark Input Parameters: 928bb7acecfSBarry Smith + dm - the `DM` object 929bb7acecfSBarry Smith . obj - optional object that provides the prefix for the options database (if NULL then the prefix in obj is used) 930bb7acecfSBarry Smith - optionname - 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 937bb7acecfSBarry Smith .seealso: `DM`, `DMView()`, `PetscObjectViewFromOptions()`, `DMCreate()`, `PetscObjectViewFromOptions()` 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)); 944fe2efc57SMark PetscFunctionReturn(0); 945fe2efc57SMark } 946fe2efc57SMark 947fe2efc57SMark /*@C 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 951d083f849SBarry Smith Collective on dm 95247c6ae99SBarry Smith 953d8d19677SJose E. Roman Input Parameters: 954bb7acecfSBarry Smith + dm - the `DM` object to view 95547c6ae99SBarry Smith - v - the viewer 95647c6ae99SBarry Smith 957cd7e8a5eSksagiyam Notes: 958bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` as the `PetscViewerFormat` one can save multiple `DMPLEX` 959bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 960bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 961cd7e8a5eSksagiyam 962224748a4SBarry Smith Level: beginner 96347c6ae99SBarry Smith 964bb7acecfSBarry Smith .seealso: `PetscViewer`, `PetscViewerFormat`, `PetscViewerSetFormat`(), `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMLoad()`, `PetscObjectSetName()` 96547c6ae99SBarry Smith 96647c6ae99SBarry Smith @*/ 967d71ae5a4SJacob Faibussowitsch PetscErrorCode DMView(DM dm, PetscViewer v) 968d71ae5a4SJacob Faibussowitsch { 96932c0f0efSBarry Smith PetscBool isbinary; 97076a8abe0SBarry Smith PetscMPIInt size; 97176a8abe0SBarry Smith PetscViewerFormat format; 97247c6ae99SBarry Smith 97347c6ae99SBarry Smith PetscFunctionBegin; 974171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 97548a46eb9SPierre Jolivet if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm), &v)); 976b1b135c8SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 97774903a4fSStefano Zampini /* Ideally, we would like to have this test on. 97874903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 97974903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 98074903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 98174903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 98274903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 98374903a4fSStefano Zampini in an error here */ 98474903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9859566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckWritable(v)); 986b1b135c8SBarry Smith 9879566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(v, &format)); 9889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 98976a8abe0SBarry Smith if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 9909566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)dm, v)); 9919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERBINARY, &isbinary)); 99232c0f0efSBarry Smith if (isbinary) { 99355849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 99432c0f0efSBarry Smith char type[256]; 99532c0f0efSBarry Smith 9969566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, &classid, 1, PETSC_INT)); 9979566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type, ((PetscObject)dm)->type_name, 256)); 9989566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, type, 256, PETSC_CHAR)); 99932c0f0efSBarry Smith } 1000dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, view, v); 100147c6ae99SBarry Smith PetscFunctionReturn(0); 100247c6ae99SBarry Smith } 100347c6ae99SBarry Smith 100447c6ae99SBarry Smith /*@ 1005bb7acecfSBarry 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, 1006bb7acecfSBarry Smith that is it has no ghost locations. 100747c6ae99SBarry Smith 1008d083f849SBarry Smith Collective on dm 100947c6ae99SBarry Smith 101047c6ae99SBarry Smith Input Parameter: 1011bb7acecfSBarry Smith . dm - the `DM` object 101247c6ae99SBarry Smith 101347c6ae99SBarry Smith Output Parameter: 101447c6ae99SBarry Smith . vec - the global vector 101547c6ae99SBarry Smith 1016073dac72SJed Brown Level: beginner 101747c6ae99SBarry Smith 1018bb7acecfSBarry Smith .seealso: `Vec`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1019bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 102047c6ae99SBarry Smith 102147c6ae99SBarry Smith @*/ 1022d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector(DM dm, Vec *vec) 1023d71ae5a4SJacob Faibussowitsch { 102447c6ae99SBarry Smith PetscFunctionBegin; 1025171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1026b9d85ea2SLisandro Dalcin PetscValidPointer(vec, 2); 1027dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createglobalvector, vec); 102876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1029c6b011d8SStefano Zampini DM vdm; 1030c6b011d8SStefano Zampini 10319566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10327a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1033c6b011d8SStefano Zampini } 103447c6ae99SBarry Smith PetscFunctionReturn(0); 103547c6ae99SBarry Smith } 103647c6ae99SBarry Smith 103747c6ae99SBarry Smith /*@ 1038bb7acecfSBarry Smith DMCreateLocalVector - Creates a local vector from a `DM` object. 103947c6ae99SBarry Smith 104047c6ae99SBarry Smith Not Collective 104147c6ae99SBarry Smith 104247c6ae99SBarry Smith Input Parameter: 1043bb7acecfSBarry Smith . dm - the `DM` object 104447c6ae99SBarry Smith 104547c6ae99SBarry Smith Output Parameter: 104647c6ae99SBarry Smith . vec - the local vector 104747c6ae99SBarry Smith 1048073dac72SJed Brown Level: beginner 104947c6ae99SBarry Smith 1050bb7acecfSBarry Smith Notes: 1051bb7acecfSBarry 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. 1052bb7acecfSBarry Smith 1053bb7acecfSBarry Smith .seealso: `Vec`, `DMCreateGlobalVector()`, `DMGetLocalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 1054bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 105547c6ae99SBarry Smith 105647c6ae99SBarry Smith @*/ 1057d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector(DM dm, Vec *vec) 1058d71ae5a4SJacob Faibussowitsch { 105947c6ae99SBarry Smith PetscFunctionBegin; 1060171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1061b9d85ea2SLisandro Dalcin PetscValidPointer(vec, 2); 1062dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalvector, vec); 106376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1064c6b011d8SStefano Zampini DM vdm; 1065c6b011d8SStefano Zampini 10669566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10677a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_LIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1068c6b011d8SStefano Zampini } 106947c6ae99SBarry Smith PetscFunctionReturn(0); 107047c6ae99SBarry Smith } 107147c6ae99SBarry Smith 10721411c6eeSJed Brown /*@ 1073bb7acecfSBarry Smith DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a `DM`. 10741411c6eeSJed Brown 1075d083f849SBarry Smith Collective on dm 10761411c6eeSJed Brown 10771411c6eeSJed Brown Input Parameter: 1078bb7acecfSBarry Smith . dm - the `DM` that provides the mapping 10791411c6eeSJed Brown 10801411c6eeSJed Brown Output Parameter: 10811411c6eeSJed Brown . ltog - the mapping 10821411c6eeSJed Brown 1083bb7acecfSBarry Smith Level: advanced 10841411c6eeSJed Brown 10851411c6eeSJed Brown Notes: 1086bb7acecfSBarry Smith The global to local mapping allows one to set values into the global vector or matrix using `VecSetValuesLocal()` and `MatSetValuesLocal()` 10871411c6eeSJed Brown 1088bb7acecfSBarry Smith Vectors obtained with `DMCreateGlobalVector()` and matrices obtained with `DMCreateMatrix()` already contain the global mapping so you do 1089bb7acecfSBarry Smith need to use this function with those objects. 1090bb7acecfSBarry Smith 1091bb7acecfSBarry Smith This mapping can then be used by `VecSetLocalToGlobalMapping()` or `MatSetLocalToGlobalMapping()`. 1092bb7acecfSBarry Smith 1093bb7acecfSBarry Smith .seealso: `DMCreateLocalVector()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `VecSetLocalToGlobalMapping()`, `MatSetLocalToGlobalMapping()`, 1094bb7acecfSBarry Smith `DMCreateMatrix()` 10951411c6eeSJed Brown @*/ 1096d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalToGlobalMapping(DM dm, ISLocalToGlobalMapping *ltog) 1097d71ae5a4SJacob Faibussowitsch { 10980be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 10991411c6eeSJed Brown 11001411c6eeSJed Brown PetscFunctionBegin; 11011411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11021411c6eeSJed Brown PetscValidPointer(ltog, 2); 11031411c6eeSJed Brown if (!dm->ltogmap) { 110437d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 110537d0c07bSMatthew G Knepley 11069566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 110737d0c07bSMatthew G Knepley if (section) { 1108a974ec88SMatthew G. Knepley const PetscInt *cdofs; 110937d0c07bSMatthew G Knepley PetscInt *ltog; 1110ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 111137d0c07bSMatthew G Knepley 11129566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 11139566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 11149566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(section, &n)); 11159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, <og)); /* We want the local+overlap size */ 111637d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1117e6befd46SJed Brown PetscInt bdof, cdof, dof, off, c, cind; 111837d0c07bSMatthew G Knepley 111937d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 11209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(section, p, &dof)); 11219566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(section, p, &cdof)); 11229566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(section, p, &cdofs)); 11239566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &off)); 11241a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 11251a7dc684SMatthew G. Knepley bdof = cdof && (dof - cdof) ? 1 : dof; 1126ad540459SPierre Jolivet if (dof) bs = bs < 0 ? bdof : PetscGCD(bs, bdof); 11275227eafbSStefano Zampini 1128e6befd46SJed Brown for (c = 0, cind = 0; c < dof; ++c, ++l) { 11295227eafbSStefano Zampini if (cind < cdof && c == cdofs[cind]) { 1130e6befd46SJed Brown ltog[l] = off < 0 ? off - c : -(off + c + 1); 1131e6befd46SJed Brown cind++; 1132e6befd46SJed Brown } else { 11335227eafbSStefano Zampini ltog[l] = (off < 0 ? -(off + 1) : off) + c - cind; 1134e6befd46SJed Brown } 113537d0c07bSMatthew G Knepley } 113637d0c07bSMatthew G Knepley } 1137bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 11389371c9d4SSatish Balay bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; 11399371c9d4SSatish Balay bsLocal[1] = bs; 11409566063dSJacob Faibussowitsch PetscCall(PetscGlobalMinMaxInt(PetscObjectComm((PetscObject)dm), bsLocal, bsMinMax)); 11419371c9d4SSatish Balay if (bsMinMax[0] != bsMinMax[1]) { 11429371c9d4SSatish Balay bs = 1; 11439371c9d4SSatish Balay } else { 11449371c9d4SSatish Balay bs = bsMinMax[0]; 11459371c9d4SSatish Balay } 11467591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 11477591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1148ccf3bd66SMatthew G. Knepley if (bs > 1) { 1149ca469d19SJed Brown for (l = 0, k = 0; l < n; l += bs, ++k) { 1150ca469d19SJed Brown // Integer division of negative values truncates toward zero(!), not toward negative infinity 1151ca469d19SJed Brown ltog[k] = ltog[l] >= 0 ? ltog[l] / bs : -(-(ltog[l] + 1) / bs + 1); 1152ca469d19SJed Brown } 1153ccf3bd66SMatthew G. Knepley n /= bs; 1154ccf3bd66SMatthew G. Knepley } 11559566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap)); 1156dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, getlocaltoglobalmapping); 115737d0c07bSMatthew G Knepley } 11581411c6eeSJed Brown *ltog = dm->ltogmap; 11591411c6eeSJed Brown PetscFunctionReturn(0); 11601411c6eeSJed Brown } 11611411c6eeSJed Brown 11621411c6eeSJed Brown /*@ 1163bb7acecfSBarry Smith DMGetBlockSize - Gets the inherent block size associated with a `DM` 11641411c6eeSJed Brown 11651411c6eeSJed Brown Not Collective 11661411c6eeSJed Brown 11671411c6eeSJed Brown Input Parameter: 1168bb7acecfSBarry Smith . dm - the `DM` with block structure 11691411c6eeSJed Brown 11701411c6eeSJed Brown Output Parameter: 11711411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11721411c6eeSJed Brown 11731411c6eeSJed Brown Level: intermediate 11741411c6eeSJed Brown 1175bb7acecfSBarry Smith Note: 1176bb7acecfSBarry Smith This might be the number of degrees of freedom at each grid point for a structured grid. 1177bb7acecfSBarry Smith 1178bb7acecfSBarry Smith Complex `DM` that represent multiphysics or staggered grids or mixed-methods do not generally have a single inherent block size, but 1179bb7acecfSBarry Smith rather different locations in the vectors may have a different block size. 1180bb7acecfSBarry Smith 1181db781477SPatrick Sanan .seealso: `ISCreateBlock()`, `VecSetBlockSize()`, `MatSetBlockSize()`, `DMGetLocalToGlobalMapping()` 11821411c6eeSJed Brown @*/ 1183d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBlockSize(DM dm, PetscInt *bs) 1184d71ae5a4SJacob Faibussowitsch { 11851411c6eeSJed Brown PetscFunctionBegin; 11861411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1187534a8f05SLisandro Dalcin PetscValidIntPointer(bs, 2); 11887a8be351SBarry Smith PetscCheck(dm->bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM does not have enough information to provide a block size yet"); 11891411c6eeSJed Brown *bs = dm->bs; 11901411c6eeSJed Brown PetscFunctionReturn(0); 11911411c6eeSJed Brown } 11921411c6eeSJed Brown 119348eeb7c8SBarry Smith /*@C 1194bb7acecfSBarry Smith DMCreateInterpolation - Gets the interpolation matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1195bb7acecfSBarry Smith `DMCreateGlobalVector()` on the coarse `DM` to similar vectors on the fine grid `DM`. 119647c6ae99SBarry Smith 1197a5bc1bf3SBarry Smith Collective on dmc 119847c6ae99SBarry Smith 1199d8d19677SJose E. Roman Input Parameters: 1200bb7acecfSBarry Smith + dmc - the `DM` object 1201bb7acecfSBarry Smith - dmf - the second, finer `DM` object 120247c6ae99SBarry Smith 1203d8d19677SJose E. Roman Output Parameters: 120447c6ae99SBarry Smith + mat - the interpolation 1205bb7acecfSBarry Smith - vec - the scaling (optional), see `DMCreateInterpolationScale()` 120647c6ae99SBarry Smith 120747c6ae99SBarry Smith Level: developer 120847c6ae99SBarry Smith 120995452b02SPatrick Sanan Notes: 1210bb7acecfSBarry 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 1211bb7acecfSBarry Smith DMCoarsen(). The coordinates set into the `DMDA` are completely ignored in computing the interpolation. 1212d52bd9f3SBarry Smith 1213bb7acecfSBarry Smith For `DMDA` objects you can use this interpolation (more precisely the interpolation from the `DMGetCoordinateDM()`) to interpolate the mesh coordinate 1214bb7acecfSBarry Smith vectors EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 121585afcc9aSBarry Smith 1216bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolationScale()` 121747c6ae99SBarry Smith 121847c6ae99SBarry Smith @*/ 1219d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolation(DM dmc, DM dmf, Mat *mat, Vec *vec) 1220d71ae5a4SJacob Faibussowitsch { 122147c6ae99SBarry Smith PetscFunctionBegin; 1222a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1223a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 1224c7d20fa0SStefano Zampini PetscValidPointer(mat, 3); 12259566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInterpolation, dmc, dmf, 0, 0)); 1226dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createinterpolation, dmf, mat, vec); 12279566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInterpolation, dmc, dmf, 0, 0)); 122847c6ae99SBarry Smith PetscFunctionReturn(0); 122947c6ae99SBarry Smith } 123047c6ae99SBarry Smith 12313ad4599aSBarry Smith /*@ 1232bb7acecfSBarry Smith DMCreateInterpolationScale - Forms L = 1/(R*1) where 1 is the vector of all ones, and R is the transpose of the interpolation between the `DM`. 1233bb7acecfSBarry Smith xcoarse = diag(L)*R*xfine preserves scale and is thus suitable for state (versus residual) restriction. In other words xcoarse is the coarse 1234bb7acecfSBarry Smith representation of xfine. 12352ed6491fSPatrick Sanan 12362ed6491fSPatrick Sanan Input Parameters: 1237bb7acecfSBarry Smith + dac - `DM` that defines a coarse mesh 1238bb7acecfSBarry Smith . daf - `DM` that defines a fine mesh 12392ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 12402ed6491fSPatrick Sanan 12412ed6491fSPatrick Sanan Output Parameter: 12422ed6491fSPatrick Sanan . scale - the scaled vector 12432ed6491fSPatrick Sanan 1244bb7acecfSBarry Smith Level: advanced 12452ed6491fSPatrick Sanan 1246e9c74fd6SRichard Tran Mills Developer Notes: 1247bb7acecfSBarry Smith If the fine-scale `DMDA` has the -dm_bind_below option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 1248e9c74fd6SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 1249e9c74fd6SRichard Tran Mills 1250bb7acecfSBarry Smith .seealso: `MatRestrict()`, `MatInterpolate()`, `DMCreateInterpolation()`, DMCreateRestriction()`, `DMCreateGlobalVector()` 12512ed6491fSPatrick Sanan 12522ed6491fSPatrick Sanan @*/ 1253d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolationScale(DM dac, DM daf, Mat mat, Vec *scale) 1254d71ae5a4SJacob Faibussowitsch { 12552ed6491fSPatrick Sanan Vec fine; 12562ed6491fSPatrick Sanan PetscScalar one = 1.0; 12579704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 1258e9c74fd6SRichard Tran Mills PetscBool bindingpropagates, isbound; 12599704db99SRichard Tran Mills #endif 12602ed6491fSPatrick Sanan 12612ed6491fSPatrick Sanan PetscFunctionBegin; 12629566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(daf, &fine)); 12639566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dac, scale)); 12649566063dSJacob Faibussowitsch PetscCall(VecSet(fine, one)); 12659704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 12669704db99SRichard Tran Mills /* If the 'fine' Vec is bound to the CPU, it makes sense to bind 'mat' as well. 12679704db99SRichard Tran Mills * Note that we only do this for the CUDA case, right now, but if we add support for MatMultTranspose() via ViennaCL, 12689704db99SRichard Tran Mills * we'll need to do it for that case, too.*/ 12699566063dSJacob Faibussowitsch PetscCall(VecGetBindingPropagates(fine, &bindingpropagates)); 1270e9c74fd6SRichard Tran Mills if (bindingpropagates) { 12719566063dSJacob Faibussowitsch PetscCall(MatSetBindingPropagates(mat, PETSC_TRUE)); 12729566063dSJacob Faibussowitsch PetscCall(VecBoundToCPU(fine, &isbound)); 12739566063dSJacob Faibussowitsch PetscCall(MatBindToCPU(mat, isbound)); 127483aa49f4SRichard Tran Mills } 12759704db99SRichard Tran Mills #endif 12769566063dSJacob Faibussowitsch PetscCall(MatRestrict(mat, fine, *scale)); 12779566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fine)); 12789566063dSJacob Faibussowitsch PetscCall(VecReciprocal(*scale)); 12792ed6491fSPatrick Sanan PetscFunctionReturn(0); 12802ed6491fSPatrick Sanan } 12812ed6491fSPatrick Sanan 12822ed6491fSPatrick Sanan /*@ 1283bb7acecfSBarry Smith DMCreateRestriction - Gets restriction matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1284bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine `DM` to similar vectors on the coarse grid `DM`. 12853ad4599aSBarry Smith 1286a5bc1bf3SBarry Smith Collective on dmc 12873ad4599aSBarry Smith 1288d8d19677SJose E. Roman Input Parameters: 1289bb7acecfSBarry Smith + dmc - the `DM` object 1290bb7acecfSBarry Smith - dmf - the second, finer `DM` object 12913ad4599aSBarry Smith 12923ad4599aSBarry Smith Output Parameter: 12933ad4599aSBarry Smith . mat - the restriction 12943ad4599aSBarry Smith 12953ad4599aSBarry Smith Level: developer 12963ad4599aSBarry Smith 1297bb7acecfSBarry Smith Note: 1298bb7acecfSBarry Smith This only works for `DMSTAG`. For many situations either the transpose of the operator obtained with `DMCreateInterpolation()` or that 1299bb7acecfSBarry Smith matrix multiplied by the vector obtained with `DMCreateInterpolationScale()` provides the desired object. 13003ad4599aSBarry Smith 1301bb7acecfSBarry Smith .seealso: `DMRestrict()`, `DMInterpolate()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateInterpolation()` 13023ad4599aSBarry Smith 13033ad4599aSBarry Smith @*/ 1304d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateRestriction(DM dmc, DM dmf, Mat *mat) 1305d71ae5a4SJacob Faibussowitsch { 13063ad4599aSBarry Smith PetscFunctionBegin; 1307a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1308a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13095a84ad33SLisandro Dalcin PetscValidPointer(mat, 3); 13109566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateRestriction, dmc, dmf, 0, 0)); 1311dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createrestriction, dmf, mat); 13129566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateRestriction, dmc, dmf, 0, 0)); 13133ad4599aSBarry Smith PetscFunctionReturn(0); 13143ad4599aSBarry Smith } 13153ad4599aSBarry Smith 131647c6ae99SBarry Smith /*@ 1317bb7acecfSBarry Smith DMCreateInjection - Gets injection matrix between two `DM` objects. This is an operator that applied to a vector obtained with 1318bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine grid maps the values to a vector on the vector on the coarse `DM` by simply selecting the values 1319bb7acecfSBarry Smith on the coarse grid points. This compares to the operator obtained by `DMCreateRestriction()` or the transpose of the operator obtained 1320bb7acecfSBarry Smith by `DMCreateInterpolation()` that uses a "local weighted average" of the values around the coarse grid point as the coarse grid value. 132147c6ae99SBarry Smith 1322a5bc1bf3SBarry Smith Collective on dac 132347c6ae99SBarry Smith 1324d8d19677SJose E. Roman Input Parameters: 1325bb7acecfSBarry Smith + dac - the `DM` object 1326bb7acecfSBarry Smith - daf - the second, finer `DM` object 132747c6ae99SBarry Smith 132847c6ae99SBarry Smith Output Parameter: 13296dbf9973SLawrence Mitchell . mat - the injection 133047c6ae99SBarry Smith 133147c6ae99SBarry Smith Level: developer 133247c6ae99SBarry Smith 1333bb7acecfSBarry Smith Note: 1334bb7acecfSBarry 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 1335bb7acecfSBarry Smith `DMCoarsen()`. The coordinates set into the `DMDA` are completely ignored in computing the injection. 133685afcc9aSBarry Smith 1337bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateInterpolation()`, 1338bb7acecfSBarry Smith `DMCreateRestriction()`, `MatRestrict()`, `MatInterpolate()` 133947c6ae99SBarry Smith 134047c6ae99SBarry Smith @*/ 1341d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInjection(DM dac, DM daf, Mat *mat) 1342d71ae5a4SJacob Faibussowitsch { 134347c6ae99SBarry Smith PetscFunctionBegin; 1344a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac, DM_CLASSID, 1); 1345a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf, DM_CLASSID, 2); 13465a84ad33SLisandro Dalcin PetscValidPointer(mat, 3); 13479566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInjection, dac, daf, 0, 0)); 1348dbbe0bcdSBarry Smith PetscUseTypeMethod(dac, createinjection, daf, mat); 13499566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInjection, dac, daf, 0, 0)); 135047c6ae99SBarry Smith PetscFunctionReturn(0); 135147c6ae99SBarry Smith } 135247c6ae99SBarry Smith 1353b412c318SBarry Smith /*@ 1354bb7acecfSBarry 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 1355bb7acecfSBarry Smith a Galerkin finite element model on the `DM` 1356bd041c0cSMatthew G. Knepley 1357a5bc1bf3SBarry Smith Collective on dac 1358bd041c0cSMatthew G. Knepley 1359d8d19677SJose E. Roman Input Parameters: 1360bb7acecfSBarry Smith + dmc - the target `DM` object 1361bb7acecfSBarry Smith - dmf - the source `DM` object 1362bd041c0cSMatthew G. Knepley 1363bd041c0cSMatthew G. Knepley Output Parameter: 1364b4937a87SMatthew G. Knepley . mat - the mass matrix 1365bd041c0cSMatthew G. Knepley 1366bd041c0cSMatthew G. Knepley Level: developer 1367bd041c0cSMatthew G. Knepley 1368bb7acecfSBarry Smith Notes: 1369bb7acecfSBarry Smith For `DMPLEX` the finite element model for the `DM` must have been already provided. 1370bb7acecfSBarry Smith 1371bb7acecfSBarry Smith if dmc is dmf then x^t M x is an approximation to the L2 norm of the vector x which is obtained by `DMCreateGlobalVector()` 1372bb7acecfSBarry Smith 1373bb7acecfSBarry Smith .seealso: `DMCreateMassMatrixLumped()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1374bd041c0cSMatthew G. Knepley @*/ 1375d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrix(DM dmc, DM dmf, Mat *mat) 1376d71ae5a4SJacob Faibussowitsch { 1377bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1378b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1379b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13805a84ad33SLisandro Dalcin PetscValidPointer(mat, 3); 13815b8ffe73SMark Adams PetscCall(PetscLogEventBegin(DM_CreateMassMatrix, 0, 0, 0, 0)); 1382dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createmassmatrix, dmf, mat); 13835b8ffe73SMark Adams PetscCall(PetscLogEventEnd(DM_CreateMassMatrix, 0, 0, 0, 0)); 1384b4937a87SMatthew G. Knepley PetscFunctionReturn(0); 1385b4937a87SMatthew G. Knepley } 1386b4937a87SMatthew G. Knepley 1387b4937a87SMatthew G. Knepley /*@ 1388bb7acecfSBarry Smith DMCreateMassMatrixLumped - Gets the lumped mass matrix for a given `DM` 1389b4937a87SMatthew G. Knepley 1390b4937a87SMatthew G. Knepley Collective on dm 1391b4937a87SMatthew G. Knepley 1392b4937a87SMatthew G. Knepley Input Parameter: 1393bb7acecfSBarry Smith . dm - the `DM` object 1394b4937a87SMatthew G. Knepley 1395b4937a87SMatthew G. Knepley Output Parameter: 1396bb7acecfSBarry Smith . lm - the lumped mass matrix, which is a diagonal matrix, represented as a vector 1397b4937a87SMatthew G. Knepley 1398b4937a87SMatthew G. Knepley Level: developer 1399b4937a87SMatthew G. Knepley 1400bb7acecfSBarry Smith Note: 1401bb7acecfSBarry Smith See `DMCreateMassMatrix()` for how to create the non-lumped version of the mass matrix. 1402bb7acecfSBarry Smith 1403bb7acecfSBarry Smith .seealso: `DMCreateMassMatrix()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1404b4937a87SMatthew G. Knepley @*/ 1405d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrixLumped(DM dm, Vec *lm) 1406d71ae5a4SJacob Faibussowitsch { 1407b4937a87SMatthew G. Knepley PetscFunctionBegin; 1408b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1409b4937a87SMatthew G. Knepley PetscValidPointer(lm, 2); 1410dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createmassmatrixlumped, lm); 1411bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 1412bd041c0cSMatthew G. Knepley } 1413bd041c0cSMatthew G. Knepley 1414bd041c0cSMatthew G. Knepley /*@ 1415bb7acecfSBarry Smith DMCreateColoring - Gets coloring of a graph associated with the `DM`. Often the graph represents the operator matrix associated with the discretization 1416bb7acecfSBarry Smith of a PDE on the `DM`. 141747c6ae99SBarry Smith 1418d083f849SBarry Smith Collective on dm 141947c6ae99SBarry Smith 1420d8d19677SJose E. Roman Input Parameters: 1421bb7acecfSBarry Smith + dm - the `DM` object 1422bb7acecfSBarry Smith - ctype - `IS_COLORING_LOCAL` or `IS_COLORING_GLOBAL` 142347c6ae99SBarry Smith 142447c6ae99SBarry Smith Output Parameter: 142547c6ae99SBarry Smith . coloring - the coloring 142647c6ae99SBarry Smith 1427ec5066bdSBarry Smith Notes: 1428bb7acecfSBarry 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 1429bb7acecfSBarry Smith matrix comes from (what this function provides). In general using the mesh produces a more optimal coloring (fewer colors). 1430ec5066bdSBarry Smith 1431bb7acecfSBarry Smith This produces a coloring with the distance of 2, see `MatSetColoringDistance()` which can be used for efficiently computing Jacobians with `MatFDColoringCreate()` 1432ec5066bdSBarry Smith 143347c6ae99SBarry Smith Level: developer 143447c6ae99SBarry Smith 1435bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatType()`, `MatColoring`, `MatFDColoringCreate()` 143647c6ae99SBarry Smith 1437aab9d709SJed Brown @*/ 1438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateColoring(DM dm, ISColoringType ctype, ISColoring *coloring) 1439d71ae5a4SJacob Faibussowitsch { 144047c6ae99SBarry Smith PetscFunctionBegin; 1441171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14425a84ad33SLisandro Dalcin PetscValidPointer(coloring, 3); 1443dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getcoloring, ctype, coloring); 144447c6ae99SBarry Smith PetscFunctionReturn(0); 144547c6ae99SBarry Smith } 144647c6ae99SBarry Smith 1447b412c318SBarry Smith /*@ 1448bb7acecfSBarry Smith DMCreateMatrix - Gets an empty matrix for a `DM` that is most commonly used to store the Jacobian of a discrete PDE operator. 144947c6ae99SBarry Smith 1450d083f849SBarry Smith Collective on dm 145147c6ae99SBarry Smith 145247c6ae99SBarry Smith Input Parameter: 1453bb7acecfSBarry Smith . dm - the `DM` object 145447c6ae99SBarry Smith 145547c6ae99SBarry Smith Output Parameter: 145647c6ae99SBarry Smith . mat - the empty Jacobian 145747c6ae99SBarry Smith 1458073dac72SJed Brown Level: beginner 145947c6ae99SBarry Smith 1460f27dd7c6SMatthew G. Knepley Options Database Keys: 1461bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 1462f27dd7c6SMatthew G. Knepley 146395452b02SPatrick Sanan Notes: 146495452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 146594013140SBarry Smith do not need to do it yourself. 146694013140SBarry Smith 146794013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 1468bb7acecfSBarry Smith the nonzero pattern call `DMSetMatrixPreallocateOnly()` 146994013140SBarry Smith 1470bb7acecfSBarry Smith For `DMDA`, when you call `MatView()` on this matrix it is displayed using the global natural ordering, NOT in the ordering used 147194013140SBarry Smith internally by PETSc. 147294013140SBarry Smith 1473bb7acecfSBarry Smith For `DMDA`, in general it is easiest to use `MatSetValuesStencil()` or `MatSetValuesLocal()` to put values into the matrix because 1474bb7acecfSBarry Smith `MatSetValues()` requires the indices for the global numbering for the `DMDA` which is complic`ated to compute 147594013140SBarry Smith 1476bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMSetMatType()`, `DMCreateMassMatrix()` 147747c6ae99SBarry Smith 1478aab9d709SJed Brown @*/ 1479d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMatrix(DM dm, Mat *mat) 1480d71ae5a4SJacob Faibussowitsch { 148147c6ae99SBarry Smith PetscFunctionBegin; 1482171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1483064a246eSJacob Faibussowitsch PetscValidPointer(mat, 2); 14849566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 14859566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateMatrix, 0, 0, 0, 0)); 1486dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, creatematrix, mat); 148776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1488c6b011d8SStefano Zampini DM mdm; 1489c6b011d8SStefano Zampini 14909566063dSJacob Faibussowitsch PetscCall(MatGetDM(*mat, &mdm)); 14917a8be351SBarry Smith PetscCheck(mdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the matrix", ((PetscObject)dm)->type_name); 1492c6b011d8SStefano Zampini } 1493e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1494e5e52638SMatthew G. Knepley if (dm->Nf) { 1495e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1496649ef022SMatthew Knepley PetscInt Nf, f; 1497e571a35bSMatthew G. Knepley 14989566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1499649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1500649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 15019566063dSJacob Faibussowitsch PetscCall((*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace)); 15029566063dSJacob Faibussowitsch PetscCall(MatSetNullSpace(*mat, nullSpace)); 15039566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1504649ef022SMatthew Knepley break; 1505e571a35bSMatthew G. Knepley } 1506649ef022SMatthew Knepley } 1507649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1508649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 15099566063dSJacob Faibussowitsch PetscCall((*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace)); 15109566063dSJacob Faibussowitsch PetscCall(MatSetNearNullSpace(*mat, nullSpace)); 15119566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1512e571a35bSMatthew G. Knepley } 1513e571a35bSMatthew G. Knepley } 1514e571a35bSMatthew G. Knepley } 15159566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateMatrix, 0, 0, 0, 0)); 151647c6ae99SBarry Smith PetscFunctionReturn(0); 151747c6ae99SBarry Smith } 151847c6ae99SBarry Smith 1519732e2eb9SMatthew G Knepley /*@ 1520bb7acecfSBarry Smith DMSetMatrixPreallocateSkip - When `DMCreateMatrix()` is called the matrix sizes and `ISLocalToGlobalMapping` will be 1521bb7acecfSBarry Smith properly set, but the data structures to store values in the matrices will not be preallocated. This is most useful to reduce initialization costs when 1522bb7acecfSBarry Smith `MatSetPreallocationCOO()` and `MatSetValuesCOO()` will be used. 1523aa0f6e3cSJed Brown 1524aa0f6e3cSJed Brown Logically Collective on dm 1525aa0f6e3cSJed Brown 1526aa0f6e3cSJed Brown Input Parameters: 1527bb7acecfSBarry Smith + dm - the `DM` 1528bb7acecfSBarry Smith - skip - `PETSC_TRUE` to skip preallocation 1529aa0f6e3cSJed Brown 1530aa0f6e3cSJed Brown Level: developer 1531aa0f6e3cSJed Brown 1532bb7acecfSBarry Smith .seealso: `DMCreateMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateOnly()` 1533aa0f6e3cSJed Brown @*/ 1534d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateSkip(DM dm, PetscBool skip) 1535d71ae5a4SJacob Faibussowitsch { 1536aa0f6e3cSJed Brown PetscFunctionBegin; 1537aa0f6e3cSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1538aa0f6e3cSJed Brown dm->prealloc_skip = skip; 1539aa0f6e3cSJed Brown PetscFunctionReturn(0); 1540aa0f6e3cSJed Brown } 1541aa0f6e3cSJed Brown 1542aa0f6e3cSJed Brown /*@ 1543bb7acecfSBarry Smith DMSetMatrixPreallocateOnly - When `DMCreateMatrix()` is called the matrix will be properly 1544732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1545732e2eb9SMatthew G Knepley 1546d083f849SBarry Smith Logically Collective on dm 1547732e2eb9SMatthew G Knepley 1548d8d19677SJose E. Roman Input Parameters: 1549bb7acecfSBarry Smith + dm - the `DM` 1550bb7acecfSBarry Smith - only - `PETSC_TRUE` if only want preallocation 1551732e2eb9SMatthew G Knepley 1552732e2eb9SMatthew G Knepley Level: developer 1553f27dd7c6SMatthew G. Knepley 1554f27dd7c6SMatthew G. Knepley Options Database Keys: 1555bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()`, `DMCreateMassMatrix()`, but do not fill it with zeros 1556f27dd7c6SMatthew G. Knepley 1557bb7acecfSBarry Smith .seealso: `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateSkip()` 1558732e2eb9SMatthew G Knepley @*/ 1559d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1560d71ae5a4SJacob Faibussowitsch { 1561732e2eb9SMatthew G Knepley PetscFunctionBegin; 1562732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1563732e2eb9SMatthew G Knepley dm->prealloc_only = only; 1564732e2eb9SMatthew G Knepley PetscFunctionReturn(0); 1565732e2eb9SMatthew G Knepley } 1566732e2eb9SMatthew G Knepley 1567b06ff27eSHong Zhang /*@ 1568bb7acecfSBarry Smith DMSetMatrixStructureOnly - When `DMCreateMatrix()` is called, the matrix structure will be created 1569bb7acecfSBarry Smith but the array for numerical values will not be allocated. 1570b06ff27eSHong Zhang 1571d083f849SBarry Smith Logically Collective on dm 1572b06ff27eSHong Zhang 1573d8d19677SJose E. Roman Input Parameters: 1574bb7acecfSBarry Smith + dm - the `DM` 1575bb7acecfSBarry Smith - only - `PETSC_TRUE` if you only want matrix stucture 1576b06ff27eSHong Zhang 1577b06ff27eSHong Zhang Level: developer 1578bb7acecfSBarry Smith 1579bb7acecfSBarry Smith .seealso: `DMCreateMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMSetMatrixPreallocateSkip()` 1580b06ff27eSHong Zhang @*/ 1581d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1582d71ae5a4SJacob Faibussowitsch { 1583b06ff27eSHong Zhang PetscFunctionBegin; 1584b06ff27eSHong Zhang PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1585b06ff27eSHong Zhang dm->structure_only = only; 1586b06ff27eSHong Zhang PetscFunctionReturn(0); 1587b06ff27eSHong Zhang } 1588b06ff27eSHong Zhang 1589a89ea682SMatthew G Knepley /*@C 1590bb7acecfSBarry Smith DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with `DMRestoreWorkArray()` 1591a89ea682SMatthew G Knepley 1592a89ea682SMatthew G Knepley Not Collective 1593a89ea682SMatthew G Knepley 1594a89ea682SMatthew G Knepley Input Parameters: 1595bb7acecfSBarry Smith + dm - the `DM` object 1596a5b23f4aSJose E. Roman . count - The minimum size 1597bb7acecfSBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, or MPIU_INT) 1598a89ea682SMatthew G Knepley 1599a89ea682SMatthew G Knepley Output Parameter: 1600a89ea682SMatthew G Knepley . array - the work array 1601a89ea682SMatthew G Knepley 1602a89ea682SMatthew G Knepley Level: developer 1603a89ea682SMatthew G Knepley 1604bb7acecfSBarry Smith Note: 1605bb7acecfSBarry Smith A `DM` may stash the array between instantations so using this routine may be more efficient than calling `PetscMalloc()` 1606bb7acecfSBarry Smith 1607bb7acecfSBarry Smith The array may contain nonzero values 1608bb7acecfSBarry Smith 1609bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMCreate()`, `DMRestoreWorkArray()`, `PetscMalloc()` 1610a89ea682SMatthew G Knepley @*/ 1611d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1612d71ae5a4SJacob Faibussowitsch { 1613aa1993deSMatthew G Knepley DMWorkLink link; 161469291d52SBarry Smith PetscMPIInt dsize; 1615a89ea682SMatthew G Knepley 1616a89ea682SMatthew G Knepley PetscFunctionBegin; 1617a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1618aa1993deSMatthew G Knepley PetscValidPointer(mem, 4); 1619aa1993deSMatthew G Knepley if (dm->workin) { 1620aa1993deSMatthew G Knepley link = dm->workin; 1621aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1622aa1993deSMatthew G Knepley } else { 16234dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&link)); 1624a89ea682SMatthew G Knepley } 16259566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_size(dtype, &dsize)); 16265056fcd2SBarry Smith if (((size_t)dsize * count) > link->bytes) { 16279566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 16289566063dSJacob Faibussowitsch PetscCall(PetscMalloc(dsize * count, &link->mem)); 1629854ce69bSBarry Smith link->bytes = dsize * count; 1630aa1993deSMatthew G Knepley } 1631aa1993deSMatthew G Knepley link->next = dm->workout; 1632aa1993deSMatthew G Knepley dm->workout = link; 1633cea3dcb8SSatish Balay #if defined(__MEMCHECK_H) && (defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) || defined(PLAT_amd64_darwin)) 163400d952a4SJed Brown VALGRIND_MAKE_MEM_NOACCESS((char *)link->mem + (size_t)dsize * count, link->bytes - (size_t)dsize * count); 163500d952a4SJed Brown VALGRIND_MAKE_MEM_UNDEFINED(link->mem, (size_t)dsize * count); 163600d952a4SJed Brown #endif 1637aa1993deSMatthew G Knepley *(void **)mem = link->mem; 1638a89ea682SMatthew G Knepley PetscFunctionReturn(0); 1639a89ea682SMatthew G Knepley } 1640a89ea682SMatthew G Knepley 1641aa1993deSMatthew G Knepley /*@C 1642bb7acecfSBarry Smith DMRestoreWorkArray - Restores a work array obtained with `DMCreateWorkArray()` 1643aa1993deSMatthew G Knepley 1644aa1993deSMatthew G Knepley Not Collective 1645aa1993deSMatthew G Knepley 1646aa1993deSMatthew G Knepley Input Parameters: 1647bb7acecfSBarry Smith + dm - the `DM` object 1648a5b23f4aSJose E. Roman . count - The minimum size 164969291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT 1650aa1993deSMatthew G Knepley 1651aa1993deSMatthew G Knepley Output Parameter: 1652aa1993deSMatthew G Knepley . array - the work array 1653aa1993deSMatthew G Knepley 1654aa1993deSMatthew G Knepley Level: developer 1655aa1993deSMatthew G Knepley 165695452b02SPatrick Sanan Developer Notes: 1657bb7acecfSBarry Smith count and dtype are ignored, they are only needed for `DMGetWorkArray()` 1658147403d9SBarry Smith 1659bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMCreate()`, `DMGetWorkArray()` 1660aa1993deSMatthew G Knepley @*/ 1661d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1662d71ae5a4SJacob Faibussowitsch { 1663aa1993deSMatthew G Knepley DMWorkLink *p, link; 1664aa1993deSMatthew G Knepley 1665aa1993deSMatthew G Knepley PetscFunctionBegin; 1666aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1667aa1993deSMatthew G Knepley PetscValidPointer(mem, 4); 1668aa1993deSMatthew G Knepley for (p = &dm->workout; (link = *p); p = &link->next) { 1669aa1993deSMatthew G Knepley if (link->mem == *(void **)mem) { 1670aa1993deSMatthew G Knepley *p = link->next; 1671aa1993deSMatthew G Knepley link->next = dm->workin; 1672aa1993deSMatthew G Knepley dm->workin = link; 16730298fd71SBarry Smith *(void **)mem = NULL; 1674aa1993deSMatthew G Knepley PetscFunctionReturn(0); 1675aa1993deSMatthew G Knepley } 1676aa1993deSMatthew G Knepley } 1677aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Array was not checked out"); 1678aa1993deSMatthew G Knepley } 1679e7c4fc90SDmitry Karpeev 16808cda7954SMatthew G. Knepley /*@C 1681bb7acecfSBarry Smith DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field, defined with `DMAddField()`, when function spaces 1682bb7acecfSBarry Smith are joined or split, such as in `DMCreateSubDM()` 16838cda7954SMatthew G. Knepley 1684bb7acecfSBarry Smith Logically collective on dm 16858cda7954SMatthew G. Knepley 16868cda7954SMatthew G. Knepley Input Parameters: 1687bb7acecfSBarry Smith + dm - The `DM` 16888cda7954SMatthew G. Knepley . field - The field number for the nullspace 16898cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 16908cda7954SMatthew G. Knepley 1691147403d9SBarry Smith Calling sequence of nullsp: 1692147403d9SBarry Smith .vb 1693147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1694147403d9SBarry Smith .ve 1695bb7acecfSBarry Smith + dm - The present `DM` 1696bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1697147403d9SBarry Smith . field - The field number in dm 1698147403d9SBarry Smith - nullSpace - The nullspace for the given field 16998cda7954SMatthew G. Knepley 170049762cbcSSatish Balay Level: intermediate 170149762cbcSSatish Balay 1702bb7acecfSBarry Smith Fortran Notes: 1703bb7acecfSBarry Smith This function is not available from Fortran. 1704bb7acecfSBarry Smith 1705bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1706147403d9SBarry Smith @*/ 1707d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM, PetscInt, PetscInt, MatNullSpace *)) 1708d71ae5a4SJacob Faibussowitsch { 1709435a35e8SMatthew G Knepley PetscFunctionBegin; 1710435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17117a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1712435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 1713435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1714435a35e8SMatthew G Knepley } 1715435a35e8SMatthew G Knepley 17168cda7954SMatthew G. Knepley /*@C 1717bb7acecfSBarry Smith DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, defined with `DMAddField()` 17188cda7954SMatthew G. Knepley 17198cda7954SMatthew G. Knepley Not collective 17208cda7954SMatthew G. Knepley 17218cda7954SMatthew G. Knepley Input Parameters: 1722bb7acecfSBarry Smith + dm - The `DM` 17238cda7954SMatthew G. Knepley - field - The field number for the nullspace 17248cda7954SMatthew G. Knepley 17258cda7954SMatthew G. Knepley Output Parameter: 17268cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 17278cda7954SMatthew G. Knepley 1728147403d9SBarry Smith Calling sequence of nullsp: 1729147403d9SBarry Smith .vb 1730147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1731147403d9SBarry Smith .ve 1732147403d9SBarry Smith + dm - The present DM 1733147403d9SBarry Smith . origField - The field number given above, in the original DM 1734147403d9SBarry Smith . field - The field number in dm 1735147403d9SBarry Smith - nullSpace - The nullspace for the given field 17368cda7954SMatthew G. Knepley 1737bb7acecfSBarry Smith Fortran Note: 1738bb7acecfSBarry Smith This function is not available from Fortran. 17398cda7954SMatthew G. Knepley 174049762cbcSSatish Balay Level: intermediate 174149762cbcSSatish Balay 1742bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetField()`, `DMSetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1743147403d9SBarry Smith @*/ 1744d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM, PetscInt, PetscInt, MatNullSpace *)) 1745d71ae5a4SJacob Faibussowitsch { 17460a50eb56SMatthew G. Knepley PetscFunctionBegin; 17470a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1748f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 17497a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 17500a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 17510a50eb56SMatthew G. Knepley PetscFunctionReturn(0); 17520a50eb56SMatthew G. Knepley } 17530a50eb56SMatthew G. Knepley 17548cda7954SMatthew G. Knepley /*@C 1755bb7acecfSBarry Smith DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 17568cda7954SMatthew G. Knepley 1757bb7acecfSBarry Smith Logically collective on dm 17588cda7954SMatthew G. Knepley 17598cda7954SMatthew G. Knepley Input Parameters: 1760bb7acecfSBarry Smith + dm - The `DM` 17618cda7954SMatthew G. Knepley . field - The field number for the nullspace 17628cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 17638cda7954SMatthew G. Knepley 1764147403d9SBarry Smith Calling sequence of nullsp: 1765147403d9SBarry Smith .vb 1766147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1767147403d9SBarry Smith .ve 1768bb7acecfSBarry Smith + dm - The present `DM` 1769bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1770147403d9SBarry Smith . field - The field number in dm 1771147403d9SBarry Smith - nullSpace - The nullspace for the given field 17728cda7954SMatthew G. Knepley 1773bb7acecfSBarry Smith Fortran Note: 1774bb7acecfSBarry Smith This function is not available from Fortran. 17758cda7954SMatthew G. Knepley 177649762cbcSSatish Balay Level: intermediate 177749762cbcSSatish Balay 1778bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()`, 1779bb7acecfSBarry Smith `MatNullSpace` 1780147403d9SBarry Smith @*/ 1781d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM, PetscInt, PetscInt, MatNullSpace *)) 1782d71ae5a4SJacob Faibussowitsch { 1783f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1784f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17857a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1786f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 1787f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1788f9d4088aSMatthew G. Knepley } 1789f9d4088aSMatthew G. Knepley 17908cda7954SMatthew G. Knepley /*@C 1791bb7acecfSBarry Smith DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 17928cda7954SMatthew G. Knepley 17938cda7954SMatthew G. Knepley Not collective 17948cda7954SMatthew G. Knepley 17958cda7954SMatthew G. Knepley Input Parameters: 1796bb7acecfSBarry Smith + dm - The `DM` 17978cda7954SMatthew G. Knepley - field - The field number for the nullspace 17988cda7954SMatthew G. Knepley 17998cda7954SMatthew G. Knepley Output Parameter: 18008cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 18018cda7954SMatthew G. Knepley 1802147403d9SBarry Smith Calling sequence of nullsp: 1803147403d9SBarry Smith .vb 1804147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1805147403d9SBarry Smith .ve 1806bb7acecfSBarry Smith + dm - The present `DM` 1807bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1808147403d9SBarry Smith . field - The field number in dm 1809147403d9SBarry Smith - nullSpace - The nullspace for the given field 18108cda7954SMatthew G. Knepley 1811bb7acecfSBarry Smith Fortran Note: 1812bb7acecfSBarry Smith This function is not available from Fortran. 18138cda7954SMatthew G. Knepley 181449762cbcSSatish Balay Level: intermediate 181549762cbcSSatish Balay 1816bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetField()`, `DMSetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, 1817bb7acecfSBarry Smith `MatNullSpace`, `DMCreateSuperDM()` 1818147403d9SBarry Smith @*/ 1819d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM, PetscInt, PetscInt, MatNullSpace *)) 1820d71ae5a4SJacob Faibussowitsch { 1821f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1822f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1823f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 18247a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1825f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 1826f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1827f9d4088aSMatthew G. Knepley } 1828f9d4088aSMatthew G. Knepley 18294f3b5142SJed Brown /*@C 1830bb7acecfSBarry Smith DMCreateFieldIS - Creates a set of `IS` objects with the global indices of dofs for each field defined with `DMAddField()` 18314d343eeaSMatthew G Knepley 18324d343eeaSMatthew G Knepley Not collective 18334d343eeaSMatthew G Knepley 18344d343eeaSMatthew G Knepley Input Parameter: 1835bb7acecfSBarry Smith . dm - the `DM` object 18364d343eeaSMatthew G Knepley 18374d343eeaSMatthew G Knepley Output Parameters: 18380298fd71SBarry Smith + numFields - The number of fields (or NULL if not requested) 1839bb7acecfSBarry Smith . fieldNames - The number of each field (or NULL if not requested) 18400298fd71SBarry Smith - fields - The global indices for each field (or NULL if not requested) 18414d343eeaSMatthew G Knepley 18424d343eeaSMatthew G Knepley Level: intermediate 18434d343eeaSMatthew G Knepley 1844bb7acecfSBarry Smith Note: 184521c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1846bb7acecfSBarry Smith `PetscFree()`, every entry of fields should be destroyed with `ISDestroy()`, and both arrays should be freed with 1847bb7acecfSBarry Smith `PetscFree()`. 184821c9b008SJed Brown 1849bb7acecfSBarry Smith Fortran Note: 1850bb7acecfSBarry Smith Not available in Fortran. 1851bb7acecfSBarry Smith 1852bb7acecfSBarry Smith Developer Note: 1853bb7acecfSBarry Smith It is not clear why both this function and `DMCreateFieldDecomposition()` exist. Having two seems redundant and confusing. This function should 1854bb7acecfSBarry Smith likely be removed. 1855bb7acecfSBarry Smith 1856bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetField()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1857bb7acecfSBarry Smith `DMCreateFieldDecomposition()` 18584d343eeaSMatthew G Knepley @*/ 1859d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 1860d71ae5a4SJacob Faibussowitsch { 186137d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 18624d343eeaSMatthew G Knepley 18634d343eeaSMatthew G Knepley PetscFunctionBegin; 18644d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 186569ca1f37SDmitry Karpeev if (numFields) { 1866534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 186769ca1f37SDmitry Karpeev *numFields = 0; 186869ca1f37SDmitry Karpeev } 186937d0c07bSMatthew G Knepley if (fieldNames) { 187037d0c07bSMatthew G Knepley PetscValidPointer(fieldNames, 3); 18710298fd71SBarry Smith *fieldNames = NULL; 187269ca1f37SDmitry Karpeev } 187369ca1f37SDmitry Karpeev if (fields) { 187469ca1f37SDmitry Karpeev PetscValidPointer(fields, 4); 18750298fd71SBarry Smith *fields = NULL; 187669ca1f37SDmitry Karpeev } 18779566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 187837d0c07bSMatthew G Knepley if (section) { 18793a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 188037d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 188137d0c07bSMatthew G Knepley 18829566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 18839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nF)); 18849566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nF, &fieldSizes, nF, &fieldNc, nF, &fieldIndices)); 18859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(sectionGlobal, &pStart, &pEnd)); 188637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 188737d0c07bSMatthew G Knepley fieldSizes[f] = 0; 18889566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(section, f, &fieldNc[f])); 188937d0c07bSMatthew G Knepley } 189037d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 189137d0c07bSMatthew G Knepley PetscInt gdof; 189237d0c07bSMatthew G Knepley 18939566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 189437d0c07bSMatthew G Knepley if (gdof > 0) { 189537d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 18963a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 189737d0c07bSMatthew G Knepley 18989566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 18999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 19003a544194SStefano Zampini fpdof = fdof - fcdof; 19013a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 19023a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 19033a544194SStefano Zampini fieldNc[f] = 1; 19043a544194SStefano Zampini } 19053a544194SStefano Zampini fieldSizes[f] += fpdof; 190637d0c07bSMatthew G Knepley } 190737d0c07bSMatthew G Knepley } 190837d0c07bSMatthew G Knepley } 190937d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fieldSizes[f], &fieldIndices[f])); 191137d0c07bSMatthew G Knepley fieldSizes[f] = 0; 191237d0c07bSMatthew G Knepley } 191337d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 191437d0c07bSMatthew G Knepley PetscInt gdof, goff; 191537d0c07bSMatthew G Knepley 19169566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 191737d0c07bSMatthew G Knepley if (gdof > 0) { 19189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &goff)); 191937d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 192037d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 192137d0c07bSMatthew G Knepley 19229566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19239566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 1924ad540459SPierre Jolivet for (fc = 0; fc < fdof - fcdof; ++fc, ++fieldSizes[f]) fieldIndices[f][fieldSizes[f]] = goff++; 192537d0c07bSMatthew G Knepley } 192637d0c07bSMatthew G Knepley } 192737d0c07bSMatthew G Knepley } 19288865f1eaSKarl Rupp if (numFields) *numFields = nF; 192937d0c07bSMatthew G Knepley if (fieldNames) { 19309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fieldNames)); 193137d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 193237d0c07bSMatthew G Knepley const char *fieldName; 193337d0c07bSMatthew G Knepley 19349566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 19359566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char **)&(*fieldNames)[f])); 193637d0c07bSMatthew G Knepley } 193737d0c07bSMatthew G Knepley } 193837d0c07bSMatthew G Knepley if (fields) { 19399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fields)); 194037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19413a544194SStefano Zampini PetscInt bs, in[2], out[2]; 19423a544194SStefano Zampini 19439566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f])); 19443a544194SStefano Zampini in[0] = -fieldNc[f]; 19453a544194SStefano Zampini in[1] = fieldNc[f]; 19461c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 19473a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 19489566063dSJacob Faibussowitsch PetscCall(ISSetBlockSize((*fields)[f], bs)); 194937d0c07bSMatthew G Knepley } 195037d0c07bSMatthew G Knepley } 19519566063dSJacob Faibussowitsch PetscCall(PetscFree3(fieldSizes, fieldNc, fieldIndices)); 1952dbbe0bcdSBarry Smith } else PetscTryTypeMethod(dm, createfieldis, numFields, fieldNames, fields); 19534d343eeaSMatthew G Knepley PetscFunctionReturn(0); 19544d343eeaSMatthew G Knepley } 19554d343eeaSMatthew G Knepley 195616621825SDmitry Karpeev /*@C 1957bb7acecfSBarry Smith DMCreateFieldDecomposition - Returns a list of `IS` objects defining a decomposition of a problem into subproblems 1958bb7acecfSBarry Smith corresponding to different fields: each `IS` contains the global indices of the dofs of the 1959bb7acecfSBarry Smith corresponding field, defined by `DMAddField()`. The optional list of `DM`s define the `DM` for each subproblem. 1960bb7acecfSBarry Smith The same as `DMCreateFieldIS()` but also returns a `DM` for each field. 1961e7c4fc90SDmitry Karpeev 1962e7c4fc90SDmitry Karpeev Not collective 1963e7c4fc90SDmitry Karpeev 1964e7c4fc90SDmitry Karpeev Input Parameter: 1965bb7acecfSBarry Smith . dm - the `DM` object 1966e7c4fc90SDmitry Karpeev 1967e7c4fc90SDmitry Karpeev Output Parameters: 1968bb7acecfSBarry Smith + len - The number of fields (or NULL if not requested) 19690298fd71SBarry Smith . namelist - The name for each field (or NULL if not requested) 19700298fd71SBarry Smith . islist - The global indices for each field (or NULL if not requested) 1971bb7acecfSBarry Smith - dmlist - The `DM`s for each field subproblem (or NULL, if not requested; if NULL is returned, no `DM`s are defined) 1972e7c4fc90SDmitry Karpeev 1973e7c4fc90SDmitry Karpeev Level: intermediate 1974e7c4fc90SDmitry Karpeev 1975bb7acecfSBarry Smith Note: 1976e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1977bb7acecfSBarry Smith `PetscFree()`, every entry of is should be destroyed with `ISDestroy()`, every entry of dm should be destroyed with `DMDestroy()`, 1978bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 1979e7c4fc90SDmitry Karpeev 1980bb7acecfSBarry Smith Fortran Note: 1981bb7acecfSBarry Smith Not available in Fortran. 1982bb7acecfSBarry Smith 1983bb7acecfSBarry Smith Developer Note: 1984bb7acecfSBarry Smith It is not clear why this function and `DMCreateFieldIS()` exist. Having two seems redundant and confusing. 1985bb7acecfSBarry Smith 1986bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMCreateFieldIS()`, `DMCreateSubDM()`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 1987e7c4fc90SDmitry Karpeev @*/ 1988d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1989d71ae5a4SJacob Faibussowitsch { 1990e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1991e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 19928865f1eaSKarl Rupp if (len) { 1993534a8f05SLisandro Dalcin PetscValidIntPointer(len, 2); 19948865f1eaSKarl Rupp *len = 0; 19958865f1eaSKarl Rupp } 19968865f1eaSKarl Rupp if (namelist) { 19978865f1eaSKarl Rupp PetscValidPointer(namelist, 3); 1998ea78f98cSLisandro Dalcin *namelist = NULL; 19998865f1eaSKarl Rupp } 20008865f1eaSKarl Rupp if (islist) { 20018865f1eaSKarl Rupp PetscValidPointer(islist, 4); 2002ea78f98cSLisandro Dalcin *islist = NULL; 20038865f1eaSKarl Rupp } 20048865f1eaSKarl Rupp if (dmlist) { 20058865f1eaSKarl Rupp PetscValidPointer(dmlist, 5); 2006ea78f98cSLisandro Dalcin *dmlist = NULL; 20078865f1eaSKarl Rupp } 2008f3f0edfdSDmitry Karpeev /* 2009f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2010f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2011f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2012f3f0edfdSDmitry Karpeev */ 20137a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 201416621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 2015435a35e8SMatthew G Knepley PetscSection section; 2016435a35e8SMatthew G Knepley PetscInt numFields, f; 2017435a35e8SMatthew G Knepley 20189566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 20199566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(section, &numFields)); 2020435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 2021f25d98f1SMatthew G. Knepley if (len) *len = numFields; 20229566063dSJacob Faibussowitsch if (namelist) PetscCall(PetscMalloc1(numFields, namelist)); 20239566063dSJacob Faibussowitsch if (islist) PetscCall(PetscMalloc1(numFields, islist)); 20249566063dSJacob Faibussowitsch if (dmlist) PetscCall(PetscMalloc1(numFields, dmlist)); 2025435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 2026435a35e8SMatthew G Knepley const char *fieldName; 2027435a35e8SMatthew G Knepley 20289566063dSJacob Faibussowitsch PetscCall(DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL)); 202903dc3394SMatthew G. Knepley if (namelist) { 20309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 20319566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char **)&(*namelist)[f])); 2032435a35e8SMatthew G Knepley } 203303dc3394SMatthew G. Knepley } 2034435a35e8SMatthew G Knepley } else { 20359566063dSJacob Faibussowitsch PetscCall(DMCreateFieldIS(dm, len, namelist, islist)); 2036e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 20370298fd71SBarry Smith if (dmlist) *dmlist = NULL; 2038e7c4fc90SDmitry Karpeev } 2039dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, createfielddecomposition, len, namelist, islist, dmlist); 204016621825SDmitry Karpeev PetscFunctionReturn(0); 204116621825SDmitry Karpeev } 204216621825SDmitry Karpeev 2043412a4547SAlexis Marboeuf /*@C 2044412a4547SAlexis Marboeuf DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in. 2045412a4547SAlexis Marboeuf The fields are defined by DMCreateFieldIS(). 2046435a35e8SMatthew G Knepley 2047435a35e8SMatthew G Knepley Not collective 2048435a35e8SMatthew G Knepley 2049435a35e8SMatthew G Knepley Input Parameters: 2050bb7acecfSBarry Smith + dm - The `DM `object 2051bb7acecfSBarry Smith . numFields - The number of fields to select 20522adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 2053435a35e8SMatthew G Knepley 2054435a35e8SMatthew G Knepley Output Parameters: 2055bb7acecfSBarry Smith + is - The global indices for all the degrees of freedom in the new sub `DM` 2056bb7acecfSBarry Smith - subdm - The `DM` for the subproblem 2057435a35e8SMatthew G Knepley 2058bb7acecfSBarry Smith Note: 2059bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 20605d3b26e6SMatthew G. Knepley 2061435a35e8SMatthew G Knepley Level: intermediate 2062435a35e8SMatthew G Knepley 2063bb7acecfSBarry Smith .seealso: `DMCreateFieldIS()`, `DMCreateFieldDecomposition()`, `DMAddField()`, `DMCreateSuperDM()`, `DM`, `IS`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2064435a35e8SMatthew G Knepley @*/ 2065d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2066d71ae5a4SJacob Faibussowitsch { 2067435a35e8SMatthew G Knepley PetscFunctionBegin; 2068435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2069dadcf809SJacob Faibussowitsch PetscValidIntPointer(fields, 3); 20708865f1eaSKarl Rupp if (is) PetscValidPointer(is, 4); 20718865f1eaSKarl Rupp if (subdm) PetscValidPointer(subdm, 5); 2072dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createsubdm, numFields, fields, is, subdm); 2073435a35e8SMatthew G Knepley PetscFunctionReturn(0); 2074435a35e8SMatthew G Knepley } 2075435a35e8SMatthew G Knepley 20762adcc780SMatthew G. Knepley /*@C 2077bb7acecfSBarry Smith DMCreateSuperDM - Returns an arrays of `IS` and `DM` encapsulating a superproblem defined by multiple `DM`s passed in. 20782adcc780SMatthew G. Knepley 20792adcc780SMatthew G. Knepley Not collective 20802adcc780SMatthew G. Knepley 2081d8d19677SJose E. Roman Input Parameters: 2082bb7acecfSBarry Smith + dms - The `DM` objects 2083bb7acecfSBarry Smith - n - The number of `DM`s 20842adcc780SMatthew G. Knepley 20852adcc780SMatthew G. Knepley Output Parameters: 2086bb7acecfSBarry Smith + is - The global indices for each of subproblem within the super `DM`, or NULL 2087bb7acecfSBarry Smith - superdm - The `DM` for the superproblem 20882adcc780SMatthew G. Knepley 2089bb7acecfSBarry Smith Note: 2090bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 20915d3b26e6SMatthew G. Knepley 20922adcc780SMatthew G. Knepley Level: intermediate 20932adcc780SMatthew G. Knepley 2094bb7acecfSBarry Smith .seealso: `DM`, `DMCreateSubDM()`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 20952adcc780SMatthew G. Knepley @*/ 2096d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt n, IS **is, DM *superdm) 2097d71ae5a4SJacob Faibussowitsch { 20982adcc780SMatthew G. Knepley PetscInt i; 20992adcc780SMatthew G. Knepley 21002adcc780SMatthew G. Knepley PetscFunctionBegin; 21012adcc780SMatthew G. Knepley PetscValidPointer(dms, 1); 2102ad540459SPierre Jolivet for (i = 0; i < n; ++i) PetscValidHeaderSpecific(dms[i], DM_CLASSID, 1); 21032adcc780SMatthew G. Knepley if (is) PetscValidPointer(is, 3); 2104a42bd24dSMatthew G. Knepley PetscValidPointer(superdm, 4); 2105bb7acecfSBarry Smith PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %" PetscInt_FMT, n); 2106bb7acecfSBarry Smith if (n) { 2107b9d85ea2SLisandro Dalcin DM dm = dms[0]; 2108dbbe0bcdSBarry Smith PetscCall((*dm->ops->createsuperdm)(dms, n, is, superdm)); 21092adcc780SMatthew G. Knepley } 21102adcc780SMatthew G. Knepley PetscFunctionReturn(0); 21112adcc780SMatthew G. Knepley } 21122adcc780SMatthew G. Knepley 211316621825SDmitry Karpeev /*@C 2114bb7acecfSBarry Smith DMCreateDomainDecomposition - Returns lists of `IS` objects defining a decomposition of a problem into subproblems 2115bb7acecfSBarry Smith corresponding to restrictions to pairs of nested subdomains: each `IS` contains the global 2116bb7acecfSBarry Smith indices of the dofs of the corresponding subdomains with in the dofs of the original `DM`. 2117bb7acecfSBarry Smith The inner subdomains conceptually define a nonoverlapping covering, while outer subdomains can overlap. 2118bb7acecfSBarry Smith The optional list of `DM`s define a `DM` for each subproblem. 211916621825SDmitry Karpeev 212016621825SDmitry Karpeev Not collective 212116621825SDmitry Karpeev 212216621825SDmitry Karpeev Input Parameter: 2123bb7acecfSBarry Smith . dm - the `DM` object 212416621825SDmitry Karpeev 212516621825SDmitry Karpeev Output Parameters: 2126bb7acecfSBarry Smith + n - The number of subproblems in the domain decomposition (or NULL if not requested) 21270298fd71SBarry Smith . namelist - The name for each subdomain (or NULL if not requested) 21280298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 21290298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 2130bb7acecfSBarry Smith - dmlist - The `DM`s for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no `DM`s are defined) 213116621825SDmitry Karpeev 213216621825SDmitry Karpeev Level: intermediate 213316621825SDmitry Karpeev 2134bb7acecfSBarry Smith Note: 213516621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 2136bb7acecfSBarry Smith `PetscFree()`, every entry of is should be destroyed with `ISDestroy()`, every entry of dm should be destroyed with `DMDestroy()`, 2137bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 213816621825SDmitry Karpeev 2139bb7acecfSBarry Smith Questions: 2140bb7acecfSBarry Smith The dmlist is for the inner subdomains or the outer subdomains or all subdomains? 2141bb7acecfSBarry Smith 2142bb7acecfSBarry Smith .seealso: `DMCreateFieldDecomposition()`, `DMDestroy()`, `DMCreateDomainDecompositionScatters()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldDecomposition()` 214316621825SDmitry Karpeev @*/ 2144d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *n, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 2145d71ae5a4SJacob Faibussowitsch { 2146be081cd6SPeter Brune DMSubDomainHookLink link; 2147be081cd6SPeter Brune PetscInt i, l; 214816621825SDmitry Karpeev 214916621825SDmitry Karpeev PetscFunctionBegin; 215016621825SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21519371c9d4SSatish Balay if (n) { 21529371c9d4SSatish Balay PetscValidIntPointer(n, 2); 21539371c9d4SSatish Balay *n = 0; 21549371c9d4SSatish Balay } 21559371c9d4SSatish Balay if (namelist) { 21569371c9d4SSatish Balay PetscValidPointer(namelist, 3); 21579371c9d4SSatish Balay *namelist = NULL; 21589371c9d4SSatish Balay } 21599371c9d4SSatish Balay if (innerislist) { 21609371c9d4SSatish Balay PetscValidPointer(innerislist, 4); 21619371c9d4SSatish Balay *innerislist = NULL; 21629371c9d4SSatish Balay } 21639371c9d4SSatish Balay if (outerislist) { 21649371c9d4SSatish Balay PetscValidPointer(outerislist, 5); 21659371c9d4SSatish Balay *outerislist = NULL; 21669371c9d4SSatish Balay } 21679371c9d4SSatish Balay if (dmlist) { 21689371c9d4SSatish Balay PetscValidPointer(dmlist, 6); 21699371c9d4SSatish Balay *dmlist = NULL; 21709371c9d4SSatish Balay } 2171f3f0edfdSDmitry Karpeev /* 2172f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2173f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2174f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2175f3f0edfdSDmitry Karpeev */ 21767a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 217716621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 2178dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createdomaindecomposition, &l, namelist, innerislist, outerislist, dmlist); 217914a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 2180f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2181be081cd6SPeter Brune for (i = 0; i < l; i++) { 2182be081cd6SPeter Brune for (link = dm->subdomainhook; link; link = link->next) { 21839566063dSJacob Faibussowitsch if (link->ddhook) PetscCall((*link->ddhook)(dm, (*dmlist)[i], link->ctx)); 2184be081cd6SPeter Brune } 2185648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2186e7c4fc90SDmitry Karpeev } 218714a18fd3SPeter Brune } 2188bb7acecfSBarry Smith if (n) *n = l; 218914a18fd3SPeter Brune } 2190e30e807fSPeter Brune PetscFunctionReturn(0); 2191e30e807fSPeter Brune } 2192e30e807fSPeter Brune 2193e30e807fSPeter Brune /*@C 2194e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 2195e30e807fSPeter Brune 2196e30e807fSPeter Brune Not collective 2197e30e807fSPeter Brune 2198e30e807fSPeter Brune Input Parameters: 2199bb7acecfSBarry Smith + dm - the `DM` object 2200e30e807fSPeter Brune . n - the number of subdomain scatters 2201e30e807fSPeter Brune - subdms - the local subdomains 2202e30e807fSPeter Brune 2203e30e807fSPeter Brune Output Parameters: 22046b867d5aSJose E. Roman + iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2205e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2206e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2207e30e807fSPeter Brune 2208bb7acecfSBarry Smith Note: 2209bb7acecfSBarry Smith This is an alternative to the iis and ois arguments in `DMCreateDomainDecomposition()` that allow for the solution 2210e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2211e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2212e30e807fSPeter Brune solution and residual data. 2213e30e807fSPeter Brune 2214bb7acecfSBarry Smith Questions: 2215bb7acecfSBarry Smith Can the subdms input be anything or are they exactly the `DM` obtained from `DMCreateDomainDecomposition()`? 2216bb7acecfSBarry Smith 2217e30e807fSPeter Brune Level: developer 2218e30e807fSPeter Brune 2219bb7acecfSBarry Smith .seealso: `DM`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2220e30e807fSPeter Brune @*/ 2221d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDomainDecompositionScatters(DM dm, PetscInt n, DM *subdms, VecScatter **iscat, VecScatter **oscat, VecScatter **gscat) 2222d71ae5a4SJacob Faibussowitsch { 2223e30e807fSPeter Brune PetscFunctionBegin; 2224e30e807fSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2225e30e807fSPeter Brune PetscValidPointer(subdms, 3); 2226dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createddscatters, n, subdms, iscat, oscat, gscat); 2227e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 2228e7c4fc90SDmitry Karpeev } 2229e7c4fc90SDmitry Karpeev 223047c6ae99SBarry Smith /*@ 2231bb7acecfSBarry Smith DMRefine - Refines a `DM` object using a standard nonadaptive refinement of the underlying mesh 223247c6ae99SBarry Smith 2233d083f849SBarry Smith Collective on dm 223447c6ae99SBarry Smith 2235d8d19677SJose E. Roman Input Parameters: 2236bb7acecfSBarry Smith + dm - the `DM` object 2237bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 223847c6ae99SBarry Smith 223947c6ae99SBarry Smith Output Parameter: 2240bb7acecfSBarry Smith . dmf - the refined `D`M, or NULL 2241ae0a1c52SMatthew G Knepley 2242f27dd7c6SMatthew G. Knepley Options Database Keys: 2243412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2244412e9a14SMatthew G. Knepley 2245bb7acecfSBarry Smith Note: 2246bb7acecfSBarry Smith If no refinement was done, the return value is NULL 224747c6ae99SBarry Smith 224847c6ae99SBarry Smith Level: developer 224947c6ae99SBarry Smith 2250bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 225147c6ae99SBarry Smith @*/ 2252d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine(DM dm, MPI_Comm comm, DM *dmf) 2253d71ae5a4SJacob Faibussowitsch { 2254c833c3b5SJed Brown DMRefineHookLink link; 225547c6ae99SBarry Smith 225647c6ae99SBarry Smith PetscFunctionBegin; 2257732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22589566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Refine, dm, 0, 0, 0)); 2259dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refine, comm, dmf); 22604057135bSMatthew G Knepley if (*dmf) { 226143842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 22628865f1eaSKarl Rupp 22639566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmf)); 22648865f1eaSKarl Rupp 2265644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 22660598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2267656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 22688865f1eaSKarl Rupp 22699566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmf, dm->mattype)); 2270c833c3b5SJed Brown for (link = dm->refinehook; link; link = link->next) { 22711baa6e33SBarry Smith if (link->refinehook) PetscCall((*link->refinehook)(dm, *dmf, link->ctx)); 2272c833c3b5SJed Brown } 2273c833c3b5SJed Brown } 22749566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Refine, dm, 0, 0, 0)); 2275c833c3b5SJed Brown PetscFunctionReturn(0); 2276c833c3b5SJed Brown } 2277c833c3b5SJed Brown 2278bb9467b5SJed Brown /*@C 2279c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2280c833c3b5SJed Brown 2281bb7acecfSBarry Smith Logically Collective on coarse 2282c833c3b5SJed Brown 22834165533cSJose E. Roman Input Parameters: 2284bb7acecfSBarry Smith + coarse - `DM` on which to run a hook when interpolating to a finer level 2285bb7acecfSBarry Smith . refinehook - function to run when setting up the finer level 2286bb7acecfSBarry Smith . interphook - function to run to update data on finer levels (once per `SNESSolve`()) 22870298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2288c833c3b5SJed Brown 2289c833c3b5SJed Brown Calling sequence of refinehook: 2290c833c3b5SJed Brown $ refinehook(DM coarse,DM fine,void *ctx); 2291c833c3b5SJed Brown 2292bb7acecfSBarry Smith + coarse - coarse level `DM` 2293bb7acecfSBarry Smith . fine - fine level `DM` to interpolate problem to 2294c833c3b5SJed Brown - ctx - optional user-defined function context 2295c833c3b5SJed Brown 2296c833c3b5SJed Brown Calling sequence for interphook: 2297c833c3b5SJed Brown $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 2298c833c3b5SJed Brown 2299bb7acecfSBarry Smith + coarse - coarse level `DM` 2300c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2301bb7acecfSBarry Smith . fine - fine level `DM` to update 2302c833c3b5SJed Brown - ctx - optional user-defined function context 2303c833c3b5SJed Brown 2304c833c3b5SJed Brown Level: advanced 2305c833c3b5SJed Brown 2306c833c3b5SJed Brown Notes: 2307bb7acecfSBarry Smith This function is only needed if auxiliary data that is attached to the `DM`s via, for example, `PetscObjectCompose()`, needs to be 2308bb7acecfSBarry Smith passed to fine grids while grid sequencing. 2309bb7acecfSBarry Smith 2310bb7acecfSBarry Smith The actual interpolation is done when `DMInterpolate()` is called. 2311c833c3b5SJed Brown 2312c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2313c833c3b5SJed Brown 2314bb7acecfSBarry Smith Fortran Note: 2315bb7acecfSBarry Smith This function is not available from Fortran. 2316bb9467b5SJed Brown 2317bb7acecfSBarry Smith .seealso: `DM`, `DMCoarsenHookAdd()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2318c833c3b5SJed Brown @*/ 2319d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHookAdd(DM coarse, PetscErrorCode (*refinehook)(DM, DM, void *), PetscErrorCode (*interphook)(DM, Mat, DM, void *), void *ctx) 2320d71ae5a4SJacob Faibussowitsch { 2321c833c3b5SJed Brown DMRefineHookLink link, *p; 2322c833c3b5SJed Brown 2323c833c3b5SJed Brown PetscFunctionBegin; 2324c833c3b5SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 23253d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 23263d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0); 23273d8e3701SJed Brown } 23289566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2329c833c3b5SJed Brown link->refinehook = refinehook; 2330c833c3b5SJed Brown link->interphook = interphook; 2331c833c3b5SJed Brown link->ctx = ctx; 23320298fd71SBarry Smith link->next = NULL; 2333c833c3b5SJed Brown *p = link; 2334c833c3b5SJed Brown PetscFunctionReturn(0); 2335c833c3b5SJed Brown } 2336c833c3b5SJed Brown 23373d8e3701SJed Brown /*@C 2338bb7acecfSBarry Smith DMRefineHookRemove - remove a callback from the list of hooks, that have been set with `DMRefineHookAdd()`, to be run when interpolating 2339bb7acecfSBarry Smith a nonlinear problem to a finer grid 23403d8e3701SJed Brown 2341bb7acecfSBarry Smith Logically Collective on coarse 23423d8e3701SJed Brown 23434165533cSJose E. Roman Input Parameters: 2344bb7acecfSBarry Smith + coarse - the `DM` on which to run a hook when restricting to a coarser level 2345bb7acecfSBarry Smith . refinehook - function to run when setting up a finer level 2346bb7acecfSBarry Smith . interphook - function to run to update data on finer levels 23473d8e3701SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 23483d8e3701SJed Brown 23493d8e3701SJed Brown Level: advanced 23503d8e3701SJed Brown 2351bb7acecfSBarry Smith Note: 23523d8e3701SJed Brown This function does nothing if the hook is not in the list. 23533d8e3701SJed Brown 2354bb7acecfSBarry Smith Fortran Note: 2355bb7acecfSBarry Smith This function is not available from Fortran. 23563d8e3701SJed Brown 2357bb7acecfSBarry Smith .seealso: `DMRefineHookAdd()`, `DMCoarsenHookRemove()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 23583d8e3701SJed Brown @*/ 2359d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHookRemove(DM coarse, PetscErrorCode (*refinehook)(DM, DM, void *), PetscErrorCode (*interphook)(DM, Mat, DM, void *), void *ctx) 2360d71ae5a4SJacob Faibussowitsch { 23613d8e3701SJed Brown DMRefineHookLink link, *p; 23623d8e3701SJed Brown 23633d8e3701SJed Brown PetscFunctionBegin; 23643d8e3701SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 23653d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 23663d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 23673d8e3701SJed Brown link = *p; 23683d8e3701SJed Brown *p = link->next; 23699566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 23703d8e3701SJed Brown break; 23713d8e3701SJed Brown } 23723d8e3701SJed Brown } 23733d8e3701SJed Brown PetscFunctionReturn(0); 23743d8e3701SJed Brown } 23753d8e3701SJed Brown 2376c833c3b5SJed Brown /*@ 2377bb7acecfSBarry Smith DMInterpolate - interpolates user-defined problem data attached to a `DM` to a finer `DM` by running hooks registered by `DMRefineHookAdd()` 2378c833c3b5SJed Brown 2379c833c3b5SJed Brown Collective if any hooks are 2380c833c3b5SJed Brown 23814165533cSJose E. Roman Input Parameters: 2382bb7acecfSBarry Smith + coarse - coarser `DM` to use as a base 2383bb7acecfSBarry Smith . interp - interpolation matrix, apply using `MatInterpolate()` 2384bb7acecfSBarry Smith - fine - finer `DM` to update 2385c833c3b5SJed Brown 2386c833c3b5SJed Brown Level: developer 2387c833c3b5SJed Brown 2388bb7acecfSBarry Smith Developer Note: 2389bb7acecfSBarry Smith This routine is called `DMInterpolate()` while the hook is called `DMRefineHookAdd()`. It would be better to have an 2390bb7acecfSBarry Smith an API with consistent terminology. 2391bb7acecfSBarry Smith 2392bb7acecfSBarry Smith .seealso: `DM`, `DMRefineHookAdd()`, `MatInterpolate()` 2393c833c3b5SJed Brown @*/ 2394d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolate(DM coarse, Mat interp, DM fine) 2395d71ae5a4SJacob Faibussowitsch { 2396c833c3b5SJed Brown DMRefineHookLink link; 2397c833c3b5SJed Brown 2398c833c3b5SJed Brown PetscFunctionBegin; 2399c833c3b5SJed Brown for (link = fine->refinehook; link; link = link->next) { 24001baa6e33SBarry Smith if (link->interphook) PetscCall((*link->interphook)(coarse, interp, fine, link->ctx)); 24014057135bSMatthew G Knepley } 240247c6ae99SBarry Smith PetscFunctionReturn(0); 240347c6ae99SBarry Smith } 240447c6ae99SBarry Smith 2405eb3f98d2SBarry Smith /*@ 24061f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 24071f3379b2SToby Isaac 2408bb7acecfSBarry Smith Collective on dm 24091f3379b2SToby Isaac 24104165533cSJose E. Roman Input Parameters: 2411bb7acecfSBarry Smith + coarse - coarse `DM` 2412bb7acecfSBarry Smith . fine - fine `DM` 2413bb7acecfSBarry Smith . interp - (optional) the matrix computed by `DMCreateInterpolation()`. Implementations may not need this, but if it 2414bb7acecfSBarry Smith is available it can avoid some recomputation. If it is provided, `MatInterpolate()` will be used if 2415bb7acecfSBarry Smith the coarse `DM` does not have a specialized implementation. 24161f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 24171f3379b2SToby Isaac 24184165533cSJose E. Roman Output Parameter: 24191f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 24201f3379b2SToby Isaac 24211f3379b2SToby Isaac Level: developer 24221f3379b2SToby Isaac 2423bb7acecfSBarry Smith Note: 2424bb7acecfSBarry Smith This function exists because the interpolation of a solution vector between meshes is not always a linear 24251f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 24261f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 24271f3379b2SToby Isaac slope-limiting reconstruction. 24281f3379b2SToby Isaac 2429bb7acecfSBarry Smith Developer Note: 2430bb7acecfSBarry Smith This doesn't just interpolate "solutions" so its API name is questionable. 2431bb7acecfSBarry Smith 2432bb7acecfSBarry Smith .seealso: `DMInterpolate()`, `DMCreateInterpolation()` 24331f3379b2SToby Isaac @*/ 2434d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 2435d71ae5a4SJacob Faibussowitsch { 24361f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM, DM, Mat, Vec, Vec) = NULL; 24371f3379b2SToby Isaac 24381f3379b2SToby Isaac PetscFunctionBegin; 24391f3379b2SToby Isaac PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 24401f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp, MAT_CLASSID, 3); 24411f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol, VEC_CLASSID, 4); 24421f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol, VEC_CLASSID, 5); 24431f3379b2SToby Isaac 24449566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)coarse, "DMInterpolateSolution_C", &interpsol)); 24451f3379b2SToby Isaac if (interpsol) { 24469566063dSJacob Faibussowitsch PetscCall((*interpsol)(coarse, fine, interp, coarseSol, fineSol)); 24471f3379b2SToby Isaac } else if (interp) { 24489566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, coarseSol, fineSol)); 244998921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 24501f3379b2SToby Isaac PetscFunctionReturn(0); 24511f3379b2SToby Isaac } 24521f3379b2SToby Isaac 24531f3379b2SToby Isaac /*@ 2454bb7acecfSBarry Smith DMGetRefineLevel - Gets the number of refinements that have generated this `DM` from some initial `DM`. 2455eb3f98d2SBarry Smith 2456eb3f98d2SBarry Smith Not Collective 2457eb3f98d2SBarry Smith 2458eb3f98d2SBarry Smith Input Parameter: 2459bb7acecfSBarry Smith . dm - the `DM` object 2460eb3f98d2SBarry Smith 2461eb3f98d2SBarry Smith Output Parameter: 2462eb3f98d2SBarry Smith . level - number of refinements 2463eb3f98d2SBarry Smith 2464eb3f98d2SBarry Smith Level: developer 2465eb3f98d2SBarry Smith 2466bb7acecfSBarry Smith Note: 2467bb7acecfSBarry Smith This can be used, by example, to set the number of coarser levels associated with this `DM` for a multigrid solver. 2468bb7acecfSBarry Smith 2469bb7acecfSBarry Smith .seealso: `DMRefine()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2470eb3f98d2SBarry Smith 2471eb3f98d2SBarry Smith @*/ 2472d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRefineLevel(DM dm, PetscInt *level) 2473d71ae5a4SJacob Faibussowitsch { 2474eb3f98d2SBarry Smith PetscFunctionBegin; 2475eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2476eb3f98d2SBarry Smith *level = dm->levelup; 2477eb3f98d2SBarry Smith PetscFunctionReturn(0); 2478eb3f98d2SBarry Smith } 2479eb3f98d2SBarry Smith 2480fef3a512SBarry Smith /*@ 2481bb7acecfSBarry Smith DMSetRefineLevel - Sets the number of refinements that have generated this `DM`. 2482fef3a512SBarry Smith 2483fef3a512SBarry Smith Not Collective 2484fef3a512SBarry Smith 2485d8d19677SJose E. Roman Input Parameters: 2486bb7acecfSBarry Smith + dm - the `DM` object 2487fef3a512SBarry Smith - level - number of refinements 2488fef3a512SBarry Smith 2489fef3a512SBarry Smith Level: advanced 2490fef3a512SBarry Smith 249195452b02SPatrick Sanan Notes: 2492bb7acecfSBarry Smith This value is used by `PCMG` to determine how many multigrid levels to use 2493fef3a512SBarry Smith 2494bb7acecfSBarry Smith The values are usually set automatically by the process that is causing the refinements of an initial `DM` by calling this routine. 2495bb7acecfSBarry Smith 2496bb7acecfSBarry Smith .seealso: `DMGetRefineLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2497fef3a512SBarry Smith 2498fef3a512SBarry Smith @*/ 2499d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRefineLevel(DM dm, PetscInt level) 2500d71ae5a4SJacob Faibussowitsch { 2501fef3a512SBarry Smith PetscFunctionBegin; 2502fef3a512SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2503fef3a512SBarry Smith dm->levelup = level; 2504fef3a512SBarry Smith PetscFunctionReturn(0); 2505fef3a512SBarry Smith } 2506fef3a512SBarry Smith 2507d410b0cfSMatthew G. Knepley /*@ 2508bb7acecfSBarry Smith DMExtrude - Extrude a `DM` object from a surface 2509d410b0cfSMatthew G. Knepley 2510d410b0cfSMatthew G. Knepley Collective on dm 2511d410b0cfSMatthew G. Knepley 2512f1a722f8SMatthew G. Knepley Input Parameters: 2513bb7acecfSBarry Smith + dm - the `DM` object 2514d410b0cfSMatthew G. Knepley - layers - the number of extruded cell layers 2515d410b0cfSMatthew G. Knepley 2516d410b0cfSMatthew G. Knepley Output Parameter: 2517bb7acecfSBarry Smith . dme - the extruded `DM`, or NULL 2518d410b0cfSMatthew G. Knepley 2519bb7acecfSBarry Smith Note: 2520bb7acecfSBarry Smith If no extrusion was done, the return value is NULL 2521d410b0cfSMatthew G. Knepley 2522d410b0cfSMatthew G. Knepley Level: developer 2523d410b0cfSMatthew G. Knepley 2524bb7acecfSBarry Smith .seealso: `DMRefine()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()` 2525d410b0cfSMatthew G. Knepley @*/ 2526d71ae5a4SJacob Faibussowitsch PetscErrorCode DMExtrude(DM dm, PetscInt layers, DM *dme) 2527d71ae5a4SJacob Faibussowitsch { 2528d410b0cfSMatthew G. Knepley PetscFunctionBegin; 2529d410b0cfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2530dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, extrude, layers, dme); 2531d410b0cfSMatthew G. Knepley if (*dme) { 2532d410b0cfSMatthew G. Knepley (*dme)->ops->creatematrix = dm->ops->creatematrix; 25339566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dme)); 2534d410b0cfSMatthew G. Knepley (*dme)->ctx = dm->ctx; 25359566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dme, dm->mattype)); 2536d410b0cfSMatthew G. Knepley } 2537d410b0cfSMatthew G. Knepley PetscFunctionReturn(0); 2538d410b0cfSMatthew G. Knepley } 2539d410b0cfSMatthew G. Knepley 2540d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2541d71ae5a4SJacob Faibussowitsch { 2542ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2543ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2544ca3d3a14SMatthew G. Knepley PetscValidPointer(tdm, 2); 2545ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 2546ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2547ca3d3a14SMatthew G. Knepley } 2548ca3d3a14SMatthew G. Knepley 2549d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2550d71ae5a4SJacob Faibussowitsch { 2551ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2552ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2553ca3d3a14SMatthew G. Knepley PetscValidPointer(tv, 2); 2554ca3d3a14SMatthew G. Knepley *tv = dm->transform; 2555ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2556ca3d3a14SMatthew G. Knepley } 2557ca3d3a14SMatthew G. Knepley 2558ca3d3a14SMatthew G. Knepley /*@ 2559bb7acecfSBarry Smith DMHasBasisTransform - Whether the `DM` employs a basis transformation from functions in global vectors to functions in local vectors 2560ca3d3a14SMatthew G. Knepley 2561ca3d3a14SMatthew G. Knepley Input Parameter: 2562ca3d3a14SMatthew G. Knepley . dm - The DM 2563ca3d3a14SMatthew G. Knepley 2564ca3d3a14SMatthew G. Knepley Output Parameter: 2565ca3d3a14SMatthew G. Knepley . flg - PETSC_TRUE if a basis transformation should be done 2566ca3d3a14SMatthew G. Knepley 2567ca3d3a14SMatthew G. Knepley Level: developer 2568ca3d3a14SMatthew G. Knepley 2569bb7acecfSBarry Smith .seealso: `DM`, `DMPlexGlobalToLocalBasis()`, `DMPlexLocalToGlobalBasis()`, `DMPlexCreateBasisRotation()` 2570ca3d3a14SMatthew G. Knepley @*/ 2571d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2572d71ae5a4SJacob Faibussowitsch { 2573ca3d3a14SMatthew G. Knepley Vec tv; 2574ca3d3a14SMatthew G. Knepley 2575ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2576ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2577534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 25789566063dSJacob Faibussowitsch PetscCall(DMGetBasisTransformVec_Internal(dm, &tv)); 2579ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 2580ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2581ca3d3a14SMatthew G. Knepley } 2582ca3d3a14SMatthew G. Knepley 2583d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2584d71ae5a4SJacob Faibussowitsch { 2585ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2586ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2587ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2588ca3d3a14SMatthew G. Knepley 2589ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 25909566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 25919566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 25929566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 25939566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 25949566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->transformDM)); 25959566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm->transformDM, &ts)); 25969566063dSJacob Faibussowitsch PetscCall(PetscSectionSetNumFields(ts, Nf)); 25979566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(ts, pStart, pEnd)); 2598ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 25999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(s, f, &Nc)); 2600ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2601ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2602ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 26039566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &dof)); 2604ca3d3a14SMatthew G. Knepley if (!dof) continue; 26059566063dSJacob Faibussowitsch PetscCall(PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim))); 26069566063dSJacob Faibussowitsch PetscCall(PetscSectionAddDof(ts, p, PetscSqr(cdim))); 2607ca3d3a14SMatthew G. Knepley } 2608ca3d3a14SMatthew G. Knepley } 26099566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(ts)); 26109566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dm->transformDM, &dm->transform)); 26119566063dSJacob Faibussowitsch PetscCall(VecGetArray(dm->transform, &ta)); 2612ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2613ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26149566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(ts, p, f, &dof)); 2615ca3d3a14SMatthew G. Knepley if (dof) { 2616ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2617ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2618ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2619ca3d3a14SMatthew G. Knepley 2620ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 26219566063dSJacob Faibussowitsch PetscCall((*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx)); 26229566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *)&tva)); 26239566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tva, A, PetscSqr(cdim))); 2624ca3d3a14SMatthew G. Knepley } 2625ca3d3a14SMatthew G. Knepley } 2626ca3d3a14SMatthew G. Knepley } 26279566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(dm->transform, &ta)); 2628ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2629ca3d3a14SMatthew G. Knepley } 2630ca3d3a14SMatthew G. Knepley 2631d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2632d71ae5a4SJacob Faibussowitsch { 2633ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2634ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2635ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2636ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2637ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2638ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2639ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 26409566063dSJacob Faibussowitsch if (newdm->transformSetUp) PetscCall(DMConstructBasisTransform_Internal(newdm)); 2641ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2642ca3d3a14SMatthew G. Knepley } 2643ca3d3a14SMatthew G. Knepley 2644bb9467b5SJed Brown /*@C 2645bb7acecfSBarry Smith DMGlobalToLocalHookAdd - adds a callback to be run when `DMGlobalToLocal()` is called 2646baf369e7SPeter Brune 2647bb7acecfSBarry Smith Logically Collective on dm 2648baf369e7SPeter Brune 26494165533cSJose E. Roman Input Parameters: 2650bb7acecfSBarry Smith + dm - the `DM` 2651bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMGlobalToLocalBegin()` 2652bb7acecfSBarry Smith . endhook - function to run after `DMGlobalToLocalEnd()` has completed 26530298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2654baf369e7SPeter Brune 2655baf369e7SPeter Brune Calling sequence for beginhook: 2656baf369e7SPeter Brune $ beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2657baf369e7SPeter Brune 2658baf369e7SPeter Brune + dm - global DM 2659baf369e7SPeter Brune . g - global vector 2660baf369e7SPeter Brune . mode - mode 2661baf369e7SPeter Brune . l - local vector 2662baf369e7SPeter Brune - ctx - optional user-defined function context 2663baf369e7SPeter Brune 2664baf369e7SPeter Brune Calling sequence for endhook: 2665ec4806b8SPeter Brune $ endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2666baf369e7SPeter Brune 2667baf369e7SPeter Brune + global - global DM 2668baf369e7SPeter Brune - ctx - optional user-defined function context 2669baf369e7SPeter Brune 2670baf369e7SPeter Brune Level: advanced 2671baf369e7SPeter Brune 2672bb7acecfSBarry Smith Note: 2673bb7acecfSBarry 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. 2674bb7acecfSBarry Smith 2675bb7acecfSBarry Smith .seealso: `DM`, `DMGlobalToLocal()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2676baf369e7SPeter Brune @*/ 2677d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalHookAdd(DM dm, PetscErrorCode (*beginhook)(DM, Vec, InsertMode, Vec, void *), PetscErrorCode (*endhook)(DM, Vec, InsertMode, Vec, void *), void *ctx) 2678d71ae5a4SJacob Faibussowitsch { 2679baf369e7SPeter Brune DMGlobalToLocalHookLink link, *p; 2680baf369e7SPeter Brune 2681baf369e7SPeter Brune PetscFunctionBegin; 2682baf369e7SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2683baf369e7SPeter Brune for (p = &dm->gtolhook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 26849566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2685baf369e7SPeter Brune link->beginhook = beginhook; 2686baf369e7SPeter Brune link->endhook = endhook; 2687baf369e7SPeter Brune link->ctx = ctx; 26880298fd71SBarry Smith link->next = NULL; 2689baf369e7SPeter Brune *p = link; 2690baf369e7SPeter Brune PetscFunctionReturn(0); 2691baf369e7SPeter Brune } 2692baf369e7SPeter Brune 2693d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 2694d71ae5a4SJacob Faibussowitsch { 26954c274da1SToby Isaac Mat cMat; 269679769bd5SJed Brown Vec cVec, cBias; 26974c274da1SToby Isaac PetscSection section, cSec; 26984c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 26994c274da1SToby Isaac 27004c274da1SToby Isaac PetscFunctionBegin; 27014c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 27029566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, &cBias)); 27034c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 27045db9a05bSToby Isaac PetscInt nRows; 27055db9a05bSToby Isaac 27069566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 27075db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 27089566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 27099566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 27109566063dSJacob Faibussowitsch PetscCall(MatMult(cMat, l, cVec)); 27119566063dSJacob Faibussowitsch if (cBias) PetscCall(VecAXPY(cVec, 1., cBias)); 27129566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 27134c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 27149566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 27154c274da1SToby Isaac if (dof) { 27164c274da1SToby Isaac PetscScalar *vals; 27179566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(cVec, cSec, p, &vals)); 27189566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(l, section, p, vals, INSERT_ALL_VALUES)); 27194c274da1SToby Isaac } 27204c274da1SToby Isaac } 27219566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 27224c274da1SToby Isaac } 27234c274da1SToby Isaac PetscFunctionReturn(0); 27244c274da1SToby Isaac } 27254c274da1SToby Isaac 272647c6ae99SBarry Smith /*@ 272701729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 272801729b5cSPatrick Sanan 2729d083f849SBarry Smith Neighbor-wise Collective on dm 273001729b5cSPatrick Sanan 273101729b5cSPatrick Sanan Input Parameters: 2732bb7acecfSBarry Smith + dm - the `DM` object 273301729b5cSPatrick Sanan . g - the global vector 2734bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 273501729b5cSPatrick Sanan - l - the local vector 273601729b5cSPatrick Sanan 273701729b5cSPatrick Sanan Notes: 2738bb7acecfSBarry Smith The communication involved in this update can be overlapped with computation by instead using 2739bb7acecfSBarry Smith `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. 2740bb7acecfSBarry Smith 2741bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 274201729b5cSPatrick Sanan 274301729b5cSPatrick Sanan Level: beginner 274401729b5cSPatrick Sanan 2745bb7acecfSBarry Smith .seealso: `DM`, `DMGlobalToLocalHookAdd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, 2746bb7acecfSBarry Smith `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, 2747bb7acecfSBarry Smith `DMGlobalToLocalBegin()` `DMGlobalToLocalEnd()` 274801729b5cSPatrick Sanan 274901729b5cSPatrick Sanan @*/ 2750d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocal(DM dm, Vec g, InsertMode mode, Vec l) 2751d71ae5a4SJacob Faibussowitsch { 275201729b5cSPatrick Sanan PetscFunctionBegin; 27539566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, g, mode, l)); 27549566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, g, mode, l)); 275501729b5cSPatrick Sanan PetscFunctionReturn(0); 275601729b5cSPatrick Sanan } 275701729b5cSPatrick Sanan 275801729b5cSPatrick Sanan /*@ 275947c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 276047c6ae99SBarry Smith 2761d083f849SBarry Smith Neighbor-wise Collective on dm 276247c6ae99SBarry Smith 276347c6ae99SBarry Smith Input Parameters: 2764bb7acecfSBarry Smith + dm - the `DM` object 276547c6ae99SBarry Smith . g - the global vector 2766bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 276747c6ae99SBarry Smith - l - the local vector 276847c6ae99SBarry Smith 276901729b5cSPatrick Sanan Level: intermediate 277047c6ae99SBarry Smith 2771bb7acecfSBarry Smith Notes: 2772bb7acecfSBarry Smith The operation is completed with `DMGlobalToLocalEnd()` 2773bb7acecfSBarry Smith 2774bb7acecfSBarry Smith One can perform local computations between the `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to overlap communication and computation 2775bb7acecfSBarry Smith 2776bb7acecfSBarry Smith `DMGlobalToLocal()` is a short form of `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` 2777bb7acecfSBarry Smith 2778bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 2779bb7acecfSBarry Smith 2780bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()` 278147c6ae99SBarry Smith 278247c6ae99SBarry Smith @*/ 2783d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 2784d71ae5a4SJacob Faibussowitsch { 27857128ae9fSMatthew G Knepley PetscSF sf; 2786baf369e7SPeter Brune DMGlobalToLocalHookLink link; 278747c6ae99SBarry Smith 278847c6ae99SBarry Smith PetscFunctionBegin; 2789171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2790baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 27911baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, g, mode, l, link->ctx)); 2792baf369e7SPeter Brune } 27939566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 27947128ae9fSMatthew G Knepley if (sf) { 2795ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2796ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2797d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 27987128ae9fSMatthew G Knepley 27997a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28009566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28019566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28029566063dSJacob Faibussowitsch PetscCall(PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE)); 28039566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28049566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28057128ae9fSMatthew G Knepley } else { 28069566063dSJacob Faibussowitsch PetscCall((*dm->ops->globaltolocalbegin)(dm, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l)); 28077128ae9fSMatthew G Knepley } 280847c6ae99SBarry Smith PetscFunctionReturn(0); 280947c6ae99SBarry Smith } 281047c6ae99SBarry Smith 281147c6ae99SBarry Smith /*@ 281247c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 281347c6ae99SBarry Smith 2814d083f849SBarry Smith Neighbor-wise Collective on dm 281547c6ae99SBarry Smith 281647c6ae99SBarry Smith Input Parameters: 2817bb7acecfSBarry Smith + dm - the `DM` object 281847c6ae99SBarry Smith . g - the global vector 2819bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 282047c6ae99SBarry Smith - l - the local vector 282147c6ae99SBarry Smith 282201729b5cSPatrick Sanan Level: intermediate 282347c6ae99SBarry Smith 2824bb7acecfSBarry Smith Note: 2825bb7acecfSBarry Smith See `DMGlobalToLocalBegin()` for details. 2826bb7acecfSBarry Smith 2827bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()` 282847c6ae99SBarry Smith 282947c6ae99SBarry Smith @*/ 2830d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 2831d71ae5a4SJacob Faibussowitsch { 28327128ae9fSMatthew G Knepley PetscSF sf; 2833ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2834ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2835ca3d3a14SMatthew G. Knepley PetscBool transform; 2836baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2837d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 283847c6ae99SBarry Smith 283947c6ae99SBarry Smith PetscFunctionBegin; 2840171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 28419566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28429566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 28437128ae9fSMatthew G Knepley if (sf) { 28447a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28457128ae9fSMatthew G Knepley 28469566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28479566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28489566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray, MPI_REPLACE)); 28499566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28509566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28519566063dSJacob Faibussowitsch if (transform) PetscCall(DMPlexGlobalToLocalBasis(dm, l)); 28527128ae9fSMatthew G Knepley } else { 28539566063dSJacob Faibussowitsch PetscCall((*dm->ops->globaltolocalend)(dm, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l)); 28547128ae9fSMatthew G Knepley } 28559566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalHook_Constraints(dm, g, mode, l, NULL)); 2856baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 28579566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 2858baf369e7SPeter Brune } 285947c6ae99SBarry Smith PetscFunctionReturn(0); 286047c6ae99SBarry Smith } 286147c6ae99SBarry Smith 2862d4d07f1eSToby Isaac /*@C 2863d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2864d4d07f1eSToby Isaac 2865bb7acecfSBarry Smith Logically Collective on dm 2866d4d07f1eSToby Isaac 28674165533cSJose E. Roman Input Parameters: 2868bb7acecfSBarry Smith + dm - the `DM` 2869bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMLocalToGlobalBegin()` 2870bb7acecfSBarry Smith . endhook - function to run after `DMLocalToGlobalEnd()` has completed 2871d4d07f1eSToby Isaac - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2872d4d07f1eSToby Isaac 2873d4d07f1eSToby Isaac Calling sequence for beginhook: 2874d4d07f1eSToby Isaac $ beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2875d4d07f1eSToby Isaac 2876bb7acecfSBarry Smith + dm - global `DM` 2877d4d07f1eSToby Isaac . l - local vector 2878d4d07f1eSToby Isaac . mode - mode 2879d4d07f1eSToby Isaac . g - global vector 2880d4d07f1eSToby Isaac - ctx - optional user-defined function context 2881d4d07f1eSToby Isaac 2882d4d07f1eSToby Isaac Calling sequence for endhook: 2883d4d07f1eSToby Isaac $ endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2884d4d07f1eSToby Isaac 2885bb7acecfSBarry Smith + global - global `DM` 2886d4d07f1eSToby Isaac . l - local vector 2887d4d07f1eSToby Isaac . mode - mode 2888d4d07f1eSToby Isaac . g - global vector 2889d4d07f1eSToby Isaac - ctx - optional user-defined function context 2890d4d07f1eSToby Isaac 2891d4d07f1eSToby Isaac Level: advanced 2892d4d07f1eSToby Isaac 2893bb7acecfSBarry Smith .seealso: `DMLocalToGlobal()`, `DMRefineHookAdd()`, `DMGlobalToLocalHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2894d4d07f1eSToby Isaac @*/ 2895d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalHookAdd(DM dm, PetscErrorCode (*beginhook)(DM, Vec, InsertMode, Vec, void *), PetscErrorCode (*endhook)(DM, Vec, InsertMode, Vec, void *), void *ctx) 2896d71ae5a4SJacob Faibussowitsch { 2897d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, *p; 2898d4d07f1eSToby Isaac 2899d4d07f1eSToby Isaac PetscFunctionBegin; 2900d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2901d4d07f1eSToby Isaac for (p = &dm->ltoghook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 29029566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2903d4d07f1eSToby Isaac link->beginhook = beginhook; 2904d4d07f1eSToby Isaac link->endhook = endhook; 2905d4d07f1eSToby Isaac link->ctx = ctx; 2906d4d07f1eSToby Isaac link->next = NULL; 2907d4d07f1eSToby Isaac *p = link; 2908d4d07f1eSToby Isaac PetscFunctionReturn(0); 2909d4d07f1eSToby Isaac } 2910d4d07f1eSToby Isaac 2911d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 2912d71ae5a4SJacob Faibussowitsch { 29134c274da1SToby Isaac Mat cMat; 29144c274da1SToby Isaac Vec cVec; 29154c274da1SToby Isaac PetscSection section, cSec; 29164c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 29174c274da1SToby Isaac 29184c274da1SToby Isaac PetscFunctionBegin; 29194c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29209566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, NULL)); 29214c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 29225db9a05bSToby Isaac PetscInt nRows; 29235db9a05bSToby Isaac 29249566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 29255db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 29269566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 29279566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 29289566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 29294c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 29309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 29314c274da1SToby Isaac if (dof) { 29324c274da1SToby Isaac PetscInt d; 29334c274da1SToby Isaac PetscScalar *vals; 29349566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(l, section, p, &vals)); 29359566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(cVec, cSec, p, vals, mode)); 29364c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 29374c274da1SToby Isaac * we just extracted */ 2938ad540459SPierre Jolivet for (d = 0; d < dof; d++) vals[d] = 0.; 29394c274da1SToby Isaac } 29404c274da1SToby Isaac } 29419566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd(cMat, cVec, l, l)); 29429566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 29434c274da1SToby Isaac } 29444c274da1SToby Isaac PetscFunctionReturn(0); 29454c274da1SToby Isaac } 294601729b5cSPatrick Sanan /*@ 294701729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 294801729b5cSPatrick Sanan 2949d083f849SBarry Smith Neighbor-wise Collective on dm 295001729b5cSPatrick Sanan 295101729b5cSPatrick Sanan Input Parameters: 2952bb7acecfSBarry Smith + dm - the `DM` object 295301729b5cSPatrick Sanan . l - the local vector 2954bb7acecfSBarry 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. 295501729b5cSPatrick Sanan - g - the global vector 295601729b5cSPatrick Sanan 295701729b5cSPatrick Sanan Notes: 295801729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 2959bb7acecfSBarry Smith `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. 296001729b5cSPatrick Sanan 2961bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 2962bb7acecfSBarry Smith 2963bb7acecfSBarry 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. 2964bb7acecfSBarry Smith 2965bb7acecfSBarry Smith Use `DMLocalToGlobalHookAdd()` to add additional operations that are performed on the data during the update process 296601729b5cSPatrick Sanan 296701729b5cSPatrick Sanan Level: beginner 296801729b5cSPatrick Sanan 2969bb7acecfSBarry Smith .seealso: `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalHookAdd()`, `DMGlobaToLocallHookAdd()` 297001729b5cSPatrick Sanan 297101729b5cSPatrick Sanan @*/ 2972d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobal(DM dm, Vec l, InsertMode mode, Vec g) 2973d71ae5a4SJacob Faibussowitsch { 297401729b5cSPatrick Sanan PetscFunctionBegin; 29759566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, l, mode, g)); 29769566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, l, mode, g)); 297701729b5cSPatrick Sanan PetscFunctionReturn(0); 297801729b5cSPatrick Sanan } 29794c274da1SToby Isaac 298047c6ae99SBarry Smith /*@ 298101729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 29829a42bb27SBarry Smith 2983d083f849SBarry Smith Neighbor-wise Collective on dm 29849a42bb27SBarry Smith 29859a42bb27SBarry Smith Input Parameters: 2986bb7acecfSBarry Smith + dm - the `DM` object 2987f6813fd5SJed Brown . l - the local vector 2988bb7acecfSBarry 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. 29891eb28f2eSBarry Smith - g - the global vector 29909a42bb27SBarry Smith 299195452b02SPatrick Sanan Notes: 2992bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 2993bb7acecfSBarry Smith 2994bb7acecfSBarry 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. 2995bb7acecfSBarry Smith 2996bb7acecfSBarry Smith Use `DMLocalToGlobalEnd()` to complete the communication process. 2997bb7acecfSBarry Smith 2998bb7acecfSBarry Smith `DMLocalToGlobal()` is a short form of `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()` 2999bb7acecfSBarry Smith 3000bb7acecfSBarry Smith `DMLocalToGlobalHookAdd()` may be used to provide additional operations that are performed during the update process. 30019a42bb27SBarry Smith 300201729b5cSPatrick Sanan Level: intermediate 30039a42bb27SBarry Smith 3004bb7acecfSBarry Smith .seealso: `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()` 30059a42bb27SBarry Smith 30069a42bb27SBarry Smith @*/ 3007d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBegin(DM dm, Vec l, InsertMode mode, Vec g) 3008d71ae5a4SJacob Faibussowitsch { 30097128ae9fSMatthew G Knepley PetscSF sf; 301084330215SMatthew G. Knepley PetscSection s, gs; 3011d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3012ca3d3a14SMatthew G. Knepley Vec tmpl; 3013ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3014ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3015fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 3016d0295fc0SJunchao Zhang PetscMemType lmtype = PETSC_MEMTYPE_HOST, gmtype = PETSC_MEMTYPE_HOST; 30179a42bb27SBarry Smith 30189a42bb27SBarry Smith PetscFunctionBegin; 3019171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3020d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 30211baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, l, mode, g, link->ctx)); 3022d4d07f1eSToby Isaac } 30239566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalHook_Constraints(dm, l, mode, g, NULL)); 30249566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 30259566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 30267128ae9fSMatthew G Knepley switch (mode) { 30277128ae9fSMatthew G Knepley case INSERT_VALUES: 30287128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 3029d71ae5a4SJacob Faibussowitsch case INSERT_BC_VALUES: 3030d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3031d71ae5a4SJacob Faibussowitsch break; 30327128ae9fSMatthew G Knepley case ADD_VALUES: 30337128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 3034d71ae5a4SJacob Faibussowitsch case ADD_BC_VALUES: 3035d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3036d71ae5a4SJacob Faibussowitsch break; 3037d71ae5a4SJacob Faibussowitsch default: 3038d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 30397128ae9fSMatthew G Knepley } 3040ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 30419566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3042ca3d3a14SMatthew G. Knepley if (transform) { 30439566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 30449566063dSJacob Faibussowitsch PetscCall(VecCopy(l, tmpl)); 30459566063dSJacob Faibussowitsch PetscCall(DMPlexLocalToGlobalBasis(dm, tmpl)); 30469566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3047fa88e482SJed Brown } else if (isInsert) { 30489566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(l, &lArray)); 3049fa88e482SJed Brown } else { 30509566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, &lmtype)); 3051fa88e482SJed Brown l_inplace = PETSC_TRUE; 3052ca3d3a14SMatthew G. Knepley } 3053fa88e482SJed Brown if (s && isInsert) { 30549566063dSJacob Faibussowitsch PetscCall(VecGetArray(g, &gArray)); 3055fa88e482SJed Brown } else { 30569566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, &gmtype)); 3057fa88e482SJed Brown g_inplace = PETSC_TRUE; 3058fa88e482SJed Brown } 3059ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 30609566063dSJacob Faibussowitsch PetscCall(PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM)); 306184330215SMatthew G. Knepley } else if (s && isInsert) { 306284330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 306384330215SMatthew G. Knepley 30649566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 30659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 30669566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g, &gStart, NULL)); 306784330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3068b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 306984330215SMatthew G. Knepley 30709566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 30719566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(gs, p, &gdof)); 30729566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 30739566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(gs, p, &gcdof)); 30749566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(s, p, &off)); 30759566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(gs, p, &goff)); 3076b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 307703442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 30787a8be351SBarry 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); 3079b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 3080b3b16f48SMatthew G. Knepley if (!gcdof) { 308184330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff - gStart + d] = lArray[off + d]; 3082b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 3083b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 308484330215SMatthew G. Knepley const PetscInt *cdofs; 308584330215SMatthew G. Knepley PetscInt cind = 0; 308684330215SMatthew G. Knepley 30879566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(s, p, &cdofs)); 3088b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 30899371c9d4SSatish Balay if ((cind < cdof) && (d == cdofs[cind])) { 30909371c9d4SSatish Balay ++cind; 30919371c9d4SSatish Balay continue; 30929371c9d4SSatish Balay } 3093b3b16f48SMatthew G. Knepley gArray[goff - gStart + e++] = lArray[off + d]; 309484330215SMatthew G. Knepley } 30957a8be351SBarry 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); 309684330215SMatthew G. Knepley } 3097ca3d3a14SMatthew G. Knepley } 3098fa88e482SJed Brown if (g_inplace) { 30999566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 3100fa88e482SJed Brown } else { 31019566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(g, &gArray)); 3102fa88e482SJed Brown } 3103ca3d3a14SMatthew G. Knepley if (transform) { 31049566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31059566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3106fa88e482SJed Brown } else if (l_inplace) { 31079566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3108ca3d3a14SMatthew G. Knepley } else { 31099566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(l, &lArray)); 3110ca3d3a14SMatthew G. Knepley } 31117128ae9fSMatthew G Knepley } else { 31129566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtoglobalbegin)(dm, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g)); 31137128ae9fSMatthew G Knepley } 31149a42bb27SBarry Smith PetscFunctionReturn(0); 31159a42bb27SBarry Smith } 31169a42bb27SBarry Smith 31179a42bb27SBarry Smith /*@ 31189a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 311947c6ae99SBarry Smith 3120d083f849SBarry Smith Neighbor-wise Collective on dm 312147c6ae99SBarry Smith 312247c6ae99SBarry Smith Input Parameters: 3123bb7acecfSBarry Smith + dm - the `DM` object 3124f6813fd5SJed Brown . l - the local vector 3125bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 3126f6813fd5SJed Brown - g - the global vector 312747c6ae99SBarry Smith 312801729b5cSPatrick Sanan Level: intermediate 312947c6ae99SBarry Smith 3130bb7acecfSBarry Smith Note: 3131bb7acecfSBarry Smith See `DMLocalToGlobalBegin()` for full details 3132bb7acecfSBarry Smith 3133bb7acecfSBarry Smith .seealso: `DMLocalToGlobalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalEnd()` 313447c6ae99SBarry Smith 313547c6ae99SBarry Smith @*/ 3136d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEnd(DM dm, Vec l, InsertMode mode, Vec g) 3137d71ae5a4SJacob Faibussowitsch { 31387128ae9fSMatthew G Knepley PetscSF sf; 313984330215SMatthew G. Knepley PetscSection s; 3140d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3141ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 314247c6ae99SBarry Smith 314347c6ae99SBarry Smith PetscFunctionBegin; 3144171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 31459566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 31469566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 31477128ae9fSMatthew G Knepley switch (mode) { 31487128ae9fSMatthew G Knepley case INSERT_VALUES: 3149d71ae5a4SJacob Faibussowitsch case INSERT_ALL_VALUES: 3150d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3151d71ae5a4SJacob Faibussowitsch break; 31527128ae9fSMatthew G Knepley case ADD_VALUES: 3153d71ae5a4SJacob Faibussowitsch case ADD_ALL_VALUES: 3154d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3155d71ae5a4SJacob Faibussowitsch break; 3156d71ae5a4SJacob Faibussowitsch default: 3157d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 31587128ae9fSMatthew G Knepley } 315984330215SMatthew G. Knepley if (sf && !isInsert) { 3160ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3161ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3162ca3d3a14SMatthew G. Knepley Vec tmpl; 316384330215SMatthew G. Knepley 31649566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3165ca3d3a14SMatthew G. Knepley if (transform) { 31669566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 31679566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3168ca3d3a14SMatthew G. Knepley } else { 31699566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, NULL)); 3170ca3d3a14SMatthew G. Knepley } 31719566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, NULL)); 31729566063dSJacob Faibussowitsch PetscCall(PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM)); 3173ca3d3a14SMatthew G. Knepley if (transform) { 31749566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31759566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3176ca3d3a14SMatthew G. Knepley } else { 31779566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3178ca3d3a14SMatthew G. Knepley } 31799566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 318084330215SMatthew G. Knepley } else if (s && isInsert) { 31817128ae9fSMatthew G Knepley } else { 31829566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtoglobalend)(dm, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g)); 31837128ae9fSMatthew G Knepley } 3184d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 31859566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 3186d4d07f1eSToby Isaac } 318747c6ae99SBarry Smith PetscFunctionReturn(0); 318847c6ae99SBarry Smith } 318947c6ae99SBarry Smith 3190f089877aSRichard Tran Mills /*@ 3191bb7acecfSBarry Smith DMLocalToLocalBegin - Begins the process of mapping values from a local vector (that include ghost points 3192bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 3193bb7acecfSBarry Smith points in the second are set correctly from values on other MPI ranks. Must be followed by `DMLocalToLocalEnd()`. 3194f089877aSRichard Tran Mills 3195d083f849SBarry Smith Neighbor-wise Collective on dm 3196f089877aSRichard Tran Mills 3197f089877aSRichard Tran Mills Input Parameters: 3198bb7acecfSBarry Smith + dm - the `DM` object 3199bc0a1609SRichard Tran Mills . g - the original local vector 3200bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3201f089877aSRichard Tran Mills 3202bc0a1609SRichard Tran Mills Output Parameter: 3203bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3204f089877aSRichard Tran Mills 3205f089877aSRichard Tran Mills Level: intermediate 3206f089877aSRichard Tran Mills 3207bb7acecfSBarry Smith .seealso: `DMLocalToLocalEnd(), `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMLocalToLocalEnd()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3208f089877aSRichard Tran Mills 3209f089877aSRichard Tran Mills @*/ 3210d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 3211d71ae5a4SJacob Faibussowitsch { 3212f089877aSRichard Tran Mills PetscFunctionBegin; 3213f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32149566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtolocalbegin)(dm, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l)); 3215f089877aSRichard Tran Mills PetscFunctionReturn(0); 3216f089877aSRichard Tran Mills } 3217f089877aSRichard Tran Mills 3218f089877aSRichard Tran Mills /*@ 3219bb7acecfSBarry Smith DMLocalToLocalEnd - Maps from a local vector to another local vector where the ghost 3220bb7acecfSBarry Smith points in the second are set correctly. Must be preceded by `DMLocalToLocalBegin()`. 3221f089877aSRichard Tran Mills 3222d083f849SBarry Smith Neighbor-wise Collective on dm 3223f089877aSRichard Tran Mills 3224f089877aSRichard Tran Mills Input Parameters: 3225bb7acecfSBarry Smith + da - the `DM` object 3226bc0a1609SRichard Tran Mills . g - the original local vector 3227bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3228f089877aSRichard Tran Mills 3229bc0a1609SRichard Tran Mills Output Parameter: 3230bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3231f089877aSRichard Tran Mills 3232f089877aSRichard Tran Mills Level: intermediate 3233f089877aSRichard Tran Mills 3234bb7acecfSBarry Smith .seealso: `DMLocalToLocalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMLocalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3235f089877aSRichard Tran Mills 3236f089877aSRichard Tran Mills @*/ 3237d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 3238d71ae5a4SJacob Faibussowitsch { 3239f089877aSRichard Tran Mills PetscFunctionBegin; 3240f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32419566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtolocalend)(dm, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l)); 3242f089877aSRichard Tran Mills PetscFunctionReturn(0); 3243f089877aSRichard Tran Mills } 3244f089877aSRichard Tran Mills 324547c6ae99SBarry Smith /*@ 3246bb7acecfSBarry Smith DMCoarsen - Coarsens a `DM` object using a standard, non-adaptive coarsening of the underlying mesh 324747c6ae99SBarry Smith 3248d083f849SBarry Smith Collective on dm 324947c6ae99SBarry Smith 3250d8d19677SJose E. Roman Input Parameters: 3251bb7acecfSBarry Smith + dm - the `DM` object 3252bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or MPI_COMM_NULL) 325347c6ae99SBarry Smith 325447c6ae99SBarry Smith Output Parameter: 3255bb7acecfSBarry Smith . dmc - the coarsened `DM` 325647c6ae99SBarry Smith 325747c6ae99SBarry Smith Level: developer 325847c6ae99SBarry Smith 3259bb7acecfSBarry Smith .seealso: `DM`, `DMRefine()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 326047c6ae99SBarry Smith 326147c6ae99SBarry Smith @*/ 3262d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 3263d71ae5a4SJacob Faibussowitsch { 3264b17ce1afSJed Brown DMCoarsenHookLink link; 326547c6ae99SBarry Smith 326647c6ae99SBarry Smith PetscFunctionBegin; 3267171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32689566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Coarsen, dm, 0, 0, 0)); 3269dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsen, comm, dmc); 3270b9d85ea2SLisandro Dalcin if (*dmc) { 3271a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 32729566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm, *dmc)); 327343842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 32749566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmc)); 3275644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 32760598a293SJed Brown (*dmc)->levelup = dm->levelup; 3277656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 32789566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmc, dm->mattype)); 3279b17ce1afSJed Brown for (link = dm->coarsenhook; link; link = link->next) { 32809566063dSJacob Faibussowitsch if (link->coarsenhook) PetscCall((*link->coarsenhook)(dm, *dmc, link->ctx)); 3281b17ce1afSJed Brown } 3282b9d85ea2SLisandro Dalcin } 32839566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Coarsen, dm, 0, 0, 0)); 32847a8be351SBarry Smith PetscCheck(*dmc, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 3285b17ce1afSJed Brown PetscFunctionReturn(0); 3286b17ce1afSJed Brown } 3287b17ce1afSJed Brown 3288bb9467b5SJed Brown /*@C 3289b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3290b17ce1afSJed Brown 3291bb7acecfSBarry Smith Logically Collective on fine 3292b17ce1afSJed Brown 32934165533cSJose E. Roman Input Parameters: 3294bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3295b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3296bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels (called once per `SNESSolve()`) 32970298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3298b17ce1afSJed Brown 3299b17ce1afSJed Brown Calling sequence of coarsenhook: 3300b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 3301b17ce1afSJed Brown 3302bb7acecfSBarry Smith + fine - fine level `DM` 3303bb7acecfSBarry Smith . coarse - coarse level `DM` to restrict problem to 3304b17ce1afSJed Brown - ctx - optional user-defined function context 3305b17ce1afSJed Brown 3306b17ce1afSJed Brown Calling sequence for restricthook: 3307c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 3308bb7acecfSBarry Smith $ 3309bb7acecfSBarry Smith + fine - fine level `DM` 3310bb7acecfSBarry Smith . mrestrict - matrix restricting a fine-level solution to the coarse grid, usually the transpose of the interpolation 3311c833c3b5SJed Brown . rscale - scaling vector for restriction 3312c833c3b5SJed Brown . inject - matrix restricting by injection 3313b17ce1afSJed Brown . coarse - coarse level DM to update 3314b17ce1afSJed Brown - ctx - optional user-defined function context 3315b17ce1afSJed Brown 3316b17ce1afSJed Brown Level: advanced 3317b17ce1afSJed Brown 3318b17ce1afSJed Brown Notes: 3319bb7acecfSBarry 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`. 3320b17ce1afSJed Brown 3321b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3322b17ce1afSJed Brown 3323b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3324bb7acecfSBarry Smith extract the finest level information from its context (instead of from the `SNES`). 3325b17ce1afSJed Brown 3326bb7acecfSBarry Smith The hooks are automatically called by `DMRestrict()` 3327bb7acecfSBarry Smith 3328bb7acecfSBarry Smith Fortran Note: 3329bb7acecfSBarry Smith This function is not available from Fortran. 3330bb9467b5SJed Brown 3331db781477SPatrick Sanan .seealso: `DMCoarsenHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3332b17ce1afSJed Brown @*/ 3333d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHookAdd(DM fine, PetscErrorCode (*coarsenhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, Mat, Vec, Mat, DM, void *), void *ctx) 3334d71ae5a4SJacob Faibussowitsch { 3335b17ce1afSJed Brown DMCoarsenHookLink link, *p; 3336b17ce1afSJed Brown 3337b17ce1afSJed Brown PetscFunctionBegin; 3338b17ce1afSJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 33391e3d8eccSJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 33401e3d8eccSJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 33411e3d8eccSJed Brown } 33429566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3343b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3344b17ce1afSJed Brown link->restricthook = restricthook; 3345b17ce1afSJed Brown link->ctx = ctx; 33460298fd71SBarry Smith link->next = NULL; 3347b17ce1afSJed Brown *p = link; 3348b17ce1afSJed Brown PetscFunctionReturn(0); 3349b17ce1afSJed Brown } 3350b17ce1afSJed Brown 3351dc822a44SJed Brown /*@C 3352bb7acecfSBarry Smith DMCoarsenHookRemove - remove a callback set with `DMCoarsenHookAdd()` 3353dc822a44SJed Brown 3354bb7acecfSBarry Smith Logically Collective on fine 3355dc822a44SJed Brown 33564165533cSJose E. Roman Input Parameters: 3357bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3358dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3359bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels 3360dc822a44SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3361dc822a44SJed Brown 3362dc822a44SJed Brown Level: advanced 3363dc822a44SJed Brown 3364bb7acecfSBarry Smith Note: 3365dc822a44SJed Brown This function does nothing if the hook is not in the list. 3366dc822a44SJed Brown 3367bb7acecfSBarry Smith Fortran Note: 3368bb7acecfSBarry Smith This function is not available from Fortran. 3369dc822a44SJed Brown 3370db781477SPatrick Sanan .seealso: `DMCoarsenHookAdd()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3371dc822a44SJed Brown @*/ 3372d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHookRemove(DM fine, PetscErrorCode (*coarsenhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, Mat, Vec, Mat, DM, void *), void *ctx) 3373d71ae5a4SJacob Faibussowitsch { 3374dc822a44SJed Brown DMCoarsenHookLink link, *p; 3375dc822a44SJed Brown 3376dc822a44SJed Brown PetscFunctionBegin; 3377dc822a44SJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 3378dc822a44SJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3379dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3380dc822a44SJed Brown link = *p; 3381dc822a44SJed Brown *p = link->next; 33829566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3383dc822a44SJed Brown break; 3384dc822a44SJed Brown } 3385dc822a44SJed Brown } 3386dc822a44SJed Brown PetscFunctionReturn(0); 3387dc822a44SJed Brown } 3388dc822a44SJed Brown 3389b17ce1afSJed Brown /*@ 3390bb7acecfSBarry Smith DMRestrict - restricts user-defined problem data to a coarser `DM` by running hooks registered by `DMCoarsenHookAdd()` 3391b17ce1afSJed Brown 3392b17ce1afSJed Brown Collective if any hooks are 3393b17ce1afSJed Brown 33944165533cSJose E. Roman Input Parameters: 3395bb7acecfSBarry Smith + fine - finer `DM` from which the data is obtained 3396bb7acecfSBarry Smith . restrct - restriction matrix, apply using `MatRestrict()`, usually the transpose of the interpolation 3397e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3398bb7acecfSBarry Smith . inject - injection matrix, also use `MatRestrict()` 3399e91eccc2SStefano Zampini - coarse - coarser DM to update 3400b17ce1afSJed Brown 3401b17ce1afSJed Brown Level: developer 3402b17ce1afSJed Brown 3403bb7acecfSBarry Smith Developer Note: 3404bb7acecfSBarry Smith Though this routine is called `DMRestrict()` the hooks are added with `DMCoarsenHookAdd()`, a consistent terminology would be better 3405bb7acecfSBarry Smith 3406bb7acecfSBarry Smith .seealso: `DMCoarsenHookAdd()`, `MatRestrict()`, `DMInterpolate()`, `DMRefineHookAdd()` 3407b17ce1afSJed Brown @*/ 3408d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestrict(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse) 3409d71ae5a4SJacob Faibussowitsch { 3410b17ce1afSJed Brown DMCoarsenHookLink link; 3411b17ce1afSJed Brown 3412b17ce1afSJed Brown PetscFunctionBegin; 3413b17ce1afSJed Brown for (link = fine->coarsenhook; link; link = link->next) { 34141baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(fine, restrct, rscale, inject, coarse, link->ctx)); 3415b17ce1afSJed Brown } 341647c6ae99SBarry Smith PetscFunctionReturn(0); 341747c6ae99SBarry Smith } 341847c6ae99SBarry Smith 3419bb9467b5SJed Brown /*@C 3420be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 34215dbd56e3SPeter Brune 3422d083f849SBarry Smith Logically Collective on global 34235dbd56e3SPeter Brune 34244165533cSJose E. Roman Input Parameters: 3425bb7acecfSBarry Smith + global - global `DM` 3426bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 34275dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 34280298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 34295dbd56e3SPeter Brune 3430ec4806b8SPeter Brune Calling sequence for ddhook: 3431ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 3432ec4806b8SPeter Brune 3433bb7acecfSBarry Smith + global - global `DM` 3434bb7acecfSBarry Smith . block - block `DM` 3435ec4806b8SPeter Brune - ctx - optional user-defined function context 3436ec4806b8SPeter Brune 34375dbd56e3SPeter Brune Calling sequence for restricthook: 3438ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 34395dbd56e3SPeter Brune 3440bb7acecfSBarry Smith + global - global `DM` 34415dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 34425dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 3443bb7acecfSBarry Smith . block - block `DM` 34445dbd56e3SPeter Brune - ctx - optional user-defined function context 34455dbd56e3SPeter Brune 34465dbd56e3SPeter Brune Level: advanced 34475dbd56e3SPeter Brune 34485dbd56e3SPeter Brune Notes: 3449bb7acecfSBarry Smith This function is only needed if auxiliary data needs to be set up on subdomain `DM`s. 34505dbd56e3SPeter Brune 34515dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 34525dbd56e3SPeter Brune 34535dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3454bb7acecfSBarry Smith extract the global information from its context (instead of from the `SNES`). 34555dbd56e3SPeter Brune 3456bb7acecfSBarry Smith Fortran Note: 3457bb7acecfSBarry Smith This function is not available from Fortran. 3458bb9467b5SJed Brown 3459bb7acecfSBarry Smith .seealso: `DMSubDomainHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 34605dbd56e3SPeter Brune @*/ 3461d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookAdd(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3462d71ae5a4SJacob Faibussowitsch { 3463be081cd6SPeter Brune DMSubDomainHookLink link, *p; 34645dbd56e3SPeter Brune 34655dbd56e3SPeter Brune PetscFunctionBegin; 34665dbd56e3SPeter Brune PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3467b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 3468b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 3469b3a6b972SJed Brown } 34709566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 34715dbd56e3SPeter Brune link->restricthook = restricthook; 3472be081cd6SPeter Brune link->ddhook = ddhook; 34735dbd56e3SPeter Brune link->ctx = ctx; 34740298fd71SBarry Smith link->next = NULL; 34755dbd56e3SPeter Brune *p = link; 34765dbd56e3SPeter Brune PetscFunctionReturn(0); 34775dbd56e3SPeter Brune } 34785dbd56e3SPeter Brune 3479b3a6b972SJed Brown /*@C 3480b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 3481b3a6b972SJed Brown 3482bb7acecfSBarry Smith Logically Collective on global 3483b3a6b972SJed Brown 34844165533cSJose E. Roman Input Parameters: 3485bb7acecfSBarry Smith + global - global `DM` 3486bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 3487b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 3488b3a6b972SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3489b3a6b972SJed Brown 3490b3a6b972SJed Brown Level: advanced 3491b3a6b972SJed Brown 3492bb7acecfSBarry Smith Fortran Note: 3493bb7acecfSBarry Smith This function is not available from Fortran. 3494b3a6b972SJed Brown 3495db781477SPatrick Sanan .seealso: `DMSubDomainHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3496b3a6b972SJed Brown @*/ 3497d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookRemove(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3498d71ae5a4SJacob Faibussowitsch { 3499b3a6b972SJed Brown DMSubDomainHookLink link, *p; 3500b3a6b972SJed Brown 3501b3a6b972SJed Brown PetscFunctionBegin; 3502b3a6b972SJed Brown PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3503b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3504b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3505b3a6b972SJed Brown link = *p; 3506b3a6b972SJed Brown *p = link->next; 35079566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3508b3a6b972SJed Brown break; 3509b3a6b972SJed Brown } 3510b3a6b972SJed Brown } 3511b3a6b972SJed Brown PetscFunctionReturn(0); 3512b3a6b972SJed Brown } 3513b3a6b972SJed Brown 35145dbd56e3SPeter Brune /*@ 3515bb7acecfSBarry Smith DMSubDomainRestrict - restricts user-defined problem data to a block `DM` by running hooks registered by `DMSubDomainHookAdd()` 35165dbd56e3SPeter Brune 35175dbd56e3SPeter Brune Collective if any hooks are 35185dbd56e3SPeter Brune 35194165533cSJose E. Roman Input Parameters: 3520bb7acecfSBarry Smith + fine - finer `DM` to use as a base 3521be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 3522be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 3523bb7acecfSBarry Smith - coarse - coarser `DM` to update 35245dbd56e3SPeter Brune 35255dbd56e3SPeter Brune Level: developer 35265dbd56e3SPeter Brune 3527db781477SPatrick Sanan .seealso: `DMCoarsenHookAdd()`, `MatRestrict()` 35285dbd56e3SPeter Brune @*/ 3529d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainRestrict(DM global, VecScatter oscatter, VecScatter gscatter, DM subdm) 3530d71ae5a4SJacob Faibussowitsch { 3531be081cd6SPeter Brune DMSubDomainHookLink link; 35325dbd56e3SPeter Brune 35335dbd56e3SPeter Brune PetscFunctionBegin; 3534be081cd6SPeter Brune for (link = global->subdomainhook; link; link = link->next) { 35351baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(global, oscatter, gscatter, subdm, link->ctx)); 35365dbd56e3SPeter Brune } 35375dbd56e3SPeter Brune PetscFunctionReturn(0); 35385dbd56e3SPeter Brune } 35395dbd56e3SPeter Brune 35405fe1f584SPeter Brune /*@ 3541bb7acecfSBarry Smith DMGetCoarsenLevel - Gets the number of coarsenings that have generated this `DM`. 35425fe1f584SPeter Brune 35435fe1f584SPeter Brune Not Collective 35445fe1f584SPeter Brune 35455fe1f584SPeter Brune Input Parameter: 3546bb7acecfSBarry Smith . dm - the `DM` object 35475fe1f584SPeter Brune 35485fe1f584SPeter Brune Output Parameter: 35496a7d9d85SPeter Brune . level - number of coarsenings 35505fe1f584SPeter Brune 35515fe1f584SPeter Brune Level: developer 35525fe1f584SPeter Brune 3553bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMSetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35545fe1f584SPeter Brune 35555fe1f584SPeter Brune @*/ 3556d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarsenLevel(DM dm, PetscInt *level) 3557d71ae5a4SJacob Faibussowitsch { 35585fe1f584SPeter Brune PetscFunctionBegin; 35595fe1f584SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3560b9d85ea2SLisandro Dalcin PetscValidIntPointer(level, 2); 35615fe1f584SPeter Brune *level = dm->leveldown; 35625fe1f584SPeter Brune PetscFunctionReturn(0); 35635fe1f584SPeter Brune } 35645fe1f584SPeter Brune 35659a64c4a8SMatthew G. Knepley /*@ 3566bb7acecfSBarry Smith DMSetCoarsenLevel - Sets the number of coarsenings that have generated this `DM`. 35679a64c4a8SMatthew G. Knepley 3568bb7acecfSBarry Smith Collective on dm 35699a64c4a8SMatthew G. Knepley 35709a64c4a8SMatthew G. Knepley Input Parameters: 3571bb7acecfSBarry Smith + dm - the `DM` object 35729a64c4a8SMatthew G. Knepley - level - number of coarsenings 35739a64c4a8SMatthew G. Knepley 35749a64c4a8SMatthew G. Knepley Level: developer 35759a64c4a8SMatthew G. Knepley 3576bb7acecfSBarry Smith Note: 3577bb7acecfSBarry Smith This is rarely used directly, the information is automatically set when a `DM` is created with `DMCoarsen()` 3578bb7acecfSBarry Smith 3579bb7acecfSBarry Smith .seealso: `DMSetCoarsenLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35809a64c4a8SMatthew G. Knepley @*/ 3581d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarsenLevel(DM dm, PetscInt level) 3582d71ae5a4SJacob Faibussowitsch { 35839a64c4a8SMatthew G. Knepley PetscFunctionBegin; 35849a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 35859a64c4a8SMatthew G. Knepley dm->leveldown = level; 35869a64c4a8SMatthew G. Knepley PetscFunctionReturn(0); 35879a64c4a8SMatthew G. Knepley } 35889a64c4a8SMatthew G. Knepley 358947c6ae99SBarry Smith /*@C 3590bb7acecfSBarry Smith DMRefineHierarchy - Refines a `DM` object, all levels at once 359147c6ae99SBarry Smith 3592d083f849SBarry Smith Collective on dm 359347c6ae99SBarry Smith 3594d8d19677SJose E. Roman Input Parameters: 3595bb7acecfSBarry Smith + dm - the `DM` object 359647c6ae99SBarry Smith - nlevels - the number of levels of refinement 359747c6ae99SBarry Smith 359847c6ae99SBarry Smith Output Parameter: 3599bb7acecfSBarry Smith . dmf - the refined `DM` hierarchy 360047c6ae99SBarry Smith 360147c6ae99SBarry Smith Level: developer 360247c6ae99SBarry Smith 3603bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMCoarsenHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 360447c6ae99SBarry Smith 360547c6ae99SBarry Smith @*/ 3606d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHierarchy(DM dm, PetscInt nlevels, DM dmf[]) 3607d71ae5a4SJacob Faibussowitsch { 360847c6ae99SBarry Smith PetscFunctionBegin; 3609171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36107a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 361147c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 3612b9d85ea2SLisandro Dalcin PetscValidPointer(dmf, 3); 361347c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 3614dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refinehierarchy, nlevels, dmf); 361547c6ae99SBarry Smith } else if (dm->ops->refine) { 361647c6ae99SBarry Smith PetscInt i; 361747c6ae99SBarry Smith 36189566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0])); 361948a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i])); 3620ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No RefineHierarchy for this DM yet"); 362147c6ae99SBarry Smith PetscFunctionReturn(0); 362247c6ae99SBarry Smith } 362347c6ae99SBarry Smith 362447c6ae99SBarry Smith /*@C 3625bb7acecfSBarry Smith DMCoarsenHierarchy - Coarsens a `DM` object, all levels at once 362647c6ae99SBarry Smith 3627d083f849SBarry Smith Collective on dm 362847c6ae99SBarry Smith 3629d8d19677SJose E. Roman Input Parameters: 3630bb7acecfSBarry Smith + dm - the `DM` object 363147c6ae99SBarry Smith - nlevels - the number of levels of coarsening 363247c6ae99SBarry Smith 363347c6ae99SBarry Smith Output Parameter: 3634bb7acecfSBarry Smith . dmc - the coarsened `DM` hierarchy 363547c6ae99SBarry Smith 363647c6ae99SBarry Smith Level: developer 363747c6ae99SBarry Smith 3638bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMRefineHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 363947c6ae99SBarry Smith 364047c6ae99SBarry Smith @*/ 3641d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 3642d71ae5a4SJacob Faibussowitsch { 364347c6ae99SBarry Smith PetscFunctionBegin; 3644171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36457a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 364647c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 364747c6ae99SBarry Smith PetscValidPointer(dmc, 3); 364847c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 3649dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsenhierarchy, nlevels, dmc); 365047c6ae99SBarry Smith } else if (dm->ops->coarsen) { 365147c6ae99SBarry Smith PetscInt i; 365247c6ae99SBarry Smith 36539566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0])); 365448a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i])); 3655ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No CoarsenHierarchy for this DM yet"); 365647c6ae99SBarry Smith PetscFunctionReturn(0); 365747c6ae99SBarry Smith } 365847c6ae99SBarry Smith 36591a266240SBarry Smith /*@C 3660bb7acecfSBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the `DM` is destroyed 36611a266240SBarry Smith 3662bb7acecfSBarry Smith Logically Collective if the function is collective 36631a266240SBarry Smith 36641a266240SBarry Smith Input Parameters: 3665bb7acecfSBarry Smith + dm - the `DM` object 36661a266240SBarry Smith - destroy - the destroy function 36671a266240SBarry Smith 36681a266240SBarry Smith Level: intermediate 36691a266240SBarry Smith 3670bb7acecfSBarry Smith .seealso: `DMSetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 36711a266240SBarry Smith 3672f07f9ceaSJed Brown @*/ 3673d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContextDestroy(DM dm, PetscErrorCode (*destroy)(void **)) 3674d71ae5a4SJacob Faibussowitsch { 36751a266240SBarry Smith PetscFunctionBegin; 3676171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36771a266240SBarry Smith dm->ctxdestroy = destroy; 36781a266240SBarry Smith PetscFunctionReturn(0); 36791a266240SBarry Smith } 36801a266240SBarry Smith 3681b07ff414SBarry Smith /*@ 3682bb7acecfSBarry Smith DMSetApplicationContext - Set a user context into a `DM` object 368347c6ae99SBarry Smith 368447c6ae99SBarry Smith Not Collective 368547c6ae99SBarry Smith 368647c6ae99SBarry Smith Input Parameters: 3687bb7acecfSBarry Smith + dm - the `DM` object 368847c6ae99SBarry Smith - ctx - the user context 368947c6ae99SBarry Smith 369047c6ae99SBarry Smith Level: intermediate 369147c6ae99SBarry Smith 3692bb7acecfSBarry Smith Note: 3693bb7acecfSBarry Smith A user context is a way to pass problem specific information that is accessable whenever the `DM` is available 3694bb7acecfSBarry Smith 3695bb7acecfSBarry Smith .seealso: `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 369647c6ae99SBarry Smith 369747c6ae99SBarry Smith @*/ 3698d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContext(DM dm, void *ctx) 3699d71ae5a4SJacob Faibussowitsch { 370047c6ae99SBarry Smith PetscFunctionBegin; 3701171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 370247c6ae99SBarry Smith dm->ctx = ctx; 370347c6ae99SBarry Smith PetscFunctionReturn(0); 370447c6ae99SBarry Smith } 370547c6ae99SBarry Smith 370647c6ae99SBarry Smith /*@ 3707bb7acecfSBarry Smith DMGetApplicationContext - Gets a user context from a `DM` object 370847c6ae99SBarry Smith 370947c6ae99SBarry Smith Not Collective 371047c6ae99SBarry Smith 371147c6ae99SBarry Smith Input Parameter: 3712bb7acecfSBarry Smith . dm - the `DM` object 371347c6ae99SBarry Smith 371447c6ae99SBarry Smith Output Parameter: 371547c6ae99SBarry Smith . ctx - the user context 371647c6ae99SBarry Smith 371747c6ae99SBarry Smith Level: intermediate 371847c6ae99SBarry Smith 3719bb7acecfSBarry Smith Note: 3720bb7acecfSBarry Smith A user context is a way to pass problem specific information that is accessable whenever the `DM` is available 3721bb7acecfSBarry Smith 3722bb7acecfSBarry Smith .seealso: `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 372347c6ae99SBarry Smith 372447c6ae99SBarry Smith @*/ 3725d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetApplicationContext(DM dm, void *ctx) 3726d71ae5a4SJacob Faibussowitsch { 372747c6ae99SBarry Smith PetscFunctionBegin; 3728171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37291b2093e4SBarry Smith *(void **)ctx = dm->ctx; 373047c6ae99SBarry Smith PetscFunctionReturn(0); 373147c6ae99SBarry Smith } 373247c6ae99SBarry Smith 373308da532bSDmitry Karpeev /*@C 3734bb7acecfSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for `SNESVI`. 373508da532bSDmitry Karpeev 3736d083f849SBarry Smith Logically Collective on dm 373708da532bSDmitry Karpeev 3738d8d19677SJose E. Roman Input Parameters: 373908da532bSDmitry Karpeev + dm - the DM object 37400298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 374108da532bSDmitry Karpeev 374208da532bSDmitry Karpeev Level: intermediate 374308da532bSDmitry Karpeev 3744bb7acecfSBarry Smith .seealso: `DMComputeVariableBounds()`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()`, 3745db781477SPatrick Sanan `DMSetJacobian()` 374608da532bSDmitry Karpeev 374708da532bSDmitry Karpeev @*/ 3748d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVariableBounds(DM dm, PetscErrorCode (*f)(DM, Vec, Vec)) 3749d71ae5a4SJacob Faibussowitsch { 375008da532bSDmitry Karpeev PetscFunctionBegin; 37515a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 375208da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 375308da532bSDmitry Karpeev PetscFunctionReturn(0); 375408da532bSDmitry Karpeev } 375508da532bSDmitry Karpeev 375608da532bSDmitry Karpeev /*@ 3757bb7acecfSBarry Smith DMHasVariableBounds - does the `DM` object have a variable bounds function? 375808da532bSDmitry Karpeev 375908da532bSDmitry Karpeev Not Collective 376008da532bSDmitry Karpeev 376108da532bSDmitry Karpeev Input Parameter: 3762bb7acecfSBarry Smith . dm - the `DM` object to destroy 376308da532bSDmitry Karpeev 376408da532bSDmitry Karpeev Output Parameter: 3765bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the variable bounds function exists 376608da532bSDmitry Karpeev 376708da532bSDmitry Karpeev Level: developer 376808da532bSDmitry Karpeev 3769bb7acecfSBarry Smith .seealso: `DMComputeVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 377008da532bSDmitry Karpeev 377108da532bSDmitry Karpeev @*/ 3772d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasVariableBounds(DM dm, PetscBool *flg) 3773d71ae5a4SJacob Faibussowitsch { 377408da532bSDmitry Karpeev PetscFunctionBegin; 37755a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3776534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 377708da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 377808da532bSDmitry Karpeev PetscFunctionReturn(0); 377908da532bSDmitry Karpeev } 378008da532bSDmitry Karpeev 378108da532bSDmitry Karpeev /*@C 3782bb7acecfSBarry Smith DMComputeVariableBounds - compute variable bounds used by `SNESVI`. 378308da532bSDmitry Karpeev 3784d083f849SBarry Smith Logically Collective on dm 378508da532bSDmitry Karpeev 3786f899ff85SJose E. Roman Input Parameter: 3787bb7acecfSBarry Smith . dm - the `DM` object 378808da532bSDmitry Karpeev 378908da532bSDmitry Karpeev Output parameters: 379008da532bSDmitry Karpeev + xl - lower bound 379108da532bSDmitry Karpeev - xu - upper bound 379208da532bSDmitry Karpeev 3793907376e6SBarry Smith Level: advanced 3794907376e6SBarry Smith 379595452b02SPatrick Sanan Notes: 379695452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 379708da532bSDmitry Karpeev 3798bb7acecfSBarry Smith .seealso: `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 379908da532bSDmitry Karpeev 380008da532bSDmitry Karpeev @*/ 3801d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 3802d71ae5a4SJacob Faibussowitsch { 380308da532bSDmitry Karpeev PetscFunctionBegin; 38045a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 380508da532bSDmitry Karpeev PetscValidHeaderSpecific(xl, VEC_CLASSID, 2); 38065a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu, VEC_CLASSID, 3); 3807dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, computevariablebounds, xl, xu); 380808da532bSDmitry Karpeev PetscFunctionReturn(0); 380908da532bSDmitry Karpeev } 381008da532bSDmitry Karpeev 3811b0ae01b7SPeter Brune /*@ 3812bb7acecfSBarry Smith DMHasColoring - does the `DM` object have a method of providing a coloring? 3813b0ae01b7SPeter Brune 3814b0ae01b7SPeter Brune Not Collective 3815b0ae01b7SPeter Brune 3816b0ae01b7SPeter Brune Input Parameter: 3817b0ae01b7SPeter Brune . dm - the DM object 3818b0ae01b7SPeter Brune 3819b0ae01b7SPeter Brune Output Parameter: 3820bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateColoring()`. 3821b0ae01b7SPeter Brune 3822b0ae01b7SPeter Brune Level: developer 3823b0ae01b7SPeter Brune 3824bb7acecfSBarry Smith .seealso: `DMCreateColoring()` 3825b0ae01b7SPeter Brune 3826b0ae01b7SPeter Brune @*/ 3827d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasColoring(DM dm, PetscBool *flg) 3828d71ae5a4SJacob Faibussowitsch { 3829b0ae01b7SPeter Brune PetscFunctionBegin; 38305a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3831534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 3832b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 3833b0ae01b7SPeter Brune PetscFunctionReturn(0); 3834b0ae01b7SPeter Brune } 3835b0ae01b7SPeter Brune 38363ad4599aSBarry Smith /*@ 3837bb7acecfSBarry Smith DMHasCreateRestriction - does the `DM` object have a method of providing a restriction? 38383ad4599aSBarry Smith 38393ad4599aSBarry Smith Not Collective 38403ad4599aSBarry Smith 38413ad4599aSBarry Smith Input Parameter: 3842bb7acecfSBarry Smith . dm - the `DM` object 38433ad4599aSBarry Smith 38443ad4599aSBarry Smith Output Parameter: 3845bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateRestriction()`. 38463ad4599aSBarry Smith 38473ad4599aSBarry Smith Level: developer 38483ad4599aSBarry Smith 3849bb7acecfSBarry Smith .seealso: `DMCreateRestriction()`, `DMHasCreateInterpolation()`, `DMHasCreateInjection()` 38503ad4599aSBarry Smith 38513ad4599aSBarry Smith @*/ 3852d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateRestriction(DM dm, PetscBool *flg) 3853d71ae5a4SJacob Faibussowitsch { 38543ad4599aSBarry Smith PetscFunctionBegin; 38555a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3856534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 38573ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 38583ad4599aSBarry Smith PetscFunctionReturn(0); 38593ad4599aSBarry Smith } 38603ad4599aSBarry Smith 3861a7058e45SLawrence Mitchell /*@ 3862bb7acecfSBarry Smith DMHasCreateInjection - does the `DM` object have a method of providing an injection? 3863a7058e45SLawrence Mitchell 3864a7058e45SLawrence Mitchell Not Collective 3865a7058e45SLawrence Mitchell 3866a7058e45SLawrence Mitchell Input Parameter: 3867bb7acecfSBarry Smith . dm - the `DM` object 3868a7058e45SLawrence Mitchell 3869a7058e45SLawrence Mitchell Output Parameter: 3870bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateInjection()`. 3871a7058e45SLawrence Mitchell 3872a7058e45SLawrence Mitchell Level: developer 3873a7058e45SLawrence Mitchell 3874bb7acecfSBarry Smith .seealso: `DMCreateInjection()`, `DMHasCreateRestriction()`, `DMHasCreateInterpolation()` 3875a7058e45SLawrence Mitchell 3876a7058e45SLawrence Mitchell @*/ 3877d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateInjection(DM dm, PetscBool *flg) 3878d71ae5a4SJacob Faibussowitsch { 3879a7058e45SLawrence Mitchell PetscFunctionBegin; 38805a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3881534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 3882dbbe0bcdSBarry Smith if (dm->ops->hascreateinjection) PetscUseTypeMethod(dm, hascreateinjection, flg); 3883ad540459SPierre Jolivet else *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 3884a7058e45SLawrence Mitchell PetscFunctionReturn(0); 3885a7058e45SLawrence Mitchell } 3886a7058e45SLawrence Mitchell 38870298fd71SBarry Smith PetscFunctionList DMList = NULL; 3888264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3889264ace61SBarry Smith 3890264ace61SBarry Smith /*@C 3891bb7acecfSBarry Smith DMSetType - Builds a `DM`, for a particular `DM` implementation. 3892264ace61SBarry Smith 3893d083f849SBarry Smith Collective on dm 3894264ace61SBarry Smith 3895264ace61SBarry Smith Input Parameters: 3896bb7acecfSBarry Smith + dm - The `DM` object 3897bb7acecfSBarry Smith - method - The name of the `DMType`, for example `DMDA`, `DMPLEX` 3898264ace61SBarry Smith 3899264ace61SBarry Smith Options Database Key: 3900bb7acecfSBarry Smith . -dm_type <type> - Sets the `DM` type; use -help for a list of available types 3901264ace61SBarry Smith 3902264ace61SBarry Smith Level: intermediate 3903264ace61SBarry Smith 3904bb7acecfSBarry Smith Note: 3905bb7acecfSBarry Smith Of the `DM` is constructed by directly calling a function to construct a particular `DM`, for example, `DMDACreate2d()` or `DMPLEXCreateBoxMesh()` 3906bb7acecfSBarry Smith 3907bb7acecfSBarry Smith .seealso: `DMType`, `DMDA`, `DMPLEX`, `DMGetType()`, `DMCreate()`, `DMDACreate2d()` 3908264ace61SBarry Smith @*/ 3909d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetType(DM dm, DMType method) 3910d71ae5a4SJacob Faibussowitsch { 3911264ace61SBarry Smith PetscErrorCode (*r)(DM); 3912264ace61SBarry Smith PetscBool match; 3913264ace61SBarry Smith 3914264ace61SBarry Smith PetscFunctionBegin; 3915264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39169566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, method, &match)); 3917264ace61SBarry Smith if (match) PetscFunctionReturn(0); 3918264ace61SBarry Smith 39199566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 39209566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(DMList, method, &r)); 39217a8be351SBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3922264ace61SBarry Smith 3923dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, destroy); 39249566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops, sizeof(*dm->ops))); 39259566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)dm, method)); 39269566063dSJacob Faibussowitsch PetscCall((*r)(dm)); 3927264ace61SBarry Smith PetscFunctionReturn(0); 3928264ace61SBarry Smith } 3929264ace61SBarry Smith 3930264ace61SBarry Smith /*@C 3931bb7acecfSBarry Smith DMGetType - Gets the `DM` type name (as a string) from the `DM`. 3932264ace61SBarry Smith 3933264ace61SBarry Smith Not Collective 3934264ace61SBarry Smith 3935264ace61SBarry Smith Input Parameter: 3936bb7acecfSBarry Smith . dm - The `DM` 3937264ace61SBarry Smith 3938264ace61SBarry Smith Output Parameter: 3939bb7acecfSBarry Smith . type - The `DMType` name 3940264ace61SBarry Smith 3941264ace61SBarry Smith Level: intermediate 3942264ace61SBarry Smith 3943bb7acecfSBarry Smith .seealso: `DMType`, `DMDA`, `DMPLEX`, `DMSetType()`, `DMCreate()` 3944264ace61SBarry Smith @*/ 3945d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetType(DM dm, DMType *type) 3946d71ae5a4SJacob Faibussowitsch { 3947264ace61SBarry Smith PetscFunctionBegin; 3948264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3949c959eef4SJed Brown PetscValidPointer(type, 2); 39509566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 3951264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 3952264ace61SBarry Smith PetscFunctionReturn(0); 3953264ace61SBarry Smith } 3954264ace61SBarry Smith 395567a56275SMatthew G Knepley /*@C 3956bb7acecfSBarry Smith DMConvert - Converts a `DM` to another `DM`, either of the same or different type. 395767a56275SMatthew G Knepley 3958d083f849SBarry Smith Collective on dm 395967a56275SMatthew G Knepley 396067a56275SMatthew G Knepley Input Parameters: 3961bb7acecfSBarry Smith + dm - the `DM` 3962bb7acecfSBarry Smith - newtype - new `DM` type (use "same" for the same type) 396367a56275SMatthew G Knepley 396467a56275SMatthew G Knepley Output Parameter: 3965bb7acecfSBarry Smith . M - pointer to new `DM` 396667a56275SMatthew G Knepley 396767a56275SMatthew G Knepley Notes: 3968bb7acecfSBarry Smith Cannot be used to convert a sequential `DM` to a parallel or a parallel to sequential, 3969bb7acecfSBarry Smith the MPI communicator of the generated `DM` is always the same as the communicator 3970bb7acecfSBarry Smith of the input `DM`. 397167a56275SMatthew G Knepley 397267a56275SMatthew G Knepley Level: intermediate 397367a56275SMatthew G Knepley 3974bb7acecfSBarry Smith .seealso: `DM`, `DMSetType()`, `DMCreate()`, `DMClone()` 397567a56275SMatthew G Knepley @*/ 3976d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 3977d71ae5a4SJacob Faibussowitsch { 397867a56275SMatthew G Knepley DM B; 397967a56275SMatthew G Knepley char convname[256]; 3980c067b6caSMatthew G. Knepley PetscBool sametype /*, issame */; 398167a56275SMatthew G Knepley 398267a56275SMatthew G Knepley PetscFunctionBegin; 398367a56275SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 398467a56275SMatthew G Knepley PetscValidType(dm, 1); 398567a56275SMatthew G Knepley PetscValidPointer(M, 3); 39869566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, newtype, &sametype)); 39879566063dSJacob Faibussowitsch /* PetscCall(PetscStrcmp(newtype, "same", &issame)); */ 3988c067b6caSMatthew G. Knepley if (sametype) { 3989c067b6caSMatthew G. Knepley *M = dm; 39909566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 3991c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 3992c067b6caSMatthew G. Knepley } else { 39930298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM *) = NULL; 399467a56275SMatthew G Knepley 399567a56275SMatthew G Knepley /* 399667a56275SMatthew G Knepley Order of precedence: 399767a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 399867a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 399967a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 400067a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 400167a56275SMatthew G Knepley 5) Use a really basic converter. 400267a56275SMatthew G Knepley */ 400367a56275SMatthew G Knepley 400467a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 40059566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40069566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40079566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40089566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40099566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40109566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)dm, convname, &conv)); 401167a56275SMatthew G Knepley if (conv) goto foundconv; 401267a56275SMatthew G Knepley 401367a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 40149566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &B)); 40159566063dSJacob Faibussowitsch PetscCall(DMSetType(B, newtype)); 40169566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40179566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40189566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40199566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40209566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40219566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 402267a56275SMatthew G Knepley if (conv) { 40239566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 402467a56275SMatthew G Knepley goto foundconv; 402567a56275SMatthew G Knepley } 402667a56275SMatthew G Knepley 402767a56275SMatthew G Knepley #if 0 402867a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 402967a56275SMatthew G Knepley conv = B->ops->convertfrom; 40309566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 403167a56275SMatthew G Knepley if (conv) goto foundconv; 403267a56275SMatthew G Knepley 403367a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 403467a56275SMatthew G Knepley if (dm->ops->convert) { 403567a56275SMatthew G Knepley conv = dm->ops->convert; 403667a56275SMatthew G Knepley } 403767a56275SMatthew G Knepley if (conv) goto foundconv; 403867a56275SMatthew G Knepley #endif 403967a56275SMatthew G Knepley 404067a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 404198921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject)dm)->type_name, newtype); 404267a56275SMatthew G Knepley 404367a56275SMatthew G Knepley foundconv: 40449566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Convert, dm, 0, 0, 0)); 40459566063dSJacob Faibussowitsch PetscCall((*conv)(dm, newtype, M)); 404612fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 404790b157c4SStefano Zampini { 40484fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 40496858538eSMatthew G. Knepley 40504fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 40514fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*M, maxCell, Lstart, L)); 4052c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 40539566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->vectype)); 40549566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*M)->vectype)); 40559566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->mattype)); 40569566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*M)->mattype)); 405712fa691eSMatthew G. Knepley } 40589566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Convert, dm, 0, 0, 0)); 405967a56275SMatthew G Knepley } 40609566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 406167a56275SMatthew G Knepley PetscFunctionReturn(0); 406267a56275SMatthew G Knepley } 4063264ace61SBarry Smith 4064264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 4065264ace61SBarry Smith 4066264ace61SBarry Smith /*@C 4067bb7acecfSBarry Smith DMRegister - Adds a new `DM` type implementation 40681c84c290SBarry Smith 40691c84c290SBarry Smith Not Collective 40701c84c290SBarry Smith 40711c84c290SBarry Smith Input Parameters: 40721c84c290SBarry Smith + name - The name of a new user-defined creation routine 40731c84c290SBarry Smith - create_func - The creation routine itself 40741c84c290SBarry Smith 40751c84c290SBarry Smith Notes: 4076bb7acecfSBarry Smith DMRegister() may be called multiple times to add several user-defined `DM`s 40771c84c290SBarry Smith 40781c84c290SBarry Smith Sample usage: 40791c84c290SBarry Smith .vb 4080bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 40811c84c290SBarry Smith .ve 40821c84c290SBarry Smith 40831c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 40841c84c290SBarry Smith .vb 40851c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 40861c84c290SBarry Smith DMSetType(DM,"my_da"); 40871c84c290SBarry Smith .ve 40881c84c290SBarry Smith or at runtime via the option 40891c84c290SBarry Smith .vb 40901c84c290SBarry Smith -da_type my_da 40911c84c290SBarry Smith .ve 4092264ace61SBarry Smith 4093264ace61SBarry Smith Level: advanced 40941c84c290SBarry Smith 4095bb7acecfSBarry Smith .seealso: `DM`, `DMType`, `DMSetType()`, `DMRegisterAll()`, `DMRegisterDestroy()` 40961c84c290SBarry Smith 4097264ace61SBarry Smith @*/ 4098d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRegister(const char sname[], PetscErrorCode (*function)(DM)) 4099d71ae5a4SJacob Faibussowitsch { 4100264ace61SBarry Smith PetscFunctionBegin; 41019566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 41029566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&DMList, sname, function)); 4103264ace61SBarry Smith PetscFunctionReturn(0); 4104264ace61SBarry Smith } 4105264ace61SBarry Smith 4106b859378eSBarry Smith /*@C 4107bb7acecfSBarry Smith DMLoad - Loads a DM that has been stored in binary with `DMView()`. 4108b859378eSBarry Smith 4109d083f849SBarry Smith Collective on viewer 4110b859378eSBarry Smith 4111b859378eSBarry Smith Input Parameters: 4112bb7acecfSBarry Smith + newdm - the newly loaded `DM`, this needs to have been created with `DMCreate()` or 4113bb7acecfSBarry Smith some related function before a call to `DMLoad()`. 4114bb7acecfSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or 4115bb7acecfSBarry Smith `PETSCVIEWERHDF5` file viewer, obtained from `PetscViewerHDF5Open()` 4116b859378eSBarry Smith 4117b859378eSBarry Smith Level: intermediate 4118b859378eSBarry Smith 4119b859378eSBarry Smith Notes: 412055849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4121b859378eSBarry Smith 4122bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` format, one can save multiple `DMPLEX` 4123bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 4124bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 4125cd7e8a5eSksagiyam 4126b859378eSBarry Smith Notes for advanced users: 4127b859378eSBarry Smith Most users should not need to know the details of the binary storage 4128bb7acecfSBarry Smith format, since `DMLoad()` and `DMView()` completely hide these details. 4129b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 4130b859378eSBarry Smith format is 4131b859378eSBarry Smith .vb 4132b859378eSBarry Smith has not yet been determined 4133b859378eSBarry Smith .ve 4134b859378eSBarry Smith 4135db781477SPatrick Sanan .seealso: `PetscViewerBinaryOpen()`, `DMView()`, `MatLoad()`, `VecLoad()` 4136b859378eSBarry Smith @*/ 4137d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4138d71ae5a4SJacob Faibussowitsch { 41399331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4140b859378eSBarry Smith 4141b859378eSBarry Smith PetscFunctionBegin; 4142b859378eSBarry Smith PetscValidHeaderSpecific(newdm, DM_CLASSID, 1); 4143b859378eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 41449566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckReadable(viewer)); 41459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 41469566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 41479566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Load, viewer, 0, 0, 0)); 41489331c7a4SMatthew G. Knepley if (isbinary) { 41499331c7a4SMatthew G. Knepley PetscInt classid; 41509331c7a4SMatthew G. Knepley char type[256]; 4151b859378eSBarry Smith 41529566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 41537a8be351SBarry Smith PetscCheck(classid == DM_FILE_CLASSID, PetscObjectComm((PetscObject)newdm), PETSC_ERR_ARG_WRONG, "Not DM next in file, classid found %d", (int)classid); 41549566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 41559566063dSJacob Faibussowitsch PetscCall(DMSetType(newdm, type)); 4156dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41579331c7a4SMatthew G. Knepley } else if (ishdf5) { 4158dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41599331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 41609566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Load, viewer, 0, 0, 0)); 4161b859378eSBarry Smith PetscFunctionReturn(0); 4162b859378eSBarry Smith } 4163b859378eSBarry Smith 41647da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 41657da65231SMatthew G Knepley 4166d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4167d71ae5a4SJacob Faibussowitsch { 41681d47ebbbSSatish Balay PetscInt f; 41691b30c384SMatthew G Knepley 41707da65231SMatthew G Knepley PetscFunctionBegin; 417163a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 417248a46eb9SPierre Jolivet for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]))); 41737da65231SMatthew G Knepley PetscFunctionReturn(0); 41747da65231SMatthew G Knepley } 41757da65231SMatthew G Knepley 4176d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4177d71ae5a4SJacob Faibussowitsch { 41781b30c384SMatthew G Knepley PetscInt f, g; 41797da65231SMatthew G Knepley 41807da65231SMatthew G Knepley PetscFunctionBegin; 418163a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41821d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 41839566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |")); 418448a46eb9SPierre Jolivet for (g = 0; g < cols; ++g) PetscCall(PetscPrintf(PETSC_COMM_SELF, " % 9.5g", (double)PetscRealPart(A[f * cols + g]))); 41859566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |\n")); 41867da65231SMatthew G Knepley } 41877da65231SMatthew G Knepley PetscFunctionReturn(0); 41887da65231SMatthew G Knepley } 4189e7c4fc90SDmitry Karpeev 4190d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4191d71ae5a4SJacob Faibussowitsch { 41920c5b8624SToby Isaac PetscInt localSize, bs; 41930c5b8624SToby Isaac PetscMPIInt size; 41940c5b8624SToby Isaac Vec x, xglob; 41950c5b8624SToby Isaac const PetscScalar *xarray; 4196e759306cSMatthew G. Knepley 4197e759306cSMatthew G. Knepley PetscFunctionBegin; 41989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 41999566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &x)); 42009566063dSJacob Faibussowitsch PetscCall(VecCopy(X, x)); 42019566063dSJacob Faibussowitsch PetscCall(VecChop(x, tol)); 42029566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "%s:\n", name)); 42030c5b8624SToby Isaac if (size > 1) { 42049566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(x, &localSize)); 42059566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xarray)); 42069566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(x, &bs)); 42079566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm), bs, localSize, PETSC_DETERMINE, xarray, &xglob)); 42080c5b8624SToby Isaac } else { 42090c5b8624SToby Isaac xglob = x; 42100c5b8624SToby Isaac } 42119566063dSJacob Faibussowitsch PetscCall(VecView(xglob, PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)dm)))); 42120c5b8624SToby Isaac if (size > 1) { 42139566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xglob)); 42149566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xarray)); 42150c5b8624SToby Isaac } 42169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 4217e759306cSMatthew G. Knepley PetscFunctionReturn(0); 4218e759306cSMatthew G. Knepley } 4219e759306cSMatthew G. Knepley 422088ed4aceSMatthew G Knepley /*@ 4221bb7acecfSBarry Smith DMGetSection - Get the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMGetLocalSection()`. Deprecated in v3.12 4222061576a5SJed Brown 4223061576a5SJed Brown Input Parameter: 4224bb7acecfSBarry Smith . dm - The `DM` 4225061576a5SJed Brown 4226061576a5SJed Brown Output Parameter: 4227bb7acecfSBarry Smith . section - The `PetscSection` 4228061576a5SJed Brown 4229061576a5SJed Brown Options Database Keys: 4230bb7acecfSBarry Smith . -dm_petscsection_view - View the `PetscSection` created by the `DM` 4231061576a5SJed Brown 4232061576a5SJed Brown Level: advanced 4233061576a5SJed Brown 4234061576a5SJed Brown Notes: 4235bb7acecfSBarry Smith Use `DMGetLocalSection()` in new code. 4236061576a5SJed Brown 4237bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 4238061576a5SJed Brown 4239db781477SPatrick Sanan .seealso: `DMGetLocalSection()`, `DMSetLocalSection()`, `DMGetGlobalSection()` 4240061576a5SJed Brown @*/ 4241d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4242d71ae5a4SJacob Faibussowitsch { 4243061576a5SJed Brown PetscFunctionBegin; 42449566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, section)); 4245061576a5SJed Brown PetscFunctionReturn(0); 4246061576a5SJed Brown } 4247061576a5SJed Brown 4248061576a5SJed Brown /*@ 4249bb7acecfSBarry Smith DMGetLocalSection - Get the `PetscSection` encoding the local data layout for the `DM`. 425088ed4aceSMatthew G Knepley 425188ed4aceSMatthew G Knepley Input Parameter: 4252bb7acecfSBarry Smith . dm - The `DM` 425388ed4aceSMatthew G Knepley 425488ed4aceSMatthew G Knepley Output Parameter: 4255bb7acecfSBarry Smith . section - The `PetscSection` 425688ed4aceSMatthew G Knepley 4257e5893cccSMatthew G. Knepley Options Database Keys: 4258bb7acecfSBarry Smith . -dm_petscsection_view - View the section created by the `DM` 4259e5893cccSMatthew G. Knepley 426088ed4aceSMatthew G Knepley Level: intermediate 426188ed4aceSMatthew G Knepley 4262bb7acecfSBarry Smith Note: 4263bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 426488ed4aceSMatthew G Knepley 4265db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetGlobalSection()` 426688ed4aceSMatthew G Knepley @*/ 4267d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 4268d71ae5a4SJacob Faibussowitsch { 426988ed4aceSMatthew G Knepley PetscFunctionBegin; 427088ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 427188ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 42721bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4273e5e52638SMatthew G. Knepley PetscInt d; 4274e5e52638SMatthew G. Knepley 427545480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 427645480ffeSMatthew G. Knepley PetscObject obj = (PetscObject)dm; 427745480ffeSMatthew G. Knepley PetscViewer viewer; 427845480ffeSMatthew G. Knepley PetscViewerFormat format; 427945480ffeSMatthew G. Knepley PetscBool flg; 428045480ffeSMatthew G. Knepley 42819566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg)); 42829566063dSJacob Faibussowitsch if (flg) PetscCall(PetscViewerPushFormat(viewer, format)); 428345480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 42849566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(dm->probs[d].ds)); 42859566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDSView(dm->probs[d].ds, viewer)); 428645480ffeSMatthew G. Knepley } 428745480ffeSMatthew G. Knepley if (flg) { 42889566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 42899566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 42909566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 429145480ffeSMatthew G. Knepley } 429245480ffeSMatthew G. Knepley } 4293dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalsection); 42949566063dSJacob Faibussowitsch if (dm->localSection) PetscCall(PetscObjectViewFromOptions((PetscObject)dm->localSection, NULL, "-dm_petscsection_view")); 42952f0f8703SMatthew G. Knepley } 42961bb6d2a8SBarry Smith *section = dm->localSection; 429788ed4aceSMatthew G Knepley PetscFunctionReturn(0); 429888ed4aceSMatthew G Knepley } 429988ed4aceSMatthew G Knepley 430088ed4aceSMatthew G Knepley /*@ 4301bb7acecfSBarry Smith DMSetSection - Set the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMSetLocalSection()`. Deprecated in v3.12 4302061576a5SJed Brown 4303061576a5SJed Brown Input Parameters: 4304bb7acecfSBarry Smith + dm - The `DM` 4305bb7acecfSBarry Smith - section - The `PetscSection` 4306061576a5SJed Brown 4307061576a5SJed Brown Level: advanced 4308061576a5SJed Brown 4309061576a5SJed Brown Notes: 4310bb7acecfSBarry Smith Use `DMSetLocalSection()` in new code. 4311061576a5SJed Brown 4312bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4313061576a5SJed Brown 4314db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetLocalSection()`, `DMSetGlobalSection()` 4315061576a5SJed Brown @*/ 4316d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSection(DM dm, PetscSection section) 4317d71ae5a4SJacob Faibussowitsch { 4318061576a5SJed Brown PetscFunctionBegin; 43199566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm, section)); 4320061576a5SJed Brown PetscFunctionReturn(0); 4321061576a5SJed Brown } 4322061576a5SJed Brown 4323061576a5SJed Brown /*@ 4324bb7acecfSBarry Smith DMSetLocalSection - Set the `PetscSection` encoding the local data layout for the `DM`. 432588ed4aceSMatthew G Knepley 432688ed4aceSMatthew G Knepley Input Parameters: 4327bb7acecfSBarry Smith + dm - The `DM` 4328bb7acecfSBarry Smith - section - The `PetscSection` 432988ed4aceSMatthew G Knepley 433088ed4aceSMatthew G Knepley Level: intermediate 433188ed4aceSMatthew G Knepley 4332bb7acecfSBarry Smith Note: 4333bb7acecfSBarry Smith Any existing Section will be destroyed 433488ed4aceSMatthew G Knepley 4335bb7acecfSBarry Smith .seealso: `PetscSection`, `DMGetLocalSection()`, `DMSetGlobalSection()` 433688ed4aceSMatthew G Knepley @*/ 4337d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 4338d71ae5a4SJacob Faibussowitsch { 4339c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4340af122d2aSMatthew G Knepley PetscInt f; 434188ed4aceSMatthew G Knepley 434288ed4aceSMatthew G Knepley PetscFunctionBegin; 434388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4344b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 43459566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 43469566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->localSection)); 43471bb6d2a8SBarry Smith dm->localSection = section; 43489566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(dm->localSection, &numFields)); 4349af122d2aSMatthew G Knepley if (numFields) { 43509566063dSJacob Faibussowitsch PetscCall(DMSetNumFields(dm, numFields)); 4351af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43520f21e855SMatthew G. Knepley PetscObject disc; 4353af122d2aSMatthew G Knepley const char *name; 4354af122d2aSMatthew G Knepley 43559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(dm->localSection, f, &name)); 43569566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, &disc)); 43579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName(disc, name)); 4358af122d2aSMatthew G Knepley } 4359af122d2aSMatthew G Knepley } 4360e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 43619566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 436288ed4aceSMatthew G Knepley PetscFunctionReturn(0); 436388ed4aceSMatthew G Knepley } 436488ed4aceSMatthew G Knepley 43659435951eSToby Isaac /*@ 4366bb7acecfSBarry Smith DMGetDefaultConstraints - Get the `PetscSection` and `Mat` that specify the local constraint interpolation. See `DMSetDefaultConstraints()` for a description of the purpose of constraint interpolation. 43679435951eSToby Isaac 4368e228b242SToby Isaac not collective 4369e228b242SToby Isaac 43709435951eSToby Isaac Input Parameter: 4371bb7acecfSBarry Smith . dm - The `DM` 43729435951eSToby Isaac 4373d8d19677SJose E. Roman Output Parameters: 4374bb7acecfSBarry 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. 4375bb7acecfSBarry 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. 437679769bd5SJed Brown - bias - Vector containing bias to be added to constrained dofs 43779435951eSToby Isaac 43789435951eSToby Isaac Level: advanced 43799435951eSToby Isaac 4380bb7acecfSBarry Smith Note: 4381bb7acecfSBarry Smith This gets borrowed references, so the user should not destroy the `PetscSection`, `Mat`, or `Vec`. 43829435951eSToby Isaac 4383db781477SPatrick Sanan .seealso: `DMSetDefaultConstraints()` 43849435951eSToby Isaac @*/ 4385d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat, Vec *bias) 4386d71ae5a4SJacob Faibussowitsch { 43879435951eSToby Isaac PetscFunctionBegin; 43889435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4389dbbe0bcdSBarry Smith if (!dm->defaultConstraint.section && !dm->defaultConstraint.mat && dm->ops->createdefaultconstraints) PetscUseTypeMethod(dm, createdefaultconstraints); 43903b8ba7d1SJed Brown if (section) *section = dm->defaultConstraint.section; 43913b8ba7d1SJed Brown if (mat) *mat = dm->defaultConstraint.mat; 439279769bd5SJed Brown if (bias) *bias = dm->defaultConstraint.bias; 43939435951eSToby Isaac PetscFunctionReturn(0); 43949435951eSToby Isaac } 43959435951eSToby Isaac 43969435951eSToby Isaac /*@ 4397bb7acecfSBarry Smith DMSetDefaultConstraints - Set the `PetscSection` and `Mat` that specify the local constraint interpolation. 43989435951eSToby Isaac 4399bb7acecfSBarry 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()`. 44009435951eSToby Isaac 4401bb7acecfSBarry 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. 44029435951eSToby Isaac 4403e228b242SToby Isaac collective on dm 4404e228b242SToby Isaac 44059435951eSToby Isaac Input Parameters: 4406bb7acecfSBarry Smith + dm - The `DM` 4407bb7acecfSBarry 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). 4408bb7acecfSBarry 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). 4409bb7acecfSBarry 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). 44109435951eSToby Isaac 44119435951eSToby Isaac Level: advanced 44129435951eSToby Isaac 4413bb7acecfSBarry Smith Note: 4414bb7acecfSBarry Smith This increments the references of the `PetscSection`, `Mat`, and `Vec`, so they user can destroy them. 44159435951eSToby Isaac 4416db781477SPatrick Sanan .seealso: `DMGetDefaultConstraints()` 44179435951eSToby Isaac @*/ 4418d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat, Vec bias) 4419d71ae5a4SJacob Faibussowitsch { 4420e228b242SToby Isaac PetscMPIInt result; 44219435951eSToby Isaac 44229435951eSToby Isaac PetscFunctionBegin; 44239435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4424e228b242SToby Isaac if (section) { 4425e228b242SToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 44269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)section), &result)); 44277a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint section must have local communicator"); 4428e228b242SToby Isaac } 4429e228b242SToby Isaac if (mat) { 4430e228b242SToby Isaac PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 44319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)mat), &result)); 44327a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint matrix must have local communicator"); 4433e228b242SToby Isaac } 443479769bd5SJed Brown if (bias) { 443579769bd5SJed Brown PetscValidHeaderSpecific(bias, VEC_CLASSID, 4); 44369566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)bias), &result)); 443779769bd5SJed Brown PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint bias must have local communicator"); 443879769bd5SJed Brown } 44399566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 44409566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->defaultConstraint.section)); 44413b8ba7d1SJed Brown dm->defaultConstraint.section = section; 44429566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 44439566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dm->defaultConstraint.mat)); 44443b8ba7d1SJed Brown dm->defaultConstraint.mat = mat; 44459566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)bias)); 44469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dm->defaultConstraint.bias)); 444779769bd5SJed Brown dm->defaultConstraint.bias = bias; 44489435951eSToby Isaac PetscFunctionReturn(0); 44499435951eSToby Isaac } 44509435951eSToby Isaac 4451497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4452507e4973SMatthew G. Knepley /* 4453bb7acecfSBarry Smith DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. Generates and error if they are not consistent. 4454507e4973SMatthew G. Knepley 4455507e4973SMatthew G. Knepley Input Parameters: 4456bb7acecfSBarry Smith + dm - The `DM` 4457bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4458bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 4459507e4973SMatthew G. Knepley 4460507e4973SMatthew G. Knepley Level: intermediate 4461507e4973SMatthew G. Knepley 4462db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMSetSectionSF()` 4463507e4973SMatthew G. Knepley */ 4464d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4465d71ae5a4SJacob Faibussowitsch { 4466507e4973SMatthew G. Knepley MPI_Comm comm; 4467507e4973SMatthew G. Knepley PetscLayout layout; 4468507e4973SMatthew G. Knepley const PetscInt *ranges; 4469507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4470507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4471507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4472507e4973SMatthew G. Knepley 4473507e4973SMatthew G. Knepley PetscFunctionBegin; 44749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4475507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44769566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 44779566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 44789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(globalSection, &pStart, &pEnd)); 44799566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(globalSection, &nroots)); 44809566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &layout)); 44819566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(layout, 1)); 44829566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(layout, nroots)); 44839566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(layout)); 44849566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRanges(layout, &ranges)); 4485507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4486f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4487507e4973SMatthew G. Knepley 44889566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(localSection, p, &dof)); 44899566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(localSection, p, &off)); 44909566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(localSection, p, &cdof)); 44919566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(globalSection, p, &gdof)); 44929566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(globalSection, p, &gcdof)); 44939566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(globalSection, p, &goff)); 4494507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 44959371c9d4SSatish Balay if ((gdof < 0 ? -(gdof + 1) : gdof) != dof) { 44969371c9d4SSatish 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)); 44979371c9d4SSatish Balay valid = PETSC_FALSE; 44989371c9d4SSatish Balay } 44999371c9d4SSatish Balay if (gcdof && (gcdof != cdof)) { 45009371c9d4SSatish 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)); 45019371c9d4SSatish Balay valid = PETSC_FALSE; 45029371c9d4SSatish Balay } 4503507e4973SMatthew G. Knepley if (gdof < 0) { 4504507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof + 1) - gcdof : gdof - gcdof; 4505507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4506507e4973SMatthew G. Knepley PetscInt offset = -(goff + 1) + d, r; 4507507e4973SMatthew G. Knepley 45089566063dSJacob Faibussowitsch PetscCall(PetscFindInt(offset, size + 1, ranges, &r)); 4509507e4973SMatthew G. Knepley if (r < 0) r = -(r + 2); 45109371c9d4SSatish Balay if ((r < 0) || (r >= size)) { 45119371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Point %" PetscInt_FMT " mapped to invalid process %" PetscInt_FMT " (%" PetscInt_FMT ", %" PetscInt_FMT ")\n", rank, p, r, gdof, goff)); 45129371c9d4SSatish Balay valid = PETSC_FALSE; 45139371c9d4SSatish Balay break; 45149371c9d4SSatish Balay } 4515507e4973SMatthew G. Knepley } 4516507e4973SMatthew G. Knepley } 4517507e4973SMatthew G. Knepley } 45189566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&layout)); 45199566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 45201c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm)); 4521507e4973SMatthew G. Knepley if (!gvalid) { 45229566063dSJacob Faibussowitsch PetscCall(DMView(dm, NULL)); 4523507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4524507e4973SMatthew G. Knepley } 4525507e4973SMatthew G. Knepley PetscFunctionReturn(0); 4526507e4973SMatthew G. Knepley } 4527f741bcd2SMatthew G. Knepley #endif 4528507e4973SMatthew G. Knepley 452988ed4aceSMatthew G Knepley /*@ 4530bb7acecfSBarry Smith DMGetGlobalSection - Get the `PetscSection` encoding the global data layout for the `DM`. 453188ed4aceSMatthew G Knepley 4532d083f849SBarry Smith Collective on dm 45338b1ab98fSJed Brown 453488ed4aceSMatthew G Knepley Input Parameter: 4535bb7acecfSBarry Smith . dm - The `DM` 453688ed4aceSMatthew G Knepley 453788ed4aceSMatthew G Knepley Output Parameter: 4538bb7acecfSBarry Smith . section - The `PetscSection` 453988ed4aceSMatthew G Knepley 454088ed4aceSMatthew G Knepley Level: intermediate 454188ed4aceSMatthew G Knepley 4542bb7acecfSBarry Smith Note: 4543bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 454488ed4aceSMatthew G Knepley 4545db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetLocalSection()` 454688ed4aceSMatthew G Knepley @*/ 4547d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 4548d71ae5a4SJacob Faibussowitsch { 454988ed4aceSMatthew G Knepley PetscFunctionBegin; 455088ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 455188ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 45521bb6d2a8SBarry Smith if (!dm->globalSection) { 4553fd59a867SMatthew G. Knepley PetscSection s; 4554fd59a867SMatthew G. Knepley 45559566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 45567a8be351SBarry Smith PetscCheck(s, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 45577a8be351SBarry Smith PetscCheck(dm->sf, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 45589566063dSJacob Faibussowitsch PetscCall(PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection)); 45599566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&dm->map)); 45609566063dSJacob Faibussowitsch PetscCall(PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map)); 45619566063dSJacob Faibussowitsch PetscCall(PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view")); 456288ed4aceSMatthew G Knepley } 45631bb6d2a8SBarry Smith *section = dm->globalSection; 456488ed4aceSMatthew G Knepley PetscFunctionReturn(0); 456588ed4aceSMatthew G Knepley } 456688ed4aceSMatthew G Knepley 4567b21d0597SMatthew G Knepley /*@ 4568bb7acecfSBarry Smith DMSetGlobalSection - Set the `PetscSection` encoding the global data layout for the `DM`. 4569b21d0597SMatthew G Knepley 4570b21d0597SMatthew G Knepley Input Parameters: 4571bb7acecfSBarry Smith + dm - The `DM` 45725080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 4573b21d0597SMatthew G Knepley 4574b21d0597SMatthew G Knepley Level: intermediate 4575b21d0597SMatthew G Knepley 4576bb7acecfSBarry Smith Note: 4577bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4578b21d0597SMatthew G Knepley 4579db781477SPatrick Sanan .seealso: `DMGetGlobalSection()`, `DMSetLocalSection()` 4580b21d0597SMatthew G Knepley @*/ 4581d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 4582d71ae5a4SJacob Faibussowitsch { 4583b21d0597SMatthew G Knepley PetscFunctionBegin; 4584b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45855080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 45869566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 45879566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 45881bb6d2a8SBarry Smith dm->globalSection = section; 4589497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 45909566063dSJacob Faibussowitsch if (section) PetscCall(DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section)); 4591507e4973SMatthew G. Knepley #endif 4592b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4593b21d0597SMatthew G Knepley } 4594b21d0597SMatthew G Knepley 459588ed4aceSMatthew G Knepley /*@ 4596bb7acecfSBarry Smith DMGetSectionSF - Get the `PetscSF` encoding the parallel dof overlap for the `DM`. If it has not been set, 4597bb7acecfSBarry Smith it is created from the default `PetscSection` layouts in the `DM`. 459888ed4aceSMatthew G Knepley 459988ed4aceSMatthew G Knepley Input Parameter: 4600bb7acecfSBarry Smith . dm - The `DM` 460188ed4aceSMatthew G Knepley 460288ed4aceSMatthew G Knepley Output Parameter: 4603bb7acecfSBarry Smith . sf - The `PetscSF` 460488ed4aceSMatthew G Knepley 460588ed4aceSMatthew G Knepley Level: intermediate 460688ed4aceSMatthew G Knepley 4607bb7acecfSBarry Smith Note: 4608bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 460988ed4aceSMatthew G Knepley 4610db781477SPatrick Sanan .seealso: `DMSetSectionSF()`, `DMCreateSectionSF()` 461188ed4aceSMatthew G Knepley @*/ 4612d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 4613d71ae5a4SJacob Faibussowitsch { 461488ed4aceSMatthew G Knepley PetscInt nroots; 461588ed4aceSMatthew G Knepley 461688ed4aceSMatthew G Knepley PetscFunctionBegin; 461788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 461888ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 461948a46eb9SPierre Jolivet if (!dm->sectionSF) PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 46209566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL)); 462188ed4aceSMatthew G Knepley if (nroots < 0) { 462288ed4aceSMatthew G Knepley PetscSection section, gSection; 462388ed4aceSMatthew G Knepley 46249566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 462531ea6d37SMatthew G Knepley if (section) { 46269566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gSection)); 46279566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSF(dm, section, gSection)); 462831ea6d37SMatthew G Knepley } else { 46290298fd71SBarry Smith *sf = NULL; 463031ea6d37SMatthew G Knepley PetscFunctionReturn(0); 463131ea6d37SMatthew G Knepley } 463288ed4aceSMatthew G Knepley } 46331bb6d2a8SBarry Smith *sf = dm->sectionSF; 463488ed4aceSMatthew G Knepley PetscFunctionReturn(0); 463588ed4aceSMatthew G Knepley } 463688ed4aceSMatthew G Knepley 463788ed4aceSMatthew G Knepley /*@ 4638bb7acecfSBarry Smith DMSetSectionSF - Set the `PetscSF` encoding the parallel dof overlap for the `DM` 463988ed4aceSMatthew G Knepley 464088ed4aceSMatthew G Knepley Input Parameters: 4641bb7acecfSBarry Smith + dm - The `DM` 4642bb7acecfSBarry Smith - sf - The `PetscSF` 464388ed4aceSMatthew G Knepley 464488ed4aceSMatthew G Knepley Level: intermediate 464588ed4aceSMatthew G Knepley 4646bb7acecfSBarry Smith Note: 4647bb7acecfSBarry Smith Any previous `PetscSF` is destroyed 464888ed4aceSMatthew G Knepley 4649db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMCreateSectionSF()` 465088ed4aceSMatthew G Knepley @*/ 4651d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 4652d71ae5a4SJacob Faibussowitsch { 465388ed4aceSMatthew G Knepley PetscFunctionBegin; 465488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4655b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 46569566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 46579566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sectionSF)); 46581bb6d2a8SBarry Smith dm->sectionSF = sf; 465988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 466088ed4aceSMatthew G Knepley } 466188ed4aceSMatthew G Knepley 466288ed4aceSMatthew G Knepley /*@C 4663bb7acecfSBarry Smith DMCreateSectionSF - Create the `PetscSF` encoding the parallel dof overlap for the `DM` based upon the `PetscSection`s 466488ed4aceSMatthew G Knepley describing the data layout. 466588ed4aceSMatthew G Knepley 466688ed4aceSMatthew G Knepley Input Parameters: 4667bb7acecfSBarry Smith + dm - The `DM` 4668bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4669bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 467088ed4aceSMatthew G Knepley 46711bb6d2a8SBarry Smith Level: developer 46721bb6d2a8SBarry Smith 4673bb7acecfSBarry Smith Note: 4674bb7acecfSBarry Smith One usually uses `DMGetSectionSF()` to obtain the `PetscSF` 4675bb7acecfSBarry Smith 4676bb7acecfSBarry Smith Developer Note: 4677bb7acecfSBarry Smith Since this routine has for arguments the two sections from the `DM` and puts the resulting `PetscSF` 4678bb7acecfSBarry Smith directly into the `DM`, perhaps this function should not take the local and global sections as 4679bb7acecfSBarry Smith input and should just obtain them from the `DM`? 46801bb6d2a8SBarry Smith 4681db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMSetSectionSF()`, `DMGetLocalSection()`, `DMGetGlobalSection()` 468288ed4aceSMatthew G Knepley @*/ 4683d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 4684d71ae5a4SJacob Faibussowitsch { 468588ed4aceSMatthew G Knepley PetscFunctionBegin; 468688ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46879566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection)); 468888ed4aceSMatthew G Knepley PetscFunctionReturn(0); 468988ed4aceSMatthew G Knepley } 4690af122d2aSMatthew G Knepley 4691b21d0597SMatthew G Knepley /*@ 4692bb7acecfSBarry Smith DMGetPointSF - Get the `PetscSF` encoding the parallel section point overlap for the `DM`. 4693bb7acecfSBarry Smith 4694bb7acecfSBarry Smith Not collective but the resulting `PetscSF` is collective 4695b21d0597SMatthew G Knepley 4696b21d0597SMatthew G Knepley Input Parameter: 4697bb7acecfSBarry Smith . dm - The `DM` 4698b21d0597SMatthew G Knepley 4699b21d0597SMatthew G Knepley Output Parameter: 4700bb7acecfSBarry Smith . sf - The `PetscSF` 4701b21d0597SMatthew G Knepley 4702b21d0597SMatthew G Knepley Level: intermediate 4703b21d0597SMatthew G Knepley 4704bb7acecfSBarry Smith Note: 4705bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 4706b21d0597SMatthew G Knepley 4707db781477SPatrick Sanan .seealso: `DMSetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4708b21d0597SMatthew G Knepley @*/ 4709d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 4710d71ae5a4SJacob Faibussowitsch { 4711b21d0597SMatthew G Knepley PetscFunctionBegin; 4712b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4713b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4714b21d0597SMatthew G Knepley *sf = dm->sf; 4715b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4716b21d0597SMatthew G Knepley } 4717b21d0597SMatthew G Knepley 4718057b4bcdSMatthew G Knepley /*@ 4719bb7acecfSBarry Smith DMSetPointSF - Set the `PetscSF` encoding the parallel section point overlap for the `DM`. 4720bb7acecfSBarry Smith 4721bb7acecfSBarry Smith Collective on dm 4722057b4bcdSMatthew G Knepley 4723057b4bcdSMatthew G Knepley Input Parameters: 4724bb7acecfSBarry Smith + dm - The `DM` 4725bb7acecfSBarry Smith - sf - The` PetscSF` 4726057b4bcdSMatthew G Knepley 4727057b4bcdSMatthew G Knepley Level: intermediate 4728057b4bcdSMatthew G Knepley 4729db781477SPatrick Sanan .seealso: `DMGetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4730057b4bcdSMatthew G Knepley @*/ 4731d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 4732d71ae5a4SJacob Faibussowitsch { 4733057b4bcdSMatthew G Knepley PetscFunctionBegin; 4734057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4735b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47369566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47379566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sf)); 4738057b4bcdSMatthew G Knepley dm->sf = sf; 4739057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4740057b4bcdSMatthew G Knepley } 4741057b4bcdSMatthew G Knepley 47424f37162bSMatthew G. Knepley /*@ 4743bb7acecfSBarry Smith DMGetNaturalSF - Get the `PetscSF` encoding the map back to the original mesh ordering 47444f37162bSMatthew G. Knepley 47454f37162bSMatthew G. Knepley Input Parameter: 4746bb7acecfSBarry Smith . dm - The `DM` 47474f37162bSMatthew G. Knepley 47484f37162bSMatthew G. Knepley Output Parameter: 4749bb7acecfSBarry Smith . sf - The `PetscSF` 47504f37162bSMatthew G. Knepley 47514f37162bSMatthew G. Knepley Level: intermediate 47524f37162bSMatthew G. Knepley 4753bb7acecfSBarry Smith Note: 4754bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 47554f37162bSMatthew G. Knepley 4756db781477SPatrick Sanan .seealso: `DMSetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47574f37162bSMatthew G. Knepley @*/ 4758d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 4759d71ae5a4SJacob Faibussowitsch { 47604f37162bSMatthew G. Knepley PetscFunctionBegin; 47614f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47624f37162bSMatthew G. Knepley PetscValidPointer(sf, 2); 47634f37162bSMatthew G. Knepley *sf = dm->sfNatural; 47644f37162bSMatthew G. Knepley PetscFunctionReturn(0); 47654f37162bSMatthew G. Knepley } 47664f37162bSMatthew G. Knepley 47674f37162bSMatthew G. Knepley /*@ 47684f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 47694f37162bSMatthew G. Knepley 47704f37162bSMatthew G. Knepley Input Parameters: 47714f37162bSMatthew G. Knepley + dm - The DM 47724f37162bSMatthew G. Knepley - sf - The PetscSF 47734f37162bSMatthew G. Knepley 47744f37162bSMatthew G. Knepley Level: intermediate 47754f37162bSMatthew G. Knepley 4776db781477SPatrick Sanan .seealso: `DMGetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47774f37162bSMatthew G. Knepley @*/ 4778d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 4779d71ae5a4SJacob Faibussowitsch { 47804f37162bSMatthew G. Knepley PetscFunctionBegin; 47814f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47824f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47839566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47849566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sfNatural)); 47854f37162bSMatthew G. Knepley dm->sfNatural = sf; 47864f37162bSMatthew G. Knepley PetscFunctionReturn(0); 47874f37162bSMatthew G. Knepley } 47884f37162bSMatthew G. Knepley 4789d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 4790d71ae5a4SJacob Faibussowitsch { 479134aa8a36SMatthew G. Knepley PetscClassId id; 479234aa8a36SMatthew G. Knepley 479334aa8a36SMatthew G. Knepley PetscFunctionBegin; 47949566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 479534aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 47969566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 479734aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 47989566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE)); 479917c1d62eSMatthew G. Knepley } else { 48009566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 480134aa8a36SMatthew G. Knepley } 480234aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 480334aa8a36SMatthew G. Knepley } 480434aa8a36SMatthew G. Knepley 4805d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 4806d71ae5a4SJacob Faibussowitsch { 480744a7f3ddSMatthew G. Knepley RegionField *tmpr; 480844a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 480944a7f3ddSMatthew G. Knepley 481044a7f3ddSMatthew G. Knepley PetscFunctionBegin; 481144a7f3ddSMatthew G. Knepley if (Nf >= NfNew) PetscFunctionReturn(0); 48129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NfNew, &tmpr)); 481344a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 48149371c9d4SSatish Balay for (f = Nf; f < NfNew; ++f) { 48159371c9d4SSatish Balay tmpr[f].disc = NULL; 48169371c9d4SSatish Balay tmpr[f].label = NULL; 48179371c9d4SSatish Balay tmpr[f].avoidTensor = PETSC_FALSE; 48189371c9d4SSatish Balay } 48199566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 482044a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 482144a7f3ddSMatthew G. Knepley dm->fields = tmpr; 482244a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 482344a7f3ddSMatthew G. Knepley } 482444a7f3ddSMatthew G. Knepley 482544a7f3ddSMatthew G. Knepley /*@ 482644a7f3ddSMatthew G. Knepley DMClearFields - Remove all fields from the DM 482744a7f3ddSMatthew G. Knepley 4828d083f849SBarry Smith Logically collective on dm 482944a7f3ddSMatthew G. Knepley 483044a7f3ddSMatthew G. Knepley Input Parameter: 483144a7f3ddSMatthew G. Knepley . dm - The DM 483244a7f3ddSMatthew G. Knepley 483344a7f3ddSMatthew G. Knepley Level: intermediate 483444a7f3ddSMatthew G. Knepley 4835db781477SPatrick Sanan .seealso: `DMGetNumFields()`, `DMSetNumFields()`, `DMSetField()` 483644a7f3ddSMatthew G. Knepley @*/ 4837d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearFields(DM dm) 4838d71ae5a4SJacob Faibussowitsch { 483944a7f3ddSMatthew G. Knepley PetscInt f; 484044a7f3ddSMatthew G. Knepley 484144a7f3ddSMatthew G. Knepley PetscFunctionBegin; 484244a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 484344a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 48449566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 48459566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 484644a7f3ddSMatthew G. Knepley } 48479566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 484844a7f3ddSMatthew G. Knepley dm->fields = NULL; 484944a7f3ddSMatthew G. Knepley dm->Nf = 0; 485044a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 485144a7f3ddSMatthew G. Knepley } 485244a7f3ddSMatthew G. Knepley 4853689b5837SMatthew G. Knepley /*@ 4854689b5837SMatthew G. Knepley DMGetNumFields - Get the number of fields in the DM 4855689b5837SMatthew G. Knepley 4856689b5837SMatthew G. Knepley Not collective 4857689b5837SMatthew G. Knepley 4858689b5837SMatthew G. Knepley Input Parameter: 4859689b5837SMatthew G. Knepley . dm - The DM 4860689b5837SMatthew G. Knepley 4861689b5837SMatthew G. Knepley Output Parameter: 4862689b5837SMatthew G. Knepley . Nf - The number of fields 4863689b5837SMatthew G. Knepley 4864689b5837SMatthew G. Knepley Level: intermediate 4865689b5837SMatthew G. Knepley 4866db781477SPatrick Sanan .seealso: `DMSetNumFields()`, `DMSetField()` 4867689b5837SMatthew G. Knepley @*/ 4868d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 4869d71ae5a4SJacob Faibussowitsch { 48700f21e855SMatthew G. Knepley PetscFunctionBegin; 48710f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4872534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 487344a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 4874af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4875af122d2aSMatthew G Knepley } 4876af122d2aSMatthew G Knepley 4877689b5837SMatthew G. Knepley /*@ 4878689b5837SMatthew G. Knepley DMSetNumFields - Set the number of fields in the DM 4879689b5837SMatthew G. Knepley 4880d083f849SBarry Smith Logically collective on dm 4881689b5837SMatthew G. Knepley 4882689b5837SMatthew G. Knepley Input Parameters: 4883689b5837SMatthew G. Knepley + dm - The DM 4884689b5837SMatthew G. Knepley - Nf - The number of fields 4885689b5837SMatthew G. Knepley 4886689b5837SMatthew G. Knepley Level: intermediate 4887689b5837SMatthew G. Knepley 4888db781477SPatrick Sanan .seealso: `DMGetNumFields()`, `DMSetField()` 4889689b5837SMatthew G. Knepley @*/ 4890d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4891d71ae5a4SJacob Faibussowitsch { 48920f21e855SMatthew G. Knepley PetscInt Nf, f; 4893af122d2aSMatthew G Knepley 4894af122d2aSMatthew G Knepley PetscFunctionBegin; 4895af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48969566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 48970f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 48980f21e855SMatthew G. Knepley PetscContainer obj; 48990f21e855SMatthew G. Knepley 49009566063dSJacob Faibussowitsch PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)dm), &obj)); 49019566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject)obj)); 49029566063dSJacob Faibussowitsch PetscCall(PetscContainerDestroy(&obj)); 4903af122d2aSMatthew G Knepley } 4904af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4905af122d2aSMatthew G Knepley } 4906af122d2aSMatthew G Knepley 4907c1929be8SMatthew G. Knepley /*@ 4908bb7acecfSBarry Smith DMGetField - Return the `DMLabel` and discretization object for a given `DM` field 4909c1929be8SMatthew G. Knepley 4910c1929be8SMatthew G. Knepley Not collective 4911c1929be8SMatthew G. Knepley 4912c1929be8SMatthew G. Knepley Input Parameters: 4913bb7acecfSBarry Smith + dm - The `DM` 4914c1929be8SMatthew G. Knepley - f - The field number 4915c1929be8SMatthew G. Knepley 491644a7f3ddSMatthew G. Knepley Output Parameters: 4917bb7acecfSBarry Smith + label - The label indicating the support of the field, or NULL for the entire mesh (pass in NULL if not needed) 4918bb7acecfSBarry Smith - disc - The discretization object (pass in NULL if not needed) 4919c1929be8SMatthew G. Knepley 492044a7f3ddSMatthew G. Knepley Level: intermediate 4921c1929be8SMatthew G. Knepley 4922db781477SPatrick Sanan .seealso: `DMAddField()`, `DMSetField()` 4923c1929be8SMatthew G. Knepley @*/ 4924d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *disc) 4925d71ae5a4SJacob Faibussowitsch { 4926af122d2aSMatthew G Knepley PetscFunctionBegin; 4927af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4928bb7acecfSBarry Smith PetscValidPointer(disc, 4); 49297a8be351SBarry 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); 493044a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 4931bb7acecfSBarry Smith if (disc) *disc = dm->fields[f].disc; 4932decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4933decb47aaSMatthew G. Knepley } 4934decb47aaSMatthew G. Knepley 4935083401c6SMatthew G. Knepley /* Does not clear the DS */ 4936d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4937d71ae5a4SJacob Faibussowitsch { 4938083401c6SMatthew G. Knepley PetscFunctionBegin; 49399566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, f + 1)); 49409566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 49419566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 4942083401c6SMatthew G. Knepley dm->fields[f].label = label; 4943bb7acecfSBarry Smith dm->fields[f].disc = disc; 49449566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 4945bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 4946083401c6SMatthew G. Knepley PetscFunctionReturn(0); 4947083401c6SMatthew G. Knepley } 4948083401c6SMatthew G. Knepley 4949c1929be8SMatthew G. Knepley /*@ 4950bb7acecfSBarry Smith DMSetField - Set the discretization object for a given `DM` field. Usually one would call `DMAddField()` which automatically handles 4951bb7acecfSBarry Smith the field numbering. 4952c1929be8SMatthew G. Knepley 4953d083f849SBarry Smith Logically collective on dm 4954c1929be8SMatthew G. Knepley 4955c1929be8SMatthew G. Knepley Input Parameters: 4956bb7acecfSBarry Smith + dm - The `DM` 4957c1929be8SMatthew G. Knepley . f - The field number 495844a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4959bb7acecfSBarry Smith - disc - The discretization object 4960c1929be8SMatthew G. Knepley 496144a7f3ddSMatthew G. Knepley Level: intermediate 4962c1929be8SMatthew G. Knepley 4963db781477SPatrick Sanan .seealso: `DMAddField()`, `DMGetField()` 4964c1929be8SMatthew G. Knepley @*/ 4965d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4966d71ae5a4SJacob Faibussowitsch { 4967decb47aaSMatthew G. Knepley PetscFunctionBegin; 4968decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4969e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 4970bb7acecfSBarry Smith PetscValidHeader(disc, 4); 49717a8be351SBarry Smith PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f); 4972bb7acecfSBarry Smith PetscCall(DMSetField_Internal(dm, f, label, disc)); 4973bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, f, disc)); 49749566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 497544a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 497644a7f3ddSMatthew G. Knepley } 497744a7f3ddSMatthew G. Knepley 497844a7f3ddSMatthew G. Knepley /*@ 4979bb7acecfSBarry 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) 4980bb7acecfSBarry Smith and a discretization object that defines the function space associated with those points. 498144a7f3ddSMatthew G. Knepley 4982d083f849SBarry Smith Logically collective on dm 498344a7f3ddSMatthew G. Knepley 498444a7f3ddSMatthew G. Knepley Input Parameters: 4985bb7acecfSBarry Smith + dm - The `DM` 498644a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4987bb7acecfSBarry Smith - disc - The discretization object 498844a7f3ddSMatthew G. Knepley 498944a7f3ddSMatthew G. Knepley Level: intermediate 499044a7f3ddSMatthew G. Knepley 4991bb7acecfSBarry Smith Notes: 4992bb7acecfSBarry Smith The label already exists or will be added to the `DM` with `DMSetLabel()`. 4993bb7acecfSBarry Smith 4994bb7acecfSBarry Smith For example, a piecewise continous pressure field can be defined by coefficients at the cell centers of a mesh and piecewise constant functions 4995bb7acecfSBarry 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 4996bb7acecfSBarry Smith geometry entities, a `DMLabel` indicating a subset of those geometric entities, and a discretization object, such as a `PetscFE`. 4997bb7acecfSBarry Smith 4998bb7acecfSBarry Smith .seealso: `DMSetLabel()`, `DMSetField()`, `DMGetField()`, `PetscFE` 499944a7f3ddSMatthew G. Knepley @*/ 5000d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject disc) 5001d71ae5a4SJacob Faibussowitsch { 500244a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 500344a7f3ddSMatthew G. Knepley 500444a7f3ddSMatthew G. Knepley PetscFunctionBegin; 500544a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5006064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5007bb7acecfSBarry Smith PetscValidHeader(disc, 3); 50089566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, Nf + 1)); 500944a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 5010bb7acecfSBarry Smith dm->fields[Nf].disc = disc; 50119566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5012bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 5013bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, Nf, disc)); 50149566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 5015af122d2aSMatthew G Knepley PetscFunctionReturn(0); 5016af122d2aSMatthew G Knepley } 50176636e97aSMatthew G Knepley 5018e5e52638SMatthew G. Knepley /*@ 5019e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 5020e0b68406SMatthew Knepley 5021e0b68406SMatthew Knepley Logically collective on dm 5022e0b68406SMatthew Knepley 5023e0b68406SMatthew Knepley Input Parameters: 5024bb7acecfSBarry Smith + dm - The `DM` 5025e0b68406SMatthew Knepley . f - The field index 5026bb7acecfSBarry Smith - avoidTensor - `PETSC_TRUE` to skip defining the field on tensor cells 5027e0b68406SMatthew Knepley 5028e0b68406SMatthew Knepley Level: intermediate 5029e0b68406SMatthew Knepley 5030db781477SPatrick Sanan .seealso: `DMGetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5031e0b68406SMatthew Knepley @*/ 5032d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5033d71ae5a4SJacob Faibussowitsch { 5034e0b68406SMatthew Knepley PetscFunctionBegin; 503563a3b9bcSJacob 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); 5036e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 5037e0b68406SMatthew Knepley PetscFunctionReturn(0); 5038e0b68406SMatthew Knepley } 5039e0b68406SMatthew Knepley 5040e0b68406SMatthew Knepley /*@ 5041e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5042e0b68406SMatthew Knepley 5043bb7acecfSBarry Smith Not collective 5044e0b68406SMatthew Knepley 5045e0b68406SMatthew Knepley Input Parameters: 5046bb7acecfSBarry Smith + dm - The `DM` 5047e0b68406SMatthew Knepley - f - The field index 5048e0b68406SMatthew Knepley 5049e0b68406SMatthew Knepley Output Parameter: 5050e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5051e0b68406SMatthew Knepley 5052e0b68406SMatthew Knepley Level: intermediate 5053e0b68406SMatthew Knepley 5054bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMSetField()`, `DMGetField()`, `DMSetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5055e0b68406SMatthew Knepley @*/ 5056d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5057d71ae5a4SJacob Faibussowitsch { 5058e0b68406SMatthew Knepley PetscFunctionBegin; 505963a3b9bcSJacob 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); 5060e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 5061e0b68406SMatthew Knepley PetscFunctionReturn(0); 5062e0b68406SMatthew Knepley } 5063e0b68406SMatthew Knepley 5064e0b68406SMatthew Knepley /*@ 5065bb7acecfSBarry Smith DMCopyFields - Copy the discretizations for the `DM` into another `DM` 5066e5e52638SMatthew G. Knepley 5067d083f849SBarry Smith Collective on dm 5068e5e52638SMatthew G. Knepley 5069e5e52638SMatthew G. Knepley Input Parameter: 5070bb7acecfSBarry Smith . dm - The `DM` 5071e5e52638SMatthew G. Knepley 5072e5e52638SMatthew G. Knepley Output Parameter: 5073bb7acecfSBarry Smith . newdm - The `DM` 5074e5e52638SMatthew G. Knepley 5075e5e52638SMatthew G. Knepley Level: advanced 5076e5e52638SMatthew G. Knepley 5077db781477SPatrick Sanan .seealso: `DMGetField()`, `DMSetField()`, `DMAddField()`, `DMCopyDS()`, `DMGetDS()`, `DMGetCellDS()` 5078e5e52638SMatthew G. Knepley @*/ 5079d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyFields(DM dm, DM newdm) 5080d71ae5a4SJacob Faibussowitsch { 5081e5e52638SMatthew G. Knepley PetscInt Nf, f; 5082e5e52638SMatthew G. Knepley 5083e5e52638SMatthew G. Knepley PetscFunctionBegin; 5084e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 50859566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 50869566063dSJacob Faibussowitsch PetscCall(DMClearFields(newdm)); 5087e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5088e5e52638SMatthew G. Knepley DMLabel label; 5089e5e52638SMatthew G. Knepley PetscObject field; 509034aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5091e5e52638SMatthew G. Knepley 50929566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, &label, &field)); 50939566063dSJacob Faibussowitsch PetscCall(DMSetField(newdm, f, label, field)); 50949566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, f, &useCone, &useClosure)); 50959566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(newdm, f, useCone, useClosure)); 509634aa8a36SMatthew G. Knepley } 509734aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 509834aa8a36SMatthew G. Knepley } 509934aa8a36SMatthew G. Knepley 510034aa8a36SMatthew G. Knepley /*@ 510134aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 510234aa8a36SMatthew G. Knepley 510334aa8a36SMatthew G. Knepley Not collective 510434aa8a36SMatthew G. Knepley 510534aa8a36SMatthew G. Knepley Input Parameters: 510634aa8a36SMatthew G. Knepley + dm - The DM object 510734aa8a36SMatthew G. Knepley - f - The field number, or PETSC_DEFAULT for the default adjacency 510834aa8a36SMatthew G. Knepley 5109d8d19677SJose E. Roman Output Parameters: 511034aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 511134aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 511234aa8a36SMatthew G. Knepley 511334aa8a36SMatthew G. Knepley Notes: 511434aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 511534aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 511634aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5117979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 511834aa8a36SMatthew G. Knepley 511934aa8a36SMatthew G. Knepley Level: developer 512034aa8a36SMatthew G. Knepley 5121db781477SPatrick Sanan .seealso: `DMSetAdjacency()`, `DMGetField()`, `DMSetField()` 512234aa8a36SMatthew G. Knepley @*/ 5123d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 5124d71ae5a4SJacob Faibussowitsch { 512534aa8a36SMatthew G. Knepley PetscFunctionBegin; 512634aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5127534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 5128534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 512934aa8a36SMatthew G. Knepley if (f < 0) { 513034aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 513134aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 513234aa8a36SMatthew G. Knepley } else { 513334aa8a36SMatthew G. Knepley PetscInt Nf; 513434aa8a36SMatthew G. Knepley 51359566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51367a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 513734aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 513834aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 513934aa8a36SMatthew G. Knepley } 514034aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 514134aa8a36SMatthew G. Knepley } 514234aa8a36SMatthew G. Knepley 514334aa8a36SMatthew G. Knepley /*@ 514434aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 514534aa8a36SMatthew G. Knepley 514634aa8a36SMatthew G. Knepley Not collective 514734aa8a36SMatthew G. Knepley 514834aa8a36SMatthew G. Knepley Input Parameters: 514934aa8a36SMatthew G. Knepley + dm - The DM object 515034aa8a36SMatthew G. Knepley . f - The field number 515134aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 515234aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 515334aa8a36SMatthew G. Knepley 515434aa8a36SMatthew G. Knepley Notes: 515534aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 515634aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 515734aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5158979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 515934aa8a36SMatthew G. Knepley 516034aa8a36SMatthew G. Knepley Level: developer 516134aa8a36SMatthew G. Knepley 5162db781477SPatrick Sanan .seealso: `DMGetAdjacency()`, `DMGetField()`, `DMSetField()` 516334aa8a36SMatthew G. Knepley @*/ 5164d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 5165d71ae5a4SJacob Faibussowitsch { 516634aa8a36SMatthew G. Knepley PetscFunctionBegin; 516734aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 516834aa8a36SMatthew G. Knepley if (f < 0) { 516934aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 517034aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 517134aa8a36SMatthew G. Knepley } else { 517234aa8a36SMatthew G. Knepley PetscInt Nf; 517334aa8a36SMatthew G. Knepley 51749566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51757a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 517634aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 517734aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5178e5e52638SMatthew G. Knepley } 5179e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5180e5e52638SMatthew G. Knepley } 5181e5e52638SMatthew G. Knepley 5182b0441da4SMatthew G. Knepley /*@ 5183b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5184b0441da4SMatthew G. Knepley 5185b0441da4SMatthew G. Knepley Not collective 5186b0441da4SMatthew G. Knepley 5187f899ff85SJose E. Roman Input Parameter: 5188b0441da4SMatthew G. Knepley . dm - The DM object 5189b0441da4SMatthew G. Knepley 5190d8d19677SJose E. Roman Output Parameters: 5191b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5192b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5193b0441da4SMatthew G. Knepley 5194b0441da4SMatthew G. Knepley Notes: 5195b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5196b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5197b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5198b0441da4SMatthew G. Knepley 5199b0441da4SMatthew G. Knepley Level: developer 5200b0441da4SMatthew G. Knepley 5201db781477SPatrick Sanan .seealso: `DMSetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5202b0441da4SMatthew G. Knepley @*/ 5203d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5204d71ae5a4SJacob Faibussowitsch { 5205b0441da4SMatthew G. Knepley PetscInt Nf; 5206b0441da4SMatthew G. Knepley 5207b0441da4SMatthew G. Knepley PetscFunctionBegin; 5208b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5209064a246eSJacob Faibussowitsch if (useCone) PetscValidBoolPointer(useCone, 2); 5210064a246eSJacob Faibussowitsch if (useClosure) PetscValidBoolPointer(useClosure, 3); 52119566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5212b0441da4SMatthew G. Knepley if (!Nf) { 52139566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5214b0441da4SMatthew G. Knepley } else { 52159566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, 0, useCone, useClosure)); 5216b0441da4SMatthew G. Knepley } 5217b0441da4SMatthew G. Knepley PetscFunctionReturn(0); 5218b0441da4SMatthew G. Knepley } 5219b0441da4SMatthew G. Knepley 5220b0441da4SMatthew G. Knepley /*@ 5221b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5222b0441da4SMatthew G. Knepley 5223b0441da4SMatthew G. Knepley Not collective 5224b0441da4SMatthew G. Knepley 5225b0441da4SMatthew G. Knepley Input Parameters: 5226b0441da4SMatthew G. Knepley + dm - The DM object 5227b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5228b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5229b0441da4SMatthew G. Knepley 5230b0441da4SMatthew G. Knepley Notes: 5231b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5232b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5233b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5234b0441da4SMatthew G. Knepley 5235b0441da4SMatthew G. Knepley Level: developer 5236b0441da4SMatthew G. Knepley 5237db781477SPatrick Sanan .seealso: `DMGetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5238b0441da4SMatthew G. Knepley @*/ 5239d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5240d71ae5a4SJacob Faibussowitsch { 5241b0441da4SMatthew G. Knepley PetscInt Nf; 5242b0441da4SMatthew G. Knepley 5243b0441da4SMatthew G. Knepley PetscFunctionBegin; 5244b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52459566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5246b0441da4SMatthew G. Knepley if (!Nf) { 52479566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5248b0441da4SMatthew G. Knepley } else { 52499566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, 0, useCone, useClosure)); 5250e5e52638SMatthew G. Knepley } 5251e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5252e5e52638SMatthew G. Knepley } 5253e5e52638SMatthew G. Knepley 5254d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompleteBCLabels_Internal(DM dm) 5255d71ae5a4SJacob Faibussowitsch { 5256799db056SMatthew G. Knepley DM plex; 5257799db056SMatthew G. Knepley DMLabel *labels, *glabels; 5258799db056SMatthew G. Knepley const char **names; 5259799db056SMatthew G. Knepley char *sendNames, *recvNames; 5260799db056SMatthew G. Knepley PetscInt Nds, s, maxLabels = 0, maxLen = 0, gmaxLen, Nl = 0, gNl, l, gl, m; 5261799db056SMatthew G. Knepley size_t len; 5262799db056SMatthew G. Knepley MPI_Comm comm; 5263799db056SMatthew G. Knepley PetscMPIInt rank, size, p, *counts, *displs; 5264783e2ec8SMatthew G. Knepley 5265783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5266799db056SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5267799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 5268799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5269799db056SMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 5270799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5271799db056SMatthew G. Knepley PetscDS dsBC; 5272799db056SMatthew G. Knepley PetscInt numBd; 5273799db056SMatthew G. Knepley 5274799db056SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC)); 5275799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5276799db056SMatthew G. Knepley maxLabels += numBd; 5277799db056SMatthew G. Knepley } 5278799db056SMatthew G. Knepley PetscCall(PetscCalloc1(maxLabels, &labels)); 5279799db056SMatthew G. Knepley /* Get list of labels to be completed */ 5280799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5281799db056SMatthew G. Knepley PetscDS dsBC; 5282799db056SMatthew G. Knepley PetscInt numBd, bd; 5283799db056SMatthew G. Knepley 5284799db056SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC)); 5285799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5286799db056SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5287799db056SMatthew G. Knepley DMLabel label; 5288799db056SMatthew G. Knepley PetscInt field; 5289799db056SMatthew G. Knepley PetscObject obj; 5290799db056SMatthew G. Knepley PetscClassId id; 5291799db056SMatthew G. Knepley 5292799db056SMatthew G. Knepley PetscCall(PetscDSGetBoundary(dsBC, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 52939566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, field, NULL, &obj)); 52949566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(obj, &id)); 5295799db056SMatthew G. Knepley if (!(id == PETSCFE_CLASSID) || !label) continue; 52969371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 52979371c9d4SSatish Balay if (labels[l] == label) break; 5298799db056SMatthew G. Knepley if (l == Nl) labels[Nl++] = label; 5299783e2ec8SMatthew G. Knepley } 5300799db056SMatthew G. Knepley } 5301799db056SMatthew G. Knepley /* Get label names */ 5302799db056SMatthew G. Knepley PetscCall(PetscMalloc1(Nl, &names)); 5303799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscObjectGetName((PetscObject)labels[l], &names[l])); 53049371c9d4SSatish Balay for (l = 0; l < Nl; ++l) { 53059371c9d4SSatish Balay PetscCall(PetscStrlen(names[l], &len)); 53069371c9d4SSatish Balay maxLen = PetscMax(maxLen, (PetscInt)len + 2); 53079371c9d4SSatish Balay } 5308799db056SMatthew G. Knepley PetscCall(PetscFree(labels)); 5309799db056SMatthew G. Knepley PetscCallMPI(MPI_Allreduce(&maxLen, &gmaxLen, 1, MPIU_INT, MPI_MAX, comm)); 5310799db056SMatthew G. Knepley PetscCall(PetscCalloc1(Nl * gmaxLen, &sendNames)); 5311799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscStrcpy(&sendNames[gmaxLen * l], names[l])); 5312799db056SMatthew G. Knepley PetscCall(PetscFree(names)); 5313799db056SMatthew G. Knepley /* Put all names on all processes */ 5314799db056SMatthew G. Knepley PetscCall(PetscCalloc2(size, &counts, size + 1, &displs)); 5315799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgather(&Nl, 1, MPI_INT, counts, 1, MPI_INT, comm)); 5316799db056SMatthew G. Knepley for (p = 0; p < size; ++p) displs[p + 1] = displs[p] + counts[p]; 5317799db056SMatthew G. Knepley gNl = displs[size]; 53189371c9d4SSatish Balay for (p = 0; p < size; ++p) { 53199371c9d4SSatish Balay counts[p] *= gmaxLen; 53209371c9d4SSatish Balay displs[p] *= gmaxLen; 53219371c9d4SSatish Balay } 5322799db056SMatthew G. Knepley PetscCall(PetscCalloc2(gNl * gmaxLen, &recvNames, gNl, &glabels)); 5323799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgatherv(sendNames, counts[rank], MPI_CHAR, recvNames, counts, displs, MPI_CHAR, comm)); 5324799db056SMatthew G. Knepley PetscCall(PetscFree2(counts, displs)); 5325799db056SMatthew G. Knepley PetscCall(PetscFree(sendNames)); 5326799db056SMatthew G. Knepley for (l = 0, gl = 0; l < gNl; ++l) { 5327799db056SMatthew G. Knepley PetscCall(DMGetLabel(dm, &recvNames[l * gmaxLen], &glabels[gl])); 5328799db056SMatthew G. Knepley PetscCheck(glabels[gl], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Label %s missing on rank %d", &recvNames[l * gmaxLen], rank); 53299371c9d4SSatish Balay for (m = 0; m < gl; ++m) 53309371c9d4SSatish Balay if (glabels[m] == glabels[gl]) continue; 53319566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 5332799db056SMatthew G. Knepley PetscCall(DMPlexLabelComplete(plex, glabels[gl])); 53339566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5334799db056SMatthew G. Knepley ++gl; 5335783e2ec8SMatthew G. Knepley } 5336799db056SMatthew G. Knepley PetscCall(PetscFree2(recvNames, glabels)); 5337783e2ec8SMatthew G. Knepley PetscFunctionReturn(0); 5338783e2ec8SMatthew G. Knepley } 5339783e2ec8SMatthew G. Knepley 5340d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5341d71ae5a4SJacob Faibussowitsch { 5342e5e52638SMatthew G. Knepley DMSpace *tmpd; 5343e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5344e5e52638SMatthew G. Knepley 5345e5e52638SMatthew G. Knepley PetscFunctionBegin; 5346e5e52638SMatthew G. Knepley if (Nds >= NdsNew) PetscFunctionReturn(0); 53479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NdsNew, &tmpd)); 5348e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 53499371c9d4SSatish Balay for (s = Nds; s < NdsNew; ++s) { 53509371c9d4SSatish Balay tmpd[s].ds = NULL; 53519371c9d4SSatish Balay tmpd[s].label = NULL; 53529371c9d4SSatish Balay tmpd[s].fields = NULL; 53539371c9d4SSatish Balay } 53549566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5355e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5356e5e52638SMatthew G. Knepley dm->probs = tmpd; 5357e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5358e5e52638SMatthew G. Knepley } 5359e5e52638SMatthew G. Knepley 5360e5e52638SMatthew G. Knepley /*@ 5361e5e52638SMatthew G. Knepley DMGetNumDS - Get the number of discrete systems in the DM 5362e5e52638SMatthew G. Knepley 5363e5e52638SMatthew G. Knepley Not collective 5364e5e52638SMatthew G. Knepley 5365e5e52638SMatthew G. Knepley Input Parameter: 5366e5e52638SMatthew G. Knepley . dm - The DM 5367e5e52638SMatthew G. Knepley 5368e5e52638SMatthew G. Knepley Output Parameter: 5369e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects 5370e5e52638SMatthew G. Knepley 5371e5e52638SMatthew G. Knepley Level: intermediate 5372e5e52638SMatthew G. Knepley 5373db781477SPatrick Sanan .seealso: `DMGetDS()`, `DMGetCellDS()` 5374e5e52638SMatthew G. Knepley @*/ 5375d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5376d71ae5a4SJacob Faibussowitsch { 5377e5e52638SMatthew G. Knepley PetscFunctionBegin; 5378e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5379534a8f05SLisandro Dalcin PetscValidIntPointer(Nds, 2); 5380e5e52638SMatthew G. Knepley *Nds = dm->Nds; 5381e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5382e5e52638SMatthew G. Knepley } 5383e5e52638SMatthew G. Knepley 5384e5e52638SMatthew G. Knepley /*@ 5385e5e52638SMatthew G. Knepley DMClearDS - Remove all discrete systems from the DM 5386e5e52638SMatthew G. Knepley 5387d083f849SBarry Smith Logically collective on dm 5388e5e52638SMatthew G. Knepley 5389e5e52638SMatthew G. Knepley Input Parameter: 5390e5e52638SMatthew G. Knepley . dm - The DM 5391e5e52638SMatthew G. Knepley 5392e5e52638SMatthew G. Knepley Level: intermediate 5393e5e52638SMatthew G. Knepley 5394db781477SPatrick Sanan .seealso: `DMGetNumDS()`, `DMGetDS()`, `DMSetField()` 5395e5e52638SMatthew G. Knepley @*/ 5396d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearDS(DM dm) 5397d71ae5a4SJacob Faibussowitsch { 5398e5e52638SMatthew G. Knepley PetscInt s; 5399e5e52638SMatthew G. Knepley 5400e5e52638SMatthew G. Knepley PetscFunctionBegin; 5401e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5402e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 54039566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 54049566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[s].label)); 54059566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[s].fields)); 5406e5e52638SMatthew G. Knepley } 54079566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5408e5e52638SMatthew G. Knepley dm->probs = NULL; 5409e5e52638SMatthew G. Knepley dm->Nds = 0; 5410e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5411e5e52638SMatthew G. Knepley } 5412e5e52638SMatthew G. Knepley 5413e5e52638SMatthew G. Knepley /*@ 5414e5e52638SMatthew G. Knepley DMGetDS - Get the default PetscDS 5415e5e52638SMatthew G. Knepley 5416e5e52638SMatthew G. Knepley Not collective 5417e5e52638SMatthew G. Knepley 5418e5e52638SMatthew G. Knepley Input Parameter: 5419e5e52638SMatthew G. Knepley . dm - The DM 5420e5e52638SMatthew G. Knepley 5421e5e52638SMatthew G. Knepley Output Parameter: 5422e5e52638SMatthew G. Knepley . prob - The default PetscDS 5423e5e52638SMatthew G. Knepley 5424e5e52638SMatthew G. Knepley Level: intermediate 5425e5e52638SMatthew G. Knepley 5426db781477SPatrick Sanan .seealso: `DMGetCellDS()`, `DMGetRegionDS()` 5427e5e52638SMatthew G. Knepley @*/ 5428d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 5429d71ae5a4SJacob Faibussowitsch { 5430e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5431e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5432e5e52638SMatthew G. Knepley PetscValidPointer(prob, 2); 5433b0143b4dSMatthew G. Knepley if (dm->Nds <= 0) { 5434b0143b4dSMatthew G. Knepley PetscDS ds; 5435b0143b4dSMatthew G. Knepley 54369566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 54379566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, NULL, NULL, ds)); 54389566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 5439b0143b4dSMatthew G. Knepley } 5440b0143b4dSMatthew G. Knepley *prob = dm->probs[0].ds; 5441e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5442e5e52638SMatthew G. Knepley } 5443e5e52638SMatthew G. Knepley 5444e5e52638SMatthew G. Knepley /*@ 5445e5e52638SMatthew G. Knepley DMGetCellDS - Get the PetscDS defined on a given cell 5446e5e52638SMatthew G. Knepley 5447e5e52638SMatthew G. Knepley Not collective 5448e5e52638SMatthew G. Knepley 5449e5e52638SMatthew G. Knepley Input Parameters: 5450e5e52638SMatthew G. Knepley + dm - The DM 5451e5e52638SMatthew G. Knepley - point - Cell for the DS 5452e5e52638SMatthew G. Knepley 5453e5e52638SMatthew G. Knepley Output Parameter: 5454e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell 5455e5e52638SMatthew G. Knepley 5456e5e52638SMatthew G. Knepley Level: developer 5457e5e52638SMatthew G. Knepley 5458db781477SPatrick Sanan .seealso: `DMGetDS()`, `DMSetRegionDS()` 5459e5e52638SMatthew G. Knepley @*/ 5460d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob) 5461d71ae5a4SJacob Faibussowitsch { 5462e5e52638SMatthew G. Knepley PetscDS probDef = NULL; 5463e5e52638SMatthew G. Knepley PetscInt s; 5464e5e52638SMatthew G. Knepley 5465e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5466e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5467e5e52638SMatthew G. Knepley PetscValidPointer(prob, 3); 546863a3b9bcSJacob Faibussowitsch PetscCheck(point >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %" PetscInt_FMT, point); 5469e5e52638SMatthew G. Knepley *prob = NULL; 5470e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5471e5e52638SMatthew G. Knepley PetscInt val; 5472e5e52638SMatthew G. Knepley 54739371c9d4SSatish Balay if (!dm->probs[s].label) { 54749371c9d4SSatish Balay probDef = dm->probs[s].ds; 54759371c9d4SSatish Balay } else { 54769566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dm->probs[s].label, point, &val)); 54779371c9d4SSatish Balay if (val >= 0) { 54789371c9d4SSatish Balay *prob = dm->probs[s].ds; 54799371c9d4SSatish Balay break; 54809371c9d4SSatish Balay } 5481e5e52638SMatthew G. Knepley } 5482e5e52638SMatthew G. Knepley } 5483e5e52638SMatthew G. Knepley if (!*prob) *prob = probDef; 5484e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5485e5e52638SMatthew G. Knepley } 5486e5e52638SMatthew G. Knepley 5487e5e52638SMatthew G. Knepley /*@ 5488e5e52638SMatthew G. Knepley DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel 5489e5e52638SMatthew G. Knepley 5490e5e52638SMatthew G. Knepley Not collective 5491e5e52638SMatthew G. Knepley 5492e5e52638SMatthew G. Knepley Input Parameters: 5493e5e52638SMatthew G. Knepley + dm - The DM 5494e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh 5495e5e52638SMatthew G. Knepley 5496b3cf3223SMatthew G. Knepley Output Parameters: 5497b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5498b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL 5499e5e52638SMatthew G. Knepley 5500154ca461SJed Brown Note: 5501154ca461SJed Brown If a non-NULL label is given, but there is no PetscDS on that specific label, 5502154ca461SJed Brown the PetscDS for the full domain (if present) is returned. Returns with 5503154ca461SJed Brown fields=NULL and prob=NULL if there is no PetscDS for the full domain. 5504e5e52638SMatthew G. Knepley 5505e5e52638SMatthew G. Knepley Level: advanced 5506e5e52638SMatthew G. Knepley 5507db781477SPatrick Sanan .seealso: `DMGetRegionNumDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5508e5e52638SMatthew G. Knepley @*/ 5509d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds) 5510d71ae5a4SJacob Faibussowitsch { 5511e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5512e5e52638SMatthew G. Knepley 5513e5e52638SMatthew G. Knepley PetscFunctionBegin; 5514e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5515e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 55169371c9d4SSatish Balay if (fields) { 55179371c9d4SSatish Balay PetscValidPointer(fields, 3); 55189371c9d4SSatish Balay *fields = NULL; 55199371c9d4SSatish Balay } 55209371c9d4SSatish Balay if (ds) { 55219371c9d4SSatish Balay PetscValidPointer(ds, 4); 55229371c9d4SSatish Balay *ds = NULL; 55239371c9d4SSatish Balay } 5524e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5525154ca461SJed Brown if (dm->probs[s].label == label || !dm->probs[s].label) { 5526b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5527b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 5528154ca461SJed Brown if (dm->probs[s].label) PetscFunctionReturn(0); 5529b3cf3223SMatthew G. Knepley } 5530e5e52638SMatthew G. Knepley } 55312df9ee95SMatthew G. Knepley PetscFunctionReturn(0); 5532e5e52638SMatthew G. Knepley } 5533e5e52638SMatthew G. Knepley 5534e5e52638SMatthew G. Knepley /*@ 5535bb7acecfSBarry Smith DMSetRegionDS - Set the `PetscDS` for a given mesh region, defined by a `DMLabel` 5536083401c6SMatthew G. Knepley 5537083401c6SMatthew G. Knepley Collective on dm 5538083401c6SMatthew G. Knepley 5539083401c6SMatthew G. Knepley Input Parameters: 5540bb7acecfSBarry Smith + dm - The `DM` 5541bb7acecfSBarry Smith . label - The `DMLabel` defining the mesh region, or NULL for the entire mesh 5542bb7acecfSBarry Smith . fields - The IS containing the `DM` field numbers for the fields in this `PetscDS`, or NULL for all fields 5543bb7acecfSBarry Smith - prob - The `PetscDS` defined on the given region 5544083401c6SMatthew G. Knepley 5545bb7acecfSBarry Smith Note: 5546bb7acecfSBarry 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, 5547083401c6SMatthew G. Knepley the fields argument is ignored. 5548083401c6SMatthew G. Knepley 5549083401c6SMatthew G. Knepley Level: advanced 5550083401c6SMatthew G. Knepley 5551db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionNumDS()`, `DMGetDS()`, `DMGetCellDS()` 5552083401c6SMatthew G. Knepley @*/ 5553d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds) 5554d71ae5a4SJacob Faibussowitsch { 5555083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5556083401c6SMatthew G. Knepley 5557083401c6SMatthew G. Knepley PetscFunctionBegin; 5558083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5559083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5560064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 5561083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5562083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 55639566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 5564083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 5565083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5566083401c6SMatthew G. Knepley } 5567083401c6SMatthew G. Knepley } 55689566063dSJacob Faibussowitsch PetscCall(DMDSEnlarge_Static(dm, Nds + 1)); 55699566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 55709566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 55719566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 5572083401c6SMatthew G. Knepley if (!label) { 5573083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5574083401c6SMatthew G. Knepley for (s = Nds - 1; s >= 0; --s) dm->probs[s + 1] = dm->probs[s]; 5575083401c6SMatthew G. Knepley Nds = 0; 5576083401c6SMatthew G. Knepley } 5577083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5578083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5579083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 5580083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5581083401c6SMatthew G. Knepley } 5582083401c6SMatthew G. Knepley 5583083401c6SMatthew G. Knepley /*@ 5584e5e52638SMatthew G. Knepley DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number 5585e5e52638SMatthew G. Knepley 5586e5e52638SMatthew G. Knepley Not collective 5587e5e52638SMatthew G. Knepley 5588e5e52638SMatthew G. Knepley Input Parameters: 5589e5e52638SMatthew G. Knepley + dm - The DM 5590e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5591e5e52638SMatthew G. Knepley 5592e5e52638SMatthew G. Knepley Output Parameters: 5593b3cf3223SMatthew G. Knepley + label - The region label, or NULL 5594b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5595083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL 5596e5e52638SMatthew G. Knepley 5597e5e52638SMatthew G. Knepley Level: advanced 5598e5e52638SMatthew G. Knepley 5599db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5600e5e52638SMatthew G. Knepley @*/ 5601d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds) 5602d71ae5a4SJacob Faibussowitsch { 5603e5e52638SMatthew G. Knepley PetscInt Nds; 5604e5e52638SMatthew G. Knepley 5605e5e52638SMatthew G. Knepley PetscFunctionBegin; 5606e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56079566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 560863a3b9bcSJacob 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); 5609e5e52638SMatthew G. Knepley if (label) { 5610e5e52638SMatthew G. Knepley PetscValidPointer(label, 3); 5611e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5612e5e52638SMatthew G. Knepley } 5613b3cf3223SMatthew G. Knepley if (fields) { 5614b3cf3223SMatthew G. Knepley PetscValidPointer(fields, 4); 5615b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5616b3cf3223SMatthew G. Knepley } 5617e5e52638SMatthew G. Knepley if (ds) { 5618b3cf3223SMatthew G. Knepley PetscValidPointer(ds, 5); 5619e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5620e5e52638SMatthew G. Knepley } 5621e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5622e5e52638SMatthew G. Knepley } 5623e5e52638SMatthew G. Knepley 5624e5e52638SMatthew G. Knepley /*@ 5625083401c6SMatthew G. Knepley DMSetRegionNumDS - Set the PetscDS for a given mesh region, defined by the region number 5626e5e52638SMatthew G. Knepley 5627083401c6SMatthew G. Knepley Not collective 5628e5e52638SMatthew G. Knepley 5629e5e52638SMatthew G. Knepley Input Parameters: 5630e5e52638SMatthew G. Knepley + dm - The DM 5631083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 5632083401c6SMatthew G. Knepley . label - The region label, or NULL 5633083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL to prevent setting 5634083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL to prevent setting 5635e5e52638SMatthew G. Knepley 5636e5e52638SMatthew G. Knepley Level: advanced 5637e5e52638SMatthew G. Knepley 5638db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5639e5e52638SMatthew G. Knepley @*/ 5640d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds) 5641d71ae5a4SJacob Faibussowitsch { 5642083401c6SMatthew G. Knepley PetscInt Nds; 5643e5e52638SMatthew G. Knepley 5644e5e52638SMatthew G. Knepley PetscFunctionBegin; 5645e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5646ad540459SPierre Jolivet if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 56479566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 564863a3b9bcSJacob 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); 56499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 56509566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[num].label)); 5651083401c6SMatthew G. Knepley dm->probs[num].label = label; 5652083401c6SMatthew G. Knepley if (fields) { 5653083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 56549566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 56559566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[num].fields)); 5656083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5657e5e52638SMatthew G. Knepley } 5658083401c6SMatthew G. Knepley if (ds) { 5659083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 56609566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 56619566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[num].ds)); 5662083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5663083401c6SMatthew G. Knepley } 5664e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5665e5e52638SMatthew G. Knepley } 5666e5e52638SMatthew G. Knepley 5667e5e52638SMatthew G. Knepley /*@ 56681d3af9e0SMatthew G. Knepley DMFindRegionNum - Find the region number for a given PetscDS, or -1 if it is not found. 56691d3af9e0SMatthew G. Knepley 56701d3af9e0SMatthew G. Knepley Not collective 56711d3af9e0SMatthew G. Knepley 56721d3af9e0SMatthew G. Knepley Input Parameters: 56731d3af9e0SMatthew G. Knepley + dm - The DM 56741d3af9e0SMatthew G. Knepley - ds - The PetscDS defined on the given region 56751d3af9e0SMatthew G. Knepley 56761d3af9e0SMatthew G. Knepley Output Parameter: 56771d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 56781d3af9e0SMatthew G. Knepley 56791d3af9e0SMatthew G. Knepley Level: advanced 56801d3af9e0SMatthew G. Knepley 5681db781477SPatrick Sanan .seealso: `DMGetRegionNumDS()`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 56821d3af9e0SMatthew G. Knepley @*/ 5683d71ae5a4SJacob Faibussowitsch PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 5684d71ae5a4SJacob Faibussowitsch { 56851d3af9e0SMatthew G. Knepley PetscInt Nds, n; 56861d3af9e0SMatthew G. Knepley 56871d3af9e0SMatthew G. Knepley PetscFunctionBegin; 56881d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56891d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 5690dadcf809SJacob Faibussowitsch PetscValidIntPointer(num, 3); 56919566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 56929371c9d4SSatish Balay for (n = 0; n < Nds; ++n) 56939371c9d4SSatish Balay if (ds == dm->probs[n].ds) break; 56941d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 56951d3af9e0SMatthew G. Knepley else *num = n; 56961d3af9e0SMatthew G. Knepley PetscFunctionReturn(0); 56971d3af9e0SMatthew G. Knepley } 56981d3af9e0SMatthew G. Knepley 56992df84da0SMatthew G. Knepley /*@C 5700bb7acecfSBarry Smith DMCreateFEDefault - Create a `PetscFE` based on the celltype for the mesh 57012df84da0SMatthew G. Knepley 57022df84da0SMatthew G. Knepley Not collective 57032df84da0SMatthew G. Knepley 5704f1a722f8SMatthew G. Knepley Input Parameters: 5705bb7acecfSBarry Smith + dm - The `DM` 57062df84da0SMatthew G. Knepley . Nc - The number of components for the field 5707bb7acecfSBarry Smith . prefix - The options prefix for the output `PetscFE`, or NULL 5708bb7acecfSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 57092df84da0SMatthew G. Knepley 57102df84da0SMatthew G. Knepley Output Parameter: 5711bb7acecfSBarry Smith . fem - The `PetscFE` 57122df84da0SMatthew G. Knepley 5713bb7acecfSBarry Smith Note: 5714bb7acecfSBarry Smith This is a convenience method that just calls `PetscFECreateByCell()` underneath. 57152df84da0SMatthew G. Knepley 57162df84da0SMatthew G. Knepley Level: intermediate 57172df84da0SMatthew G. Knepley 5718db781477SPatrick Sanan .seealso: `PetscFECreateByCell()`, `DMAddField()`, `DMCreateDS()`, `DMGetCellDS()`, `DMGetRegionDS()` 57192df84da0SMatthew G. Knepley @*/ 5720d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFEDefault(DM dm, PetscInt Nc, const char prefix[], PetscInt qorder, PetscFE *fem) 5721d71ae5a4SJacob Faibussowitsch { 57222df84da0SMatthew G. Knepley DMPolytopeType ct; 57232df84da0SMatthew G. Knepley PetscInt dim, cStart; 57242df84da0SMatthew G. Knepley 57252df84da0SMatthew G. Knepley PetscFunctionBegin; 57262df84da0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57272df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 2); 57282df84da0SMatthew G. Knepley if (prefix) PetscValidCharPointer(prefix, 3); 57292df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, qorder, 4); 57302df84da0SMatthew G. Knepley PetscValidPointer(fem, 5); 57319566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 57329566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 57339566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 57349566063dSJacob Faibussowitsch PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, Nc, ct, prefix, qorder, fem)); 57352df84da0SMatthew G. Knepley PetscFunctionReturn(0); 57362df84da0SMatthew G. Knepley } 57372df84da0SMatthew G. Knepley 57381d3af9e0SMatthew G. Knepley /*@ 5739bb7acecfSBarry Smith DMCreateDS - Create the discrete systems for the `DM` based upon the fields added to the `DM` 5740e5e52638SMatthew G. Knepley 5741d083f849SBarry Smith Collective on dm 5742e5e52638SMatthew G. Knepley 5743e5e52638SMatthew G. Knepley Input Parameter: 5744bb7acecfSBarry Smith . dm - The `DM` 5745e5e52638SMatthew G. Knepley 574645480ffeSMatthew G. Knepley Options Database Keys: 5747bb7acecfSBarry Smith . -dm_petscds_view - View all the `PetscDS` objects in this `DM` 574845480ffeSMatthew G. Knepley 5749bb7acecfSBarry Smith Note: 5750bb7acecfSBarry Smith If the label has a `PetscDS` defined, it will be replaced. Otherwise, it will be added to the `DM`. 5751e5e52638SMatthew G. Knepley 5752e5e52638SMatthew G. Knepley Level: intermediate 5753e5e52638SMatthew G. Knepley 5754db781477SPatrick Sanan .seealso: `DMSetField`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 5755e5e52638SMatthew G. Knepley @*/ 5756d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDS(DM dm) 5757d71ae5a4SJacob Faibussowitsch { 5758e5e52638SMatthew G. Knepley MPI_Comm comm; 5759083401c6SMatthew G. Knepley PetscDS dsDef; 5760083401c6SMatthew G. Knepley DMLabel *labelSet; 5761f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5762f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5763e5e52638SMatthew G. Knepley 5764e5e52638SMatthew G. Knepley PetscFunctionBegin; 5765e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5766e5e52638SMatthew G. Knepley if (!dm->fields) PetscFunctionReturn(0); 57679566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 57689566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dE)); 5769083401c6SMatthew G. Knepley /* Determine how many regions we have */ 57709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &labelSet)); 5771083401c6SMatthew G. Knepley Nl = 0; 5772083401c6SMatthew G. Knepley Ndef = 0; 5773083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5774083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5775083401c6SMatthew G. Knepley PetscInt l; 5776083401c6SMatthew G. Knepley 5777f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5778f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5779f918ec44SMatthew G. Knepley { 5780f918ec44SMatthew G. Knepley PetscClassId id; 5781f918ec44SMatthew G. Knepley 57829566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(dm->fields[f].disc, &id)); 5783f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5784f918ec44SMatthew G. Knepley Ceed ceed; 5785f918ec44SMatthew G. Knepley 57869566063dSJacob Faibussowitsch PetscCall(DMGetCeed(dm, &ceed)); 57879566063dSJacob Faibussowitsch PetscCall(PetscFESetCeed((PetscFE)dm->fields[f].disc, ceed)); 5788f918ec44SMatthew G. Knepley } 5789f918ec44SMatthew G. Knepley } 5790f918ec44SMatthew G. Knepley #endif 57919371c9d4SSatish Balay if (!label) { 57929371c9d4SSatish Balay ++Ndef; 57939371c9d4SSatish Balay continue; 57949371c9d4SSatish Balay } 57959371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 57969371c9d4SSatish Balay if (label == labelSet[l]) break; 5797083401c6SMatthew G. Knepley if (l < Nl) continue; 5798083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5799083401c6SMatthew G. Knepley } 5800083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 58019566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef)); 5802083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5803b3cf3223SMatthew G. Knepley IS fields; 5804b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5805b3cf3223SMatthew G. Knepley 58069371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58079371c9d4SSatish Balay if (!dm->fields[f].label) ++nf; 58087a8be351SBarry Smith PetscCheck(nf, comm, PETSC_ERR_PLIB, "All fields have labels, but we are trying to create a default DS"); 58099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 58109371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58119371c9d4SSatish Balay if (!dm->fields[f].label) fld[nf++] = f; 58129566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 58139566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 58149566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 58159566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 581688f0c812SMatthew G. Knepley 58179566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 58189566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, NULL, fields, dsDef)); 58199566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 58209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 58212df9ee95SMatthew G. Knepley } 58229566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef)); 58239566063dSJacob Faibussowitsch if (dsDef) PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 5824083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5825083401c6SMatthew G. Knepley if (Ndef && Nl) { 58260122748bSMatthew G. Knepley DM plex; 5827083401c6SMatthew G. Knepley DMLabel cellLabel; 5828083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5829083401c6SMatthew G. Knepley PetscInt *fields; 5830083401c6SMatthew G. Knepley const PetscInt *cells; 5831083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 58320122748bSMatthew G. Knepley 58339566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 58349566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(plex, &depth)); 58359566063dSJacob Faibussowitsch PetscCall(DMGetStratumIS(plex, "dim", depth, &allcellIS)); 58369566063dSJacob Faibussowitsch if (!allcellIS) PetscCall(DMGetStratumIS(plex, "depth", depth, &allcellIS)); 58375fedec97SMatthew G. Knepley /* TODO This looks like it only works for one label */ 5838083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5839083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5840083401c6SMatthew G. Knepley IS pointIS; 5841083401c6SMatthew G. Knepley 58429566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 58439566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, 1, &pointIS)); 58449566063dSJacob Faibussowitsch PetscCall(ISDifference(allcellIS, pointIS, &defcellIS)); 58459566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointIS)); 5846083401c6SMatthew G. Knepley } 58479566063dSJacob Faibussowitsch PetscCall(ISDestroy(&allcellIS)); 5848083401c6SMatthew G. Knepley 58499566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel)); 58509566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(defcellIS, &n)); 58519566063dSJacob Faibussowitsch PetscCall(ISGetIndices(defcellIS, &cells)); 58529566063dSJacob Faibussowitsch for (c = 0; c < n; ++c) PetscCall(DMLabelSetValue(cellLabel, cells[c], 1)); 58539566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(defcellIS, &cells)); 58549566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 58559566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(plex, cellLabel)); 5856083401c6SMatthew G. Knepley 58579566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Ndef, &fields)); 58589371c9d4SSatish Balay for (f = 0; f < Nf; ++f) 58599371c9d4SSatish Balay if (!dm->fields[f].label) fields[nf++] = f; 58609566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fieldIS)); 58619566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fieldIS, "dm_fields_")); 58629566063dSJacob Faibussowitsch PetscCall(ISSetType(fieldIS, ISGENERAL)); 58639566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER)); 5864083401c6SMatthew G. Knepley 58659566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 58669566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, cellLabel, fieldIS, dsDef)); 58679566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 58689566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&cellLabel)); 58699566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 58709566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fieldIS)); 58719566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5872083401c6SMatthew G. Knepley } 5873083401c6SMatthew G. Knepley /* Create label DSes 5874083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5875083401c6SMatthew G. Knepley */ 5876083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5877083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5878083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5879083401c6SMatthew G. Knepley PetscDS ds; 5880083401c6SMatthew G. Knepley IS fields; 5881083401c6SMatthew G. Knepley PetscInt *fld, nf; 5882083401c6SMatthew G. Knepley 58839566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 58849371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58859371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 58869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 58879371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58889371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 58899566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 58909566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 58919566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 58929566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 58939566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, label, fields, ds)); 58949566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 58959566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(ds, dE)); 5896083401c6SMatthew G. Knepley { 5897083401c6SMatthew G. Knepley DMPolytopeType ct; 5898083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 58995fedec97SMatthew G. Knepley PetscBool isCohesiveLocal = PETSC_FALSE, isCohesive; 59000122748bSMatthew G. Knepley 59019566063dSJacob Faibussowitsch PetscCall(DMLabelGetBounds(label, &lStart, &lEnd)); 5902665f567fSMatthew G. Knepley if (lStart >= 0) { 59039566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, lStart, &ct)); 5904412e9a14SMatthew G. Knepley switch (ct) { 5905412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5906412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5907412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5908d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5909d71ae5a4SJacob Faibussowitsch isCohesiveLocal = PETSC_TRUE; 5910d71ae5a4SJacob Faibussowitsch break; 5911d71ae5a4SJacob Faibussowitsch default: 5912d71ae5a4SJacob Faibussowitsch break; 5913412e9a14SMatthew G. Knepley } 5914665f567fSMatthew G. Knepley } 59159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&isCohesiveLocal, &isCohesive, 1, MPIU_BOOL, MPI_LOR, comm)); 59165fedec97SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) { 59175fedec97SMatthew G. Knepley if (label == dm->fields[f].label || !dm->fields[f].label) { 59185fedec97SMatthew G. Knepley if (label == dm->fields[f].label) { 59199566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, nf, NULL)); 59209566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(ds, nf, isCohesive)); 59215fedec97SMatthew G. Knepley } 59225fedec97SMatthew G. Knepley ++nf; 59235fedec97SMatthew G. Knepley } 59245fedec97SMatthew G. Knepley } 5925e5e52638SMatthew G. Knepley } 59269566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 5927e5e52638SMatthew G. Knepley } 59289566063dSJacob Faibussowitsch PetscCall(PetscFree(labelSet)); 5929e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5930083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5931083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 5932083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5933083401c6SMatthew G. Knepley const PetscInt *fld; 59345fedec97SMatthew G. Knepley PetscInt nf, dsnf; 59355fedec97SMatthew G. Knepley PetscBool isCohesive; 5936e5e52638SMatthew G. Knepley 59379566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsnf)); 59389566063dSJacob Faibussowitsch PetscCall(PetscDSIsCohesive(ds, &isCohesive)); 59399566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(fields, &nf)); 59409566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fields, &fld)); 5941083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5942083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 59435fedec97SMatthew G. Knepley PetscBool isCohesiveField; 5944e5e52638SMatthew G. Knepley PetscClassId id; 5945e5e52638SMatthew G. Knepley 59465fedec97SMatthew G. Knepley /* Handle DS with no fields */ 59479566063dSJacob Faibussowitsch if (dsnf) PetscCall(PetscDSGetCohesive(ds, f, &isCohesiveField)); 59485fedec97SMatthew G. Knepley /* If this is a cohesive cell, then regular fields need the lower dimensional discretization */ 59499566063dSJacob Faibussowitsch if (isCohesive && !isCohesiveField) PetscCall(PetscFEGetHeightSubspace((PetscFE)disc, 1, (PetscFE *)&disc)); 59509566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, f, disc)); 5951083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 59529566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 5953e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 5954e5e52638SMatthew G. Knepley } 59559566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fields, &fld)); 5956e5e52638SMatthew G. Knepley } 5957f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 59589566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)dm)->prefix, "-dm_ds_jet_degree", &k, &flg)); 5959f9244615SMatthew G. Knepley if (flg) { 59603b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 59613b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 59623b4aee56SMatthew G. Knepley PetscInt Nf, f; 59633b4aee56SMatthew G. Knepley 59649566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 59659566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSSetJetDegree(ds, f, k)); 59663b4aee56SMatthew G. Knepley } 5967f9244615SMatthew G. Knepley } 5968e5e52638SMatthew G. Knepley /* Setup DSes */ 5969e5e52638SMatthew G. Knepley if (doSetup) { 59709566063dSJacob Faibussowitsch for (s = 0; s < dm->Nds; ++s) PetscCall(PetscDSSetUp(dm->probs[s].ds)); 5971e5e52638SMatthew G. Knepley } 5972e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5973e5e52638SMatthew G. Knepley } 5974e5e52638SMatthew G. Knepley 5975e5e52638SMatthew G. Knepley /*@ 5976bb7acecfSBarry Smith DMComputeExactSolution - Compute the exact solution for a given `DM`, using the `PetscDS` information. 59777f96f943SMatthew G. Knepley 5978bb7acecfSBarry Smith Collective on `DM` 5979f2cacb80SMatthew G. Knepley 59807f96f943SMatthew G. Knepley Input Parameters: 5981bb7acecfSBarry Smith + dm - The `DM` 59827f96f943SMatthew G. Knepley - time - The time 59837f96f943SMatthew G. Knepley 59847f96f943SMatthew G. Knepley Output Parameters: 5985f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5986f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 59877f96f943SMatthew G. Knepley 5988bb7acecfSBarry Smith Note: 5989bb7acecfSBarry Smith The user must call `PetscDSSetExactSolution()` before using this routine 59907f96f943SMatthew G. Knepley 59917f96f943SMatthew G. Knepley Level: developer 59927f96f943SMatthew G. Knepley 5993db781477SPatrick Sanan .seealso: `PetscDSSetExactSolution()` 59947f96f943SMatthew G. Knepley @*/ 5995d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 5996d71ae5a4SJacob Faibussowitsch { 59977f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 59987f96f943SMatthew G. Knepley void **ectxs; 59997f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 60007f96f943SMatthew G. Knepley 60017f96f943SMatthew G. Knepley PetscFunctionBegin; 6002f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6003f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 6004f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 60059566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 60069566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exacts, Nf, &ectxs)); 60079566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 60087f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 60097f96f943SMatthew G. Knepley PetscDS ds; 60107f96f943SMatthew G. Knepley DMLabel label; 60117f96f943SMatthew G. Knepley IS fieldIS; 60127f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 60137f96f943SMatthew G. Knepley PetscInt dsNf, f; 60147f96f943SMatthew G. Knepley 60159566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds)); 60169566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 60179566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fieldIS, &fields)); 60189566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 60199566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6020f2cacb80SMatthew G. Knepley if (u) { 60217f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 60227f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 60239566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field])); 60247f96f943SMatthew G. Knepley } 60259566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 60267f96f943SMatthew G. Knepley if (label) { 60279566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u)); 60287f96f943SMatthew G. Knepley } else { 60299566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u)); 60307f96f943SMatthew G. Knepley } 60317f96f943SMatthew G. Knepley } 6032f2cacb80SMatthew G. Knepley if (u_t) { 60339566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 60349566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6035f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 6036f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 60379566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field])); 6038f2cacb80SMatthew G. Knepley } 60399566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 6040f2cacb80SMatthew G. Knepley if (label) { 60419566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t)); 6042f2cacb80SMatthew G. Knepley } else { 60439566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t)); 6044f2cacb80SMatthew G. Knepley } 6045f2cacb80SMatthew G. Knepley } 6046f2cacb80SMatthew G. Knepley } 6047f2cacb80SMatthew G. Knepley if (u) { 60489566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution")); 60499566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u, "exact_")); 6050f2cacb80SMatthew G. Knepley } 6051f2cacb80SMatthew G. Knepley if (u_t) { 60529566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution Time Derivative")); 60539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u_t, "exact_t_")); 6054f2cacb80SMatthew G. Knepley } 60559566063dSJacob Faibussowitsch PetscCall(PetscFree2(exacts, ectxs)); 60567f96f943SMatthew G. Knepley PetscFunctionReturn(0); 60577f96f943SMatthew G. Knepley } 60587f96f943SMatthew G. Knepley 6059d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscDS ds) 6060d71ae5a4SJacob Faibussowitsch { 606145480ffeSMatthew G. Knepley PetscDS dsNew; 606245480ffeSMatthew G. Knepley DSBoundary b; 60636a02485aSMatthew G. Knepley PetscInt cdim, Nf, f, d; 60645fedec97SMatthew G. Knepley PetscBool isCohesive; 606545480ffeSMatthew G. Knepley void *ctx; 606645480ffeSMatthew G. Knepley 606745480ffeSMatthew G. Knepley PetscFunctionBegin; 60689566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)ds), &dsNew)); 60699566063dSJacob Faibussowitsch PetscCall(PetscDSCopyConstants(ds, dsNew)); 60709566063dSJacob Faibussowitsch PetscCall(PetscDSCopyExactSolutions(ds, dsNew)); 60719566063dSJacob Faibussowitsch PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew)); 60729566063dSJacob Faibussowitsch PetscCall(PetscDSCopyEquations(ds, dsNew)); 60739566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 607445480ffeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 60759566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(ds, f, &ctx)); 60769566063dSJacob Faibussowitsch PetscCall(PetscDSSetContext(dsNew, f, ctx)); 60779566063dSJacob Faibussowitsch PetscCall(PetscDSGetCohesive(ds, f, &isCohesive)); 60789566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive)); 60796a02485aSMatthew G. Knepley PetscCall(PetscDSGetJetDegree(ds, f, &d)); 60806a02485aSMatthew G. Knepley PetscCall(PetscDSSetJetDegree(dsNew, f, d)); 608145480ffeSMatthew G. Knepley } 608245480ffeSMatthew G. Knepley if (Nf) { 60839566063dSJacob Faibussowitsch PetscCall(PetscDSGetCoordinateDimension(ds, &cdim)); 60849566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim)); 608545480ffeSMatthew G. Knepley } 60869566063dSJacob Faibussowitsch PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew)); 608745480ffeSMatthew G. Knepley for (b = dsNew->boundary; b; b = b->next) { 60889566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, b->lname, &b->label)); 608945480ffeSMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 60907a8be351SBarry Smith //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name); 609145480ffeSMatthew G. Knepley } 609245480ffeSMatthew G. Knepley 60939566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, label, fields, dsNew)); 60949566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsNew)); 609545480ffeSMatthew G. Knepley PetscFunctionReturn(0); 609645480ffeSMatthew G. Knepley } 609745480ffeSMatthew G. Knepley 60987f96f943SMatthew G. Knepley /*@ 6099bb7acecfSBarry Smith DMCopyDS - Copy the discrete systems for the `DM` into another `DM` 6100e5e52638SMatthew G. Knepley 6101d083f849SBarry Smith Collective on dm 6102e5e52638SMatthew G. Knepley 6103e5e52638SMatthew G. Knepley Input Parameter: 6104bb7acecfSBarry Smith . dm - The `DM` 6105e5e52638SMatthew G. Knepley 6106e5e52638SMatthew G. Knepley Output Parameter: 6107bb7acecfSBarry Smith . newdm - The `DM` 6108e5e52638SMatthew G. Knepley 6109e5e52638SMatthew G. Knepley Level: advanced 6110e5e52638SMatthew G. Knepley 6111db781477SPatrick Sanan .seealso: `DMCopyFields()`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 6112e5e52638SMatthew G. Knepley @*/ 6113d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDS(DM dm, DM newdm) 6114d71ae5a4SJacob Faibussowitsch { 6115e5e52638SMatthew G. Knepley PetscInt Nds, s; 6116e5e52638SMatthew G. Knepley 6117e5e52638SMatthew G. Knepley PetscFunctionBegin; 6118e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 61199566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 61209566063dSJacob Faibussowitsch PetscCall(DMClearDS(newdm)); 6121e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6122e5e52638SMatthew G. Knepley DMLabel label; 6123b3cf3223SMatthew G. Knepley IS fields; 612445480ffeSMatthew G. Knepley PetscDS ds, newds; 6125783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6126e5e52638SMatthew G. Knepley 61279566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fields, &ds)); 6128b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 61299566063dSJacob Faibussowitsch PetscCall(DMTransferDS_Internal(newdm, label, fields, ds)); 6130*d5b43468SJose E. Roman /* Complete new labels in the new DS */ 61319566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(newdm, label, NULL, &newds)); 61329566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumBoundary(newds, &Nbd)); 6133783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6134b8025e53SMatthew G. Knepley PetscWeakForm wf; 613545480ffeSMatthew G. Knepley DMLabel label; 6136783e2ec8SMatthew G. Knepley PetscInt field; 6137783e2ec8SMatthew G. Knepley 61389566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 61399566063dSJacob Faibussowitsch PetscCall(PetscWeakFormReplaceLabel(wf, label)); 6140783e2ec8SMatthew G. Knepley } 6141e5e52638SMatthew G. Knepley } 6142799db056SMatthew G. Knepley PetscCall(DMCompleteBCLabels_Internal(newdm)); 6143e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6144e5e52638SMatthew G. Knepley } 6145e5e52638SMatthew G. Knepley 6146e5e52638SMatthew G. Knepley /*@ 6147bb7acecfSBarry Smith DMCopyDisc - Copy the fields and discrete systems for the `DM` into another `DM` 6148e5e52638SMatthew G. Knepley 6149d083f849SBarry Smith Collective on dm 6150e5e52638SMatthew G. Knepley 6151e5e52638SMatthew G. Knepley Input Parameter: 6152bb7acecfSBarry Smith . dm - The `DM` 6153e5e52638SMatthew G. Knepley 6154e5e52638SMatthew G. Knepley Output Parameter: 6155bb7acecfSBarry Smith . newdm - The `DM` 6156e5e52638SMatthew G. Knepley 6157e5e52638SMatthew G. Knepley Level: advanced 6158e5e52638SMatthew G. Knepley 6159bb7acecfSBarry Smith Developer Note: 6160bb7acecfSBarry Smith Really ugly name, nothing in PETSc is called a `Disc` plus it is an ugly abbreviation 6161bb7acecfSBarry Smith 6162db781477SPatrick Sanan .seealso: `DMCopyFields()`, `DMCopyDS()` 6163e5e52638SMatthew G. Knepley @*/ 6164d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6165d71ae5a4SJacob Faibussowitsch { 6166e5e52638SMatthew G. Knepley PetscFunctionBegin; 61679566063dSJacob Faibussowitsch PetscCall(DMCopyFields(dm, newdm)); 61689566063dSJacob Faibussowitsch PetscCall(DMCopyDS(dm, newdm)); 6169e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6170e5e52638SMatthew G. Knepley } 6171e5e52638SMatthew G. Knepley 6172c73cfb54SMatthew G. Knepley /*@ 6173bb7acecfSBarry Smith DMGetDimension - Return the topological dimension of the `DM` 6174c73cfb54SMatthew G. Knepley 6175c73cfb54SMatthew G. Knepley Not collective 6176c73cfb54SMatthew G. Knepley 6177c73cfb54SMatthew G. Knepley Input Parameter: 6178bb7acecfSBarry Smith . dm - The `DM` 6179c73cfb54SMatthew G. Knepley 6180c73cfb54SMatthew G. Knepley Output Parameter: 6181c73cfb54SMatthew G. Knepley . dim - The topological dimension 6182c73cfb54SMatthew G. Knepley 6183c73cfb54SMatthew G. Knepley Level: beginner 6184c73cfb54SMatthew G. Knepley 6185db781477SPatrick Sanan .seealso: `DMSetDimension()`, `DMCreate()` 6186c73cfb54SMatthew G. Knepley @*/ 6187d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6188d71ae5a4SJacob Faibussowitsch { 6189c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6190c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6191534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 6192c73cfb54SMatthew G. Knepley *dim = dm->dim; 6193c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6194c73cfb54SMatthew G. Knepley } 6195c73cfb54SMatthew G. Knepley 6196c73cfb54SMatthew G. Knepley /*@ 6197bb7acecfSBarry Smith DMSetDimension - Set the topological dimension of the `DM` 6198c73cfb54SMatthew G. Knepley 6199c73cfb54SMatthew G. Knepley Collective on dm 6200c73cfb54SMatthew G. Knepley 6201c73cfb54SMatthew G. Knepley Input Parameters: 6202bb7acecfSBarry Smith + dm - The `DM` 6203c73cfb54SMatthew G. Knepley - dim - The topological dimension 6204c73cfb54SMatthew G. Knepley 6205c73cfb54SMatthew G. Knepley Level: beginner 6206c73cfb54SMatthew G. Knepley 6207db781477SPatrick Sanan .seealso: `DMGetDimension()`, `DMCreate()` 6208c73cfb54SMatthew G. Knepley @*/ 6209d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6210d71ae5a4SJacob Faibussowitsch { 6211e5e52638SMatthew G. Knepley PetscDS ds; 621245480ffeSMatthew G. Knepley PetscInt Nds, n; 6213f17e8794SMatthew G. Knepley 6214c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6215c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6216c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6217c73cfb54SMatthew G. Knepley dm->dim = dim; 6218d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 62199566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 622045480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 62219566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds)); 62229566063dSJacob Faibussowitsch if (ds->dimEmbed < 0) PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 622345480ffeSMatthew G. Knepley } 6224d17bd122SMatthew G. Knepley } 6225c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6226c73cfb54SMatthew G. Knepley } 6227c73cfb54SMatthew G. Knepley 6228793f3fe5SMatthew G. Knepley /*@ 6229793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6230793f3fe5SMatthew G. Knepley 6231d083f849SBarry Smith Collective on dm 6232793f3fe5SMatthew G. Knepley 6233793f3fe5SMatthew G. Knepley Input Parameters: 6234bb7acecfSBarry Smith + dm - the `DM` 6235793f3fe5SMatthew G. Knepley - dim - the dimension 6236793f3fe5SMatthew G. Knepley 6237793f3fe5SMatthew G. Knepley Output Parameters: 6238793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6239aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6240793f3fe5SMatthew G. Knepley 6241793f3fe5SMatthew G. Knepley Note: 6242793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6243a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6244793f3fe5SMatthew G. Knepley then the interval is empty. 6245793f3fe5SMatthew G. Knepley 6246793f3fe5SMatthew G. Knepley Level: intermediate 6247793f3fe5SMatthew G. Knepley 6248db781477SPatrick Sanan .seealso: `DMPLEX`, `DMPlexGetDepthStratum()`, `DMPlexGetHeightStratum()` 6249793f3fe5SMatthew G. Knepley @*/ 6250d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6251d71ae5a4SJacob Faibussowitsch { 6252793f3fe5SMatthew G. Knepley PetscInt d; 6253793f3fe5SMatthew G. Knepley 6254793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6255793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 62569566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &d)); 62577a8be351SBarry Smith PetscCheck((dim >= 0) && (dim <= d), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %" PetscInt_FMT, dim); 6258dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getdimpoints, dim, pStart, pEnd); 6259793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 6260793f3fe5SMatthew G. Knepley } 6261793f3fe5SMatthew G. Knepley 62626636e97aSMatthew G Knepley /*@ 6263bb7acecfSBarry Smith DMGetOutputDM - Retrieve the `DM` associated with the layout for output 6264f4d763aaSMatthew G. Knepley 62658f700142SStefano Zampini Collective on dm 62668f700142SStefano Zampini 6267f4d763aaSMatthew G. Knepley Input Parameter: 6268bb7acecfSBarry Smith . dm - The original `DM` 6269f4d763aaSMatthew G. Knepley 6270f4d763aaSMatthew G. Knepley Output Parameter: 6271bb7acecfSBarry Smith . odm - The `DM` which provides the layout for output 6272f4d763aaSMatthew G. Knepley 6273f4d763aaSMatthew G. Knepley Level: intermediate 6274f4d763aaSMatthew G. Knepley 6275bb7acecfSBarry Smith Note: 6276bb7acecfSBarry Smith In some situations the vector obtained with `DMCreateGlobalVector()` excludes points for degrees of freedom that are associated with fixed (Dirichelet) boundary 6277bb7acecfSBarry 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 6278bb7acecfSBarry Smith locations for those dof so that they can be output to a file or other viewer along with the unconstrained dof. 6279bb7acecfSBarry Smith 6280bb7acecfSBarry Smith .seealso: `VecView()`, `DMGetGlobalSection()`, `DMCreateGlobalVector()`, `PetscSectionHasConstraints()`, `DMSetGlobalSection()` 6281f4d763aaSMatthew G. Knepley @*/ 6282d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 6283d71ae5a4SJacob Faibussowitsch { 6284c26acbdeSMatthew G. Knepley PetscSection section; 62852d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 628614f150ffSMatthew G. Knepley 628714f150ffSMatthew G. Knepley PetscFunctionBegin; 628814f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 628914f150ffSMatthew G. Knepley PetscValidPointer(odm, 2); 62909566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 62919566063dSJacob Faibussowitsch PetscCall(PetscSectionHasConstraints(section, &hasConstraints)); 62929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)dm))); 62932d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 6294c26acbdeSMatthew G. Knepley *odm = dm; 6295c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 6296c26acbdeSMatthew G. Knepley } 629714f150ffSMatthew G. Knepley if (!dm->dmBC) { 6298c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 629914f150ffSMatthew G. Knepley PetscSF sf; 630014f150ffSMatthew G. Knepley 63019566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->dmBC)); 63029566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, dm->dmBC)); 63039566063dSJacob Faibussowitsch PetscCall(PetscSectionClone(section, &newSection)); 63049566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm->dmBC, newSection)); 63059566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&newSection)); 63069566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm->dmBC, &sf)); 63079566063dSJacob Faibussowitsch PetscCall(PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection)); 63089566063dSJacob Faibussowitsch PetscCall(DMSetGlobalSection(dm->dmBC, gsection)); 63099566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&gsection)); 631014f150ffSMatthew G. Knepley } 631114f150ffSMatthew G. Knepley *odm = dm->dmBC; 631214f150ffSMatthew G. Knepley PetscFunctionReturn(0); 631314f150ffSMatthew G. Knepley } 6314f4d763aaSMatthew G. Knepley 6315f4d763aaSMatthew G. Knepley /*@ 6316cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 6317f4d763aaSMatthew G. Knepley 6318f4d763aaSMatthew G. Knepley Input Parameter: 6319bb7acecfSBarry Smith . dm - The original `DM` 6320f4d763aaSMatthew G. Knepley 6321cdb7a50dSMatthew G. Knepley Output Parameters: 6322cdb7a50dSMatthew G. Knepley + num - The output sequence number 6323cdb7a50dSMatthew G. Knepley - val - The output sequence value 6324f4d763aaSMatthew G. Knepley 6325f4d763aaSMatthew G. Knepley Level: intermediate 6326f4d763aaSMatthew G. Knepley 6327bb7acecfSBarry Smith Note: 6328bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6329bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6330bb7acecfSBarry Smith 6331bb7acecfSBarry Smith Developer Note: 6332bb7acecfSBarry Smith The `DM` serves as a convenient place to store the current iteration value. The iteration is not 6333bb7acecfSBarry Smith not directly related to the `DM`. 6334f4d763aaSMatthew G. Knepley 6335db781477SPatrick Sanan .seealso: `VecView()` 6336f4d763aaSMatthew G. Knepley @*/ 6337d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 6338d71ae5a4SJacob Faibussowitsch { 6339f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6340f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63419371c9d4SSatish Balay if (num) { 63429371c9d4SSatish Balay PetscValidIntPointer(num, 2); 63439371c9d4SSatish Balay *num = dm->outputSequenceNum; 63449371c9d4SSatish Balay } 63459371c9d4SSatish Balay if (val) { 63469371c9d4SSatish Balay PetscValidRealPointer(val, 3); 63479371c9d4SSatish Balay *val = dm->outputSequenceVal; 63489371c9d4SSatish Balay } 6349f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 6350f4d763aaSMatthew G. Knepley } 6351f4d763aaSMatthew G. Knepley 6352f4d763aaSMatthew G. Knepley /*@ 6353cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 6354f4d763aaSMatthew G. Knepley 6355f4d763aaSMatthew G. Knepley Input Parameters: 6356bb7acecfSBarry Smith + dm - The original `DM` 6357cdb7a50dSMatthew G. Knepley . num - The output sequence number 6358cdb7a50dSMatthew G. Knepley - val - The output sequence value 6359f4d763aaSMatthew G. Knepley 6360f4d763aaSMatthew G. Knepley Level: intermediate 6361f4d763aaSMatthew G. Knepley 6362bb7acecfSBarry Smith Note: 6363bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6364bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6365f4d763aaSMatthew G. Knepley 6366db781477SPatrick Sanan .seealso: `VecView()` 6367f4d763aaSMatthew G. Knepley @*/ 6368d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 6369d71ae5a4SJacob Faibussowitsch { 6370f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6371f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6372f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 6373cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 6374cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 6375cdb7a50dSMatthew G. Knepley } 6376cdb7a50dSMatthew G. Knepley 6377cdb7a50dSMatthew G. Knepley /*@C 6378bb7acecfSBarry Smith DMOutputSequenceLoad - Retrieve the sequence value from a `PetscViewer` 6379cdb7a50dSMatthew G. Knepley 6380cdb7a50dSMatthew G. Knepley Input Parameters: 6381bb7acecfSBarry Smith + dm - The original `DM` 6382cdb7a50dSMatthew G. Knepley . name - The sequence name 6383cdb7a50dSMatthew G. Knepley - num - The output sequence number 6384cdb7a50dSMatthew G. Knepley 6385cdb7a50dSMatthew G. Knepley Output Parameter: 6386cdb7a50dSMatthew G. Knepley . val - The output sequence value 6387cdb7a50dSMatthew G. Knepley 6388cdb7a50dSMatthew G. Knepley Level: intermediate 6389cdb7a50dSMatthew G. Knepley 6390bb7acecfSBarry Smith Note: 6391bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6392bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6393bb7acecfSBarry Smith 6394bb7acecfSBarry Smith Developer Note: 6395bb7acecfSBarry Smith It is unclear at the user API level why a `DM` is needed as input 6396cdb7a50dSMatthew G. Knepley 6397db781477SPatrick Sanan .seealso: `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6398cdb7a50dSMatthew G. Knepley @*/ 6399d71ae5a4SJacob Faibussowitsch PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 6400d71ae5a4SJacob Faibussowitsch { 6401cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 6402cdb7a50dSMatthew G. Knepley 6403cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 6404cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6405cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6406064a246eSJacob Faibussowitsch PetscValidRealPointer(val, 5); 64079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6408cdb7a50dSMatthew G. Knepley if (ishdf5) { 6409cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6410cdb7a50dSMatthew G. Knepley PetscScalar value; 6411cdb7a50dSMatthew G. Knepley 64129566063dSJacob Faibussowitsch PetscCall(DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer)); 64134aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 6414cdb7a50dSMatthew G. Knepley #endif 6415cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 6416f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 6417f4d763aaSMatthew G. Knepley } 64188e4ac7eaSMatthew G. Knepley 64198e4ac7eaSMatthew G. Knepley /*@ 6420bb7acecfSBarry Smith DMGetUseNatural - Get the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 64218e4ac7eaSMatthew G. Knepley 64228e4ac7eaSMatthew G. Knepley Not collective 64238e4ac7eaSMatthew G. Knepley 64248e4ac7eaSMatthew G. Knepley Input Parameter: 6425bb7acecfSBarry Smith . dm - The `DM` 64268e4ac7eaSMatthew G. Knepley 64278e4ac7eaSMatthew G. Knepley Output Parameter: 6428bb7acecfSBarry Smith . useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 64298e4ac7eaSMatthew G. Knepley 64308e4ac7eaSMatthew G. Knepley Level: beginner 64318e4ac7eaSMatthew G. Knepley 6432db781477SPatrick Sanan .seealso: `DMSetUseNatural()`, `DMCreate()` 64338e4ac7eaSMatthew G. Knepley @*/ 6434d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 6435d71ae5a4SJacob Faibussowitsch { 64368e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 64378e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6438534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 64398e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 64408e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 64418e4ac7eaSMatthew G. Knepley } 64428e4ac7eaSMatthew G. Knepley 64438e4ac7eaSMatthew G. Knepley /*@ 6444bb7acecfSBarry Smith DMSetUseNatural - Set the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 64458e4ac7eaSMatthew G. Knepley 64468e4ac7eaSMatthew G. Knepley Collective on dm 64478e4ac7eaSMatthew G. Knepley 64488e4ac7eaSMatthew G. Knepley Input Parameters: 6449bb7acecfSBarry Smith + dm - The `DM` 6450bb7acecfSBarry Smith - useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 64518e4ac7eaSMatthew G. Knepley 6452bb7acecfSBarry Smith Note: 6453bb7acecfSBarry Smith This also causes the map to be build after `DMCreateSubDM()` and `DMCreateSuperDM()` 64545d3b26e6SMatthew G. Knepley 64558e4ac7eaSMatthew G. Knepley Level: beginner 64568e4ac7eaSMatthew G. Knepley 6457db781477SPatrick Sanan .seealso: `DMGetUseNatural()`, `DMCreate()`, `DMPlexDistribute()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 64588e4ac7eaSMatthew G. Knepley @*/ 6459d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 6460d71ae5a4SJacob Faibussowitsch { 64618e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 64628e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64638833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 64648e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 64658e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 64668e4ac7eaSMatthew G. Knepley } 6467c58f1c22SToby Isaac 6468c58f1c22SToby Isaac /*@C 6469bb7acecfSBarry Smith DMCreateLabel - Create a label of the given name if it does not already exist in the `DM` 6470c58f1c22SToby Isaac 6471c58f1c22SToby Isaac Not Collective 6472c58f1c22SToby Isaac 6473c58f1c22SToby Isaac Input Parameters: 6474bb7acecfSBarry Smith + dm - The `DM` object 6475c58f1c22SToby Isaac - name - The label name 6476c58f1c22SToby Isaac 6477c58f1c22SToby Isaac Level: intermediate 6478c58f1c22SToby Isaac 6479db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6480c58f1c22SToby Isaac @*/ 6481d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabel(DM dm, const char name[]) 6482d71ae5a4SJacob Faibussowitsch { 64835d80c0bfSVaclav Hapla PetscBool flg; 64845d80c0bfSVaclav Hapla DMLabel label; 6485c58f1c22SToby Isaac 6486c58f1c22SToby Isaac PetscFunctionBegin; 6487c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6488c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 64899566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 6490c58f1c22SToby Isaac if (!flg) { 64919566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 64929566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 64939566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 6494c58f1c22SToby Isaac } 6495c58f1c22SToby Isaac PetscFunctionReturn(0); 6496c58f1c22SToby Isaac } 6497c58f1c22SToby Isaac 6498c58f1c22SToby Isaac /*@C 6499bb7acecfSBarry 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. 65000fdc7489SMatthew Knepley 65010fdc7489SMatthew Knepley Not Collective 65020fdc7489SMatthew Knepley 65030fdc7489SMatthew Knepley Input Parameters: 6504bb7acecfSBarry Smith + dm - The `DM` object 65050fdc7489SMatthew Knepley . l - The index for the label 65060fdc7489SMatthew Knepley - name - The label name 65070fdc7489SMatthew Knepley 65080fdc7489SMatthew Knepley Level: intermediate 65090fdc7489SMatthew Knepley 6510db781477SPatrick Sanan .seealso: `DMCreateLabel()`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 65110fdc7489SMatthew Knepley @*/ 6512d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 6513d71ae5a4SJacob Faibussowitsch { 65140fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 65150fdc7489SMatthew Knepley DMLabel label; 65160fdc7489SMatthew Knepley PetscInt Nl, m; 65170fdc7489SMatthew Knepley PetscBool flg, match; 65180fdc7489SMatthew Knepley const char *lname; 65190fdc7489SMatthew Knepley 65200fdc7489SMatthew Knepley PetscFunctionBegin; 65210fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6522064a246eSJacob Faibussowitsch PetscValidCharPointer(name, 3); 65239566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 65240fdc7489SMatthew Knepley if (!flg) { 65259566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 65269566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 65279566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 65280fdc7489SMatthew Knepley } 65299566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 653063a3b9bcSJacob Faibussowitsch PetscCheck(l < Nl, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", l, Nl); 65310fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 65329566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)orig->label, &lname)); 65339566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &match)); 65340fdc7489SMatthew Knepley if (match) break; 65350fdc7489SMatthew Knepley } 65360fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 65370fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 65380fdc7489SMatthew Knepley else prev->next = orig->next; 65390fdc7489SMatthew Knepley if (!l) { 65400fdc7489SMatthew Knepley orig->next = dm->labels; 65410fdc7489SMatthew Knepley dm->labels = orig; 65420fdc7489SMatthew Knepley } else { 65439371c9d4SSatish Balay for (m = 0, prev = dm->labels; m < l - 1; ++m, prev = prev->next) 65449371c9d4SSatish Balay ; 65450fdc7489SMatthew Knepley orig->next = prev->next; 65460fdc7489SMatthew Knepley prev->next = orig; 65470fdc7489SMatthew Knepley } 65480fdc7489SMatthew Knepley PetscFunctionReturn(0); 65490fdc7489SMatthew Knepley } 65500fdc7489SMatthew Knepley 65510fdc7489SMatthew Knepley /*@C 6552bb7acecfSBarry Smith DMGetLabelValue - Get the value in a `DMLabel` for the given point, with -1 as the default 6553c58f1c22SToby Isaac 6554c58f1c22SToby Isaac Not Collective 6555c58f1c22SToby Isaac 6556c58f1c22SToby Isaac Input Parameters: 6557bb7acecfSBarry Smith + dm - The `DM` object 6558c58f1c22SToby Isaac . name - The label name 6559c58f1c22SToby Isaac - point - The mesh point 6560c58f1c22SToby Isaac 6561c58f1c22SToby Isaac Output Parameter: 6562c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 6563c58f1c22SToby Isaac 6564c58f1c22SToby Isaac Level: beginner 6565c58f1c22SToby Isaac 6566db781477SPatrick Sanan .seealso: `DMLabelGetValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6567c58f1c22SToby Isaac @*/ 6568d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 6569d71ae5a4SJacob Faibussowitsch { 6570c58f1c22SToby Isaac DMLabel label; 6571c58f1c22SToby Isaac 6572c58f1c22SToby Isaac PetscFunctionBegin; 6573c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6574c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 65759566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 65767a8be351SBarry Smith PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 65779566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, point, value)); 6578c58f1c22SToby Isaac PetscFunctionReturn(0); 6579c58f1c22SToby Isaac } 6580c58f1c22SToby Isaac 6581c58f1c22SToby Isaac /*@C 6582bb7acecfSBarry Smith DMSetLabelValue - Add a point to a `DMLabel` with given value 6583c58f1c22SToby Isaac 6584c58f1c22SToby Isaac Not Collective 6585c58f1c22SToby Isaac 6586c58f1c22SToby Isaac Input Parameters: 6587bb7acecfSBarry Smith + dm - The `DM` object 6588c58f1c22SToby Isaac . name - The label name 6589c58f1c22SToby Isaac . point - The mesh point 6590c58f1c22SToby Isaac - value - The label value for this point 6591c58f1c22SToby Isaac 6592c58f1c22SToby Isaac Output Parameter: 6593c58f1c22SToby Isaac 6594c58f1c22SToby Isaac Level: beginner 6595c58f1c22SToby Isaac 6596db781477SPatrick Sanan .seealso: `DMLabelSetValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6597c58f1c22SToby Isaac @*/ 6598d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6599d71ae5a4SJacob Faibussowitsch { 6600c58f1c22SToby Isaac DMLabel label; 6601c58f1c22SToby Isaac 6602c58f1c22SToby Isaac PetscFunctionBegin; 6603c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6604c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 66059566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6606c58f1c22SToby Isaac if (!label) { 66079566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 66089566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6609c58f1c22SToby Isaac } 66109566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, point, value)); 6611c58f1c22SToby Isaac PetscFunctionReturn(0); 6612c58f1c22SToby Isaac } 6613c58f1c22SToby Isaac 6614c58f1c22SToby Isaac /*@C 6615bb7acecfSBarry Smith DMClearLabelValue - Remove a point from a `DMLabel` with given value 6616c58f1c22SToby Isaac 6617c58f1c22SToby Isaac Not Collective 6618c58f1c22SToby Isaac 6619c58f1c22SToby Isaac Input Parameters: 6620bb7acecfSBarry Smith + dm - The `DM` object 6621c58f1c22SToby Isaac . name - The label name 6622c58f1c22SToby Isaac . point - The mesh point 6623c58f1c22SToby Isaac - value - The label value for this point 6624c58f1c22SToby Isaac 6625c58f1c22SToby Isaac Level: beginner 6626c58f1c22SToby Isaac 6627db781477SPatrick Sanan .seealso: `DMLabelClearValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6628c58f1c22SToby Isaac @*/ 6629d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6630d71ae5a4SJacob Faibussowitsch { 6631c58f1c22SToby Isaac DMLabel label; 6632c58f1c22SToby Isaac 6633c58f1c22SToby Isaac PetscFunctionBegin; 6634c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6635c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 66369566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6637c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 66389566063dSJacob Faibussowitsch PetscCall(DMLabelClearValue(label, point, value)); 6639c58f1c22SToby Isaac PetscFunctionReturn(0); 6640c58f1c22SToby Isaac } 6641c58f1c22SToby Isaac 6642c58f1c22SToby Isaac /*@C 6643bb7acecfSBarry Smith DMGetLabelSize - Get the value of `DMLabelGetNumValues()` of a `DMLabel` in the `DM` 6644c58f1c22SToby Isaac 6645c58f1c22SToby Isaac Not Collective 6646c58f1c22SToby Isaac 6647c58f1c22SToby Isaac Input Parameters: 6648bb7acecfSBarry Smith + dm - The `DM` object 6649c58f1c22SToby Isaac - name - The label name 6650c58f1c22SToby Isaac 6651c58f1c22SToby Isaac Output Parameter: 6652c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 6653c58f1c22SToby Isaac 6654c58f1c22SToby Isaac Level: beginner 6655c58f1c22SToby Isaac 6656bb7acecfSBarry Smith Developer Note: 6657bb7acecfSBarry Smith This should be renamed to something like `DMGetLabelNumValues()` or removed. 6658bb7acecfSBarry Smith 6659bb7acecfSBarry Smith .seealso: `DMLabelGetNumValues()`, `DMSetLabelValue()`, `DMGetLabel()` 6660c58f1c22SToby Isaac @*/ 6661d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 6662d71ae5a4SJacob Faibussowitsch { 6663c58f1c22SToby Isaac DMLabel label; 6664c58f1c22SToby Isaac 6665c58f1c22SToby Isaac PetscFunctionBegin; 6666c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6667c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6668534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 66699566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6670c58f1c22SToby Isaac *size = 0; 6671c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 66729566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, size)); 6673c58f1c22SToby Isaac PetscFunctionReturn(0); 6674c58f1c22SToby Isaac } 6675c58f1c22SToby Isaac 6676c58f1c22SToby Isaac /*@C 6677bb7acecfSBarry Smith DMGetLabelIdIS - Get the `DMLabelGetValueIS()` from a `DMLabel` in the `DM` 6678c58f1c22SToby Isaac 6679c58f1c22SToby Isaac Not Collective 6680c58f1c22SToby Isaac 6681c58f1c22SToby Isaac Input Parameters: 6682bb7acecfSBarry Smith + mesh - The `DM` object 6683c58f1c22SToby Isaac - name - The label name 6684c58f1c22SToby Isaac 6685c58f1c22SToby Isaac Output Parameter: 6686c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 6687c58f1c22SToby Isaac 6688c58f1c22SToby Isaac Level: beginner 6689c58f1c22SToby Isaac 6690db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMGetLabelSize()` 6691c58f1c22SToby Isaac @*/ 6692d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 6693d71ae5a4SJacob Faibussowitsch { 6694c58f1c22SToby Isaac DMLabel label; 6695c58f1c22SToby Isaac 6696c58f1c22SToby Isaac PetscFunctionBegin; 6697c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6698c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6699c58f1c22SToby Isaac PetscValidPointer(ids, 3); 67009566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6701c58f1c22SToby Isaac *ids = NULL; 6702dab2e251SBlaise Bourdin if (label) { 67039566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, ids)); 6704dab2e251SBlaise Bourdin } else { 6705dab2e251SBlaise Bourdin /* returning an empty IS */ 67069566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 0, NULL, PETSC_USE_POINTER, ids)); 6707dab2e251SBlaise Bourdin } 6708c58f1c22SToby Isaac PetscFunctionReturn(0); 6709c58f1c22SToby Isaac } 6710c58f1c22SToby Isaac 6711c58f1c22SToby Isaac /*@C 6712c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 6713c58f1c22SToby Isaac 6714c58f1c22SToby Isaac Not Collective 6715c58f1c22SToby Isaac 6716c58f1c22SToby Isaac Input Parameters: 6717bb7acecfSBarry Smith + dm - The `DM` object 6718c58f1c22SToby Isaac . name - The label name 6719c58f1c22SToby Isaac - value - The stratum value 6720c58f1c22SToby Isaac 6721c58f1c22SToby Isaac Output Parameter: 6722bb7acecfSBarry Smith . size - The number of points, also called the stratum size 6723c58f1c22SToby Isaac 6724c58f1c22SToby Isaac Level: beginner 6725c58f1c22SToby Isaac 6726db781477SPatrick Sanan .seealso: `DMLabelGetStratumSize()`, `DMGetLabelSize()`, `DMGetLabelIds()` 6727c58f1c22SToby Isaac @*/ 6728d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 6729d71ae5a4SJacob Faibussowitsch { 6730c58f1c22SToby Isaac DMLabel label; 6731c58f1c22SToby Isaac 6732c58f1c22SToby Isaac PetscFunctionBegin; 6733c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6734c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6735534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 67369566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6737c58f1c22SToby Isaac *size = 0; 6738c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 67399566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, value, size)); 6740c58f1c22SToby Isaac PetscFunctionReturn(0); 6741c58f1c22SToby Isaac } 6742c58f1c22SToby Isaac 6743c58f1c22SToby Isaac /*@C 6744c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 6745c58f1c22SToby Isaac 6746c58f1c22SToby Isaac Not Collective 6747c58f1c22SToby Isaac 6748c58f1c22SToby Isaac Input Parameters: 6749bb7acecfSBarry Smith + dm - The `DM` object 6750c58f1c22SToby Isaac . name - The label name 6751c58f1c22SToby Isaac - value - The stratum value 6752c58f1c22SToby Isaac 6753c58f1c22SToby Isaac Output Parameter: 6754c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 6755c58f1c22SToby Isaac 6756c58f1c22SToby Isaac Level: beginner 6757c58f1c22SToby Isaac 6758db781477SPatrick Sanan .seealso: `DMLabelGetStratumIS()`, `DMGetStratumSize()` 6759c58f1c22SToby Isaac @*/ 6760d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 6761d71ae5a4SJacob Faibussowitsch { 6762c58f1c22SToby Isaac DMLabel label; 6763c58f1c22SToby Isaac 6764c58f1c22SToby Isaac PetscFunctionBegin; 6765c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6766c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6767c58f1c22SToby Isaac PetscValidPointer(points, 4); 67689566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6769c58f1c22SToby Isaac *points = NULL; 6770c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 67719566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, value, points)); 6772c58f1c22SToby Isaac PetscFunctionReturn(0); 6773c58f1c22SToby Isaac } 6774c58f1c22SToby Isaac 67754de306b1SToby Isaac /*@C 67769044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 67774de306b1SToby Isaac 67784de306b1SToby Isaac Not Collective 67794de306b1SToby Isaac 67804de306b1SToby Isaac Input Parameters: 6781bb7acecfSBarry Smith + dm - The `DM` object 67824de306b1SToby Isaac . name - The label name 67834de306b1SToby Isaac . value - The stratum value 67844de306b1SToby Isaac - points - The stratum points 67854de306b1SToby Isaac 67864de306b1SToby Isaac Level: beginner 67874de306b1SToby Isaac 6788bb7acecfSBarry Smith .seealso: `DMLabel`, `DMClearLabelStratum()`, `DMLabelClearStratum()`, `DMLabelSetStratumIS()`, `DMGetStratumSize()` 67894de306b1SToby Isaac @*/ 6790d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 6791d71ae5a4SJacob Faibussowitsch { 67924de306b1SToby Isaac DMLabel label; 67934de306b1SToby Isaac 67944de306b1SToby Isaac PetscFunctionBegin; 67954de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67964de306b1SToby Isaac PetscValidCharPointer(name, 2); 67974de306b1SToby Isaac PetscValidPointer(points, 4); 67989566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 67994de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 68009566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, points)); 68014de306b1SToby Isaac PetscFunctionReturn(0); 68024de306b1SToby Isaac } 68034de306b1SToby Isaac 6804c58f1c22SToby Isaac /*@C 6805bb7acecfSBarry Smith DMClearLabelStratum - Remove all points from a stratum from a `DMLabel` 6806c58f1c22SToby Isaac 6807c58f1c22SToby Isaac Not Collective 6808c58f1c22SToby Isaac 6809c58f1c22SToby Isaac Input Parameters: 6810bb7acecfSBarry Smith + dm - The `DM` object 6811c58f1c22SToby Isaac . name - The label name 6812c58f1c22SToby Isaac - value - The label value for this point 6813c58f1c22SToby Isaac 6814c58f1c22SToby Isaac Output Parameter: 6815c58f1c22SToby Isaac 6816c58f1c22SToby Isaac Level: beginner 6817c58f1c22SToby Isaac 6818bb7acecfSBarry Smith .seealso: `DMLabel`, `DMLabelClearStratum()`, `DMSetLabelValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6819c58f1c22SToby Isaac @*/ 6820d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 6821d71ae5a4SJacob Faibussowitsch { 6822c58f1c22SToby Isaac DMLabel label; 6823c58f1c22SToby Isaac 6824c58f1c22SToby Isaac PetscFunctionBegin; 6825c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6826c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 68279566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6828c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 68299566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 6830c58f1c22SToby Isaac PetscFunctionReturn(0); 6831c58f1c22SToby Isaac } 6832c58f1c22SToby Isaac 6833c58f1c22SToby Isaac /*@ 6834bb7acecfSBarry Smith DMGetNumLabels - Return the number of labels defined by on the `DM` 6835c58f1c22SToby Isaac 6836c58f1c22SToby Isaac Not Collective 6837c58f1c22SToby Isaac 6838c58f1c22SToby Isaac Input Parameter: 6839bb7acecfSBarry Smith . dm - The `DM` object 6840c58f1c22SToby Isaac 6841c58f1c22SToby Isaac Output Parameter: 6842c58f1c22SToby Isaac . numLabels - the number of Labels 6843c58f1c22SToby Isaac 6844c58f1c22SToby Isaac Level: intermediate 6845c58f1c22SToby Isaac 6846bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabelByNum()`, `DMGetLabelName()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6847c58f1c22SToby Isaac @*/ 6848d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 6849d71ae5a4SJacob Faibussowitsch { 68505d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6851c58f1c22SToby Isaac PetscInt n = 0; 6852c58f1c22SToby Isaac 6853c58f1c22SToby Isaac PetscFunctionBegin; 6854c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6855534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 68569371c9d4SSatish Balay while (next) { 68579371c9d4SSatish Balay ++n; 68589371c9d4SSatish Balay next = next->next; 68599371c9d4SSatish Balay } 6860c58f1c22SToby Isaac *numLabels = n; 6861c58f1c22SToby Isaac PetscFunctionReturn(0); 6862c58f1c22SToby Isaac } 6863c58f1c22SToby Isaac 6864c58f1c22SToby Isaac /*@C 6865c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 6866c58f1c22SToby Isaac 6867c58f1c22SToby Isaac Not Collective 6868c58f1c22SToby Isaac 6869c58f1c22SToby Isaac Input Parameters: 6870bb7acecfSBarry Smith + dm - The `DM` object 6871c58f1c22SToby Isaac - n - the label number 6872c58f1c22SToby Isaac 6873c58f1c22SToby Isaac Output Parameter: 6874c58f1c22SToby Isaac . name - the label name 6875c58f1c22SToby Isaac 6876c58f1c22SToby Isaac Level: intermediate 6877c58f1c22SToby Isaac 6878bb7acecfSBarry Smith Developer Note: 6879bb7acecfSBarry Smith Some of the functions that appropriate on labels using their number have the suffix ByNum, others do not. 6880bb7acecfSBarry Smith 6881bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabelByNum()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6882c58f1c22SToby Isaac @*/ 6883d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 6884d71ae5a4SJacob Faibussowitsch { 68855d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6886c58f1c22SToby Isaac PetscInt l = 0; 6887c58f1c22SToby Isaac 6888c58f1c22SToby Isaac PetscFunctionBegin; 6889c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6890c58f1c22SToby Isaac PetscValidPointer(name, 3); 6891c58f1c22SToby Isaac while (next) { 6892c58f1c22SToby Isaac if (l == n) { 68939566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, name)); 6894c58f1c22SToby Isaac PetscFunctionReturn(0); 6895c58f1c22SToby Isaac } 6896c58f1c22SToby Isaac ++l; 6897c58f1c22SToby Isaac next = next->next; 6898c58f1c22SToby Isaac } 689963a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 6900c58f1c22SToby Isaac } 6901c58f1c22SToby Isaac 6902c58f1c22SToby Isaac /*@C 6903bb7acecfSBarry Smith DMHasLabel - Determine whether the `DM` has a label of a given name 6904c58f1c22SToby Isaac 6905c58f1c22SToby Isaac Not Collective 6906c58f1c22SToby Isaac 6907c58f1c22SToby Isaac Input Parameters: 6908bb7acecfSBarry Smith + dm - The `DM` object 6909c58f1c22SToby Isaac - name - The label name 6910c58f1c22SToby Isaac 6911c58f1c22SToby Isaac Output Parameter: 6912bb7acecfSBarry Smith . hasLabel - `PETSC_TRUE` if the label is present 6913c58f1c22SToby Isaac 6914c58f1c22SToby Isaac Level: intermediate 6915c58f1c22SToby Isaac 6916bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabel()`, `DMGetLabelByNum()`, `DMCreateLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6917c58f1c22SToby Isaac @*/ 6918d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 6919d71ae5a4SJacob Faibussowitsch { 69205d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6921d67d17b1SMatthew G. Knepley const char *lname; 6922c58f1c22SToby Isaac 6923c58f1c22SToby Isaac PetscFunctionBegin; 6924c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6925c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6926534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 6927c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 6928c58f1c22SToby Isaac while (next) { 69299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 69309566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, hasLabel)); 6931c58f1c22SToby Isaac if (*hasLabel) break; 6932c58f1c22SToby Isaac next = next->next; 6933c58f1c22SToby Isaac } 6934c58f1c22SToby Isaac PetscFunctionReturn(0); 6935c58f1c22SToby Isaac } 6936c58f1c22SToby Isaac 6937c58f1c22SToby Isaac /*@C 6938bb7acecfSBarry Smith DMGetLabel - Return the label of a given name, or NULL, from a `DM` 6939c58f1c22SToby Isaac 6940c58f1c22SToby Isaac Not Collective 6941c58f1c22SToby Isaac 6942c58f1c22SToby Isaac Input Parameters: 6943bb7acecfSBarry Smith + dm - The `DM` object 6944c58f1c22SToby Isaac - name - The label name 6945c58f1c22SToby Isaac 6946c58f1c22SToby Isaac Output Parameter: 6947bb7acecfSBarry Smith . label - The `DMLabel`, or NULL if the label is absent 6948c58f1c22SToby Isaac 6949bb7acecfSBarry Smith Default labels in a `DMPLEX`: 6950bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 6951bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 6952bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 6953bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 6954bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 6955bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 69566d7c9049SMatthew G. Knepley 6957c58f1c22SToby Isaac Level: intermediate 6958c58f1c22SToby Isaac 6959bb7acecfSBarry Smith .seealso: `DMLabel`, `DMHasLabel()`, `DMGetLabelByNum()`, `DMAddLabel()`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 6960c58f1c22SToby Isaac @*/ 6961d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 6962d71ae5a4SJacob Faibussowitsch { 69635d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6964c58f1c22SToby Isaac PetscBool hasLabel; 6965d67d17b1SMatthew G. Knepley const char *lname; 6966c58f1c22SToby Isaac 6967c58f1c22SToby Isaac PetscFunctionBegin; 6968c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6969c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6970c58f1c22SToby Isaac PetscValidPointer(label, 3); 6971c58f1c22SToby Isaac *label = NULL; 6972c58f1c22SToby Isaac while (next) { 69739566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 69749566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 6975c58f1c22SToby Isaac if (hasLabel) { 6976c58f1c22SToby Isaac *label = next->label; 6977c58f1c22SToby Isaac break; 6978c58f1c22SToby Isaac } 6979c58f1c22SToby Isaac next = next->next; 6980c58f1c22SToby Isaac } 6981c58f1c22SToby Isaac PetscFunctionReturn(0); 6982c58f1c22SToby Isaac } 6983c58f1c22SToby Isaac 6984c58f1c22SToby Isaac /*@C 6985bb7acecfSBarry Smith DMGetLabelByNum - Return the nth label on a `DM` 6986c58f1c22SToby Isaac 6987c58f1c22SToby Isaac Not Collective 6988c58f1c22SToby Isaac 6989c58f1c22SToby Isaac Input Parameters: 6990bb7acecfSBarry Smith + dm - The `DM` object 6991c58f1c22SToby Isaac - n - the label number 6992c58f1c22SToby Isaac 6993c58f1c22SToby Isaac Output Parameter: 6994c58f1c22SToby Isaac . label - the label 6995c58f1c22SToby Isaac 6996c58f1c22SToby Isaac Level: intermediate 6997c58f1c22SToby Isaac 6998bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6999c58f1c22SToby Isaac @*/ 7000d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7001d71ae5a4SJacob Faibussowitsch { 70025d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7003c58f1c22SToby Isaac PetscInt l = 0; 7004c58f1c22SToby Isaac 7005c58f1c22SToby Isaac PetscFunctionBegin; 7006c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7007c58f1c22SToby Isaac PetscValidPointer(label, 3); 7008c58f1c22SToby Isaac while (next) { 7009c58f1c22SToby Isaac if (l == n) { 7010c58f1c22SToby Isaac *label = next->label; 7011c58f1c22SToby Isaac PetscFunctionReturn(0); 7012c58f1c22SToby Isaac } 7013c58f1c22SToby Isaac ++l; 7014c58f1c22SToby Isaac next = next->next; 7015c58f1c22SToby Isaac } 701663a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7017c58f1c22SToby Isaac } 7018c58f1c22SToby Isaac 7019c58f1c22SToby Isaac /*@C 7020bb7acecfSBarry Smith DMAddLabel - Add the label to this `DM` 7021c58f1c22SToby Isaac 7022c58f1c22SToby Isaac Not Collective 7023c58f1c22SToby Isaac 7024c58f1c22SToby Isaac Input Parameters: 7025bb7acecfSBarry Smith + dm - The `DM` object 7026bb7acecfSBarry Smith - label - The `DMLabel` 7027c58f1c22SToby Isaac 7028c58f1c22SToby Isaac Level: developer 7029c58f1c22SToby Isaac 7030bb7acecfSBarry Smith .seealso: `DMLabel`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7031c58f1c22SToby Isaac @*/ 7032d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7033d71ae5a4SJacob Faibussowitsch { 70345d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7035c58f1c22SToby Isaac PetscBool hasLabel; 7036d67d17b1SMatthew G. Knepley const char *lname; 70375d80c0bfSVaclav Hapla PetscBool flg; 7038c58f1c22SToby Isaac 7039c58f1c22SToby Isaac PetscFunctionBegin; 7040c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70419566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 70429566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, lname, &hasLabel)); 70437a8be351SBarry Smith PetscCheck(!hasLabel, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 70449566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(1, &tmpLabel)); 7045c58f1c22SToby Isaac tmpLabel->label = label; 7046c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 70475d80c0bfSVaclav Hapla for (p = &dm->labels; (l = *p); p = &l->next) { } 70485d80c0bfSVaclav Hapla *p = tmpLabel; 70499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 70509566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 70515d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 70529566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 7053ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 7054c58f1c22SToby Isaac PetscFunctionReturn(0); 7055c58f1c22SToby Isaac } 7056c58f1c22SToby Isaac 7057c58f1c22SToby Isaac /*@C 70584a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 70594a7ee7d0SMatthew G. Knepley 70604a7ee7d0SMatthew G. Knepley Not Collective 70614a7ee7d0SMatthew G. Knepley 70624a7ee7d0SMatthew G. Knepley Input Parameters: 7063bb7acecfSBarry Smith + dm - The `DM` object 7064bb7acecfSBarry Smith - label - The `DMLabel`, having the same name, to substitute 70654a7ee7d0SMatthew G. Knepley 7066bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7067bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7068bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7069bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7070bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7071bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7072bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 70734a7ee7d0SMatthew G. Knepley 70744a7ee7d0SMatthew G. Knepley Level: intermediate 70754a7ee7d0SMatthew G. Knepley 7076bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 70774a7ee7d0SMatthew G. Knepley @*/ 7078d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabel(DM dm, DMLabel label) 7079d71ae5a4SJacob Faibussowitsch { 70804a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 70814a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 70824a7ee7d0SMatthew G. Knepley const char *name, *lname; 70834a7ee7d0SMatthew G. Knepley 70844a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 70854a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70864a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 70879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 70884a7ee7d0SMatthew G. Knepley while (next) { 70899566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 70909566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 70914a7ee7d0SMatthew G. Knepley if (hasLabel) { 70929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 70939566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 70944a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 70959566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 70964a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 70979566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 70984a7ee7d0SMatthew G. Knepley next->label = label; 70994a7ee7d0SMatthew G. Knepley break; 71004a7ee7d0SMatthew G. Knepley } 71014a7ee7d0SMatthew G. Knepley next = next->next; 71024a7ee7d0SMatthew G. Knepley } 71034a7ee7d0SMatthew G. Knepley PetscFunctionReturn(0); 71044a7ee7d0SMatthew G. Knepley } 71054a7ee7d0SMatthew G. Knepley 71064a7ee7d0SMatthew G. Knepley /*@C 7107bb7acecfSBarry Smith DMRemoveLabel - Remove the label given by name from this `DM` 7108c58f1c22SToby Isaac 7109c58f1c22SToby Isaac Not Collective 7110c58f1c22SToby Isaac 7111c58f1c22SToby Isaac Input Parameters: 7112bb7acecfSBarry Smith + dm - The `DM` object 7113c58f1c22SToby Isaac - name - The label name 7114c58f1c22SToby Isaac 7115c58f1c22SToby Isaac Output Parameter: 7116bb7acecfSBarry Smith . label - The `DMLabel`, or NULL if the label is absent. Pass in NULL to call `DMLabelDestroy()` on the label, otherwise the 7117bb7acecfSBarry Smith caller is responsible for calling `DMLabelDestroy()`. 7118c58f1c22SToby Isaac 7119c58f1c22SToby Isaac Level: developer 7120c58f1c22SToby Isaac 7121bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabelBySelf()` 7122c58f1c22SToby Isaac @*/ 7123d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7124d71ae5a4SJacob Faibussowitsch { 712595d578d6SVaclav Hapla DMLabelLink link, *pnext; 7126c58f1c22SToby Isaac PetscBool hasLabel; 7127d67d17b1SMatthew G. Knepley const char *lname; 7128c58f1c22SToby Isaac 7129c58f1c22SToby Isaac PetscFunctionBegin; 7130c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7131e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 7132e5472504SVaclav Hapla if (label) { 7133e5472504SVaclav Hapla PetscValidPointer(label, 3); 7134c58f1c22SToby Isaac *label = NULL; 7135e5472504SVaclav Hapla } 71365d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 71379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)link->label, &lname)); 71389566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7139c58f1c22SToby Isaac if (hasLabel) { 714095d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 71419566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &hasLabel)); 714295d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 71439566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &hasLabel)); 7144ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 714595d578d6SVaclav Hapla if (label) *label = link->label; 71469566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&link->label)); 71479566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7148c58f1c22SToby Isaac break; 7149c58f1c22SToby Isaac } 7150c58f1c22SToby Isaac } 7151c58f1c22SToby Isaac PetscFunctionReturn(0); 7152c58f1c22SToby Isaac } 7153c58f1c22SToby Isaac 7154306894acSVaclav Hapla /*@ 7155bb7acecfSBarry Smith DMRemoveLabelBySelf - Remove the label from this `DM` 7156306894acSVaclav Hapla 7157306894acSVaclav Hapla Not Collective 7158306894acSVaclav Hapla 7159306894acSVaclav Hapla Input Parameters: 7160bb7acecfSBarry Smith + dm - The `DM` object 7161bb7acecfSBarry Smith . label - The `DMLabel` to be removed from the `DM` 7162306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 7163306894acSVaclav Hapla 7164306894acSVaclav Hapla Level: developer 7165306894acSVaclav Hapla 7166bb7acecfSBarry Smith Note: 7167306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7168bb7acecfSBarry Smith If the `DM` has an exclusive reference to the label, the label gets destroyed and 7169306894acSVaclav Hapla *label nullified. 7170306894acSVaclav Hapla 7171bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()` `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabel()` 7172306894acSVaclav Hapla @*/ 7173d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7174d71ae5a4SJacob Faibussowitsch { 717543e45a93SVaclav Hapla DMLabelLink link, *pnext; 7176306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7177306894acSVaclav Hapla 7178306894acSVaclav Hapla PetscFunctionBegin; 7179306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7180306894acSVaclav Hapla PetscValidPointer(label, 2); 7181f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 7182306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7183306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm, failNotFound, 3); 71845d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 718543e45a93SVaclav Hapla if (*label == link->label) { 7186306894acSVaclav Hapla hasLabel = PETSC_TRUE; 718743e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7188306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7189ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 719043e45a93SVaclav Hapla if (((PetscObject)link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 71919566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&link->label)); 71929566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7193306894acSVaclav Hapla break; 7194306894acSVaclav Hapla } 7195306894acSVaclav Hapla } 71967a8be351SBarry Smith PetscCheck(hasLabel || !failNotFound, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 7197306894acSVaclav Hapla PetscFunctionReturn(0); 7198306894acSVaclav Hapla } 7199306894acSVaclav Hapla 7200c58f1c22SToby Isaac /*@C 7201c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7202c58f1c22SToby Isaac 7203c58f1c22SToby Isaac Not Collective 7204c58f1c22SToby Isaac 7205c58f1c22SToby Isaac Input Parameters: 7206bb7acecfSBarry Smith + dm - The `DM` object 7207c58f1c22SToby Isaac - name - The label name 7208c58f1c22SToby Isaac 7209c58f1c22SToby Isaac Output Parameter: 7210c58f1c22SToby Isaac . output - The flag for output 7211c58f1c22SToby Isaac 7212c58f1c22SToby Isaac Level: developer 7213c58f1c22SToby Isaac 7214bb7acecfSBarry Smith .seealso: `DMLabel`, `DMSetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7215c58f1c22SToby Isaac @*/ 7216d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7217d71ae5a4SJacob Faibussowitsch { 72185d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7219d67d17b1SMatthew G. Knepley const char *lname; 7220c58f1c22SToby Isaac 7221c58f1c22SToby Isaac PetscFunctionBegin; 7222c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7223dadcf809SJacob Faibussowitsch PetscValidCharPointer(name, 2); 7224dadcf809SJacob Faibussowitsch PetscValidBoolPointer(output, 3); 7225c58f1c22SToby Isaac while (next) { 7226c58f1c22SToby Isaac PetscBool flg; 7227c58f1c22SToby Isaac 72289566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 72299566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 72309371c9d4SSatish Balay if (flg) { 72319371c9d4SSatish Balay *output = next->output; 72329371c9d4SSatish Balay PetscFunctionReturn(0); 72339371c9d4SSatish Balay } 7234c58f1c22SToby Isaac next = next->next; 7235c58f1c22SToby Isaac } 723698921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7237c58f1c22SToby Isaac } 7238c58f1c22SToby Isaac 7239c58f1c22SToby Isaac /*@C 7240bb7acecfSBarry Smith DMSetLabelOutput - Set if a given label should be saved to a `PetscViewer` in calls to `DMView()` 7241c58f1c22SToby Isaac 7242c58f1c22SToby Isaac Not Collective 7243c58f1c22SToby Isaac 7244c58f1c22SToby Isaac Input Parameters: 7245bb7acecfSBarry Smith + dm - The `DM` object 7246c58f1c22SToby Isaac . name - The label name 7247bb7acecfSBarry Smith - output - `PETSC_TRUE` to save the label to the viewer 7248c58f1c22SToby Isaac 7249c58f1c22SToby Isaac Level: developer 7250c58f1c22SToby Isaac 7251bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetOutputFlag()`, `DMGetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7252c58f1c22SToby Isaac @*/ 7253d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7254d71ae5a4SJacob Faibussowitsch { 72555d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7256d67d17b1SMatthew G. Knepley const char *lname; 7257c58f1c22SToby Isaac 7258c58f1c22SToby Isaac PetscFunctionBegin; 7259c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7260534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 7261c58f1c22SToby Isaac while (next) { 7262c58f1c22SToby Isaac PetscBool flg; 7263c58f1c22SToby Isaac 72649566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 72659566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 72669371c9d4SSatish Balay if (flg) { 72679371c9d4SSatish Balay next->output = output; 72689371c9d4SSatish Balay PetscFunctionReturn(0); 72699371c9d4SSatish Balay } 7270c58f1c22SToby Isaac next = next->next; 7271c58f1c22SToby Isaac } 727298921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7273c58f1c22SToby Isaac } 7274c58f1c22SToby Isaac 7275c58f1c22SToby Isaac /*@ 7276bb7acecfSBarry Smith DMCopyLabels - Copy labels from one `DM` mesh to another `DM` with a superset of the points 7277c58f1c22SToby Isaac 7278d083f849SBarry Smith Collective on dmA 7279c58f1c22SToby Isaac 7280d8d19677SJose E. Roman Input Parameters: 7281bb7acecfSBarry Smith + dmA - The `DM` object with initial labels 7282bb7acecfSBarry Smith . dmB - The `DM` object to which labels are copied 7283bb7acecfSBarry Smith . mode - Copy labels by pointers (`PETSC_OWN_POINTER`) or duplicate them (`PETSC_COPY_VALUES`) 7284bb7acecfSBarry Smith . all - Copy all labels including "depth", "dim", and "celltype" (`PETSC_TRUE`) which are otherwise ignored (`PETSC_FALSE`) 7285bb7acecfSBarry Smith - emode - How to behave when a `DMLabel` in the source and destination `DM`s with the same name is encountered (see `DMCopyLabelsMode`) 7286c58f1c22SToby Isaac 7287c58f1c22SToby Isaac Level: intermediate 7288c58f1c22SToby Isaac 7289bb7acecfSBarry Smith Note: 72902cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 7291c58f1c22SToby Isaac 7292bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode` 7293c58f1c22SToby Isaac @*/ 7294d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 7295d71ae5a4SJacob Faibussowitsch { 72962cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 7297c58f1c22SToby Isaac const char *name; 7298c58f1c22SToby Isaac PetscBool flg; 72995d80c0bfSVaclav Hapla DMLabelLink link; 7300c58f1c22SToby Isaac 73015d80c0bfSVaclav Hapla PetscFunctionBegin; 73025d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 73035d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 73045d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode, 3); 73055d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 73067a8be351SBarry Smith PetscCheck(mode != PETSC_USE_POINTER, PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 73075d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 73085d80c0bfSVaclav Hapla for (link = dmA->labels; link; link = link->next) { 73095d80c0bfSVaclav Hapla label = link->label; 73109566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 73115d80c0bfSVaclav Hapla if (!all) { 73129566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &flg)); 7313c58f1c22SToby Isaac if (flg) continue; 73149566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "dim", &flg)); 73157d5acc75SStefano Zampini if (flg) continue; 73169566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &flg)); 7317ba2698f1SMatthew G. Knepley if (flg) continue; 73185d80c0bfSVaclav Hapla } 73199566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmB, name, &labelOld)); 73202cbb9b06SVaclav Hapla if (labelOld) { 73212cbb9b06SVaclav Hapla switch (emode) { 7322d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_KEEP: 7323d71ae5a4SJacob Faibussowitsch continue; 7324d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_REPLACE: 7325d71ae5a4SJacob Faibussowitsch PetscCall(DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE)); 7326d71ae5a4SJacob Faibussowitsch break; 7327d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_FAIL: 7328d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 7329d71ae5a4SJacob Faibussowitsch default: 7330d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", (int)emode); 73312cbb9b06SVaclav Hapla } 73322cbb9b06SVaclav Hapla } 73335d80c0bfSVaclav Hapla if (mode == PETSC_COPY_VALUES) { 73349566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, &labelNew)); 73355d80c0bfSVaclav Hapla } else { 73365d80c0bfSVaclav Hapla labelNew = label; 73375d80c0bfSVaclav Hapla } 73389566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmB, labelNew)); 73399566063dSJacob Faibussowitsch if (mode == PETSC_COPY_VALUES) PetscCall(DMLabelDestroy(&labelNew)); 7340c58f1c22SToby Isaac } 7341c58f1c22SToby Isaac PetscFunctionReturn(0); 7342c58f1c22SToby Isaac } 7343461a15a0SLisandro Dalcin 7344609dae6eSVaclav Hapla /*@C 7345bb7acecfSBarry Smith DMCompareLabels - Compare labels of two `DMPLEX` meshes 7346609dae6eSVaclav Hapla 73475efe38ccSVaclav Hapla Collective 7348609dae6eSVaclav Hapla 7349609dae6eSVaclav Hapla Input Parameters: 7350bb7acecfSBarry Smith + dm0 - First `DM` object 7351bb7acecfSBarry Smith - dm1 - Second `DM` object 7352609dae6eSVaclav Hapla 7353609dae6eSVaclav Hapla Output Parameters 73545efe38ccSVaclav Hapla + equal - (Optional) Flag whether labels of dm0 and dm1 are the same 7355609dae6eSVaclav Hapla - message - (Optional) Message describing the difference, or NULL if there is no difference 7356609dae6eSVaclav Hapla 7357609dae6eSVaclav Hapla Level: intermediate 7358609dae6eSVaclav Hapla 7359609dae6eSVaclav Hapla Notes: 7360bb7acecfSBarry Smith The output flag equal will be the same on all processes. 7361bb7acecfSBarry Smith 7362bb7acecfSBarry Smith If equal is passed as NULL and difference is found, an error is thrown on all processes. 7363bb7acecfSBarry Smith 7364bb7acecfSBarry Smith Make sure to pass equal is NULL on all processes or none of them. 7365609dae6eSVaclav Hapla 73665efe38ccSVaclav Hapla The output message is set independently on each rank. 7367bb7acecfSBarry Smith 7368bb7acecfSBarry Smith message must be freed with `PetscFree()` 7369bb7acecfSBarry Smith 7370bb7acecfSBarry Smith If message is passed as NULL and a difference is found, the difference description is printed to stderr in synchronized manner. 7371bb7acecfSBarry Smith 7372bb7acecfSBarry Smith Make sure to pass message as NULL on all processes or no processes. 7373609dae6eSVaclav Hapla 7374609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 7375bb7acecfSBarry Smith `DMLabelCompare()` is used to compare each pair of labels with the same name. 7376609dae6eSVaclav Hapla 7377bb7acecfSBarry Smith Fortran Note: 7378bb7acecfSBarry Smith This function is not available from Fortran. 7379609dae6eSVaclav Hapla 7380bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode`, `DMLabelCompare()` 7381609dae6eSVaclav Hapla @*/ 7382d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *equal, char **message) 7383d71ae5a4SJacob Faibussowitsch { 73845efe38ccSVaclav Hapla PetscInt n, i; 7385609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 73865efe38ccSVaclav Hapla PetscBool eq; 7387609dae6eSVaclav Hapla MPI_Comm comm; 73885efe38ccSVaclav Hapla PetscMPIInt rank; 7389609dae6eSVaclav Hapla 7390609dae6eSVaclav Hapla PetscFunctionBegin; 7391609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0, DM_CLASSID, 1); 7392609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1, DM_CLASSID, 2); 7393609dae6eSVaclav Hapla PetscCheckSameComm(dm0, 1, dm1, 2); 73945efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal, 3); 7395609dae6eSVaclav Hapla if (message) PetscValidPointer(message, 4); 73969566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm0, &comm)); 73979566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 73985efe38ccSVaclav Hapla { 73995efe38ccSVaclav Hapla PetscInt n1; 74005efe38ccSVaclav Hapla 74019566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm0, &n)); 74029566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm1, &n1)); 74035efe38ccSVaclav Hapla eq = (PetscBool)(n == n1); 740448a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %" PetscInt_FMT " != %" PetscInt_FMT " = Number of labels in dm1", n, n1)); 74059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 74065efe38ccSVaclav Hapla if (!eq) goto finish; 74075efe38ccSVaclav Hapla } 74085efe38ccSVaclav Hapla for (i = 0; i < n; i++) { 7409609dae6eSVaclav Hapla DMLabel l0, l1; 7410609dae6eSVaclav Hapla const char *name; 7411609dae6eSVaclav Hapla char *msgInner; 7412609dae6eSVaclav Hapla 7413609dae6eSVaclav Hapla /* Ignore label order */ 74149566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm0, i, &l0)); 74159566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name)); 74169566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm1, name, &l1)); 7417609dae6eSVaclav Hapla if (!l1) { 741863a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%" PetscInt_FMT " in dm0) not found in dm1", name, i)); 74195efe38ccSVaclav Hapla eq = PETSC_FALSE; 74205efe38ccSVaclav Hapla break; 7421609dae6eSVaclav Hapla } 74229566063dSJacob Faibussowitsch PetscCall(DMLabelCompare(comm, l0, l1, &eq, &msgInner)); 74239566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(msg, msgInner, sizeof(msg))); 74249566063dSJacob Faibussowitsch PetscCall(PetscFree(msgInner)); 74255efe38ccSVaclav Hapla if (!eq) break; 7426609dae6eSVaclav Hapla } 74279566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 7428609dae6eSVaclav Hapla finish: 74295efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 7430609dae6eSVaclav Hapla if (message) { 7431609dae6eSVaclav Hapla *message = NULL; 743248a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 74335efe38ccSVaclav Hapla } else { 743448a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 74359566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 74365efe38ccSVaclav Hapla } 74375efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 74385efe38ccSVaclav Hapla if (equal) *equal = eq; 74397a8be351SBarry Smith else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels are not the same in dm0 and dm1"); 7440609dae6eSVaclav Hapla PetscFunctionReturn(0); 7441609dae6eSVaclav Hapla } 7442609dae6eSVaclav Hapla 7443d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 7444d71ae5a4SJacob Faibussowitsch { 7445461a15a0SLisandro Dalcin PetscFunctionBegin; 7446461a15a0SLisandro Dalcin PetscValidPointer(label, 2); 7447461a15a0SLisandro Dalcin if (!*label) { 74489566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 74499566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, label)); 7450461a15a0SLisandro Dalcin } 74519566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(*label, point, value)); 7452461a15a0SLisandro Dalcin PetscFunctionReturn(0); 7453461a15a0SLisandro Dalcin } 7454461a15a0SLisandro Dalcin 74550fdc7489SMatthew Knepley /* 74560fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 74570fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 74580fdc7489SMatthew Knepley (label, id) pair in the DM. 74590fdc7489SMatthew Knepley 74600fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 74610fdc7489SMatthew Knepley each label. 74620fdc7489SMatthew Knepley */ 7463d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 7464d71ae5a4SJacob Faibussowitsch { 74650fdc7489SMatthew Knepley DMUniversalLabel ul; 74660fdc7489SMatthew Knepley PetscBool *active; 74670fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 74680fdc7489SMatthew Knepley 74690fdc7489SMatthew Knepley PetscFunctionBegin; 74709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &ul)); 74719566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label)); 74729566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 74739566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nl, &active)); 74740fdc7489SMatthew Knepley ul->Nl = 0; 74750fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 74760fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 74770fdc7489SMatthew Knepley const char *name; 74780fdc7489SMatthew Knepley 74799566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 74809566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "depth", 6, &isdepth)); 74819566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "celltype", 9, &iscelltype)); 74820fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 74830fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 74840fdc7489SMatthew Knepley } 74859566063dSJacob 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)); 74860fdc7489SMatthew Knepley ul->Nv = 0; 74870fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 74880fdc7489SMatthew Knepley DMLabel label; 74890fdc7489SMatthew Knepley PetscInt nv; 74900fdc7489SMatthew Knepley const char *name; 74910fdc7489SMatthew Knepley 74920fdc7489SMatthew Knepley if (!active[l]) continue; 74939566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 74949566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 74959566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 74969566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &ul->names[m])); 74970fdc7489SMatthew Knepley ul->indices[m] = l; 74980fdc7489SMatthew Knepley ul->Nv += nv; 74990fdc7489SMatthew Knepley ul->offsets[m + 1] = nv; 75000fdc7489SMatthew Knepley ul->bits[m + 1] = PetscCeilReal(PetscLog2Real(nv + 1)); 75010fdc7489SMatthew Knepley ++m; 75020fdc7489SMatthew Knepley } 75030fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 75040fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l - 1] + ul->offsets[l]; 75050fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l - 1] + ul->bits[l]; 75060fdc7489SMatthew Knepley } 75070fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 75080fdc7489SMatthew Knepley PetscInt b; 75090fdc7489SMatthew Knepley 75100fdc7489SMatthew Knepley ul->masks[l] = 0; 75110fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l + 1]; ++b) ul->masks[l] |= 1 << b; 75120fdc7489SMatthew Knepley } 75139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ul->Nv, &ul->values)); 75140fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 75150fdc7489SMatthew Knepley DMLabel label; 75160fdc7489SMatthew Knepley IS valueIS; 75170fdc7489SMatthew Knepley const PetscInt *varr; 75180fdc7489SMatthew Knepley PetscInt nv, v; 75190fdc7489SMatthew Knepley 75200fdc7489SMatthew Knepley if (!active[l]) continue; 75219566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 75229566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 75239566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &valueIS)); 75249566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &varr)); 7525ad540459SPierre Jolivet for (v = 0; v < nv; ++v) ul->values[ul->offsets[m] + v] = varr[v]; 75269566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(valueIS, &varr)); 75279566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valueIS)); 75289566063dSJacob Faibussowitsch PetscCall(PetscSortInt(nv, &ul->values[ul->offsets[m]])); 75290fdc7489SMatthew Knepley ++m; 75300fdc7489SMatthew Knepley } 75319566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 75320fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 75330fdc7489SMatthew Knepley PetscInt uval = 0; 75340fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 75350fdc7489SMatthew Knepley 75360fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 75370fdc7489SMatthew Knepley DMLabel label; 75380649b39aSStefano Zampini PetscInt val, defval, loc, nv; 75390fdc7489SMatthew Knepley 75400fdc7489SMatthew Knepley if (!active[l]) continue; 75419566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 75429566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &val)); 75439566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &defval)); 75449371c9d4SSatish Balay if (val == defval) { 75459371c9d4SSatish Balay ++m; 75469371c9d4SSatish Balay continue; 75479371c9d4SSatish Balay } 75480649b39aSStefano Zampini nv = ul->offsets[m + 1] - ul->offsets[m]; 75490fdc7489SMatthew Knepley marked = PETSC_TRUE; 75509566063dSJacob Faibussowitsch PetscCall(PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc)); 755163a3b9bcSJacob Faibussowitsch PetscCheck(loc >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %" PetscInt_FMT " not found in compression array", val); 75520fdc7489SMatthew Knepley uval += (loc + 1) << ul->bits[m]; 75530fdc7489SMatthew Knepley ++m; 75540fdc7489SMatthew Knepley } 75559566063dSJacob Faibussowitsch if (marked) PetscCall(DMLabelSetValue(ul->label, p, uval)); 75560fdc7489SMatthew Knepley } 75579566063dSJacob Faibussowitsch PetscCall(PetscFree(active)); 75580fdc7489SMatthew Knepley *universal = ul; 75590fdc7489SMatthew Knepley PetscFunctionReturn(0); 75600fdc7489SMatthew Knepley } 75610fdc7489SMatthew Knepley 7562d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 7563d71ae5a4SJacob Faibussowitsch { 75640fdc7489SMatthew Knepley PetscInt l; 75650fdc7489SMatthew Knepley 75660fdc7489SMatthew Knepley PetscFunctionBegin; 75679566063dSJacob Faibussowitsch for (l = 0; l < (*universal)->Nl; ++l) PetscCall(PetscFree((*universal)->names[l])); 75689566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&(*universal)->label)); 75699566063dSJacob Faibussowitsch PetscCall(PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks)); 75709566063dSJacob Faibussowitsch PetscCall(PetscFree((*universal)->values)); 75719566063dSJacob Faibussowitsch PetscCall(PetscFree(*universal)); 75720fdc7489SMatthew Knepley *universal = NULL; 75730fdc7489SMatthew Knepley PetscFunctionReturn(0); 75740fdc7489SMatthew Knepley } 75750fdc7489SMatthew Knepley 7576d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 7577d71ae5a4SJacob Faibussowitsch { 75780fdc7489SMatthew Knepley PetscFunctionBegin; 75790fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 75800fdc7489SMatthew Knepley *ulabel = ul->label; 75810fdc7489SMatthew Knepley PetscFunctionReturn(0); 75820fdc7489SMatthew Knepley } 75830fdc7489SMatthew Knepley 7584d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 7585d71ae5a4SJacob Faibussowitsch { 75860fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 75870fdc7489SMatthew Knepley 75880fdc7489SMatthew Knepley PetscFunctionBegin; 7589064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 75900fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 75919566063dSJacob Faibussowitsch if (preserveOrder) PetscCall(DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l])); 75929566063dSJacob Faibussowitsch else PetscCall(DMCreateLabel(dm, ul->names[l])); 75930fdc7489SMatthew Knepley } 75940fdc7489SMatthew Knepley if (preserveOrder) { 75950fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 75960fdc7489SMatthew Knepley const char *name; 75970fdc7489SMatthew Knepley PetscBool match; 75980fdc7489SMatthew Knepley 75999566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, ul->indices[l], &name)); 76009566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, ul->names[l], &match)); 760163a3b9bcSJacob 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]); 76020fdc7489SMatthew Knepley } 76030fdc7489SMatthew Knepley } 76040fdc7489SMatthew Knepley PetscFunctionReturn(0); 76050fdc7489SMatthew Knepley } 76060fdc7489SMatthew Knepley 7607d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 7608d71ae5a4SJacob Faibussowitsch { 76090fdc7489SMatthew Knepley PetscInt l; 76100fdc7489SMatthew Knepley 76110fdc7489SMatthew Knepley PetscFunctionBegin; 76120fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 76130fdc7489SMatthew Knepley DMLabel label; 76140fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 76150fdc7489SMatthew Knepley 76160fdc7489SMatthew Knepley if (lval) { 76179566063dSJacob Faibussowitsch if (useIndex) PetscCall(DMGetLabelByNum(dm, ul->indices[l], &label)); 76189566063dSJacob Faibussowitsch else PetscCall(DMGetLabel(dm, ul->names[l], &label)); 76199566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, p, ul->values[ul->offsets[l] + lval - 1])); 76200fdc7489SMatthew Knepley } 76210fdc7489SMatthew Knepley } 76220fdc7489SMatthew Knepley PetscFunctionReturn(0); 76230fdc7489SMatthew Knepley } 7624a8fb8f29SToby Isaac 7625a8fb8f29SToby Isaac /*@ 7626bb7acecfSBarry Smith DMGetCoarseDM - Get the coarse `DM`from which this `DM` was obtained by refinement 7627bb7acecfSBarry Smith 7628bb7acecfSBarry Smith Not collective 7629a8fb8f29SToby Isaac 7630a8fb8f29SToby Isaac Input Parameter: 7631bb7acecfSBarry Smith . dm - The `DM` object 7632a8fb8f29SToby Isaac 7633a8fb8f29SToby Isaac Output Parameter: 7634bb7acecfSBarry Smith . cdm - The coarse `DM` 7635a8fb8f29SToby Isaac 7636a8fb8f29SToby Isaac Level: intermediate 7637a8fb8f29SToby Isaac 7638bb7acecfSBarry Smith .seealso: `DMSetCoarseDM()`, `DMCoarsen()` 7639a8fb8f29SToby Isaac @*/ 7640d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 7641d71ae5a4SJacob Faibussowitsch { 7642a8fb8f29SToby Isaac PetscFunctionBegin; 7643a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7644a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 7645a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 7646a8fb8f29SToby Isaac PetscFunctionReturn(0); 7647a8fb8f29SToby Isaac } 7648a8fb8f29SToby Isaac 7649a8fb8f29SToby Isaac /*@ 7650bb7acecfSBarry Smith DMSetCoarseDM - Set the coarse `DM` from which this `DM` was obtained by refinement 7651a8fb8f29SToby Isaac 7652a8fb8f29SToby Isaac Input Parameters: 7653bb7acecfSBarry Smith + dm - The `DM` object 7654bb7acecfSBarry Smith - cdm - The coarse `DM` 7655a8fb8f29SToby Isaac 7656a8fb8f29SToby Isaac Level: intermediate 7657a8fb8f29SToby Isaac 7658bb7acecfSBarry Smith Note: 7659bb7acecfSBarry Smith Normally this is set automatically by `DMRefine()` 7660bb7acecfSBarry Smith 7661bb7acecfSBarry Smith .seealso: `DMGetCoarseDM()`, `DMCoarsen()`, `DMSetRefine()`, `DMSetFineDM()` 7662a8fb8f29SToby Isaac @*/ 7663d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 7664d71ae5a4SJacob Faibussowitsch { 7665a8fb8f29SToby Isaac PetscFunctionBegin; 7666a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7667a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 766889d734beSBarry Smith if (dm == cdm) cdm = NULL; 76699566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cdm)); 76709566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->coarseMesh)); 7671a8fb8f29SToby Isaac dm->coarseMesh = cdm; 7672a8fb8f29SToby Isaac PetscFunctionReturn(0); 7673a8fb8f29SToby Isaac } 7674a8fb8f29SToby Isaac 767588bdff64SToby Isaac /*@ 7676bb7acecfSBarry Smith DMGetFineDM - Get the fine mesh from which this `DM` was obtained by coarsening 767788bdff64SToby Isaac 767888bdff64SToby Isaac Input Parameter: 7679bb7acecfSBarry Smith . dm - The `DM` object 768088bdff64SToby Isaac 768188bdff64SToby Isaac Output Parameter: 7682bb7acecfSBarry Smith . fdm - The fine `DM` 768388bdff64SToby Isaac 768488bdff64SToby Isaac Level: intermediate 768588bdff64SToby Isaac 7686bb7acecfSBarry Smith .seealso: `DMSetFineDM()`, `DMCoarsen()`, `DMRefine()` 768788bdff64SToby Isaac @*/ 7688d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 7689d71ae5a4SJacob Faibussowitsch { 769088bdff64SToby Isaac PetscFunctionBegin; 769188bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 769288bdff64SToby Isaac PetscValidPointer(fdm, 2); 769388bdff64SToby Isaac *fdm = dm->fineMesh; 769488bdff64SToby Isaac PetscFunctionReturn(0); 769588bdff64SToby Isaac } 769688bdff64SToby Isaac 769788bdff64SToby Isaac /*@ 7698bb7acecfSBarry Smith DMSetFineDM - Set the fine mesh from which this was obtained by coarsening 769988bdff64SToby Isaac 770088bdff64SToby Isaac Input Parameters: 7701bb7acecfSBarry Smith + dm - The `DM` object 7702bb7acecfSBarry Smith - fdm - The fine `DM` 770388bdff64SToby Isaac 7704bb7acecfSBarry Smith Level: developer 770588bdff64SToby Isaac 7706bb7acecfSBarry Smith Note: 7707bb7acecfSBarry Smith Normally this is set automatically by `DMCoarsen()` 7708bb7acecfSBarry Smith 7709bb7acecfSBarry Smith .seealso: `DMGetFineDM()`, `DMCoarsen()`, `DMRefine()` 771088bdff64SToby Isaac @*/ 7711d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFineDM(DM dm, DM fdm) 7712d71ae5a4SJacob Faibussowitsch { 771388bdff64SToby Isaac PetscFunctionBegin; 771488bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 771588bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 771689d734beSBarry Smith if (dm == fdm) fdm = NULL; 77179566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fdm)); 77189566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->fineMesh)); 771988bdff64SToby Isaac dm->fineMesh = fdm; 772088bdff64SToby Isaac PetscFunctionReturn(0); 772188bdff64SToby Isaac } 772288bdff64SToby Isaac 7723a6ba4734SToby Isaac /*@C 7724bb7acecfSBarry Smith DMAddBoundary - Add a boundary condition to a model represented by a `DM` 7725a6ba4734SToby Isaac 7726783e2ec8SMatthew G. Knepley Collective on dm 7727783e2ec8SMatthew G. Knepley 7728a6ba4734SToby Isaac Input Parameters: 7729bb7acecfSBarry Smith + dm - The `DM`, with a `PetscDS` that matches the problem being constrained 7730bb7acecfSBarry Smith . type - The type of condition, e.g. `DM_BC_ESSENTIAL_ANALYTIC`, `DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann) 7731a6ba4734SToby Isaac . name - The BC name 773245480ffeSMatthew G. Knepley . label - The label defining constrained points 7733bb7acecfSBarry Smith . Nv - The number of `DMLabel` values for constrained points 773445480ffeSMatthew G. Knepley . values - An array of values for constrained points 7735a6ba4734SToby Isaac . field - The field to constrain 773645480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 7737a6ba4734SToby Isaac . comps - An array of constrained component numbers 7738a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 773956cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 7740a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 7741a6ba4734SToby Isaac 774245480ffeSMatthew G. Knepley Output Parameter: 774345480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 774445480ffeSMatthew G. Knepley 7745a6ba4734SToby Isaac Options Database Keys: 7746a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 7747a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 7748a6ba4734SToby Isaac 7749bb7acecfSBarry Smith Notes: 7750bb7acecfSBarry Smith Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, then the calling sequence is: 775156cf3b9cSMatthew G. Knepley 775256cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 775356cf3b9cSMatthew G. Knepley 7754bb7acecfSBarry Smith If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is: 775556cf3b9cSMatthew G. Knepley 775656cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 775756cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 775856cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 775956cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 776056cf3b9cSMatthew G. Knepley 776156cf3b9cSMatthew G. Knepley + dim - the spatial dimension 776256cf3b9cSMatthew G. Knepley . Nf - the number of fields 776356cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 776456cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 776556cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 776656cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 776756cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 776856cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 776956cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 777056cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 777156cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 777256cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 777356cf3b9cSMatthew G. Knepley . t - current time 777456cf3b9cSMatthew G. Knepley . x - coordinates of the current point 777556cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 777656cf3b9cSMatthew G. Knepley . constants - constant parameters 777756cf3b9cSMatthew G. Knepley - bcval - output values at the current point 777856cf3b9cSMatthew G. Knepley 7779ed808b8fSJed Brown Level: intermediate 7780a6ba4734SToby Isaac 7781db781477SPatrick Sanan .seealso: `DSGetBoundary()`, `PetscDSAddBoundary()` 7782a6ba4734SToby Isaac @*/ 7783d71ae5a4SJacob 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) 7784d71ae5a4SJacob Faibussowitsch { 7785e5e52638SMatthew G. Knepley PetscDS ds; 7786a6ba4734SToby Isaac 7787a6ba4734SToby Isaac PetscFunctionBegin; 7788a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7789783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 779045480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 779145480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 779245480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 779345480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 779401a5d20dSJed Brown PetscCheck(!dm->localSection, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot add boundary to DM after creating local section"); 77959566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7796799db056SMatthew G. Knepley /* Complete label */ 7797799db056SMatthew G. Knepley if (label) { 7798799db056SMatthew G. Knepley PetscObject obj; 7799799db056SMatthew G. Knepley PetscClassId id; 7800799db056SMatthew G. Knepley 7801799db056SMatthew G. Knepley PetscCall(DMGetField(dm, field, NULL, &obj)); 7802799db056SMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 7803799db056SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 7804799db056SMatthew G. Knepley DM plex; 7805799db056SMatthew G. Knepley 7806799db056SMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 7807799db056SMatthew G. Knepley if (plex) PetscCall(DMPlexLabelComplete(plex, label)); 7808799db056SMatthew G. Knepley PetscCall(DMDestroy(&plex)); 7809799db056SMatthew G. Knepley } 7810799db056SMatthew G. Knepley } 78119566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd)); 7812a6ba4734SToby Isaac PetscFunctionReturn(0); 7813a6ba4734SToby Isaac } 7814a6ba4734SToby Isaac 781545480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 7816d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPopulateBoundary(DM dm) 7817d71ae5a4SJacob Faibussowitsch { 7818e5e52638SMatthew G. Knepley PetscDS ds; 7819dff059c6SToby Isaac DMBoundary *lastnext; 7820e6f8dbb6SToby Isaac DSBoundary dsbound; 7821e6f8dbb6SToby Isaac 7822e6f8dbb6SToby Isaac PetscFunctionBegin; 78239566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7824e5e52638SMatthew G. Knepley dsbound = ds->boundary; 782547a1f5adSToby Isaac if (dm->boundary) { 782647a1f5adSToby Isaac DMBoundary next = dm->boundary; 782747a1f5adSToby Isaac 782847a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 782947a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 783047a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 783147a1f5adSToby Isaac while (next) { 783247a1f5adSToby Isaac DMBoundary b = next; 783347a1f5adSToby Isaac 783447a1f5adSToby Isaac next = b->next; 78359566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 7836a6ba4734SToby Isaac } 783747a1f5adSToby Isaac dm->boundary = NULL; 7838a6ba4734SToby Isaac } 783947a1f5adSToby Isaac 7840dff059c6SToby Isaac lastnext = &(dm->boundary); 7841e6f8dbb6SToby Isaac while (dsbound) { 7842e6f8dbb6SToby Isaac DMBoundary dmbound; 7843e6f8dbb6SToby Isaac 78449566063dSJacob Faibussowitsch PetscCall(PetscNew(&dmbound)); 7845e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 784645480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 784747a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 7848dff059c6SToby Isaac *lastnext = dmbound; 7849dff059c6SToby Isaac lastnext = &(dmbound->next); 7850dff059c6SToby Isaac dsbound = dsbound->next; 7851a6ba4734SToby Isaac } 7852a6ba4734SToby Isaac PetscFunctionReturn(0); 7853a6ba4734SToby Isaac } 7854a6ba4734SToby Isaac 7855bb7acecfSBarry Smith /* TODO: missing manual page */ 7856d71ae5a4SJacob Faibussowitsch PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 7857d71ae5a4SJacob Faibussowitsch { 7858b95f2879SToby Isaac DMBoundary b; 7859a6ba4734SToby Isaac 7860a6ba4734SToby Isaac PetscFunctionBegin; 7861a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7862534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 7863a6ba4734SToby Isaac *isBd = PETSC_FALSE; 78649566063dSJacob Faibussowitsch PetscCall(DMPopulateBoundary(dm)); 7865b95f2879SToby Isaac b = dm->boundary; 7866a6ba4734SToby Isaac while (b && !(*isBd)) { 7867e6f8dbb6SToby Isaac DMLabel label = b->label; 7868e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 7869a6ba4734SToby Isaac PetscInt i; 7870a6ba4734SToby Isaac 787145480ffeSMatthew G. Knepley if (label) { 78729566063dSJacob Faibussowitsch for (i = 0; i < dsb->Nv && !(*isBd); ++i) PetscCall(DMLabelStratumHasPoint(label, dsb->values[i], point, isBd)); 7873a6ba4734SToby Isaac } 7874a6ba4734SToby Isaac b = b->next; 7875a6ba4734SToby Isaac } 7876a6ba4734SToby Isaac PetscFunctionReturn(0); 7877a6ba4734SToby Isaac } 78784d6f44ffSToby Isaac 78794d6f44ffSToby Isaac /*@C 7880bb7acecfSBarry Smith DMProjectFunction - This projects the given function into the function space provided by a `DM`, putting the coefficients in a global vector. 7881a6e0b375SMatthew G. Knepley 7882bb7acecfSBarry Smith Collective on dm 78834d6f44ffSToby Isaac 78844d6f44ffSToby Isaac Input Parameters: 7885bb7acecfSBarry Smith + dm - The `DM` 78860709b2feSToby Isaac . time - The time 78874d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 78884d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 78894d6f44ffSToby Isaac - mode - The insertion mode for values 78904d6f44ffSToby Isaac 78914d6f44ffSToby Isaac Output Parameter: 78924d6f44ffSToby Isaac . X - vector 78934d6f44ffSToby Isaac 78944d6f44ffSToby Isaac Calling sequence of func: 789577b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 78964d6f44ffSToby Isaac 78974d6f44ffSToby Isaac + dim - The spatial dimension 78988ec8862eSJed Brown . time - The time at which to sample 78994d6f44ffSToby Isaac . x - The coordinates 790077b739a6SMatthew Knepley . Nc - The number of components 79014d6f44ffSToby Isaac . u - The output field values 79024d6f44ffSToby Isaac - ctx - optional user-defined function context 79034d6f44ffSToby Isaac 79044d6f44ffSToby Isaac Level: developer 79054d6f44ffSToby Isaac 7906bb7acecfSBarry Smith Developer Notes: 7907bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7908bb7acecfSBarry Smith 7909bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7910bb7acecfSBarry Smith 7911db781477SPatrick Sanan .seealso: `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 79124d6f44ffSToby Isaac @*/ 7913d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 7914d71ae5a4SJacob Faibussowitsch { 79154d6f44ffSToby Isaac Vec localX; 79164d6f44ffSToby Isaac 79174d6f44ffSToby Isaac PetscFunctionBegin; 79184d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 79199566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 79209566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX)); 79219566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 79229566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 79239566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 79244d6f44ffSToby Isaac PetscFunctionReturn(0); 79254d6f44ffSToby Isaac } 79264d6f44ffSToby Isaac 7927a6e0b375SMatthew G. Knepley /*@C 7928bb7acecfSBarry Smith DMProjectFunctionLocal - This projects the given function into the function space provided by a `DM`, putting the coefficients in a local vector. 7929a6e0b375SMatthew G. Knepley 7930a6e0b375SMatthew G. Knepley Not collective 7931a6e0b375SMatthew G. Knepley 7932a6e0b375SMatthew G. Knepley Input Parameters: 7933bb7acecfSBarry Smith + dm - The `DM` 7934a6e0b375SMatthew G. Knepley . time - The time 7935a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 7936a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 7937a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 7938a6e0b375SMatthew G. Knepley 7939a6e0b375SMatthew G. Knepley Output Parameter: 7940a6e0b375SMatthew G. Knepley . localX - vector 7941a6e0b375SMatthew G. Knepley 7942a6e0b375SMatthew G. Knepley Calling sequence of func: 794377b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 7944a6e0b375SMatthew G. Knepley 7945a6e0b375SMatthew G. Knepley + dim - The spatial dimension 7946a6e0b375SMatthew G. Knepley . x - The coordinates 794777b739a6SMatthew Knepley . Nc - The number of components 7948a6e0b375SMatthew G. Knepley . u - The output field values 7949a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 7950a6e0b375SMatthew G. Knepley 7951a6e0b375SMatthew G. Knepley Level: developer 7952a6e0b375SMatthew G. Knepley 7953bb7acecfSBarry Smith Developer Notes: 7954bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7955bb7acecfSBarry Smith 7956bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7957bb7acecfSBarry Smith 7958db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 7959a6e0b375SMatthew G. Knepley @*/ 7960d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 7961d71ae5a4SJacob Faibussowitsch { 79624d6f44ffSToby Isaac PetscFunctionBegin; 79634d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7964064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 79659566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlocal)(dm, time, funcs, ctxs, mode, localX)); 79664d6f44ffSToby Isaac PetscFunctionReturn(0); 79674d6f44ffSToby Isaac } 79684d6f44ffSToby Isaac 7969a6e0b375SMatthew G. Knepley /*@C 7970bb7acecfSBarry 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. 7971a6e0b375SMatthew G. Knepley 7972bb7acecfSBarry Smith Collective on dm 7973a6e0b375SMatthew G. Knepley 7974a6e0b375SMatthew G. Knepley Input Parameters: 7975bb7acecfSBarry Smith + dm - The `DM` 7976a6e0b375SMatthew G. Knepley . time - The time 7977bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 7978a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 7979bb7acecfSBarry Smith . ctxs - Optional array of contexts to pass to each coordinate function. ctxs may be null. 7980a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 7981a6e0b375SMatthew G. Knepley 7982a6e0b375SMatthew G. Knepley Output Parameter: 7983a6e0b375SMatthew G. Knepley . X - vector 7984a6e0b375SMatthew G. Knepley 7985a6e0b375SMatthew G. Knepley Calling sequence of func: 798677b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 7987a6e0b375SMatthew G. Knepley 7988a6e0b375SMatthew G. Knepley + dim - The spatial dimension 7989a6e0b375SMatthew G. Knepley . x - The coordinates 799077b739a6SMatthew Knepley . Nc - The number of components 7991a6e0b375SMatthew G. Knepley . u - The output field values 7992a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 7993a6e0b375SMatthew G. Knepley 7994a6e0b375SMatthew G. Knepley Level: developer 7995a6e0b375SMatthew G. Knepley 7996bb7acecfSBarry Smith Developer Notes: 7997bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7998bb7acecfSBarry Smith 7999bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8000bb7acecfSBarry Smith 8001db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabelLocal()`, `DMComputeL2Diff()` 8002a6e0b375SMatthew G. Knepley @*/ 8003d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 8004d71ae5a4SJacob Faibussowitsch { 80052c53366bSMatthew G. Knepley Vec localX; 80062c53366bSMatthew G. Knepley 80072c53366bSMatthew G. Knepley PetscFunctionBegin; 80082c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 80099566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 80109566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 80119566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 80129566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 80139566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 80142c53366bSMatthew G. Knepley PetscFunctionReturn(0); 80152c53366bSMatthew G. Knepley } 80162c53366bSMatthew G. Knepley 8017a6e0b375SMatthew G. Knepley /*@C 8018bb7acecfSBarry 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. 8019a6e0b375SMatthew G. Knepley 8020a6e0b375SMatthew G. Knepley Not collective 8021a6e0b375SMatthew G. Knepley 8022a6e0b375SMatthew G. Knepley Input Parameters: 8023bb7acecfSBarry Smith + dm - The `DM` 8024a6e0b375SMatthew G. Knepley . time - The time 8025bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8026a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8027a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8028a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8029a6e0b375SMatthew G. Knepley 8030a6e0b375SMatthew G. Knepley Output Parameter: 8031a6e0b375SMatthew G. Knepley . localX - vector 8032a6e0b375SMatthew G. Knepley 8033a6e0b375SMatthew G. Knepley Calling sequence of func: 803477b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 8035a6e0b375SMatthew G. Knepley 8036a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8037a6e0b375SMatthew G. Knepley . x - The coordinates 803877b739a6SMatthew Knepley . Nc - The number of components 8039a6e0b375SMatthew G. Knepley . u - The output field values 8040a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8041a6e0b375SMatthew G. Knepley 8042a6e0b375SMatthew G. Knepley Level: developer 8043a6e0b375SMatthew G. Knepley 8044bb7acecfSBarry Smith Developer Notes: 8045bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8046bb7acecfSBarry Smith 8047bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8048bb7acecfSBarry Smith 8049db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8050a6e0b375SMatthew G. Knepley @*/ 8051d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 8052d71ae5a4SJacob Faibussowitsch { 80534d6f44ffSToby Isaac PetscFunctionBegin; 80544d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8055064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 80569566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlabellocal)(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 80574d6f44ffSToby Isaac PetscFunctionReturn(0); 80584d6f44ffSToby Isaac } 80592716604bSToby Isaac 8060a6e0b375SMatthew G. Knepley /*@C 8061bb7acecfSBarry 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. 8062a6e0b375SMatthew G. Knepley 8063a6e0b375SMatthew G. Knepley Not collective 8064a6e0b375SMatthew G. Knepley 8065a6e0b375SMatthew G. Knepley Input Parameters: 8066bb7acecfSBarry Smith + dm - The `DM` 8067a6e0b375SMatthew G. Knepley . time - The time 8068a6e0b375SMatthew G. Knepley . localU - The input field vector 8069a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8070a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8071a6e0b375SMatthew G. Knepley 8072a6e0b375SMatthew G. Knepley Output Parameter: 8073a6e0b375SMatthew G. Knepley . localX - The output vector 8074a6e0b375SMatthew G. Knepley 8075a6e0b375SMatthew G. Knepley Calling sequence of func: 8076a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8077a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8078a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8079a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8080a6e0b375SMatthew G. Knepley 8081a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8082a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8083a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8084a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8085a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8086a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8087a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8088a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8089a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8090a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8091a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8092a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8093a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8094a6e0b375SMatthew G. Knepley . t - The current time 8095a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8096a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8097a6e0b375SMatthew G. Knepley . constants - The value of each constant 8098a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8099a6e0b375SMatthew G. Knepley 8100bb7acecfSBarry Smith Note: 8101bb7acecfSBarry 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. 8102bb7acecfSBarry 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 8103bb7acecfSBarry 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 8104a6e0b375SMatthew 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. 8105a6e0b375SMatthew G. Knepley 8106a6e0b375SMatthew G. Knepley Level: intermediate 8107a6e0b375SMatthew G. Knepley 8108bb7acecfSBarry Smith Developer Notes: 8109bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8110bb7acecfSBarry Smith 8111bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8112bb7acecfSBarry Smith 8113db781477SPatrick Sanan .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8114a6e0b375SMatthew G. Knepley @*/ 8115d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, void (**funcs)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), InsertMode mode, Vec localX) 8116d71ae5a4SJacob Faibussowitsch { 81178c6c5593SMatthew G. Knepley PetscFunctionBegin; 81188c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 81198c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU, VEC_CLASSID, 3); 81208c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 81219566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlocal)(dm, time, localU, funcs, mode, localX)); 81228c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 81238c6c5593SMatthew G. Knepley } 81248c6c5593SMatthew G. Knepley 8125a6e0b375SMatthew G. Knepley /*@C 8126a6e0b375SMatthew 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. 8127a6e0b375SMatthew G. Knepley 8128a6e0b375SMatthew G. Knepley Not collective 8129a6e0b375SMatthew G. Knepley 8130a6e0b375SMatthew G. Knepley Input Parameters: 8131bb7acecfSBarry Smith + dm - The `DM` 8132a6e0b375SMatthew G. Knepley . time - The time 8133bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8134a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8135a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8136bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8137a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8138a6e0b375SMatthew G. Knepley . localU - The input field vector 8139a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8140a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8141a6e0b375SMatthew G. Knepley 8142a6e0b375SMatthew G. Knepley Output Parameter: 8143a6e0b375SMatthew G. Knepley . localX - The output vector 8144a6e0b375SMatthew G. Knepley 8145a6e0b375SMatthew G. Knepley Calling sequence of func: 8146a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8147a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8148a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8149a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8150a6e0b375SMatthew G. Knepley 8151a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8152a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8153a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8154a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8155a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8156a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8157a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8158a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8159a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8160a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8161a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8162a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8163a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8164a6e0b375SMatthew G. Knepley . t - The current time 8165a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8166a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8167a6e0b375SMatthew G. Knepley . constants - The value of each constant 8168a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8169a6e0b375SMatthew G. Knepley 8170bb7acecfSBarry Smith Note: 8171bb7acecfSBarry 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. 8172bb7acecfSBarry 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 8173bb7acecfSBarry 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 8174a6e0b375SMatthew 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. 8175a6e0b375SMatthew G. Knepley 8176a6e0b375SMatthew G. Knepley Level: intermediate 8177a6e0b375SMatthew G. Knepley 8178bb7acecfSBarry Smith Developer Notes: 8179bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8180bb7acecfSBarry Smith 8181bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8182bb7acecfSBarry Smith 8183d29d7c6eSMatthew G. Knepley .seealso: `DMProjectField()`, `DMProjectFieldLabel()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8184a6e0b375SMatthew G. Knepley @*/ 8185d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, void (**funcs)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), InsertMode mode, Vec localX) 8186d71ae5a4SJacob Faibussowitsch { 81878c6c5593SMatthew G. Knepley PetscFunctionBegin; 81888c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8189064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8190064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 81919566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 81928c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 81938c6c5593SMatthew G. Knepley } 81948c6c5593SMatthew G. Knepley 81952716604bSToby Isaac /*@C 8196d29d7c6eSMatthew 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. 8197d29d7c6eSMatthew G. Knepley 8198d29d7c6eSMatthew G. Knepley Not collective 8199d29d7c6eSMatthew G. Knepley 8200d29d7c6eSMatthew G. Knepley Input Parameters: 8201bb7acecfSBarry Smith + dm - The `DM` 8202d29d7c6eSMatthew G. Knepley . time - The time 8203bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8204d29d7c6eSMatthew G. Knepley . numIds - The number of label ids to use 8205d29d7c6eSMatthew G. Knepley . ids - The label ids to use for marking 8206bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8207d29d7c6eSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8208d29d7c6eSMatthew G. Knepley . U - The input field vector 8209d29d7c6eSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8210d29d7c6eSMatthew G. Knepley - mode - The insertion mode for values 8211d29d7c6eSMatthew G. Knepley 8212d29d7c6eSMatthew G. Knepley Output Parameter: 8213d29d7c6eSMatthew G. Knepley . X - The output vector 8214d29d7c6eSMatthew G. Knepley 8215d29d7c6eSMatthew G. Knepley Calling sequence of func: 8216d29d7c6eSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8217d29d7c6eSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8218d29d7c6eSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8219d29d7c6eSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8220d29d7c6eSMatthew G. Knepley 8221d29d7c6eSMatthew G. Knepley + dim - The spatial dimension 8222d29d7c6eSMatthew G. Knepley . Nf - The number of input fields 8223d29d7c6eSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8224d29d7c6eSMatthew G. Knepley . uOff - The offset of each field in u[] 8225d29d7c6eSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8226d29d7c6eSMatthew G. Knepley . u - The field values at this point in space 8227d29d7c6eSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8228d29d7c6eSMatthew G. Knepley . u_x - The field derivatives at this point in space 8229d29d7c6eSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8230d29d7c6eSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8231d29d7c6eSMatthew G. Knepley . a - The auxiliary field values at this point in space 8232d29d7c6eSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8233d29d7c6eSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8234d29d7c6eSMatthew G. Knepley . t - The current time 8235d29d7c6eSMatthew G. Knepley . x - The coordinates of this point 8236d29d7c6eSMatthew G. Knepley . numConstants - The number of constants 8237d29d7c6eSMatthew G. Knepley . constants - The value of each constant 8238d29d7c6eSMatthew G. Knepley - f - The value of the function at this point in space 8239d29d7c6eSMatthew G. Knepley 8240bb7acecfSBarry Smith Note: 8241bb7acecfSBarry 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. 8242bb7acecfSBarry 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 8243bb7acecfSBarry 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 8244d29d7c6eSMatthew 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. 8245d29d7c6eSMatthew G. Knepley 8246d29d7c6eSMatthew G. Knepley Level: intermediate 8247d29d7c6eSMatthew G. Knepley 8248bb7acecfSBarry Smith Developer Notes: 8249bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8250bb7acecfSBarry Smith 8251bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8252bb7acecfSBarry Smith 8253d29d7c6eSMatthew G. Knepley .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8254d29d7c6eSMatthew G. Knepley @*/ 8255d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFieldLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec U, void (**funcs)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), InsertMode mode, Vec X) 8256d71ae5a4SJacob Faibussowitsch { 8257d29d7c6eSMatthew G. Knepley DM dmIn; 8258d29d7c6eSMatthew G. Knepley Vec localU, localX; 8259d29d7c6eSMatthew G. Knepley 8260d29d7c6eSMatthew G. Knepley PetscFunctionBegin; 8261d29d7c6eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8262d29d7c6eSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn)); 8263d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dmIn, &localU)); 8264d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &localX)); 826572fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dmIn, U, mode, localU)); 826672fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dmIn, U, mode, localU)); 8267d29d7c6eSMatthew G. Knepley PetscCall(DMProjectFieldLabelLocal(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8268d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 8269d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 8270d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &localX)); 8271d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dmIn, &localU)); 8272d29d7c6eSMatthew G. Knepley PetscFunctionReturn(0); 8273d29d7c6eSMatthew G. Knepley } 8274d29d7c6eSMatthew G. Knepley 8275d29d7c6eSMatthew G. Knepley /*@C 8276ece3a9fcSMatthew 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. 8277ece3a9fcSMatthew G. Knepley 8278ece3a9fcSMatthew G. Knepley Not collective 8279ece3a9fcSMatthew G. Knepley 8280ece3a9fcSMatthew G. Knepley Input Parameters: 8281bb7acecfSBarry Smith + dm - The `DM` 8282ece3a9fcSMatthew G. Knepley . time - The time 8283bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain boundary to output 8284ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8285ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8286bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8287ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8288ece3a9fcSMatthew G. Knepley . localU - The input field vector 8289ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8290ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8291ece3a9fcSMatthew G. Knepley 8292ece3a9fcSMatthew G. Knepley Output Parameter: 8293ece3a9fcSMatthew G. Knepley . localX - The output vector 8294ece3a9fcSMatthew G. Knepley 8295ece3a9fcSMatthew G. Knepley Calling sequence of func: 8296ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8297ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8298ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8299ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8300ece3a9fcSMatthew G. Knepley 8301ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8302ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8303ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8304ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8305ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8306ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8307ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8308ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8309ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8310ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8311ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8312ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8313ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8314ece3a9fcSMatthew G. Knepley . t - The current time 8315ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8316ece3a9fcSMatthew G. Knepley . n - The face normal 8317ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8318ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8319ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8320ece3a9fcSMatthew G. Knepley 8321ece3a9fcSMatthew G. Knepley Note: 8322bb7acecfSBarry 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. 8323bb7acecfSBarry 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 8324bb7acecfSBarry 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 8325ece3a9fcSMatthew 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. 8326ece3a9fcSMatthew G. Knepley 8327ece3a9fcSMatthew G. Knepley Level: intermediate 8328ece3a9fcSMatthew G. Knepley 8329bb7acecfSBarry Smith Developer Notes: 8330bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8331bb7acecfSBarry Smith 8332bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8333bb7acecfSBarry Smith 8334db781477SPatrick Sanan .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8335ece3a9fcSMatthew G. Knepley @*/ 8336d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, void (**funcs)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), InsertMode mode, Vec localX) 8337d71ae5a4SJacob Faibussowitsch { 8338ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8339ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8340064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8341064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 83429566063dSJacob Faibussowitsch PetscCall((dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8343ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 8344ece3a9fcSMatthew G. Knepley } 8345ece3a9fcSMatthew G. Knepley 8346ece3a9fcSMatthew G. Knepley /*@C 83472716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 83482716604bSToby Isaac 8349bb7acecfSBarry Smith Collective on dm 8350bb7acecfSBarry Smith 83512716604bSToby Isaac Input Parameters: 8352bb7acecfSBarry Smith + dm - The `DM` 83530709b2feSToby Isaac . time - The time 83542716604bSToby Isaac . funcs - The functions to evaluate for each field component 83552716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8356574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 83572716604bSToby Isaac 83582716604bSToby Isaac Output Parameter: 83592716604bSToby Isaac . diff - The diff ||u - u_h||_2 83602716604bSToby Isaac 83612716604bSToby Isaac Level: developer 83622716604bSToby Isaac 8363bb7acecfSBarry Smith Developer Notes: 8364bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8365bb7acecfSBarry Smith 8366bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8367bb7acecfSBarry Smith 8368db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 83692716604bSToby Isaac @*/ 8370d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 8371d71ae5a4SJacob Faibussowitsch { 83722716604bSToby Isaac PetscFunctionBegin; 83732716604bSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8374b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 83759566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2diff)(dm, time, funcs, ctxs, X, diff)); 83762716604bSToby Isaac PetscFunctionReturn(0); 83772716604bSToby Isaac } 8378b698f381SToby Isaac 8379b698f381SToby Isaac /*@C 8380b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8381b698f381SToby Isaac 8382d083f849SBarry Smith Collective on dm 8383d083f849SBarry Smith 8384b698f381SToby Isaac Input Parameters: 8385bb7acecfSBarry Smith + dm - The `DM` 8386b698f381SToby Isaac , time - The time 8387b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8388b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8389574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8390b698f381SToby Isaac - n - The vector to project along 8391b698f381SToby Isaac 8392b698f381SToby Isaac Output Parameter: 8393b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8394b698f381SToby Isaac 8395b698f381SToby Isaac Level: developer 8396b698f381SToby Isaac 8397bb7acecfSBarry Smith Developer Notes: 8398bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8399bb7acecfSBarry Smith 8400bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8401bb7acecfSBarry Smith 8402bb7acecfSBarry Smith .seealso: `DMProjectFunction()`, `DMComputeL2Diff()`, `DMComputeL2FieldDiff()` 8403b698f381SToby Isaac @*/ 8404d71ae5a4SJacob 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) 8405d71ae5a4SJacob Faibussowitsch { 8406b698f381SToby Isaac PetscFunctionBegin; 8407b698f381SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8408b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 84099566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2gradientdiff)(dm, time, funcs, ctxs, X, n, diff)); 8410b698f381SToby Isaac PetscFunctionReturn(0); 8411b698f381SToby Isaac } 8412b698f381SToby Isaac 84132a16baeaSToby Isaac /*@C 84142a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 84152a16baeaSToby Isaac 8416d083f849SBarry Smith Collective on dm 8417d083f849SBarry Smith 84182a16baeaSToby Isaac Input Parameters: 8419bb7acecfSBarry Smith + dm - The `DM` 84202a16baeaSToby Isaac . time - The time 84212a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 84222a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8423574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 84242a16baeaSToby Isaac 84252a16baeaSToby Isaac Output Parameter: 84262a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 84272a16baeaSToby Isaac 84282a16baeaSToby Isaac Level: developer 84292a16baeaSToby Isaac 8430bb7acecfSBarry Smith Developer Notes: 8431bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8432bb7acecfSBarry Smith 8433bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8434bb7acecfSBarry Smith 8435db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 84362a16baeaSToby Isaac @*/ 8437d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 8438d71ae5a4SJacob Faibussowitsch { 84392a16baeaSToby Isaac PetscFunctionBegin; 84402a16baeaSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 84412a16baeaSToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 84429566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2fielddiff)(dm, time, funcs, ctxs, X, diff)); 84432a16baeaSToby Isaac PetscFunctionReturn(0); 84442a16baeaSToby Isaac } 84452a16baeaSToby Isaac 8446df0b854cSToby Isaac /*@C 8447bb7acecfSBarry Smith DMGetNeighbors - Gets an array containing the MPI ranks of all the processes neighbors 8448502a2867SDave May 8449502a2867SDave May Not Collective 8450502a2867SDave May 8451502a2867SDave May Input Parameter: 8452bb7acecfSBarry Smith . dm - The `DM` 8453502a2867SDave May 84540a19bb7dSprj- Output Parameters: 84550a19bb7dSprj- + nranks - the number of neighbours 84560a19bb7dSprj- - ranks - the neighbors ranks 8457502a2867SDave May 8458bb7acecfSBarry Smith Note: 8459bb7acecfSBarry Smith Do not free the array, it is freed when the `DM` is destroyed. 8460502a2867SDave May 8461502a2867SDave May Level: beginner 8462502a2867SDave May 8463db781477SPatrick Sanan .seealso: `DMDAGetNeighbors()`, `PetscSFGetRootRanks()` 8464502a2867SDave May @*/ 8465d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNeighbors(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 8466d71ae5a4SJacob Faibussowitsch { 8467502a2867SDave May PetscFunctionBegin; 8468502a2867SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 84699566063dSJacob Faibussowitsch PetscCall((dm->ops->getneighbors)(dm, nranks, ranks)); 8470502a2867SDave May PetscFunctionReturn(0); 8471502a2867SDave May } 8472502a2867SDave May 8473531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 8474531c7667SBarry Smith 8475531c7667SBarry Smith /* 8476531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 8477531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 8478531c7667SBarry Smith */ 8479d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringApply_AIJDM(Mat J, MatFDColoring coloring, Vec x1, void *sctx) 8480d71ae5a4SJacob Faibussowitsch { 8481531c7667SBarry Smith PetscFunctionBegin; 8482531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8483531c7667SBarry Smith Vec x1local; 8484531c7667SBarry Smith DM dm; 84859566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 84867a8be351SBarry Smith PetscCheck(dm, PetscObjectComm((PetscObject)J), PETSC_ERR_ARG_INCOMP, "IS_COLORING_LOCAL requires a DM"); 84879566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &x1local)); 84889566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, x1, INSERT_VALUES, x1local)); 84899566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, x1, INSERT_VALUES, x1local)); 8490531c7667SBarry Smith x1 = x1local; 8491531c7667SBarry Smith } 84929566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply_AIJ(J, coloring, x1, sctx)); 8493531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8494531c7667SBarry Smith DM dm; 84959566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 84969566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &x1)); 8497531c7667SBarry Smith } 8498531c7667SBarry Smith PetscFunctionReturn(0); 8499531c7667SBarry Smith } 8500531c7667SBarry Smith 8501531c7667SBarry Smith /*@ 8502bb7acecfSBarry Smith MatFDColoringUseDM - allows a `MatFDColoring` object to use the `DM` associated with the matrix to compute a `IS_COLORING_LOCAL` coloring 8503531c7667SBarry Smith 8504531c7667SBarry Smith Input Parameter: 8505bb7acecfSBarry Smith . coloring - the `MatFDColoring` object 8506531c7667SBarry Smith 8507bb7acecfSBarry Smith Developer Note: 8508bb7acecfSBarry Smith this routine exists because the PETSc `Mat` library does not know about the `DM` objects 8509531c7667SBarry Smith 85101b266c99SBarry Smith Level: advanced 85111b266c99SBarry Smith 8512db781477SPatrick Sanan .seealso: `MatFDColoring`, `MatFDColoringCreate()`, `ISColoringType` 8513531c7667SBarry Smith @*/ 8514d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringUseDM(Mat coloring, MatFDColoring fdcoloring) 8515d71ae5a4SJacob Faibussowitsch { 8516531c7667SBarry Smith PetscFunctionBegin; 8517531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 8518531c7667SBarry Smith PetscFunctionReturn(0); 8519531c7667SBarry Smith } 85208320bc6fSPatrick Sanan 85218320bc6fSPatrick Sanan /*@ 8522bb7acecfSBarry Smith DMGetCompatibility - determine if two `DM`s are compatible 85238320bc6fSPatrick Sanan 85248320bc6fSPatrick Sanan Collective 85258320bc6fSPatrick Sanan 85268320bc6fSPatrick Sanan Input Parameters: 8527bb7acecfSBarry Smith + dm1 - the first `DM` 8528bb7acecfSBarry Smith - dm2 - the second `DM` 85298320bc6fSPatrick Sanan 85308320bc6fSPatrick Sanan Output Parameters: 8531bb7acecfSBarry Smith + compatible - whether or not the two `DM`s are compatible 8532bb7acecfSBarry Smith - set - whether or not the compatible value was actually determined and set 85338320bc6fSPatrick Sanan 85348320bc6fSPatrick Sanan Notes: 8535bb7acecfSBarry Smith Two `DM`s are deemed compatible if they represent the same parallel decomposition 85363d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 85378320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 8538bb7acecfSBarry Smith Loosely speaking, compatible `DM`s represent the same domain and parallel 85393d862458SPatrick Sanan decomposition, but hold different data. 85408320bc6fSPatrick Sanan 85418320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 8542bb7acecfSBarry Smith over a pair of vectors obtained from different `DM`s. 85438320bc6fSPatrick Sanan 8544bb7acecfSBarry Smith For example, two `DMDA` objects are compatible if they have the same local 85458320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 85468320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 8547bb7acecfSBarry Smith either `DM` in bounds for a loop over vectors derived from either `DM`. 85488320bc6fSPatrick Sanan 8549bb7acecfSBarry Smith Consider the operation of summing data living on a 2-dof `DMDA` to data living 8550bb7acecfSBarry Smith on a 1-dof `DMDA`, which should be compatible, as in the following snippet. 85518320bc6fSPatrick Sanan .vb 85528320bc6fSPatrick Sanan ... 85539566063dSJacob Faibussowitsch PetscCall(DMGetCompatibility(da1,da2,&compatible,&set)); 85548320bc6fSPatrick Sanan if (set && compatible) { 85559566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1)); 85569566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2)); 85579566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL)); 85588320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 85598320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 85608320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 85618320bc6fSPatrick Sanan } 85628320bc6fSPatrick Sanan } 85639566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1)); 85649566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2)); 85658320bc6fSPatrick Sanan } else { 85668320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 85678320bc6fSPatrick Sanan } 85688320bc6fSPatrick Sanan ... 85698320bc6fSPatrick Sanan .ve 85708320bc6fSPatrick Sanan 8571bb7acecfSBarry Smith Checking compatibility might be expensive for a given implementation of `DM`, 85728320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 85738320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 85748320bc6fSPatrick Sanan always check the "set" output parameter. 85758320bc6fSPatrick Sanan 8576bb7acecfSBarry Smith A `DM` is always compatible with itself. 85778320bc6fSPatrick Sanan 8578bb7acecfSBarry Smith In the current implementation, `DM`s which live on "unequal" communicators 85798320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 85808320bc6fSPatrick Sanan incompatible. 85818320bc6fSPatrick Sanan 85828320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 8583bb7acecfSBarry Smith is required on each rank. However, in `DM` implementations which store all this 85848320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 85858320bc6fSPatrick Sanan 8586bb7acecfSBarry Smith Developer Note: 8587bb7acecfSBarry Smith Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B 85883d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 8589a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 8590bb7acecfSBarry Smith compatibility. It is left to `DM` implementers to ensure that symmetry is 85918320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 85923d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 8593bb7acecfSBarry Smith of other `DM` types and let *set = PETSC_FALSE if found. 85948320bc6fSPatrick Sanan 85958320bc6fSPatrick Sanan Level: advanced 85968320bc6fSPatrick Sanan 8597db781477SPatrick Sanan .seealso: `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()` 85988320bc6fSPatrick Sanan @*/ 8599d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCompatibility(DM dm1, DM dm2, PetscBool *compatible, PetscBool *set) 8600d71ae5a4SJacob Faibussowitsch { 86018320bc6fSPatrick Sanan PetscMPIInt compareResult; 86028320bc6fSPatrick Sanan DMType type, type2; 86038320bc6fSPatrick Sanan PetscBool sameType; 86048320bc6fSPatrick Sanan 86058320bc6fSPatrick Sanan PetscFunctionBegin; 8606a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 86078320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 86088320bc6fSPatrick Sanan 86098320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 8610a5bc1bf3SBarry Smith if (dm1 == dm2) { 86118320bc6fSPatrick Sanan *set = PETSC_TRUE; 86128320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 86138320bc6fSPatrick Sanan PetscFunctionReturn(0); 86148320bc6fSPatrick Sanan } 86158320bc6fSPatrick Sanan 86168320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 86178320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 86188320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 86198320bc6fSPatrick Sanan determined by the implementation-specific logic */ 86209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)dm1), PetscObjectComm((PetscObject)dm2), &compareResult)); 86218320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 86228320bc6fSPatrick Sanan *set = PETSC_TRUE; 86238320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 86248320bc6fSPatrick Sanan PetscFunctionReturn(0); 86258320bc6fSPatrick Sanan } 86268320bc6fSPatrick Sanan 86278320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 8628a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 8629dbbe0bcdSBarry Smith PetscUseTypeMethod(dm1, getcompatibility, dm2, compatible, set); 8630b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 86318320bc6fSPatrick Sanan } 86328320bc6fSPatrick Sanan 8633a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 86348320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 86359566063dSJacob Faibussowitsch PetscCall(DMGetType(dm1, &type)); 86369566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2, &type2)); 86379566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, type2, &sameType)); 86388320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 8639dbbe0bcdSBarry Smith PetscUseTypeMethod(dm2, getcompatibility, dm1, compatible, set); /* Note argument order */ 86408320bc6fSPatrick Sanan } else { 86418320bc6fSPatrick Sanan *set = PETSC_FALSE; 86428320bc6fSPatrick Sanan } 86438320bc6fSPatrick Sanan PetscFunctionReturn(0); 86448320bc6fSPatrick Sanan } 8645c0f0dcc3SMatthew G. Knepley 8646c0f0dcc3SMatthew G. Knepley /*@C 8647bb7acecfSBarry Smith DMMonitorSet - Sets an additional monitor function that is to be used after a solve to monitor discretization performance. 8648c0f0dcc3SMatthew G. Knepley 8649bb7acecfSBarry Smith Logically Collective on dm 8650c0f0dcc3SMatthew G. Knepley 8651c0f0dcc3SMatthew G. Knepley Input Parameters: 8652bb7acecfSBarry Smith + DM - the `DM` 8653c0f0dcc3SMatthew G. Knepley . f - the monitor function 8654c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 8655c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 8656c0f0dcc3SMatthew G. Knepley 8657c0f0dcc3SMatthew G. Knepley Options Database Keys: 8658bb7acecfSBarry Smith - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `DMMonitorSet()`, but 8659c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 8660c0f0dcc3SMatthew G. Knepley 8661bb7acecfSBarry Smith Note: 8662c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 8663bb7acecfSBarry Smith `DMMonitorSet()` multiple times or with `DMMonitorSetFromOptions()`; all will be called in the 8664c0f0dcc3SMatthew G. Knepley order in which they were set. 8665c0f0dcc3SMatthew G. Knepley 8666bb7acecfSBarry Smith Fortran Note: 8667bb7acecfSBarry Smith Only a single monitor function can be set for each `DM` object 8668bb7acecfSBarry Smith 8669bb7acecfSBarry Smith Developer Note: 8670bb7acecfSBarry Smith This API has a generic name but seems specific to a very particular aspect of the use of `DM` 8671c0f0dcc3SMatthew G. Knepley 8672c0f0dcc3SMatthew G. Knepley Level: intermediate 8673c0f0dcc3SMatthew G. Knepley 8674bb7acecfSBarry Smith .seealso: `DMMonitorCancel()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8675c0f0dcc3SMatthew G. Knepley @*/ 8676d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 8677d71ae5a4SJacob Faibussowitsch { 8678c0f0dcc3SMatthew G. Knepley PetscInt m; 8679c0f0dcc3SMatthew G. Knepley 8680c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8681c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8682c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 8683c0f0dcc3SMatthew G. Knepley PetscBool identical; 8684c0f0dcc3SMatthew G. Knepley 86859566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical)); 8686c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 8687c0f0dcc3SMatthew G. Knepley } 86887a8be351SBarry Smith PetscCheck(dm->numbermonitors < MAXDMMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 8689c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 8690c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 8691c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *)mctx; 8692c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8693c0f0dcc3SMatthew G. Knepley } 8694c0f0dcc3SMatthew G. Knepley 8695c0f0dcc3SMatthew G. Knepley /*@ 8696bb7acecfSBarry Smith DMMonitorCancel - Clears all the monitor functions for a `DM` object. 8697c0f0dcc3SMatthew G. Knepley 8698bb7acecfSBarry Smith Logically Collective on dm 8699c0f0dcc3SMatthew G. Knepley 8700c0f0dcc3SMatthew G. Knepley Input Parameter: 8701c0f0dcc3SMatthew G. Knepley . dm - the DM 8702c0f0dcc3SMatthew G. Knepley 8703c0f0dcc3SMatthew G. Knepley Options Database Key: 8704c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 8705bb7acecfSBarry Smith into a code by calls to `DMonitorSet()`, but does not cancel those 8706c0f0dcc3SMatthew G. Knepley set via the options database 8707c0f0dcc3SMatthew G. Knepley 8708bb7acecfSBarry Smith Note: 8709bb7acecfSBarry Smith There is no way to clear one specific monitor from a `DM` object. 8710c0f0dcc3SMatthew G. Knepley 8711c0f0dcc3SMatthew G. Knepley Level: intermediate 8712c0f0dcc3SMatthew G. Knepley 8713bb7acecfSBarry Smith .seealso: `DMMonitorSet()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8714c0f0dcc3SMatthew G. Knepley @*/ 8715d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorCancel(DM dm) 8716d71ae5a4SJacob Faibussowitsch { 8717c0f0dcc3SMatthew G. Knepley PetscInt m; 8718c0f0dcc3SMatthew G. Knepley 8719c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8720c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8721c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 87229566063dSJacob Faibussowitsch if (dm->monitordestroy[m]) PetscCall((*dm->monitordestroy[m])(&dm->monitorcontext[m])); 8723c0f0dcc3SMatthew G. Knepley } 8724c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 8725c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8726c0f0dcc3SMatthew G. Knepley } 8727c0f0dcc3SMatthew G. Knepley 8728c0f0dcc3SMatthew G. Knepley /*@C 8729c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 8730c0f0dcc3SMatthew G. Knepley 8731bb7acecfSBarry Smith Collective on dm 8732c0f0dcc3SMatthew G. Knepley 8733c0f0dcc3SMatthew G. Knepley Input Parameters: 8734bb7acecfSBarry Smith + dm - `DM` object you wish to monitor 8735c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 8736c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 8737c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 8738c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 8739bb7acecfSBarry 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 8740c0f0dcc3SMatthew G. Knepley 8741c0f0dcc3SMatthew G. Knepley Output Parameter: 8742c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 8743c0f0dcc3SMatthew G. Knepley 8744c0f0dcc3SMatthew G. Knepley Level: developer 8745c0f0dcc3SMatthew G. Knepley 8746db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 8747db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 8748db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 8749db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 8750c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 8751db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 8752bb7acecfSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `DMMonitor()`, `DMMonitorSet()` 8753c0f0dcc3SMatthew G. Knepley @*/ 8754d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 8755d71ae5a4SJacob Faibussowitsch { 8756c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 8757c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 8758c0f0dcc3SMatthew G. Knepley 8759c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8760c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 87619566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)dm), ((PetscObject)dm)->options, ((PetscObject)dm)->prefix, name, &viewer, &format, flg)); 8762c0f0dcc3SMatthew G. Knepley if (*flg) { 8763c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 8764c0f0dcc3SMatthew G. Knepley 87659566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 87669566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 87679566063dSJacob Faibussowitsch if (monitorsetup) PetscCall((*monitorsetup)(dm, vf)); 87689566063dSJacob Faibussowitsch PetscCall(DMMonitorSet(dm, (PetscErrorCode(*)(DM, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 8769c0f0dcc3SMatthew G. Knepley } 8770c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8771c0f0dcc3SMatthew G. Knepley } 8772c0f0dcc3SMatthew G. Knepley 8773c0f0dcc3SMatthew G. Knepley /*@ 8774c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 8775c0f0dcc3SMatthew G. Knepley 8776bb7acecfSBarry Smith Collective on dm 8777c0f0dcc3SMatthew G. Knepley 8778c0f0dcc3SMatthew G. Knepley Input Parameters: 8779bb7acecfSBarry Smith . dm - The `DM` 8780c0f0dcc3SMatthew G. Knepley 8781c0f0dcc3SMatthew G. Knepley Level: developer 8782c0f0dcc3SMatthew G. Knepley 8783bb7acecfSBarry Smith Question: 8784bb7acecfSBarry Smith Note should indicate when during the life of the `DM` the monitor is run. It appears to be related to the discretization process seems rather specialized 8785bb7acecfSBarry Smith since some `DM` have no concept of discretization 8786bb7acecfSBarry Smith 8787bb7acecfSBarry Smith .seealso: `DMMonitorSet()`, `DMMonitorSetFromOptions()` 8788c0f0dcc3SMatthew G. Knepley @*/ 8789d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitor(DM dm) 8790d71ae5a4SJacob Faibussowitsch { 8791c0f0dcc3SMatthew G. Knepley PetscInt m; 8792c0f0dcc3SMatthew G. Knepley 8793c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8794c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 8795c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 879648a46eb9SPierre Jolivet for (m = 0; m < dm->numbermonitors; ++m) PetscCall((*dm->monitor[m])(dm, dm->monitorcontext[m])); 8797c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8798c0f0dcc3SMatthew G. Knepley } 87992e4af2aeSMatthew G. Knepley 88002e4af2aeSMatthew G. Knepley /*@ 8801bb7acecfSBarry Smith DMComputeError - Computes the error assuming the user has provided the exact solution functions 88022e4af2aeSMatthew G. Knepley 8803bb7acecfSBarry Smith Collective on dm 88042e4af2aeSMatthew G. Knepley 88052e4af2aeSMatthew G. Knepley Input Parameters: 8806bb7acecfSBarry Smith + dm - The `DM` 88076b867d5aSJose E. Roman - sol - The solution vector 88082e4af2aeSMatthew G. Knepley 88096b867d5aSJose E. Roman Input/Output Parameter: 88106b867d5aSJose E. Roman . errors - An array of length Nf, the number of fields, or NULL for no output; on output 88116b867d5aSJose E. Roman contains the error in each field 88126b867d5aSJose E. Roman 88136b867d5aSJose E. Roman Output Parameter: 88146b867d5aSJose E. Roman . errorVec - A vector to hold the cellwise error (may be NULL) 88152e4af2aeSMatthew G. Knepley 8816bb7acecfSBarry Smith Note: 8817bb7acecfSBarry Smith The exact solutions come from the `PetscDS` object, and the time comes from `DMGetOutputSequenceNumber()`. 88182e4af2aeSMatthew G. Knepley 88192e4af2aeSMatthew G. Knepley Level: developer 88202e4af2aeSMatthew G. Knepley 8821db781477SPatrick Sanan .seealso: `DMMonitorSet()`, `DMGetRegionNumDS()`, `PetscDSGetExactSolution()`, `DMGetOutputSequenceNumber()` 88222e4af2aeSMatthew G. Knepley @*/ 8823d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 8824d71ae5a4SJacob Faibussowitsch { 88252e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 88262e4af2aeSMatthew G. Knepley void **ctxs; 88272e4af2aeSMatthew G. Knepley PetscReal time; 88282e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 88292e4af2aeSMatthew G. Knepley 88302e4af2aeSMatthew G. Knepley PetscFunctionBegin; 88319566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 88329566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nf, &exactSol, Nf, &ctxs)); 88339566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 88342e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 88352e4af2aeSMatthew G. Knepley PetscDS ds; 88362e4af2aeSMatthew G. Knepley DMLabel label; 88372e4af2aeSMatthew G. Knepley IS fieldIS; 88382e4af2aeSMatthew G. Knepley const PetscInt *fields; 88392e4af2aeSMatthew G. Knepley PetscInt dsNf; 88402e4af2aeSMatthew G. Knepley 88419566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds)); 88429566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 88439566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISGetIndices(fieldIS, &fields)); 88442e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 88452e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 88469566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field])); 88472e4af2aeSMatthew G. Knepley } 88489566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISRestoreIndices(fieldIS, &fields)); 88492e4af2aeSMatthew G. Knepley } 8850ad540459SPierre 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); 88519566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, NULL, &time)); 88529566063dSJacob Faibussowitsch if (errors) PetscCall(DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors)); 88532e4af2aeSMatthew G. Knepley if (errorVec) { 88542e4af2aeSMatthew G. Knepley DM edm; 88552e4af2aeSMatthew G. Knepley DMPolytopeType ct; 88562e4af2aeSMatthew G. Knepley PetscBool simplex; 88572e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 88582e4af2aeSMatthew G. Knepley 88599566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &edm)); 88609566063dSJacob Faibussowitsch PetscCall(DMGetDimension(edm, &dim)); 88619566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 88629566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 88632e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 88649566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 88652e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 88662e4af2aeSMatthew G. Knepley PetscFE fe, efe; 88672e4af2aeSMatthew G. Knepley PetscQuadrature q; 88682e4af2aeSMatthew G. Knepley const char *name; 88692e4af2aeSMatthew G. Knepley 88709566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, (PetscObject *)&fe)); 88719566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe)); 88729566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 88739566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)efe, name)); 88749566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 88759566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(efe, q)); 88769566063dSJacob Faibussowitsch PetscCall(DMSetField(edm, f, NULL, (PetscObject)efe)); 88779566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&efe)); 88782e4af2aeSMatthew G. Knepley } 88799566063dSJacob Faibussowitsch PetscCall(DMCreateDS(edm)); 88802e4af2aeSMatthew G. Knepley 88819566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(edm, errorVec)); 88829566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*errorVec, "Error")); 88839566063dSJacob Faibussowitsch PetscCall(DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec)); 88849566063dSJacob Faibussowitsch PetscCall(DMDestroy(&edm)); 88852e4af2aeSMatthew G. Knepley } 88869566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, ctxs)); 88872e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 88882e4af2aeSMatthew G. Knepley } 88899a2a23afSMatthew G. Knepley 88909a2a23afSMatthew G. Knepley /*@ 8891bb7acecfSBarry Smith DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this `DM` 88929a2a23afSMatthew G. Knepley 88939a2a23afSMatthew G. Knepley Not collective 88949a2a23afSMatthew G. Knepley 88959a2a23afSMatthew G. Knepley Input Parameter: 8896bb7acecfSBarry Smith . dm - The `DM` 88979a2a23afSMatthew G. Knepley 88989a2a23afSMatthew G. Knepley Output Parameter: 8899a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 89009a2a23afSMatthew G. Knepley 89019a2a23afSMatthew G. Knepley Level: advanced 89029a2a23afSMatthew G. Knepley 8903bb7acecfSBarry Smith .seealso: `DMSetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 89049a2a23afSMatthew G. Knepley @*/ 8905d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 8906d71ae5a4SJacob Faibussowitsch { 89079a2a23afSMatthew G. Knepley PetscFunctionBegin; 89089a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89099566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize(dm->auxData, numAux)); 89109a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89119a2a23afSMatthew G. Knepley } 89129a2a23afSMatthew G. Knepley 89139a2a23afSMatthew G. Knepley /*@ 8914ac17215fSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value, and equation part 89159a2a23afSMatthew G. Knepley 89169a2a23afSMatthew G. Knepley Not collective 89179a2a23afSMatthew G. Knepley 89189a2a23afSMatthew G. Knepley Input Parameters: 8919bb7acecfSBarry Smith + dm - The `DM` 8920bb7acecfSBarry Smith . label - The `DMLabel` 8921ac17215fSMatthew G. Knepley . value - The label value indicating the region 8922ac17215fSMatthew G. Knepley - part - The equation part, or 0 if unused 89239a2a23afSMatthew G. Knepley 89249a2a23afSMatthew G. Knepley Output Parameter: 8925bb7acecfSBarry Smith . aux - The `Vec` holding auxiliary field data 89269a2a23afSMatthew G. Knepley 8927bb7acecfSBarry Smith Note: 8928bb7acecfSBarry Smith If no auxiliary vector is found for this (label, value), (NULL, 0, 0) is checked as well. 892904c51a94SMatthew G. Knepley 89309a2a23afSMatthew G. Knepley Level: advanced 89319a2a23afSMatthew G. Knepley 8932bb7acecfSBarry Smith .seealso: `DMSetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryLabels()` 89339a2a23afSMatthew G. Knepley @*/ 8934d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec *aux) 8935d71ae5a4SJacob Faibussowitsch { 8936ac17215fSMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0, 0}; 893704c51a94SMatthew G. Knepley PetscBool has; 89389a2a23afSMatthew G. Knepley 89399a2a23afSMatthew G. Knepley PetscFunctionBegin; 89409a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89419a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 89429a2a23afSMatthew G. Knepley key.label = label; 89439a2a23afSMatthew G. Knepley key.value = value; 8944ac17215fSMatthew G. Knepley key.part = part; 89459566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxHas(dm->auxData, key, &has)); 89469566063dSJacob Faibussowitsch if (has) PetscCall(PetscHMapAuxGet(dm->auxData, key, aux)); 89479566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxGet(dm->auxData, wild, aux)); 89489a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89499a2a23afSMatthew G. Knepley } 89509a2a23afSMatthew G. Knepley 89519a2a23afSMatthew G. Knepley /*@ 8952bb7acecfSBarry Smith DMSetAuxiliaryVec - Set an auxiliary vector for region specified by the given label and value, and equation part 89539a2a23afSMatthew G. Knepley 8954bb7acecfSBarry Smith Not collective because auxilary vectors are not parallel 89559a2a23afSMatthew G. Knepley 89569a2a23afSMatthew G. Knepley Input Parameters: 8957bb7acecfSBarry Smith + dm - The `DM` 8958bb7acecfSBarry Smith . label - The `DMLabel` 89599a2a23afSMatthew G. Knepley . value - The label value indicating the region 8960ac17215fSMatthew G. Knepley . part - The equation part, or 0 if unused 8961bb7acecfSBarry Smith - aux - The `Vec` holding auxiliary field data 89629a2a23afSMatthew G. Knepley 89639a2a23afSMatthew G. Knepley Level: advanced 89649a2a23afSMatthew G. Knepley 8965bb7acecfSBarry Smith .seealso: `DMGetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMCopyAuxiliaryVec()` 89669a2a23afSMatthew G. Knepley @*/ 8967d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec aux) 8968d71ae5a4SJacob Faibussowitsch { 89699a2a23afSMatthew G. Knepley Vec old; 89709a2a23afSMatthew G. Knepley PetscHashAuxKey key; 89719a2a23afSMatthew G. Knepley 89729a2a23afSMatthew G. Knepley PetscFunctionBegin; 89739a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89749a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 89759a2a23afSMatthew G. Knepley key.label = label; 89769a2a23afSMatthew G. Knepley key.value = value; 8977ac17215fSMatthew G. Knepley key.part = part; 89789566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGet(dm->auxData, key, &old)); 89799566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)aux)); 89809566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)old)); 89819566063dSJacob Faibussowitsch if (!aux) PetscCall(PetscHMapAuxDel(dm->auxData, key)); 89829566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxSet(dm->auxData, key, aux)); 89839a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89849a2a23afSMatthew G. Knepley } 89859a2a23afSMatthew G. Knepley 89869a2a23afSMatthew G. Knepley /*@C 8987bb7acecfSBarry Smith DMGetAuxiliaryLabels - Get the labels, values, and parts for all auxiliary vectors in this `DM` 89889a2a23afSMatthew G. Knepley 89899a2a23afSMatthew G. Knepley Not collective 89909a2a23afSMatthew G. Knepley 89919a2a23afSMatthew G. Knepley Input Parameter: 8992bb7acecfSBarry Smith . dm - The `DM` 89939a2a23afSMatthew G. Knepley 89949a2a23afSMatthew G. Knepley Output Parameters: 8995bb7acecfSBarry Smith + labels - The `DMLabel`s for each `Vec` 8996bb7acecfSBarry Smith . values - The label values for each `Vec` 8997bb7acecfSBarry Smith - parts - The equation parts for each `Vec` 89989a2a23afSMatthew G. Knepley 8999bb7acecfSBarry Smith Note: 9000bb7acecfSBarry Smith The arrays passed in must be at least as large as `DMGetNumAuxiliaryVec()`. 90019a2a23afSMatthew G. Knepley 90029a2a23afSMatthew G. Knepley Level: advanced 90039a2a23afSMatthew G. Knepley 9004bb7acecfSBarry Smith .seealso: `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMSetAuxiliaryVec()`, DMCopyAuxiliaryVec()` 90059a2a23afSMatthew G. Knepley @*/ 9006d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[], PetscInt parts[]) 9007d71ae5a4SJacob Faibussowitsch { 90089a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 90099a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 90109a2a23afSMatthew G. Knepley 90119a2a23afSMatthew G. Knepley PetscFunctionBegin; 90129a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90139a2a23afSMatthew G. Knepley PetscValidPointer(labels, 2); 9014dadcf809SJacob Faibussowitsch PetscValidIntPointer(values, 3); 9015dadcf809SJacob Faibussowitsch PetscValidIntPointer(parts, 4); 90169566063dSJacob Faibussowitsch PetscCall(DMGetNumAuxiliaryVec(dm, &n)); 90179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &keys)); 90189566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetKeys(dm->auxData, &off, keys)); 90199371c9d4SSatish Balay for (i = 0; i < n; ++i) { 90209371c9d4SSatish Balay labels[i] = keys[i].label; 90219371c9d4SSatish Balay values[i] = keys[i].value; 90229371c9d4SSatish Balay parts[i] = keys[i].part; 90239371c9d4SSatish Balay } 90249566063dSJacob Faibussowitsch PetscCall(PetscFree(keys)); 90259a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 90269a2a23afSMatthew G. Knepley } 90279a2a23afSMatthew G. Knepley 90289a2a23afSMatthew G. Knepley /*@ 9029bb7acecfSBarry Smith DMCopyAuxiliaryVec - Copy the auxiliary vector data on a `DM` to a new `DM` 90309a2a23afSMatthew G. Knepley 90319a2a23afSMatthew G. Knepley Not collective 90329a2a23afSMatthew G. Knepley 90339a2a23afSMatthew G. Knepley Input Parameter: 9034bb7acecfSBarry Smith . dm - The `DM` 90359a2a23afSMatthew G. Knepley 90369a2a23afSMatthew G. Knepley Output Parameter: 9037bb7acecfSBarry Smith . dmNew - The new `DM`, now with the same auxiliary data 90389a2a23afSMatthew G. Knepley 90399a2a23afSMatthew G. Knepley Level: advanced 90409a2a23afSMatthew G. Knepley 9041bb7acecfSBarry Smith Note: 9042bb7acecfSBarry Smith This is a shallow copy of the auxiliary vectors 9043bb7acecfSBarry Smith 9044db781477SPatrick Sanan .seealso: `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 90459a2a23afSMatthew G. Knepley @*/ 9046d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 9047d71ae5a4SJacob Faibussowitsch { 90489a2a23afSMatthew G. Knepley PetscFunctionBegin; 90499a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90509566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&dmNew->auxData)); 90519566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData)); 90529a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 90539a2a23afSMatthew G. Knepley } 9054b5a892a1SMatthew G. Knepley 9055b5a892a1SMatthew G. Knepley /*@C 9056bb7acecfSBarry Smith DMPolytopeMatchOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9057b5a892a1SMatthew G. Knepley 9058b5a892a1SMatthew G. Knepley Not collective 9059b5a892a1SMatthew G. Knepley 9060b5a892a1SMatthew G. Knepley Input Parameters: 9061bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9062b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9063b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9064b5a892a1SMatthew G. Knepley 9065b5a892a1SMatthew G. Knepley Output Parameters: 9066bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9067b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9068b5a892a1SMatthew G. Knepley 9069b5a892a1SMatthew G. Knepley Level: advanced 9070b5a892a1SMatthew G. Knepley 9071bb7acecfSBarry Smith Note: 9072bb7acecfSBarry Smith An arrangement is a face order combined with an orientation for each face 9073bb7acecfSBarry Smith 9074bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9075bb7acecfSBarry Smith that labels each arrangement (face ordering plus orientation for each face). 9076bb7acecfSBarry Smith 9077bb7acecfSBarry Smith See `DMPolytopeMatchVertexOrientation()` to find a new vertex orientation that takes the source vertex arrangement to the target vertex arrangement 9078bb7acecfSBarry Smith 9079bb7acecfSBarry Smith .seealso: `DMPolytopeGetOrientation()`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetVertexOrientation()` 9080b5a892a1SMatthew G. Knepley @*/ 9081d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9082d71ae5a4SJacob Faibussowitsch { 9083b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 9084b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct) / 2; 9085b5a892a1SMatthew G. Knepley PetscInt o, c; 9086b5a892a1SMatthew G. Knepley 9087b5a892a1SMatthew G. Knepley PetscFunctionBegin; 90889371c9d4SSatish Balay if (!nO) { 90899371c9d4SSatish Balay *ornt = 0; 90909371c9d4SSatish Balay *found = PETSC_TRUE; 90919371c9d4SSatish Balay PetscFunctionReturn(0); 90929371c9d4SSatish Balay } 9093b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9094b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 9095b5a892a1SMatthew G. Knepley 90969371c9d4SSatish Balay for (c = 0; c < cS; ++c) 90979371c9d4SSatish Balay if (sourceCone[arr[c * 2]] != targetCone[c]) break; 90989371c9d4SSatish Balay if (c == cS) { 90999371c9d4SSatish Balay *ornt = o; 91009371c9d4SSatish Balay break; 91019371c9d4SSatish Balay } 9102b5a892a1SMatthew G. Knepley } 9103b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 9104b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9105b5a892a1SMatthew G. Knepley } 9106b5a892a1SMatthew G. Knepley 9107b5a892a1SMatthew G. Knepley /*@C 9108bb7acecfSBarry Smith DMPolytopeGetOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9109b5a892a1SMatthew G. Knepley 9110b5a892a1SMatthew G. Knepley Not collective 9111b5a892a1SMatthew G. Knepley 9112b5a892a1SMatthew G. Knepley Input Parameters: 9113bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9114b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9115b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9116b5a892a1SMatthew G. Knepley 9117b5a892a1SMatthew G. Knepley Output Parameters: 9118bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9119b5a892a1SMatthew G. Knepley 9120b5a892a1SMatthew G. Knepley Level: advanced 9121b5a892a1SMatthew G. Knepley 9122bb7acecfSBarry Smith Note: 9123bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchOrientation()` except it will generate an error if no suitable orientation can be found. 9124bb7acecfSBarry Smith 9125bb7acecfSBarry Smith Developer Note: 9126bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchOrientation()` and error if none is found 9127bb7acecfSBarry Smith 9128bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeMatchOrientation()`, `DMPolytopeGetVertexOrientation()`, `DMPolytopeMatchVertexOrientation()` 9129b5a892a1SMatthew G. Knepley @*/ 9130d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9131d71ae5a4SJacob Faibussowitsch { 9132b5a892a1SMatthew G. Knepley PetscBool found; 9133b5a892a1SMatthew G. Knepley 9134b5a892a1SMatthew G. Knepley PetscFunctionBegin; 91359566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found)); 91367a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 9137b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9138b5a892a1SMatthew G. Knepley } 9139b5a892a1SMatthew G. Knepley 9140b5a892a1SMatthew G. Knepley /*@C 9141bb7acecfSBarry Smith DMPolytopeMatchVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9142b5a892a1SMatthew G. Knepley 9143b5a892a1SMatthew G. Knepley Not collective 9144b5a892a1SMatthew G. Knepley 9145b5a892a1SMatthew G. Knepley Input Parameters: 9146bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9147b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 9148b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 9149b5a892a1SMatthew G. Knepley 9150b5a892a1SMatthew G. Knepley Output Parameters: 9151bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9152b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9153b5a892a1SMatthew G. Knepley 9154b5a892a1SMatthew G. Knepley Level: advanced 9155b5a892a1SMatthew G. Knepley 9156bb7acecfSBarry Smith Note: 9157bb7acecfSBarry Smith An arrangement is a vertex order 9158bb7acecfSBarry Smith 9159bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9160bb7acecfSBarry Smith that labels each arrangement (vertex ordering). 9161bb7acecfSBarry Smith 9162bb7acecfSBarry Smith See `DMPolytopeMatchOrientation()` to find a new face orientation that takes the source face arrangement to the target face arrangement 9163bb7acecfSBarry Smith 9164bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchOrientation()`, `DMPolytopeTypeGetNumVertices()`, `DMPolytopeTypeGetVertexArrangment()` 9165b5a892a1SMatthew G. Knepley @*/ 9166d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 9167d71ae5a4SJacob Faibussowitsch { 9168b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 9169b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct) / 2; 9170b5a892a1SMatthew G. Knepley PetscInt o, c; 9171b5a892a1SMatthew G. Knepley 9172b5a892a1SMatthew G. Knepley PetscFunctionBegin; 91739371c9d4SSatish Balay if (!nO) { 91749371c9d4SSatish Balay *ornt = 0; 91759371c9d4SSatish Balay *found = PETSC_TRUE; 91769371c9d4SSatish Balay PetscFunctionReturn(0); 91779371c9d4SSatish Balay } 9178b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9179b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangment(ct, o); 9180b5a892a1SMatthew G. Knepley 91819371c9d4SSatish Balay for (c = 0; c < cS; ++c) 91829371c9d4SSatish Balay if (sourceVert[arr[c]] != targetVert[c]) break; 91839371c9d4SSatish Balay if (c == cS) { 91849371c9d4SSatish Balay *ornt = o; 91859371c9d4SSatish Balay break; 91869371c9d4SSatish Balay } 9187b5a892a1SMatthew G. Knepley } 9188b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 9189b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9190b5a892a1SMatthew G. Knepley } 9191b5a892a1SMatthew G. Knepley 9192b5a892a1SMatthew G. Knepley /*@C 9193bb7acecfSBarry Smith DMPolytopeGetVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9194b5a892a1SMatthew G. Knepley 9195b5a892a1SMatthew G. Knepley Not collective 9196b5a892a1SMatthew G. Knepley 9197b5a892a1SMatthew G. Knepley Input Parameters: 9198bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9199b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 9200b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 9201b5a892a1SMatthew G. Knepley 9202b5a892a1SMatthew G. Knepley Output Parameters: 9203bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9204b5a892a1SMatthew G. Knepley 9205b5a892a1SMatthew G. Knepley Level: advanced 9206b5a892a1SMatthew G. Knepley 9207bb7acecfSBarry Smith Note: 9208bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchVertexOrientation()` except it errors if not orientation is possible. 9209bb7acecfSBarry Smith 9210bb7acecfSBarry Smith Developer Note: 9211bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchVertexOrientation()` and error if none is found 9212bb7acecfSBarry Smith 9213bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetOrientation()` 9214b5a892a1SMatthew G. Knepley @*/ 9215d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9216d71ae5a4SJacob Faibussowitsch { 9217b5a892a1SMatthew G. Knepley PetscBool found; 9218b5a892a1SMatthew G. Knepley 9219b5a892a1SMatthew G. Knepley PetscFunctionBegin; 92209566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found)); 92217a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 9222b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9223b5a892a1SMatthew G. Knepley } 9224012bc364SMatthew G. Knepley 9225012bc364SMatthew G. Knepley /*@C 9226012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 9227012bc364SMatthew G. Knepley 9228012bc364SMatthew G. Knepley Not collective 9229012bc364SMatthew G. Knepley 9230012bc364SMatthew G. Knepley Input Parameters: 9231bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9232012bc364SMatthew G. Knepley - point - Coordinates of the point 9233012bc364SMatthew G. Knepley 9234012bc364SMatthew G. Knepley Output Parameters: 9235012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 9236012bc364SMatthew G. Knepley 9237012bc364SMatthew G. Knepley Level: advanced 9238012bc364SMatthew G. Knepley 9239bb7acecfSBarry Smith .seealso: `DM`, `DMPolytopeType`, `DMLocatePoints()` 9240012bc364SMatthew G. Knepley @*/ 9241d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 9242d71ae5a4SJacob Faibussowitsch { 9243012bc364SMatthew G. Knepley PetscReal sum = 0.0; 9244012bc364SMatthew G. Knepley PetscInt d; 9245012bc364SMatthew G. Knepley 9246012bc364SMatthew G. Knepley PetscFunctionBegin; 9247012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 9248012bc364SMatthew G. Knepley switch (ct) { 9249012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 9250012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 9251012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 92529371c9d4SSatish Balay if (point[d] < -1.0) { 92539371c9d4SSatish Balay *inside = PETSC_FALSE; 92549371c9d4SSatish Balay break; 92559371c9d4SSatish Balay } 9256012bc364SMatthew G. Knepley sum += point[d]; 9257012bc364SMatthew G. Knepley } 92589371c9d4SSatish Balay if (sum > PETSC_SMALL) { 92599371c9d4SSatish Balay *inside = PETSC_FALSE; 92609371c9d4SSatish Balay break; 92619371c9d4SSatish Balay } 9262012bc364SMatthew G. Knepley break; 9263012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 9264012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 9265012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 92669371c9d4SSatish Balay if (PetscAbsReal(point[d]) > 1. + PETSC_SMALL) { 92679371c9d4SSatish Balay *inside = PETSC_FALSE; 9268012bc364SMatthew G. Knepley break; 92699371c9d4SSatish Balay } 92709371c9d4SSatish Balay break; 9271d71ae5a4SJacob Faibussowitsch default: 9272d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 9273012bc364SMatthew G. Knepley } 9274012bc364SMatthew G. Knepley PetscFunctionReturn(0); 9275012bc364SMatthew G. Knepley } 9276