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); 3214*9f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 3215*9f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 3216*9f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 3217f089877aSRichard Tran Mills PetscFunctionReturn(0); 3218f089877aSRichard Tran Mills } 3219f089877aSRichard Tran Mills 3220f089877aSRichard Tran Mills /*@ 3221bb7acecfSBarry Smith DMLocalToLocalEnd - Maps from a local vector to another local vector where the ghost 3222bb7acecfSBarry Smith points in the second are set correctly. Must be preceded by `DMLocalToLocalBegin()`. 3223f089877aSRichard Tran Mills 3224d083f849SBarry Smith Neighbor-wise Collective on dm 3225f089877aSRichard Tran Mills 3226f089877aSRichard Tran Mills Input Parameters: 3227bb7acecfSBarry Smith + da - the `DM` object 3228bc0a1609SRichard Tran Mills . g - the original local vector 3229bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3230f089877aSRichard Tran Mills 3231bc0a1609SRichard Tran Mills Output Parameter: 3232bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3233f089877aSRichard Tran Mills 3234f089877aSRichard Tran Mills Level: intermediate 3235f089877aSRichard Tran Mills 3236bb7acecfSBarry Smith .seealso: `DMLocalToLocalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMLocalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3237f089877aSRichard Tran Mills 3238f089877aSRichard Tran Mills @*/ 3239d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 3240d71ae5a4SJacob Faibussowitsch { 3241f089877aSRichard Tran Mills PetscFunctionBegin; 3242f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3243*9f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 3244*9f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 3245*9f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 3246f089877aSRichard Tran Mills PetscFunctionReturn(0); 3247f089877aSRichard Tran Mills } 3248f089877aSRichard Tran Mills 324947c6ae99SBarry Smith /*@ 3250bb7acecfSBarry Smith DMCoarsen - Coarsens a `DM` object using a standard, non-adaptive coarsening of the underlying mesh 325147c6ae99SBarry Smith 3252d083f849SBarry Smith Collective on dm 325347c6ae99SBarry Smith 3254d8d19677SJose E. Roman Input Parameters: 3255bb7acecfSBarry Smith + dm - the `DM` object 3256bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or MPI_COMM_NULL) 325747c6ae99SBarry Smith 325847c6ae99SBarry Smith Output Parameter: 3259bb7acecfSBarry Smith . dmc - the coarsened `DM` 326047c6ae99SBarry Smith 326147c6ae99SBarry Smith Level: developer 326247c6ae99SBarry Smith 3263bb7acecfSBarry Smith .seealso: `DM`, `DMRefine()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 326447c6ae99SBarry Smith 326547c6ae99SBarry Smith @*/ 3266d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 3267d71ae5a4SJacob Faibussowitsch { 3268b17ce1afSJed Brown DMCoarsenHookLink link; 326947c6ae99SBarry Smith 327047c6ae99SBarry Smith PetscFunctionBegin; 3271171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32729566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Coarsen, dm, 0, 0, 0)); 3273dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsen, comm, dmc); 3274b9d85ea2SLisandro Dalcin if (*dmc) { 3275a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 32769566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm, *dmc)); 327743842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 32789566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmc)); 3279644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 32800598a293SJed Brown (*dmc)->levelup = dm->levelup; 3281656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 32829566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmc, dm->mattype)); 3283b17ce1afSJed Brown for (link = dm->coarsenhook; link; link = link->next) { 32849566063dSJacob Faibussowitsch if (link->coarsenhook) PetscCall((*link->coarsenhook)(dm, *dmc, link->ctx)); 3285b17ce1afSJed Brown } 3286b9d85ea2SLisandro Dalcin } 32879566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Coarsen, dm, 0, 0, 0)); 32887a8be351SBarry Smith PetscCheck(*dmc, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 3289b17ce1afSJed Brown PetscFunctionReturn(0); 3290b17ce1afSJed Brown } 3291b17ce1afSJed Brown 3292bb9467b5SJed Brown /*@C 3293b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3294b17ce1afSJed Brown 3295bb7acecfSBarry Smith Logically Collective on fine 3296b17ce1afSJed Brown 32974165533cSJose E. Roman Input Parameters: 3298bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3299b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3300bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels (called once per `SNESSolve()`) 33010298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3302b17ce1afSJed Brown 3303b17ce1afSJed Brown Calling sequence of coarsenhook: 3304b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 3305b17ce1afSJed Brown 3306bb7acecfSBarry Smith + fine - fine level `DM` 3307bb7acecfSBarry Smith . coarse - coarse level `DM` to restrict problem to 3308b17ce1afSJed Brown - ctx - optional user-defined function context 3309b17ce1afSJed Brown 3310b17ce1afSJed Brown Calling sequence for restricthook: 3311c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 3312bb7acecfSBarry Smith $ 3313bb7acecfSBarry Smith + fine - fine level `DM` 3314bb7acecfSBarry Smith . mrestrict - matrix restricting a fine-level solution to the coarse grid, usually the transpose of the interpolation 3315c833c3b5SJed Brown . rscale - scaling vector for restriction 3316c833c3b5SJed Brown . inject - matrix restricting by injection 3317b17ce1afSJed Brown . coarse - coarse level DM to update 3318b17ce1afSJed Brown - ctx - optional user-defined function context 3319b17ce1afSJed Brown 3320b17ce1afSJed Brown Level: advanced 3321b17ce1afSJed Brown 3322b17ce1afSJed Brown Notes: 3323bb7acecfSBarry 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`. 3324b17ce1afSJed Brown 3325b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3326b17ce1afSJed Brown 3327b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3328bb7acecfSBarry Smith extract the finest level information from its context (instead of from the `SNES`). 3329b17ce1afSJed Brown 3330bb7acecfSBarry Smith The hooks are automatically called by `DMRestrict()` 3331bb7acecfSBarry Smith 3332bb7acecfSBarry Smith Fortran Note: 3333bb7acecfSBarry Smith This function is not available from Fortran. 3334bb9467b5SJed Brown 3335db781477SPatrick Sanan .seealso: `DMCoarsenHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3336b17ce1afSJed Brown @*/ 3337d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHookAdd(DM fine, PetscErrorCode (*coarsenhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, Mat, Vec, Mat, DM, void *), void *ctx) 3338d71ae5a4SJacob Faibussowitsch { 3339b17ce1afSJed Brown DMCoarsenHookLink link, *p; 3340b17ce1afSJed Brown 3341b17ce1afSJed Brown PetscFunctionBegin; 3342b17ce1afSJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 33431e3d8eccSJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 33441e3d8eccSJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 33451e3d8eccSJed Brown } 33469566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3347b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3348b17ce1afSJed Brown link->restricthook = restricthook; 3349b17ce1afSJed Brown link->ctx = ctx; 33500298fd71SBarry Smith link->next = NULL; 3351b17ce1afSJed Brown *p = link; 3352b17ce1afSJed Brown PetscFunctionReturn(0); 3353b17ce1afSJed Brown } 3354b17ce1afSJed Brown 3355dc822a44SJed Brown /*@C 3356bb7acecfSBarry Smith DMCoarsenHookRemove - remove a callback set with `DMCoarsenHookAdd()` 3357dc822a44SJed Brown 3358bb7acecfSBarry Smith Logically Collective on fine 3359dc822a44SJed Brown 33604165533cSJose E. Roman Input Parameters: 3361bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3362dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3363bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels 3364dc822a44SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3365dc822a44SJed Brown 3366dc822a44SJed Brown Level: advanced 3367dc822a44SJed Brown 3368bb7acecfSBarry Smith Note: 3369dc822a44SJed Brown This function does nothing if the hook is not in the list. 3370dc822a44SJed Brown 3371bb7acecfSBarry Smith Fortran Note: 3372bb7acecfSBarry Smith This function is not available from Fortran. 3373dc822a44SJed Brown 3374db781477SPatrick Sanan .seealso: `DMCoarsenHookAdd()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3375dc822a44SJed Brown @*/ 3376d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHookRemove(DM fine, PetscErrorCode (*coarsenhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, Mat, Vec, Mat, DM, void *), void *ctx) 3377d71ae5a4SJacob Faibussowitsch { 3378dc822a44SJed Brown DMCoarsenHookLink link, *p; 3379dc822a44SJed Brown 3380dc822a44SJed Brown PetscFunctionBegin; 3381dc822a44SJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 3382dc822a44SJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3383dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3384dc822a44SJed Brown link = *p; 3385dc822a44SJed Brown *p = link->next; 33869566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3387dc822a44SJed Brown break; 3388dc822a44SJed Brown } 3389dc822a44SJed Brown } 3390dc822a44SJed Brown PetscFunctionReturn(0); 3391dc822a44SJed Brown } 3392dc822a44SJed Brown 3393b17ce1afSJed Brown /*@ 3394bb7acecfSBarry Smith DMRestrict - restricts user-defined problem data to a coarser `DM` by running hooks registered by `DMCoarsenHookAdd()` 3395b17ce1afSJed Brown 3396b17ce1afSJed Brown Collective if any hooks are 3397b17ce1afSJed Brown 33984165533cSJose E. Roman Input Parameters: 3399bb7acecfSBarry Smith + fine - finer `DM` from which the data is obtained 3400bb7acecfSBarry Smith . restrct - restriction matrix, apply using `MatRestrict()`, usually the transpose of the interpolation 3401e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3402bb7acecfSBarry Smith . inject - injection matrix, also use `MatRestrict()` 3403e91eccc2SStefano Zampini - coarse - coarser DM to update 3404b17ce1afSJed Brown 3405b17ce1afSJed Brown Level: developer 3406b17ce1afSJed Brown 3407bb7acecfSBarry Smith Developer Note: 3408bb7acecfSBarry Smith Though this routine is called `DMRestrict()` the hooks are added with `DMCoarsenHookAdd()`, a consistent terminology would be better 3409bb7acecfSBarry Smith 3410bb7acecfSBarry Smith .seealso: `DMCoarsenHookAdd()`, `MatRestrict()`, `DMInterpolate()`, `DMRefineHookAdd()` 3411b17ce1afSJed Brown @*/ 3412d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestrict(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse) 3413d71ae5a4SJacob Faibussowitsch { 3414b17ce1afSJed Brown DMCoarsenHookLink link; 3415b17ce1afSJed Brown 3416b17ce1afSJed Brown PetscFunctionBegin; 3417b17ce1afSJed Brown for (link = fine->coarsenhook; link; link = link->next) { 34181baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(fine, restrct, rscale, inject, coarse, link->ctx)); 3419b17ce1afSJed Brown } 342047c6ae99SBarry Smith PetscFunctionReturn(0); 342147c6ae99SBarry Smith } 342247c6ae99SBarry Smith 3423bb9467b5SJed Brown /*@C 3424be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 34255dbd56e3SPeter Brune 3426d083f849SBarry Smith Logically Collective on global 34275dbd56e3SPeter Brune 34284165533cSJose E. Roman Input Parameters: 3429bb7acecfSBarry Smith + global - global `DM` 3430bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 34315dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 34320298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 34335dbd56e3SPeter Brune 3434ec4806b8SPeter Brune Calling sequence for ddhook: 3435ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 3436ec4806b8SPeter Brune 3437bb7acecfSBarry Smith + global - global `DM` 3438bb7acecfSBarry Smith . block - block `DM` 3439ec4806b8SPeter Brune - ctx - optional user-defined function context 3440ec4806b8SPeter Brune 34415dbd56e3SPeter Brune Calling sequence for restricthook: 3442ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 34435dbd56e3SPeter Brune 3444bb7acecfSBarry Smith + global - global `DM` 34455dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 34465dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 3447bb7acecfSBarry Smith . block - block `DM` 34485dbd56e3SPeter Brune - ctx - optional user-defined function context 34495dbd56e3SPeter Brune 34505dbd56e3SPeter Brune Level: advanced 34515dbd56e3SPeter Brune 34525dbd56e3SPeter Brune Notes: 3453bb7acecfSBarry Smith This function is only needed if auxiliary data needs to be set up on subdomain `DM`s. 34545dbd56e3SPeter Brune 34555dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 34565dbd56e3SPeter Brune 34575dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3458bb7acecfSBarry Smith extract the global information from its context (instead of from the `SNES`). 34595dbd56e3SPeter Brune 3460bb7acecfSBarry Smith Fortran Note: 3461bb7acecfSBarry Smith This function is not available from Fortran. 3462bb9467b5SJed Brown 3463bb7acecfSBarry Smith .seealso: `DMSubDomainHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 34645dbd56e3SPeter Brune @*/ 3465d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookAdd(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3466d71ae5a4SJacob Faibussowitsch { 3467be081cd6SPeter Brune DMSubDomainHookLink link, *p; 34685dbd56e3SPeter Brune 34695dbd56e3SPeter Brune PetscFunctionBegin; 34705dbd56e3SPeter Brune PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3471b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 3472b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 3473b3a6b972SJed Brown } 34749566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 34755dbd56e3SPeter Brune link->restricthook = restricthook; 3476be081cd6SPeter Brune link->ddhook = ddhook; 34775dbd56e3SPeter Brune link->ctx = ctx; 34780298fd71SBarry Smith link->next = NULL; 34795dbd56e3SPeter Brune *p = link; 34805dbd56e3SPeter Brune PetscFunctionReturn(0); 34815dbd56e3SPeter Brune } 34825dbd56e3SPeter Brune 3483b3a6b972SJed Brown /*@C 3484b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 3485b3a6b972SJed Brown 3486bb7acecfSBarry Smith Logically Collective on global 3487b3a6b972SJed Brown 34884165533cSJose E. Roman Input Parameters: 3489bb7acecfSBarry Smith + global - global `DM` 3490bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 3491b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 3492b3a6b972SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3493b3a6b972SJed Brown 3494b3a6b972SJed Brown Level: advanced 3495b3a6b972SJed Brown 3496bb7acecfSBarry Smith Fortran Note: 3497bb7acecfSBarry Smith This function is not available from Fortran. 3498b3a6b972SJed Brown 3499db781477SPatrick Sanan .seealso: `DMSubDomainHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3500b3a6b972SJed Brown @*/ 3501d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookRemove(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3502d71ae5a4SJacob Faibussowitsch { 3503b3a6b972SJed Brown DMSubDomainHookLink link, *p; 3504b3a6b972SJed Brown 3505b3a6b972SJed Brown PetscFunctionBegin; 3506b3a6b972SJed Brown PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3507b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3508b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3509b3a6b972SJed Brown link = *p; 3510b3a6b972SJed Brown *p = link->next; 35119566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3512b3a6b972SJed Brown break; 3513b3a6b972SJed Brown } 3514b3a6b972SJed Brown } 3515b3a6b972SJed Brown PetscFunctionReturn(0); 3516b3a6b972SJed Brown } 3517b3a6b972SJed Brown 35185dbd56e3SPeter Brune /*@ 3519bb7acecfSBarry Smith DMSubDomainRestrict - restricts user-defined problem data to a block `DM` by running hooks registered by `DMSubDomainHookAdd()` 35205dbd56e3SPeter Brune 35215dbd56e3SPeter Brune Collective if any hooks are 35225dbd56e3SPeter Brune 35234165533cSJose E. Roman Input Parameters: 3524bb7acecfSBarry Smith + fine - finer `DM` to use as a base 3525be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 3526be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 3527bb7acecfSBarry Smith - coarse - coarser `DM` to update 35285dbd56e3SPeter Brune 35295dbd56e3SPeter Brune Level: developer 35305dbd56e3SPeter Brune 3531db781477SPatrick Sanan .seealso: `DMCoarsenHookAdd()`, `MatRestrict()` 35325dbd56e3SPeter Brune @*/ 3533d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainRestrict(DM global, VecScatter oscatter, VecScatter gscatter, DM subdm) 3534d71ae5a4SJacob Faibussowitsch { 3535be081cd6SPeter Brune DMSubDomainHookLink link; 35365dbd56e3SPeter Brune 35375dbd56e3SPeter Brune PetscFunctionBegin; 3538be081cd6SPeter Brune for (link = global->subdomainhook; link; link = link->next) { 35391baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(global, oscatter, gscatter, subdm, link->ctx)); 35405dbd56e3SPeter Brune } 35415dbd56e3SPeter Brune PetscFunctionReturn(0); 35425dbd56e3SPeter Brune } 35435dbd56e3SPeter Brune 35445fe1f584SPeter Brune /*@ 3545bb7acecfSBarry Smith DMGetCoarsenLevel - Gets the number of coarsenings that have generated this `DM`. 35465fe1f584SPeter Brune 35475fe1f584SPeter Brune Not Collective 35485fe1f584SPeter Brune 35495fe1f584SPeter Brune Input Parameter: 3550bb7acecfSBarry Smith . dm - the `DM` object 35515fe1f584SPeter Brune 35525fe1f584SPeter Brune Output Parameter: 35536a7d9d85SPeter Brune . level - number of coarsenings 35545fe1f584SPeter Brune 35555fe1f584SPeter Brune Level: developer 35565fe1f584SPeter Brune 3557bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMSetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35585fe1f584SPeter Brune 35595fe1f584SPeter Brune @*/ 3560d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarsenLevel(DM dm, PetscInt *level) 3561d71ae5a4SJacob Faibussowitsch { 35625fe1f584SPeter Brune PetscFunctionBegin; 35635fe1f584SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3564b9d85ea2SLisandro Dalcin PetscValidIntPointer(level, 2); 35655fe1f584SPeter Brune *level = dm->leveldown; 35665fe1f584SPeter Brune PetscFunctionReturn(0); 35675fe1f584SPeter Brune } 35685fe1f584SPeter Brune 35699a64c4a8SMatthew G. Knepley /*@ 3570bb7acecfSBarry Smith DMSetCoarsenLevel - Sets the number of coarsenings that have generated this `DM`. 35719a64c4a8SMatthew G. Knepley 3572bb7acecfSBarry Smith Collective on dm 35739a64c4a8SMatthew G. Knepley 35749a64c4a8SMatthew G. Knepley Input Parameters: 3575bb7acecfSBarry Smith + dm - the `DM` object 35769a64c4a8SMatthew G. Knepley - level - number of coarsenings 35779a64c4a8SMatthew G. Knepley 35789a64c4a8SMatthew G. Knepley Level: developer 35799a64c4a8SMatthew G. Knepley 3580bb7acecfSBarry Smith Note: 3581bb7acecfSBarry Smith This is rarely used directly, the information is automatically set when a `DM` is created with `DMCoarsen()` 3582bb7acecfSBarry Smith 3583bb7acecfSBarry Smith .seealso: `DMSetCoarsenLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35849a64c4a8SMatthew G. Knepley @*/ 3585d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarsenLevel(DM dm, PetscInt level) 3586d71ae5a4SJacob Faibussowitsch { 35879a64c4a8SMatthew G. Knepley PetscFunctionBegin; 35889a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 35899a64c4a8SMatthew G. Knepley dm->leveldown = level; 35909a64c4a8SMatthew G. Knepley PetscFunctionReturn(0); 35919a64c4a8SMatthew G. Knepley } 35929a64c4a8SMatthew G. Knepley 359347c6ae99SBarry Smith /*@C 3594bb7acecfSBarry Smith DMRefineHierarchy - Refines a `DM` object, all levels at once 359547c6ae99SBarry Smith 3596d083f849SBarry Smith Collective on dm 359747c6ae99SBarry Smith 3598d8d19677SJose E. Roman Input Parameters: 3599bb7acecfSBarry Smith + dm - the `DM` object 360047c6ae99SBarry Smith - nlevels - the number of levels of refinement 360147c6ae99SBarry Smith 360247c6ae99SBarry Smith Output Parameter: 3603bb7acecfSBarry Smith . dmf - the refined `DM` hierarchy 360447c6ae99SBarry Smith 360547c6ae99SBarry Smith Level: developer 360647c6ae99SBarry Smith 3607bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMCoarsenHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 360847c6ae99SBarry Smith 360947c6ae99SBarry Smith @*/ 3610d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHierarchy(DM dm, PetscInt nlevels, DM dmf[]) 3611d71ae5a4SJacob Faibussowitsch { 361247c6ae99SBarry Smith PetscFunctionBegin; 3613171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36147a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 361547c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 3616b9d85ea2SLisandro Dalcin PetscValidPointer(dmf, 3); 361747c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 3618dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refinehierarchy, nlevels, dmf); 361947c6ae99SBarry Smith } else if (dm->ops->refine) { 362047c6ae99SBarry Smith PetscInt i; 362147c6ae99SBarry Smith 36229566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0])); 362348a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i])); 3624ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No RefineHierarchy for this DM yet"); 362547c6ae99SBarry Smith PetscFunctionReturn(0); 362647c6ae99SBarry Smith } 362747c6ae99SBarry Smith 362847c6ae99SBarry Smith /*@C 3629bb7acecfSBarry Smith DMCoarsenHierarchy - Coarsens a `DM` object, all levels at once 363047c6ae99SBarry Smith 3631d083f849SBarry Smith Collective on dm 363247c6ae99SBarry Smith 3633d8d19677SJose E. Roman Input Parameters: 3634bb7acecfSBarry Smith + dm - the `DM` object 363547c6ae99SBarry Smith - nlevels - the number of levels of coarsening 363647c6ae99SBarry Smith 363747c6ae99SBarry Smith Output Parameter: 3638bb7acecfSBarry Smith . dmc - the coarsened `DM` hierarchy 363947c6ae99SBarry Smith 364047c6ae99SBarry Smith Level: developer 364147c6ae99SBarry Smith 3642bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMRefineHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 364347c6ae99SBarry Smith 364447c6ae99SBarry Smith @*/ 3645d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 3646d71ae5a4SJacob Faibussowitsch { 364747c6ae99SBarry Smith PetscFunctionBegin; 3648171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36497a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 365047c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 365147c6ae99SBarry Smith PetscValidPointer(dmc, 3); 365247c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 3653dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsenhierarchy, nlevels, dmc); 365447c6ae99SBarry Smith } else if (dm->ops->coarsen) { 365547c6ae99SBarry Smith PetscInt i; 365647c6ae99SBarry Smith 36579566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0])); 365848a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i])); 3659ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No CoarsenHierarchy for this DM yet"); 366047c6ae99SBarry Smith PetscFunctionReturn(0); 366147c6ae99SBarry Smith } 366247c6ae99SBarry Smith 36631a266240SBarry Smith /*@C 3664bb7acecfSBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the `DM` is destroyed 36651a266240SBarry Smith 3666bb7acecfSBarry Smith Logically Collective if the function is collective 36671a266240SBarry Smith 36681a266240SBarry Smith Input Parameters: 3669bb7acecfSBarry Smith + dm - the `DM` object 36701a266240SBarry Smith - destroy - the destroy function 36711a266240SBarry Smith 36721a266240SBarry Smith Level: intermediate 36731a266240SBarry Smith 3674bb7acecfSBarry Smith .seealso: `DMSetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 36751a266240SBarry Smith 3676f07f9ceaSJed Brown @*/ 3677d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContextDestroy(DM dm, PetscErrorCode (*destroy)(void **)) 3678d71ae5a4SJacob Faibussowitsch { 36791a266240SBarry Smith PetscFunctionBegin; 3680171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36811a266240SBarry Smith dm->ctxdestroy = destroy; 36821a266240SBarry Smith PetscFunctionReturn(0); 36831a266240SBarry Smith } 36841a266240SBarry Smith 3685b07ff414SBarry Smith /*@ 3686bb7acecfSBarry Smith DMSetApplicationContext - Set a user context into a `DM` object 368747c6ae99SBarry Smith 368847c6ae99SBarry Smith Not Collective 368947c6ae99SBarry Smith 369047c6ae99SBarry Smith Input Parameters: 3691bb7acecfSBarry Smith + dm - the `DM` object 369247c6ae99SBarry Smith - ctx - the user context 369347c6ae99SBarry Smith 369447c6ae99SBarry Smith Level: intermediate 369547c6ae99SBarry Smith 3696bb7acecfSBarry Smith Note: 3697bb7acecfSBarry Smith A user context is a way to pass problem specific information that is accessable whenever the `DM` is available 3698bb7acecfSBarry Smith 3699bb7acecfSBarry Smith .seealso: `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 370047c6ae99SBarry Smith 370147c6ae99SBarry Smith @*/ 3702d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContext(DM dm, void *ctx) 3703d71ae5a4SJacob Faibussowitsch { 370447c6ae99SBarry Smith PetscFunctionBegin; 3705171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 370647c6ae99SBarry Smith dm->ctx = ctx; 370747c6ae99SBarry Smith PetscFunctionReturn(0); 370847c6ae99SBarry Smith } 370947c6ae99SBarry Smith 371047c6ae99SBarry Smith /*@ 3711bb7acecfSBarry Smith DMGetApplicationContext - Gets a user context from a `DM` object 371247c6ae99SBarry Smith 371347c6ae99SBarry Smith Not Collective 371447c6ae99SBarry Smith 371547c6ae99SBarry Smith Input Parameter: 3716bb7acecfSBarry Smith . dm - the `DM` object 371747c6ae99SBarry Smith 371847c6ae99SBarry Smith Output Parameter: 371947c6ae99SBarry Smith . ctx - the user context 372047c6ae99SBarry Smith 372147c6ae99SBarry Smith Level: intermediate 372247c6ae99SBarry Smith 3723bb7acecfSBarry Smith Note: 3724bb7acecfSBarry Smith A user context is a way to pass problem specific information that is accessable whenever the `DM` is available 3725bb7acecfSBarry Smith 3726bb7acecfSBarry Smith .seealso: `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 372747c6ae99SBarry Smith 372847c6ae99SBarry Smith @*/ 3729d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetApplicationContext(DM dm, void *ctx) 3730d71ae5a4SJacob Faibussowitsch { 373147c6ae99SBarry Smith PetscFunctionBegin; 3732171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37331b2093e4SBarry Smith *(void **)ctx = dm->ctx; 373447c6ae99SBarry Smith PetscFunctionReturn(0); 373547c6ae99SBarry Smith } 373647c6ae99SBarry Smith 373708da532bSDmitry Karpeev /*@C 3738bb7acecfSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for `SNESVI`. 373908da532bSDmitry Karpeev 3740d083f849SBarry Smith Logically Collective on dm 374108da532bSDmitry Karpeev 3742d8d19677SJose E. Roman Input Parameters: 374308da532bSDmitry Karpeev + dm - the DM object 37440298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 374508da532bSDmitry Karpeev 374608da532bSDmitry Karpeev Level: intermediate 374708da532bSDmitry Karpeev 3748bb7acecfSBarry Smith .seealso: `DMComputeVariableBounds()`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()`, 3749db781477SPatrick Sanan `DMSetJacobian()` 375008da532bSDmitry Karpeev 375108da532bSDmitry Karpeev @*/ 3752d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVariableBounds(DM dm, PetscErrorCode (*f)(DM, Vec, Vec)) 3753d71ae5a4SJacob Faibussowitsch { 375408da532bSDmitry Karpeev PetscFunctionBegin; 37555a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 375608da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 375708da532bSDmitry Karpeev PetscFunctionReturn(0); 375808da532bSDmitry Karpeev } 375908da532bSDmitry Karpeev 376008da532bSDmitry Karpeev /*@ 3761bb7acecfSBarry Smith DMHasVariableBounds - does the `DM` object have a variable bounds function? 376208da532bSDmitry Karpeev 376308da532bSDmitry Karpeev Not Collective 376408da532bSDmitry Karpeev 376508da532bSDmitry Karpeev Input Parameter: 3766bb7acecfSBarry Smith . dm - the `DM` object to destroy 376708da532bSDmitry Karpeev 376808da532bSDmitry Karpeev Output Parameter: 3769bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the variable bounds function exists 377008da532bSDmitry Karpeev 377108da532bSDmitry Karpeev Level: developer 377208da532bSDmitry Karpeev 3773bb7acecfSBarry Smith .seealso: `DMComputeVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 377408da532bSDmitry Karpeev 377508da532bSDmitry Karpeev @*/ 3776d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasVariableBounds(DM dm, PetscBool *flg) 3777d71ae5a4SJacob Faibussowitsch { 377808da532bSDmitry Karpeev PetscFunctionBegin; 37795a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3780534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 378108da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 378208da532bSDmitry Karpeev PetscFunctionReturn(0); 378308da532bSDmitry Karpeev } 378408da532bSDmitry Karpeev 378508da532bSDmitry Karpeev /*@C 3786bb7acecfSBarry Smith DMComputeVariableBounds - compute variable bounds used by `SNESVI`. 378708da532bSDmitry Karpeev 3788d083f849SBarry Smith Logically Collective on dm 378908da532bSDmitry Karpeev 3790f899ff85SJose E. Roman Input Parameter: 3791bb7acecfSBarry Smith . dm - the `DM` object 379208da532bSDmitry Karpeev 379308da532bSDmitry Karpeev Output parameters: 379408da532bSDmitry Karpeev + xl - lower bound 379508da532bSDmitry Karpeev - xu - upper bound 379608da532bSDmitry Karpeev 3797907376e6SBarry Smith Level: advanced 3798907376e6SBarry Smith 379995452b02SPatrick Sanan Notes: 380095452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 380108da532bSDmitry Karpeev 3802bb7acecfSBarry Smith .seealso: `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 380308da532bSDmitry Karpeev 380408da532bSDmitry Karpeev @*/ 3805d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 3806d71ae5a4SJacob Faibussowitsch { 380708da532bSDmitry Karpeev PetscFunctionBegin; 38085a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 380908da532bSDmitry Karpeev PetscValidHeaderSpecific(xl, VEC_CLASSID, 2); 38105a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu, VEC_CLASSID, 3); 3811dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, computevariablebounds, xl, xu); 381208da532bSDmitry Karpeev PetscFunctionReturn(0); 381308da532bSDmitry Karpeev } 381408da532bSDmitry Karpeev 3815b0ae01b7SPeter Brune /*@ 3816bb7acecfSBarry Smith DMHasColoring - does the `DM` object have a method of providing a coloring? 3817b0ae01b7SPeter Brune 3818b0ae01b7SPeter Brune Not Collective 3819b0ae01b7SPeter Brune 3820b0ae01b7SPeter Brune Input Parameter: 3821b0ae01b7SPeter Brune . dm - the DM object 3822b0ae01b7SPeter Brune 3823b0ae01b7SPeter Brune Output Parameter: 3824bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateColoring()`. 3825b0ae01b7SPeter Brune 3826b0ae01b7SPeter Brune Level: developer 3827b0ae01b7SPeter Brune 3828bb7acecfSBarry Smith .seealso: `DMCreateColoring()` 3829b0ae01b7SPeter Brune 3830b0ae01b7SPeter Brune @*/ 3831d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasColoring(DM dm, PetscBool *flg) 3832d71ae5a4SJacob Faibussowitsch { 3833b0ae01b7SPeter Brune PetscFunctionBegin; 38345a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3835534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 3836b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 3837b0ae01b7SPeter Brune PetscFunctionReturn(0); 3838b0ae01b7SPeter Brune } 3839b0ae01b7SPeter Brune 38403ad4599aSBarry Smith /*@ 3841bb7acecfSBarry Smith DMHasCreateRestriction - does the `DM` object have a method of providing a restriction? 38423ad4599aSBarry Smith 38433ad4599aSBarry Smith Not Collective 38443ad4599aSBarry Smith 38453ad4599aSBarry Smith Input Parameter: 3846bb7acecfSBarry Smith . dm - the `DM` object 38473ad4599aSBarry Smith 38483ad4599aSBarry Smith Output Parameter: 3849bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateRestriction()`. 38503ad4599aSBarry Smith 38513ad4599aSBarry Smith Level: developer 38523ad4599aSBarry Smith 3853bb7acecfSBarry Smith .seealso: `DMCreateRestriction()`, `DMHasCreateInterpolation()`, `DMHasCreateInjection()` 38543ad4599aSBarry Smith 38553ad4599aSBarry Smith @*/ 3856d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateRestriction(DM dm, PetscBool *flg) 3857d71ae5a4SJacob Faibussowitsch { 38583ad4599aSBarry Smith PetscFunctionBegin; 38595a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3860534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 38613ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 38623ad4599aSBarry Smith PetscFunctionReturn(0); 38633ad4599aSBarry Smith } 38643ad4599aSBarry Smith 3865a7058e45SLawrence Mitchell /*@ 3866bb7acecfSBarry Smith DMHasCreateInjection - does the `DM` object have a method of providing an injection? 3867a7058e45SLawrence Mitchell 3868a7058e45SLawrence Mitchell Not Collective 3869a7058e45SLawrence Mitchell 3870a7058e45SLawrence Mitchell Input Parameter: 3871bb7acecfSBarry Smith . dm - the `DM` object 3872a7058e45SLawrence Mitchell 3873a7058e45SLawrence Mitchell Output Parameter: 3874bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateInjection()`. 3875a7058e45SLawrence Mitchell 3876a7058e45SLawrence Mitchell Level: developer 3877a7058e45SLawrence Mitchell 3878bb7acecfSBarry Smith .seealso: `DMCreateInjection()`, `DMHasCreateRestriction()`, `DMHasCreateInterpolation()` 3879a7058e45SLawrence Mitchell 3880a7058e45SLawrence Mitchell @*/ 3881d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateInjection(DM dm, PetscBool *flg) 3882d71ae5a4SJacob Faibussowitsch { 3883a7058e45SLawrence Mitchell PetscFunctionBegin; 38845a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3885534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 3886dbbe0bcdSBarry Smith if (dm->ops->hascreateinjection) PetscUseTypeMethod(dm, hascreateinjection, flg); 3887ad540459SPierre Jolivet else *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 3888a7058e45SLawrence Mitchell PetscFunctionReturn(0); 3889a7058e45SLawrence Mitchell } 3890a7058e45SLawrence Mitchell 38910298fd71SBarry Smith PetscFunctionList DMList = NULL; 3892264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3893264ace61SBarry Smith 3894264ace61SBarry Smith /*@C 3895bb7acecfSBarry Smith DMSetType - Builds a `DM`, for a particular `DM` implementation. 3896264ace61SBarry Smith 3897d083f849SBarry Smith Collective on dm 3898264ace61SBarry Smith 3899264ace61SBarry Smith Input Parameters: 3900bb7acecfSBarry Smith + dm - The `DM` object 3901bb7acecfSBarry Smith - method - The name of the `DMType`, for example `DMDA`, `DMPLEX` 3902264ace61SBarry Smith 3903264ace61SBarry Smith Options Database Key: 3904bb7acecfSBarry Smith . -dm_type <type> - Sets the `DM` type; use -help for a list of available types 3905264ace61SBarry Smith 3906264ace61SBarry Smith Level: intermediate 3907264ace61SBarry Smith 3908bb7acecfSBarry Smith Note: 3909bb7acecfSBarry Smith Of the `DM` is constructed by directly calling a function to construct a particular `DM`, for example, `DMDACreate2d()` or `DMPLEXCreateBoxMesh()` 3910bb7acecfSBarry Smith 3911bb7acecfSBarry Smith .seealso: `DMType`, `DMDA`, `DMPLEX`, `DMGetType()`, `DMCreate()`, `DMDACreate2d()` 3912264ace61SBarry Smith @*/ 3913d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetType(DM dm, DMType method) 3914d71ae5a4SJacob Faibussowitsch { 3915264ace61SBarry Smith PetscErrorCode (*r)(DM); 3916264ace61SBarry Smith PetscBool match; 3917264ace61SBarry Smith 3918264ace61SBarry Smith PetscFunctionBegin; 3919264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39209566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, method, &match)); 3921264ace61SBarry Smith if (match) PetscFunctionReturn(0); 3922264ace61SBarry Smith 39239566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 39249566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(DMList, method, &r)); 39257a8be351SBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3926264ace61SBarry Smith 3927dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, destroy); 39289566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops, sizeof(*dm->ops))); 39299566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)dm, method)); 39309566063dSJacob Faibussowitsch PetscCall((*r)(dm)); 3931264ace61SBarry Smith PetscFunctionReturn(0); 3932264ace61SBarry Smith } 3933264ace61SBarry Smith 3934264ace61SBarry Smith /*@C 3935bb7acecfSBarry Smith DMGetType - Gets the `DM` type name (as a string) from the `DM`. 3936264ace61SBarry Smith 3937264ace61SBarry Smith Not Collective 3938264ace61SBarry Smith 3939264ace61SBarry Smith Input Parameter: 3940bb7acecfSBarry Smith . dm - The `DM` 3941264ace61SBarry Smith 3942264ace61SBarry Smith Output Parameter: 3943bb7acecfSBarry Smith . type - The `DMType` name 3944264ace61SBarry Smith 3945264ace61SBarry Smith Level: intermediate 3946264ace61SBarry Smith 3947bb7acecfSBarry Smith .seealso: `DMType`, `DMDA`, `DMPLEX`, `DMSetType()`, `DMCreate()` 3948264ace61SBarry Smith @*/ 3949d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetType(DM dm, DMType *type) 3950d71ae5a4SJacob Faibussowitsch { 3951264ace61SBarry Smith PetscFunctionBegin; 3952264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3953c959eef4SJed Brown PetscValidPointer(type, 2); 39549566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 3955264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 3956264ace61SBarry Smith PetscFunctionReturn(0); 3957264ace61SBarry Smith } 3958264ace61SBarry Smith 395967a56275SMatthew G Knepley /*@C 3960bb7acecfSBarry Smith DMConvert - Converts a `DM` to another `DM`, either of the same or different type. 396167a56275SMatthew G Knepley 3962d083f849SBarry Smith Collective on dm 396367a56275SMatthew G Knepley 396467a56275SMatthew G Knepley Input Parameters: 3965bb7acecfSBarry Smith + dm - the `DM` 3966bb7acecfSBarry Smith - newtype - new `DM` type (use "same" for the same type) 396767a56275SMatthew G Knepley 396867a56275SMatthew G Knepley Output Parameter: 3969bb7acecfSBarry Smith . M - pointer to new `DM` 397067a56275SMatthew G Knepley 397167a56275SMatthew G Knepley Notes: 3972bb7acecfSBarry Smith Cannot be used to convert a sequential `DM` to a parallel or a parallel to sequential, 3973bb7acecfSBarry Smith the MPI communicator of the generated `DM` is always the same as the communicator 3974bb7acecfSBarry Smith of the input `DM`. 397567a56275SMatthew G Knepley 397667a56275SMatthew G Knepley Level: intermediate 397767a56275SMatthew G Knepley 3978bb7acecfSBarry Smith .seealso: `DM`, `DMSetType()`, `DMCreate()`, `DMClone()` 397967a56275SMatthew G Knepley @*/ 3980d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 3981d71ae5a4SJacob Faibussowitsch { 398267a56275SMatthew G Knepley DM B; 398367a56275SMatthew G Knepley char convname[256]; 3984c067b6caSMatthew G. Knepley PetscBool sametype /*, issame */; 398567a56275SMatthew G Knepley 398667a56275SMatthew G Knepley PetscFunctionBegin; 398767a56275SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 398867a56275SMatthew G Knepley PetscValidType(dm, 1); 398967a56275SMatthew G Knepley PetscValidPointer(M, 3); 39909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, newtype, &sametype)); 39919566063dSJacob Faibussowitsch /* PetscCall(PetscStrcmp(newtype, "same", &issame)); */ 3992c067b6caSMatthew G. Knepley if (sametype) { 3993c067b6caSMatthew G. Knepley *M = dm; 39949566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 3995c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 3996c067b6caSMatthew G. Knepley } else { 39970298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM *) = NULL; 399867a56275SMatthew G Knepley 399967a56275SMatthew G Knepley /* 400067a56275SMatthew G Knepley Order of precedence: 400167a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 400267a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 400367a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 400467a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 400567a56275SMatthew G Knepley 5) Use a really basic converter. 400667a56275SMatthew G Knepley */ 400767a56275SMatthew G Knepley 400867a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 40099566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40109566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40119566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40129566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40139566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40149566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)dm, convname, &conv)); 401567a56275SMatthew G Knepley if (conv) goto foundconv; 401667a56275SMatthew G Knepley 401767a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 40189566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &B)); 40199566063dSJacob Faibussowitsch PetscCall(DMSetType(B, newtype)); 40209566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40219566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40229566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40239566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40249566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40259566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 402667a56275SMatthew G Knepley if (conv) { 40279566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 402867a56275SMatthew G Knepley goto foundconv; 402967a56275SMatthew G Knepley } 403067a56275SMatthew G Knepley 403167a56275SMatthew G Knepley #if 0 403267a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 403367a56275SMatthew G Knepley conv = B->ops->convertfrom; 40349566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 403567a56275SMatthew G Knepley if (conv) goto foundconv; 403667a56275SMatthew G Knepley 403767a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 403867a56275SMatthew G Knepley if (dm->ops->convert) { 403967a56275SMatthew G Knepley conv = dm->ops->convert; 404067a56275SMatthew G Knepley } 404167a56275SMatthew G Knepley if (conv) goto foundconv; 404267a56275SMatthew G Knepley #endif 404367a56275SMatthew G Knepley 404467a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 404598921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject)dm)->type_name, newtype); 404667a56275SMatthew G Knepley 404767a56275SMatthew G Knepley foundconv: 40489566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Convert, dm, 0, 0, 0)); 40499566063dSJacob Faibussowitsch PetscCall((*conv)(dm, newtype, M)); 405012fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 405190b157c4SStefano Zampini { 40524fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 40536858538eSMatthew G. Knepley 40544fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 40554fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*M, maxCell, Lstart, L)); 4056c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 40579566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->vectype)); 40589566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*M)->vectype)); 40599566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->mattype)); 40609566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*M)->mattype)); 406112fa691eSMatthew G. Knepley } 40629566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Convert, dm, 0, 0, 0)); 406367a56275SMatthew G Knepley } 40649566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 406567a56275SMatthew G Knepley PetscFunctionReturn(0); 406667a56275SMatthew G Knepley } 4067264ace61SBarry Smith 4068264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 4069264ace61SBarry Smith 4070264ace61SBarry Smith /*@C 4071bb7acecfSBarry Smith DMRegister - Adds a new `DM` type implementation 40721c84c290SBarry Smith 40731c84c290SBarry Smith Not Collective 40741c84c290SBarry Smith 40751c84c290SBarry Smith Input Parameters: 40761c84c290SBarry Smith + name - The name of a new user-defined creation routine 40771c84c290SBarry Smith - create_func - The creation routine itself 40781c84c290SBarry Smith 40791c84c290SBarry Smith Notes: 4080bb7acecfSBarry Smith DMRegister() may be called multiple times to add several user-defined `DM`s 40811c84c290SBarry Smith 40821c84c290SBarry Smith Sample usage: 40831c84c290SBarry Smith .vb 4084bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 40851c84c290SBarry Smith .ve 40861c84c290SBarry Smith 40871c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 40881c84c290SBarry Smith .vb 40891c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 40901c84c290SBarry Smith DMSetType(DM,"my_da"); 40911c84c290SBarry Smith .ve 40921c84c290SBarry Smith or at runtime via the option 40931c84c290SBarry Smith .vb 40941c84c290SBarry Smith -da_type my_da 40951c84c290SBarry Smith .ve 4096264ace61SBarry Smith 4097264ace61SBarry Smith Level: advanced 40981c84c290SBarry Smith 4099bb7acecfSBarry Smith .seealso: `DM`, `DMType`, `DMSetType()`, `DMRegisterAll()`, `DMRegisterDestroy()` 41001c84c290SBarry Smith 4101264ace61SBarry Smith @*/ 4102d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRegister(const char sname[], PetscErrorCode (*function)(DM)) 4103d71ae5a4SJacob Faibussowitsch { 4104264ace61SBarry Smith PetscFunctionBegin; 41059566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 41069566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&DMList, sname, function)); 4107264ace61SBarry Smith PetscFunctionReturn(0); 4108264ace61SBarry Smith } 4109264ace61SBarry Smith 4110b859378eSBarry Smith /*@C 4111bb7acecfSBarry Smith DMLoad - Loads a DM that has been stored in binary with `DMView()`. 4112b859378eSBarry Smith 4113d083f849SBarry Smith Collective on viewer 4114b859378eSBarry Smith 4115b859378eSBarry Smith Input Parameters: 4116bb7acecfSBarry Smith + newdm - the newly loaded `DM`, this needs to have been created with `DMCreate()` or 4117bb7acecfSBarry Smith some related function before a call to `DMLoad()`. 4118bb7acecfSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or 4119bb7acecfSBarry Smith `PETSCVIEWERHDF5` file viewer, obtained from `PetscViewerHDF5Open()` 4120b859378eSBarry Smith 4121b859378eSBarry Smith Level: intermediate 4122b859378eSBarry Smith 4123b859378eSBarry Smith Notes: 412455849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4125b859378eSBarry Smith 4126bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` format, one can save multiple `DMPLEX` 4127bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 4128bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 4129cd7e8a5eSksagiyam 4130b859378eSBarry Smith Notes for advanced users: 4131b859378eSBarry Smith Most users should not need to know the details of the binary storage 4132bb7acecfSBarry Smith format, since `DMLoad()` and `DMView()` completely hide these details. 4133b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 4134b859378eSBarry Smith format is 4135b859378eSBarry Smith .vb 4136b859378eSBarry Smith has not yet been determined 4137b859378eSBarry Smith .ve 4138b859378eSBarry Smith 4139db781477SPatrick Sanan .seealso: `PetscViewerBinaryOpen()`, `DMView()`, `MatLoad()`, `VecLoad()` 4140b859378eSBarry Smith @*/ 4141d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4142d71ae5a4SJacob Faibussowitsch { 41439331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4144b859378eSBarry Smith 4145b859378eSBarry Smith PetscFunctionBegin; 4146b859378eSBarry Smith PetscValidHeaderSpecific(newdm, DM_CLASSID, 1); 4147b859378eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 41489566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckReadable(viewer)); 41499566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 41509566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 41519566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Load, viewer, 0, 0, 0)); 41529331c7a4SMatthew G. Knepley if (isbinary) { 41539331c7a4SMatthew G. Knepley PetscInt classid; 41549331c7a4SMatthew G. Knepley char type[256]; 4155b859378eSBarry Smith 41569566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 41577a8be351SBarry Smith PetscCheck(classid == DM_FILE_CLASSID, PetscObjectComm((PetscObject)newdm), PETSC_ERR_ARG_WRONG, "Not DM next in file, classid found %d", (int)classid); 41589566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 41599566063dSJacob Faibussowitsch PetscCall(DMSetType(newdm, type)); 4160dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41619331c7a4SMatthew G. Knepley } else if (ishdf5) { 4162dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41639331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 41649566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Load, viewer, 0, 0, 0)); 4165b859378eSBarry Smith PetscFunctionReturn(0); 4166b859378eSBarry Smith } 4167b859378eSBarry Smith 41687da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 41697da65231SMatthew G Knepley 4170d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4171d71ae5a4SJacob Faibussowitsch { 41721d47ebbbSSatish Balay PetscInt f; 41731b30c384SMatthew G Knepley 41747da65231SMatthew G Knepley PetscFunctionBegin; 417563a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 417648a46eb9SPierre Jolivet for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]))); 41777da65231SMatthew G Knepley PetscFunctionReturn(0); 41787da65231SMatthew G Knepley } 41797da65231SMatthew G Knepley 4180d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4181d71ae5a4SJacob Faibussowitsch { 41821b30c384SMatthew G Knepley PetscInt f, g; 41837da65231SMatthew G Knepley 41847da65231SMatthew G Knepley PetscFunctionBegin; 418563a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41861d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 41879566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |")); 418848a46eb9SPierre Jolivet for (g = 0; g < cols; ++g) PetscCall(PetscPrintf(PETSC_COMM_SELF, " % 9.5g", (double)PetscRealPart(A[f * cols + g]))); 41899566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |\n")); 41907da65231SMatthew G Knepley } 41917da65231SMatthew G Knepley PetscFunctionReturn(0); 41927da65231SMatthew G Knepley } 4193e7c4fc90SDmitry Karpeev 4194d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4195d71ae5a4SJacob Faibussowitsch { 41960c5b8624SToby Isaac PetscInt localSize, bs; 41970c5b8624SToby Isaac PetscMPIInt size; 41980c5b8624SToby Isaac Vec x, xglob; 41990c5b8624SToby Isaac const PetscScalar *xarray; 4200e759306cSMatthew G. Knepley 4201e759306cSMatthew G. Knepley PetscFunctionBegin; 42029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 42039566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &x)); 42049566063dSJacob Faibussowitsch PetscCall(VecCopy(X, x)); 42059566063dSJacob Faibussowitsch PetscCall(VecChop(x, tol)); 42069566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "%s:\n", name)); 42070c5b8624SToby Isaac if (size > 1) { 42089566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(x, &localSize)); 42099566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xarray)); 42109566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(x, &bs)); 42119566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm), bs, localSize, PETSC_DETERMINE, xarray, &xglob)); 42120c5b8624SToby Isaac } else { 42130c5b8624SToby Isaac xglob = x; 42140c5b8624SToby Isaac } 42159566063dSJacob Faibussowitsch PetscCall(VecView(xglob, PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)dm)))); 42160c5b8624SToby Isaac if (size > 1) { 42179566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xglob)); 42189566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xarray)); 42190c5b8624SToby Isaac } 42209566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 4221e759306cSMatthew G. Knepley PetscFunctionReturn(0); 4222e759306cSMatthew G. Knepley } 4223e759306cSMatthew G. Knepley 422488ed4aceSMatthew G Knepley /*@ 4225bb7acecfSBarry Smith DMGetSection - Get the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMGetLocalSection()`. Deprecated in v3.12 4226061576a5SJed Brown 4227061576a5SJed Brown Input Parameter: 4228bb7acecfSBarry Smith . dm - The `DM` 4229061576a5SJed Brown 4230061576a5SJed Brown Output Parameter: 4231bb7acecfSBarry Smith . section - The `PetscSection` 4232061576a5SJed Brown 4233061576a5SJed Brown Options Database Keys: 4234bb7acecfSBarry Smith . -dm_petscsection_view - View the `PetscSection` created by the `DM` 4235061576a5SJed Brown 4236061576a5SJed Brown Level: advanced 4237061576a5SJed Brown 4238061576a5SJed Brown Notes: 4239bb7acecfSBarry Smith Use `DMGetLocalSection()` in new code. 4240061576a5SJed Brown 4241bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 4242061576a5SJed Brown 4243db781477SPatrick Sanan .seealso: `DMGetLocalSection()`, `DMSetLocalSection()`, `DMGetGlobalSection()` 4244061576a5SJed Brown @*/ 4245d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4246d71ae5a4SJacob Faibussowitsch { 4247061576a5SJed Brown PetscFunctionBegin; 42489566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, section)); 4249061576a5SJed Brown PetscFunctionReturn(0); 4250061576a5SJed Brown } 4251061576a5SJed Brown 4252061576a5SJed Brown /*@ 4253bb7acecfSBarry Smith DMGetLocalSection - Get the `PetscSection` encoding the local data layout for the `DM`. 425488ed4aceSMatthew G Knepley 425588ed4aceSMatthew G Knepley Input Parameter: 4256bb7acecfSBarry Smith . dm - The `DM` 425788ed4aceSMatthew G Knepley 425888ed4aceSMatthew G Knepley Output Parameter: 4259bb7acecfSBarry Smith . section - The `PetscSection` 426088ed4aceSMatthew G Knepley 4261e5893cccSMatthew G. Knepley Options Database Keys: 4262bb7acecfSBarry Smith . -dm_petscsection_view - View the section created by the `DM` 4263e5893cccSMatthew G. Knepley 426488ed4aceSMatthew G Knepley Level: intermediate 426588ed4aceSMatthew G Knepley 4266bb7acecfSBarry Smith Note: 4267bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 426888ed4aceSMatthew G Knepley 4269db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetGlobalSection()` 427088ed4aceSMatthew G Knepley @*/ 4271d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 4272d71ae5a4SJacob Faibussowitsch { 427388ed4aceSMatthew G Knepley PetscFunctionBegin; 427488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 427588ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 42761bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4277e5e52638SMatthew G. Knepley PetscInt d; 4278e5e52638SMatthew G. Knepley 427945480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 428045480ffeSMatthew G. Knepley PetscObject obj = (PetscObject)dm; 428145480ffeSMatthew G. Knepley PetscViewer viewer; 428245480ffeSMatthew G. Knepley PetscViewerFormat format; 428345480ffeSMatthew G. Knepley PetscBool flg; 428445480ffeSMatthew G. Knepley 42859566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg)); 42869566063dSJacob Faibussowitsch if (flg) PetscCall(PetscViewerPushFormat(viewer, format)); 428745480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 42889566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(dm->probs[d].ds)); 42899566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDSView(dm->probs[d].ds, viewer)); 429045480ffeSMatthew G. Knepley } 429145480ffeSMatthew G. Knepley if (flg) { 42929566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 42939566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 42949566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 429545480ffeSMatthew G. Knepley } 429645480ffeSMatthew G. Knepley } 4297dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalsection); 42989566063dSJacob Faibussowitsch if (dm->localSection) PetscCall(PetscObjectViewFromOptions((PetscObject)dm->localSection, NULL, "-dm_petscsection_view")); 42992f0f8703SMatthew G. Knepley } 43001bb6d2a8SBarry Smith *section = dm->localSection; 430188ed4aceSMatthew G Knepley PetscFunctionReturn(0); 430288ed4aceSMatthew G Knepley } 430388ed4aceSMatthew G Knepley 430488ed4aceSMatthew G Knepley /*@ 4305bb7acecfSBarry Smith DMSetSection - Set the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMSetLocalSection()`. Deprecated in v3.12 4306061576a5SJed Brown 4307061576a5SJed Brown Input Parameters: 4308bb7acecfSBarry Smith + dm - The `DM` 4309bb7acecfSBarry Smith - section - The `PetscSection` 4310061576a5SJed Brown 4311061576a5SJed Brown Level: advanced 4312061576a5SJed Brown 4313061576a5SJed Brown Notes: 4314bb7acecfSBarry Smith Use `DMSetLocalSection()` in new code. 4315061576a5SJed Brown 4316bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4317061576a5SJed Brown 4318db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetLocalSection()`, `DMSetGlobalSection()` 4319061576a5SJed Brown @*/ 4320d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSection(DM dm, PetscSection section) 4321d71ae5a4SJacob Faibussowitsch { 4322061576a5SJed Brown PetscFunctionBegin; 43239566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm, section)); 4324061576a5SJed Brown PetscFunctionReturn(0); 4325061576a5SJed Brown } 4326061576a5SJed Brown 4327061576a5SJed Brown /*@ 4328bb7acecfSBarry Smith DMSetLocalSection - Set the `PetscSection` encoding the local data layout for the `DM`. 432988ed4aceSMatthew G Knepley 433088ed4aceSMatthew G Knepley Input Parameters: 4331bb7acecfSBarry Smith + dm - The `DM` 4332bb7acecfSBarry Smith - section - The `PetscSection` 433388ed4aceSMatthew G Knepley 433488ed4aceSMatthew G Knepley Level: intermediate 433588ed4aceSMatthew G Knepley 4336bb7acecfSBarry Smith Note: 4337bb7acecfSBarry Smith Any existing Section will be destroyed 433888ed4aceSMatthew G Knepley 4339bb7acecfSBarry Smith .seealso: `PetscSection`, `DMGetLocalSection()`, `DMSetGlobalSection()` 434088ed4aceSMatthew G Knepley @*/ 4341d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 4342d71ae5a4SJacob Faibussowitsch { 4343c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4344af122d2aSMatthew G Knepley PetscInt f; 434588ed4aceSMatthew G Knepley 434688ed4aceSMatthew G Knepley PetscFunctionBegin; 434788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4348b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 43499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 43509566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->localSection)); 43511bb6d2a8SBarry Smith dm->localSection = section; 43529566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(dm->localSection, &numFields)); 4353af122d2aSMatthew G Knepley if (numFields) { 43549566063dSJacob Faibussowitsch PetscCall(DMSetNumFields(dm, numFields)); 4355af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43560f21e855SMatthew G. Knepley PetscObject disc; 4357af122d2aSMatthew G Knepley const char *name; 4358af122d2aSMatthew G Knepley 43599566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(dm->localSection, f, &name)); 43609566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, &disc)); 43619566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName(disc, name)); 4362af122d2aSMatthew G Knepley } 4363af122d2aSMatthew G Knepley } 4364e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 43659566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 436688ed4aceSMatthew G Knepley PetscFunctionReturn(0); 436788ed4aceSMatthew G Knepley } 436888ed4aceSMatthew G Knepley 43699435951eSToby Isaac /*@ 4370bb7acecfSBarry Smith DMGetDefaultConstraints - Get the `PetscSection` and `Mat` that specify the local constraint interpolation. See `DMSetDefaultConstraints()` for a description of the purpose of constraint interpolation. 43719435951eSToby Isaac 4372e228b242SToby Isaac not collective 4373e228b242SToby Isaac 43749435951eSToby Isaac Input Parameter: 4375bb7acecfSBarry Smith . dm - The `DM` 43769435951eSToby Isaac 4377d8d19677SJose E. Roman Output Parameters: 4378bb7acecfSBarry 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. 4379bb7acecfSBarry 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. 438079769bd5SJed Brown - bias - Vector containing bias to be added to constrained dofs 43819435951eSToby Isaac 43829435951eSToby Isaac Level: advanced 43839435951eSToby Isaac 4384bb7acecfSBarry Smith Note: 4385bb7acecfSBarry Smith This gets borrowed references, so the user should not destroy the `PetscSection`, `Mat`, or `Vec`. 43869435951eSToby Isaac 4387db781477SPatrick Sanan .seealso: `DMSetDefaultConstraints()` 43889435951eSToby Isaac @*/ 4389d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat, Vec *bias) 4390d71ae5a4SJacob Faibussowitsch { 43919435951eSToby Isaac PetscFunctionBegin; 43929435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4393dbbe0bcdSBarry Smith if (!dm->defaultConstraint.section && !dm->defaultConstraint.mat && dm->ops->createdefaultconstraints) PetscUseTypeMethod(dm, createdefaultconstraints); 43943b8ba7d1SJed Brown if (section) *section = dm->defaultConstraint.section; 43953b8ba7d1SJed Brown if (mat) *mat = dm->defaultConstraint.mat; 439679769bd5SJed Brown if (bias) *bias = dm->defaultConstraint.bias; 43979435951eSToby Isaac PetscFunctionReturn(0); 43989435951eSToby Isaac } 43999435951eSToby Isaac 44009435951eSToby Isaac /*@ 4401bb7acecfSBarry Smith DMSetDefaultConstraints - Set the `PetscSection` and `Mat` that specify the local constraint interpolation. 44029435951eSToby Isaac 4403bb7acecfSBarry 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()`. 44049435951eSToby Isaac 4405bb7acecfSBarry 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. 44069435951eSToby Isaac 4407e228b242SToby Isaac collective on dm 4408e228b242SToby Isaac 44099435951eSToby Isaac Input Parameters: 4410bb7acecfSBarry Smith + dm - The `DM` 4411bb7acecfSBarry 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). 4412bb7acecfSBarry 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). 4413bb7acecfSBarry 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). 44149435951eSToby Isaac 44159435951eSToby Isaac Level: advanced 44169435951eSToby Isaac 4417bb7acecfSBarry Smith Note: 4418bb7acecfSBarry Smith This increments the references of the `PetscSection`, `Mat`, and `Vec`, so they user can destroy them. 44199435951eSToby Isaac 4420db781477SPatrick Sanan .seealso: `DMGetDefaultConstraints()` 44219435951eSToby Isaac @*/ 4422d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat, Vec bias) 4423d71ae5a4SJacob Faibussowitsch { 4424e228b242SToby Isaac PetscMPIInt result; 44259435951eSToby Isaac 44269435951eSToby Isaac PetscFunctionBegin; 44279435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4428e228b242SToby Isaac if (section) { 4429e228b242SToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 44309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)section), &result)); 44317a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint section must have local communicator"); 4432e228b242SToby Isaac } 4433e228b242SToby Isaac if (mat) { 4434e228b242SToby Isaac PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 44359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)mat), &result)); 44367a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint matrix must have local communicator"); 4437e228b242SToby Isaac } 443879769bd5SJed Brown if (bias) { 443979769bd5SJed Brown PetscValidHeaderSpecific(bias, VEC_CLASSID, 4); 44409566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)bias), &result)); 444179769bd5SJed Brown PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint bias must have local communicator"); 444279769bd5SJed Brown } 44439566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 44449566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->defaultConstraint.section)); 44453b8ba7d1SJed Brown dm->defaultConstraint.section = section; 44469566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 44479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dm->defaultConstraint.mat)); 44483b8ba7d1SJed Brown dm->defaultConstraint.mat = mat; 44499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)bias)); 44509566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dm->defaultConstraint.bias)); 445179769bd5SJed Brown dm->defaultConstraint.bias = bias; 44529435951eSToby Isaac PetscFunctionReturn(0); 44539435951eSToby Isaac } 44549435951eSToby Isaac 4455497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4456507e4973SMatthew G. Knepley /* 4457bb7acecfSBarry Smith DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. Generates and error if they are not consistent. 4458507e4973SMatthew G. Knepley 4459507e4973SMatthew G. Knepley Input Parameters: 4460bb7acecfSBarry Smith + dm - The `DM` 4461bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4462bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 4463507e4973SMatthew G. Knepley 4464507e4973SMatthew G. Knepley Level: intermediate 4465507e4973SMatthew G. Knepley 4466db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMSetSectionSF()` 4467507e4973SMatthew G. Knepley */ 4468d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4469d71ae5a4SJacob Faibussowitsch { 4470507e4973SMatthew G. Knepley MPI_Comm comm; 4471507e4973SMatthew G. Knepley PetscLayout layout; 4472507e4973SMatthew G. Knepley const PetscInt *ranges; 4473507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4474507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4475507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4476507e4973SMatthew G. Knepley 4477507e4973SMatthew G. Knepley PetscFunctionBegin; 44789566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4479507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44809566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 44819566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 44829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(globalSection, &pStart, &pEnd)); 44839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(globalSection, &nroots)); 44849566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &layout)); 44859566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(layout, 1)); 44869566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(layout, nroots)); 44879566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(layout)); 44889566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRanges(layout, &ranges)); 4489507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4490f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4491507e4973SMatthew G. Knepley 44929566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(localSection, p, &dof)); 44939566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(localSection, p, &off)); 44949566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(localSection, p, &cdof)); 44959566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(globalSection, p, &gdof)); 44969566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(globalSection, p, &gcdof)); 44979566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(globalSection, p, &goff)); 4498507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 44999371c9d4SSatish Balay if ((gdof < 0 ? -(gdof + 1) : gdof) != dof) { 45009371c9d4SSatish 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)); 45019371c9d4SSatish Balay valid = PETSC_FALSE; 45029371c9d4SSatish Balay } 45039371c9d4SSatish Balay if (gcdof && (gcdof != cdof)) { 45049371c9d4SSatish 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)); 45059371c9d4SSatish Balay valid = PETSC_FALSE; 45069371c9d4SSatish Balay } 4507507e4973SMatthew G. Knepley if (gdof < 0) { 4508507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof + 1) - gcdof : gdof - gcdof; 4509507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4510507e4973SMatthew G. Knepley PetscInt offset = -(goff + 1) + d, r; 4511507e4973SMatthew G. Knepley 45129566063dSJacob Faibussowitsch PetscCall(PetscFindInt(offset, size + 1, ranges, &r)); 4513507e4973SMatthew G. Knepley if (r < 0) r = -(r + 2); 45149371c9d4SSatish Balay if ((r < 0) || (r >= size)) { 45159371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Point %" PetscInt_FMT " mapped to invalid process %" PetscInt_FMT " (%" PetscInt_FMT ", %" PetscInt_FMT ")\n", rank, p, r, gdof, goff)); 45169371c9d4SSatish Balay valid = PETSC_FALSE; 45179371c9d4SSatish Balay break; 45189371c9d4SSatish Balay } 4519507e4973SMatthew G. Knepley } 4520507e4973SMatthew G. Knepley } 4521507e4973SMatthew G. Knepley } 45229566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&layout)); 45239566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 45241c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm)); 4525507e4973SMatthew G. Knepley if (!gvalid) { 45269566063dSJacob Faibussowitsch PetscCall(DMView(dm, NULL)); 4527507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4528507e4973SMatthew G. Knepley } 4529507e4973SMatthew G. Knepley PetscFunctionReturn(0); 4530507e4973SMatthew G. Knepley } 4531f741bcd2SMatthew G. Knepley #endif 4532507e4973SMatthew G. Knepley 453388ed4aceSMatthew G Knepley /*@ 4534bb7acecfSBarry Smith DMGetGlobalSection - Get the `PetscSection` encoding the global data layout for the `DM`. 453588ed4aceSMatthew G Knepley 4536d083f849SBarry Smith Collective on dm 45378b1ab98fSJed Brown 453888ed4aceSMatthew G Knepley Input Parameter: 4539bb7acecfSBarry Smith . dm - The `DM` 454088ed4aceSMatthew G Knepley 454188ed4aceSMatthew G Knepley Output Parameter: 4542bb7acecfSBarry Smith . section - The `PetscSection` 454388ed4aceSMatthew G Knepley 454488ed4aceSMatthew G Knepley Level: intermediate 454588ed4aceSMatthew G Knepley 4546bb7acecfSBarry Smith Note: 4547bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 454888ed4aceSMatthew G Knepley 4549db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetLocalSection()` 455088ed4aceSMatthew G Knepley @*/ 4551d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 4552d71ae5a4SJacob Faibussowitsch { 455388ed4aceSMatthew G Knepley PetscFunctionBegin; 455488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 455588ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 45561bb6d2a8SBarry Smith if (!dm->globalSection) { 4557fd59a867SMatthew G. Knepley PetscSection s; 4558fd59a867SMatthew G. Knepley 45599566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 45607a8be351SBarry Smith PetscCheck(s, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 45617a8be351SBarry Smith PetscCheck(dm->sf, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 45629566063dSJacob Faibussowitsch PetscCall(PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection)); 45639566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&dm->map)); 45649566063dSJacob Faibussowitsch PetscCall(PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map)); 45659566063dSJacob Faibussowitsch PetscCall(PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view")); 456688ed4aceSMatthew G Knepley } 45671bb6d2a8SBarry Smith *section = dm->globalSection; 456888ed4aceSMatthew G Knepley PetscFunctionReturn(0); 456988ed4aceSMatthew G Knepley } 457088ed4aceSMatthew G Knepley 4571b21d0597SMatthew G Knepley /*@ 4572bb7acecfSBarry Smith DMSetGlobalSection - Set the `PetscSection` encoding the global data layout for the `DM`. 4573b21d0597SMatthew G Knepley 4574b21d0597SMatthew G Knepley Input Parameters: 4575bb7acecfSBarry Smith + dm - The `DM` 45765080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 4577b21d0597SMatthew G Knepley 4578b21d0597SMatthew G Knepley Level: intermediate 4579b21d0597SMatthew G Knepley 4580bb7acecfSBarry Smith Note: 4581bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4582b21d0597SMatthew G Knepley 4583db781477SPatrick Sanan .seealso: `DMGetGlobalSection()`, `DMSetLocalSection()` 4584b21d0597SMatthew G Knepley @*/ 4585d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 4586d71ae5a4SJacob Faibussowitsch { 4587b21d0597SMatthew G Knepley PetscFunctionBegin; 4588b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45895080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 45909566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 45919566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 45921bb6d2a8SBarry Smith dm->globalSection = section; 4593497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 45949566063dSJacob Faibussowitsch if (section) PetscCall(DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section)); 4595507e4973SMatthew G. Knepley #endif 4596b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4597b21d0597SMatthew G Knepley } 4598b21d0597SMatthew G Knepley 459988ed4aceSMatthew G Knepley /*@ 4600bb7acecfSBarry Smith DMGetSectionSF - Get the `PetscSF` encoding the parallel dof overlap for the `DM`. If it has not been set, 4601bb7acecfSBarry Smith it is created from the default `PetscSection` layouts in the `DM`. 460288ed4aceSMatthew G Knepley 460388ed4aceSMatthew G Knepley Input Parameter: 4604bb7acecfSBarry Smith . dm - The `DM` 460588ed4aceSMatthew G Knepley 460688ed4aceSMatthew G Knepley Output Parameter: 4607bb7acecfSBarry Smith . sf - The `PetscSF` 460888ed4aceSMatthew G Knepley 460988ed4aceSMatthew G Knepley Level: intermediate 461088ed4aceSMatthew G Knepley 4611bb7acecfSBarry Smith Note: 4612bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 461388ed4aceSMatthew G Knepley 4614db781477SPatrick Sanan .seealso: `DMSetSectionSF()`, `DMCreateSectionSF()` 461588ed4aceSMatthew G Knepley @*/ 4616d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 4617d71ae5a4SJacob Faibussowitsch { 461888ed4aceSMatthew G Knepley PetscInt nroots; 461988ed4aceSMatthew G Knepley 462088ed4aceSMatthew G Knepley PetscFunctionBegin; 462188ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 462288ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 462348a46eb9SPierre Jolivet if (!dm->sectionSF) PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 46249566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL)); 462588ed4aceSMatthew G Knepley if (nroots < 0) { 462688ed4aceSMatthew G Knepley PetscSection section, gSection; 462788ed4aceSMatthew G Knepley 46289566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 462931ea6d37SMatthew G Knepley if (section) { 46309566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gSection)); 46319566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSF(dm, section, gSection)); 463231ea6d37SMatthew G Knepley } else { 46330298fd71SBarry Smith *sf = NULL; 463431ea6d37SMatthew G Knepley PetscFunctionReturn(0); 463531ea6d37SMatthew G Knepley } 463688ed4aceSMatthew G Knepley } 46371bb6d2a8SBarry Smith *sf = dm->sectionSF; 463888ed4aceSMatthew G Knepley PetscFunctionReturn(0); 463988ed4aceSMatthew G Knepley } 464088ed4aceSMatthew G Knepley 464188ed4aceSMatthew G Knepley /*@ 4642bb7acecfSBarry Smith DMSetSectionSF - Set the `PetscSF` encoding the parallel dof overlap for the `DM` 464388ed4aceSMatthew G Knepley 464488ed4aceSMatthew G Knepley Input Parameters: 4645bb7acecfSBarry Smith + dm - The `DM` 4646bb7acecfSBarry Smith - sf - The `PetscSF` 464788ed4aceSMatthew G Knepley 464888ed4aceSMatthew G Knepley Level: intermediate 464988ed4aceSMatthew G Knepley 4650bb7acecfSBarry Smith Note: 4651bb7acecfSBarry Smith Any previous `PetscSF` is destroyed 465288ed4aceSMatthew G Knepley 4653db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMCreateSectionSF()` 465488ed4aceSMatthew G Knepley @*/ 4655d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 4656d71ae5a4SJacob Faibussowitsch { 465788ed4aceSMatthew G Knepley PetscFunctionBegin; 465888ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4659b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 46609566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 46619566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sectionSF)); 46621bb6d2a8SBarry Smith dm->sectionSF = sf; 466388ed4aceSMatthew G Knepley PetscFunctionReturn(0); 466488ed4aceSMatthew G Knepley } 466588ed4aceSMatthew G Knepley 466688ed4aceSMatthew G Knepley /*@C 4667bb7acecfSBarry Smith DMCreateSectionSF - Create the `PetscSF` encoding the parallel dof overlap for the `DM` based upon the `PetscSection`s 466888ed4aceSMatthew G Knepley describing the data layout. 466988ed4aceSMatthew G Knepley 467088ed4aceSMatthew G Knepley Input Parameters: 4671bb7acecfSBarry Smith + dm - The `DM` 4672bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4673bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 467488ed4aceSMatthew G Knepley 46751bb6d2a8SBarry Smith Level: developer 46761bb6d2a8SBarry Smith 4677bb7acecfSBarry Smith Note: 4678bb7acecfSBarry Smith One usually uses `DMGetSectionSF()` to obtain the `PetscSF` 4679bb7acecfSBarry Smith 4680bb7acecfSBarry Smith Developer Note: 4681bb7acecfSBarry Smith Since this routine has for arguments the two sections from the `DM` and puts the resulting `PetscSF` 4682bb7acecfSBarry Smith directly into the `DM`, perhaps this function should not take the local and global sections as 4683bb7acecfSBarry Smith input and should just obtain them from the `DM`? 46841bb6d2a8SBarry Smith 4685db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMSetSectionSF()`, `DMGetLocalSection()`, `DMGetGlobalSection()` 468688ed4aceSMatthew G Knepley @*/ 4687d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 4688d71ae5a4SJacob Faibussowitsch { 468988ed4aceSMatthew G Knepley PetscFunctionBegin; 469088ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46919566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection)); 469288ed4aceSMatthew G Knepley PetscFunctionReturn(0); 469388ed4aceSMatthew G Knepley } 4694af122d2aSMatthew G Knepley 4695b21d0597SMatthew G Knepley /*@ 4696bb7acecfSBarry Smith DMGetPointSF - Get the `PetscSF` encoding the parallel section point overlap for the `DM`. 4697bb7acecfSBarry Smith 4698bb7acecfSBarry Smith Not collective but the resulting `PetscSF` is collective 4699b21d0597SMatthew G Knepley 4700b21d0597SMatthew G Knepley Input Parameter: 4701bb7acecfSBarry Smith . dm - The `DM` 4702b21d0597SMatthew G Knepley 4703b21d0597SMatthew G Knepley Output Parameter: 4704bb7acecfSBarry Smith . sf - The `PetscSF` 4705b21d0597SMatthew G Knepley 4706b21d0597SMatthew G Knepley Level: intermediate 4707b21d0597SMatthew G Knepley 4708bb7acecfSBarry Smith Note: 4709bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 4710b21d0597SMatthew G Knepley 4711db781477SPatrick Sanan .seealso: `DMSetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4712b21d0597SMatthew G Knepley @*/ 4713d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 4714d71ae5a4SJacob Faibussowitsch { 4715b21d0597SMatthew G Knepley PetscFunctionBegin; 4716b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4717b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4718b21d0597SMatthew G Knepley *sf = dm->sf; 4719b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4720b21d0597SMatthew G Knepley } 4721b21d0597SMatthew G Knepley 4722057b4bcdSMatthew G Knepley /*@ 4723bb7acecfSBarry Smith DMSetPointSF - Set the `PetscSF` encoding the parallel section point overlap for the `DM`. 4724bb7acecfSBarry Smith 4725bb7acecfSBarry Smith Collective on dm 4726057b4bcdSMatthew G Knepley 4727057b4bcdSMatthew G Knepley Input Parameters: 4728bb7acecfSBarry Smith + dm - The `DM` 4729bb7acecfSBarry Smith - sf - The` PetscSF` 4730057b4bcdSMatthew G Knepley 4731057b4bcdSMatthew G Knepley Level: intermediate 4732057b4bcdSMatthew G Knepley 4733db781477SPatrick Sanan .seealso: `DMGetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4734057b4bcdSMatthew G Knepley @*/ 4735d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 4736d71ae5a4SJacob Faibussowitsch { 4737057b4bcdSMatthew G Knepley PetscFunctionBegin; 4738057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4739b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47409566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47419566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sf)); 4742057b4bcdSMatthew G Knepley dm->sf = sf; 4743057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4744057b4bcdSMatthew G Knepley } 4745057b4bcdSMatthew G Knepley 47464f37162bSMatthew G. Knepley /*@ 4747bb7acecfSBarry Smith DMGetNaturalSF - Get the `PetscSF` encoding the map back to the original mesh ordering 47484f37162bSMatthew G. Knepley 47494f37162bSMatthew G. Knepley Input Parameter: 4750bb7acecfSBarry Smith . dm - The `DM` 47514f37162bSMatthew G. Knepley 47524f37162bSMatthew G. Knepley Output Parameter: 4753bb7acecfSBarry Smith . sf - The `PetscSF` 47544f37162bSMatthew G. Knepley 47554f37162bSMatthew G. Knepley Level: intermediate 47564f37162bSMatthew G. Knepley 4757bb7acecfSBarry Smith Note: 4758bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 47594f37162bSMatthew G. Knepley 4760db781477SPatrick Sanan .seealso: `DMSetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47614f37162bSMatthew G. Knepley @*/ 4762d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 4763d71ae5a4SJacob Faibussowitsch { 47644f37162bSMatthew G. Knepley PetscFunctionBegin; 47654f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47664f37162bSMatthew G. Knepley PetscValidPointer(sf, 2); 47674f37162bSMatthew G. Knepley *sf = dm->sfNatural; 47684f37162bSMatthew G. Knepley PetscFunctionReturn(0); 47694f37162bSMatthew G. Knepley } 47704f37162bSMatthew G. Knepley 47714f37162bSMatthew G. Knepley /*@ 47724f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 47734f37162bSMatthew G. Knepley 47744f37162bSMatthew G. Knepley Input Parameters: 47754f37162bSMatthew G. Knepley + dm - The DM 47764f37162bSMatthew G. Knepley - sf - The PetscSF 47774f37162bSMatthew G. Knepley 47784f37162bSMatthew G. Knepley Level: intermediate 47794f37162bSMatthew G. Knepley 4780db781477SPatrick Sanan .seealso: `DMGetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47814f37162bSMatthew G. Knepley @*/ 4782d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 4783d71ae5a4SJacob Faibussowitsch { 47844f37162bSMatthew G. Knepley PetscFunctionBegin; 47854f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47864f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47879566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47889566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sfNatural)); 47894f37162bSMatthew G. Knepley dm->sfNatural = sf; 47904f37162bSMatthew G. Knepley PetscFunctionReturn(0); 47914f37162bSMatthew G. Knepley } 47924f37162bSMatthew G. Knepley 4793d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 4794d71ae5a4SJacob Faibussowitsch { 479534aa8a36SMatthew G. Knepley PetscClassId id; 479634aa8a36SMatthew G. Knepley 479734aa8a36SMatthew G. Knepley PetscFunctionBegin; 47989566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 479934aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 48009566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 480134aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 48029566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE)); 480317c1d62eSMatthew G. Knepley } else { 48049566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 480534aa8a36SMatthew G. Knepley } 480634aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 480734aa8a36SMatthew G. Knepley } 480834aa8a36SMatthew G. Knepley 4809d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 4810d71ae5a4SJacob Faibussowitsch { 481144a7f3ddSMatthew G. Knepley RegionField *tmpr; 481244a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 481344a7f3ddSMatthew G. Knepley 481444a7f3ddSMatthew G. Knepley PetscFunctionBegin; 481544a7f3ddSMatthew G. Knepley if (Nf >= NfNew) PetscFunctionReturn(0); 48169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NfNew, &tmpr)); 481744a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 48189371c9d4SSatish Balay for (f = Nf; f < NfNew; ++f) { 48199371c9d4SSatish Balay tmpr[f].disc = NULL; 48209371c9d4SSatish Balay tmpr[f].label = NULL; 48219371c9d4SSatish Balay tmpr[f].avoidTensor = PETSC_FALSE; 48229371c9d4SSatish Balay } 48239566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 482444a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 482544a7f3ddSMatthew G. Knepley dm->fields = tmpr; 482644a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 482744a7f3ddSMatthew G. Knepley } 482844a7f3ddSMatthew G. Knepley 482944a7f3ddSMatthew G. Knepley /*@ 483044a7f3ddSMatthew G. Knepley DMClearFields - Remove all fields from the DM 483144a7f3ddSMatthew G. Knepley 4832d083f849SBarry Smith Logically collective on dm 483344a7f3ddSMatthew G. Knepley 483444a7f3ddSMatthew G. Knepley Input Parameter: 483544a7f3ddSMatthew G. Knepley . dm - The DM 483644a7f3ddSMatthew G. Knepley 483744a7f3ddSMatthew G. Knepley Level: intermediate 483844a7f3ddSMatthew G. Knepley 4839db781477SPatrick Sanan .seealso: `DMGetNumFields()`, `DMSetNumFields()`, `DMSetField()` 484044a7f3ddSMatthew G. Knepley @*/ 4841d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearFields(DM dm) 4842d71ae5a4SJacob Faibussowitsch { 484344a7f3ddSMatthew G. Knepley PetscInt f; 484444a7f3ddSMatthew G. Knepley 484544a7f3ddSMatthew G. Knepley PetscFunctionBegin; 484644a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 484744a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 48489566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 48499566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 485044a7f3ddSMatthew G. Knepley } 48519566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 485244a7f3ddSMatthew G. Knepley dm->fields = NULL; 485344a7f3ddSMatthew G. Knepley dm->Nf = 0; 485444a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 485544a7f3ddSMatthew G. Knepley } 485644a7f3ddSMatthew G. Knepley 4857689b5837SMatthew G. Knepley /*@ 4858689b5837SMatthew G. Knepley DMGetNumFields - Get the number of fields in the DM 4859689b5837SMatthew G. Knepley 4860689b5837SMatthew G. Knepley Not collective 4861689b5837SMatthew G. Knepley 4862689b5837SMatthew G. Knepley Input Parameter: 4863689b5837SMatthew G. Knepley . dm - The DM 4864689b5837SMatthew G. Knepley 4865689b5837SMatthew G. Knepley Output Parameter: 4866689b5837SMatthew G. Knepley . Nf - The number of fields 4867689b5837SMatthew G. Knepley 4868689b5837SMatthew G. Knepley Level: intermediate 4869689b5837SMatthew G. Knepley 4870db781477SPatrick Sanan .seealso: `DMSetNumFields()`, `DMSetField()` 4871689b5837SMatthew G. Knepley @*/ 4872d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 4873d71ae5a4SJacob Faibussowitsch { 48740f21e855SMatthew G. Knepley PetscFunctionBegin; 48750f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4876534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 487744a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 4878af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4879af122d2aSMatthew G Knepley } 4880af122d2aSMatthew G Knepley 4881689b5837SMatthew G. Knepley /*@ 4882689b5837SMatthew G. Knepley DMSetNumFields - Set the number of fields in the DM 4883689b5837SMatthew G. Knepley 4884d083f849SBarry Smith Logically collective on dm 4885689b5837SMatthew G. Knepley 4886689b5837SMatthew G. Knepley Input Parameters: 4887689b5837SMatthew G. Knepley + dm - The DM 4888689b5837SMatthew G. Knepley - Nf - The number of fields 4889689b5837SMatthew G. Knepley 4890689b5837SMatthew G. Knepley Level: intermediate 4891689b5837SMatthew G. Knepley 4892db781477SPatrick Sanan .seealso: `DMGetNumFields()`, `DMSetField()` 4893689b5837SMatthew G. Knepley @*/ 4894d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4895d71ae5a4SJacob Faibussowitsch { 48960f21e855SMatthew G. Knepley PetscInt Nf, f; 4897af122d2aSMatthew G Knepley 4898af122d2aSMatthew G Knepley PetscFunctionBegin; 4899af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49009566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 49010f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 49020f21e855SMatthew G. Knepley PetscContainer obj; 49030f21e855SMatthew G. Knepley 49049566063dSJacob Faibussowitsch PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)dm), &obj)); 49059566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject)obj)); 49069566063dSJacob Faibussowitsch PetscCall(PetscContainerDestroy(&obj)); 4907af122d2aSMatthew G Knepley } 4908af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4909af122d2aSMatthew G Knepley } 4910af122d2aSMatthew G Knepley 4911c1929be8SMatthew G. Knepley /*@ 4912bb7acecfSBarry Smith DMGetField - Return the `DMLabel` and discretization object for a given `DM` field 4913c1929be8SMatthew G. Knepley 4914c1929be8SMatthew G. Knepley Not collective 4915c1929be8SMatthew G. Knepley 4916c1929be8SMatthew G. Knepley Input Parameters: 4917bb7acecfSBarry Smith + dm - The `DM` 4918c1929be8SMatthew G. Knepley - f - The field number 4919c1929be8SMatthew G. Knepley 492044a7f3ddSMatthew G. Knepley Output Parameters: 4921bb7acecfSBarry Smith + label - The label indicating the support of the field, or NULL for the entire mesh (pass in NULL if not needed) 4922bb7acecfSBarry Smith - disc - The discretization object (pass in NULL if not needed) 4923c1929be8SMatthew G. Knepley 492444a7f3ddSMatthew G. Knepley Level: intermediate 4925c1929be8SMatthew G. Knepley 4926db781477SPatrick Sanan .seealso: `DMAddField()`, `DMSetField()` 4927c1929be8SMatthew G. Knepley @*/ 4928d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *disc) 4929d71ae5a4SJacob Faibussowitsch { 4930af122d2aSMatthew G Knepley PetscFunctionBegin; 4931af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4932bb7acecfSBarry Smith PetscValidPointer(disc, 4); 49337a8be351SBarry 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); 493444a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 4935bb7acecfSBarry Smith if (disc) *disc = dm->fields[f].disc; 4936decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4937decb47aaSMatthew G. Knepley } 4938decb47aaSMatthew G. Knepley 4939083401c6SMatthew G. Knepley /* Does not clear the DS */ 4940d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4941d71ae5a4SJacob Faibussowitsch { 4942083401c6SMatthew G. Knepley PetscFunctionBegin; 49439566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, f + 1)); 49449566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 49459566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 4946083401c6SMatthew G. Knepley dm->fields[f].label = label; 4947bb7acecfSBarry Smith dm->fields[f].disc = disc; 49489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 4949bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 4950083401c6SMatthew G. Knepley PetscFunctionReturn(0); 4951083401c6SMatthew G. Knepley } 4952083401c6SMatthew G. Knepley 4953c1929be8SMatthew G. Knepley /*@ 4954bb7acecfSBarry Smith DMSetField - Set the discretization object for a given `DM` field. Usually one would call `DMAddField()` which automatically handles 4955bb7acecfSBarry Smith the field numbering. 4956c1929be8SMatthew G. Knepley 4957d083f849SBarry Smith Logically collective on dm 4958c1929be8SMatthew G. Knepley 4959c1929be8SMatthew G. Knepley Input Parameters: 4960bb7acecfSBarry Smith + dm - The `DM` 4961c1929be8SMatthew G. Knepley . f - The field number 496244a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4963bb7acecfSBarry Smith - disc - The discretization object 4964c1929be8SMatthew G. Knepley 496544a7f3ddSMatthew G. Knepley Level: intermediate 4966c1929be8SMatthew G. Knepley 4967db781477SPatrick Sanan .seealso: `DMAddField()`, `DMGetField()` 4968c1929be8SMatthew G. Knepley @*/ 4969d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4970d71ae5a4SJacob Faibussowitsch { 4971decb47aaSMatthew G. Knepley PetscFunctionBegin; 4972decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4973e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 4974bb7acecfSBarry Smith PetscValidHeader(disc, 4); 49757a8be351SBarry Smith PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f); 4976bb7acecfSBarry Smith PetscCall(DMSetField_Internal(dm, f, label, disc)); 4977bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, f, disc)); 49789566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 497944a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 498044a7f3ddSMatthew G. Knepley } 498144a7f3ddSMatthew G. Knepley 498244a7f3ddSMatthew G. Knepley /*@ 4983bb7acecfSBarry 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) 4984bb7acecfSBarry Smith and a discretization object that defines the function space associated with those points. 498544a7f3ddSMatthew G. Knepley 4986d083f849SBarry Smith Logically collective on dm 498744a7f3ddSMatthew G. Knepley 498844a7f3ddSMatthew G. Knepley Input Parameters: 4989bb7acecfSBarry Smith + dm - The `DM` 499044a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4991bb7acecfSBarry Smith - disc - The discretization object 499244a7f3ddSMatthew G. Knepley 499344a7f3ddSMatthew G. Knepley Level: intermediate 499444a7f3ddSMatthew G. Knepley 4995bb7acecfSBarry Smith Notes: 4996bb7acecfSBarry Smith The label already exists or will be added to the `DM` with `DMSetLabel()`. 4997bb7acecfSBarry Smith 4998bb7acecfSBarry Smith For example, a piecewise continous pressure field can be defined by coefficients at the cell centers of a mesh and piecewise constant functions 4999bb7acecfSBarry 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 5000bb7acecfSBarry Smith geometry entities, a `DMLabel` indicating a subset of those geometric entities, and a discretization object, such as a `PetscFE`. 5001bb7acecfSBarry Smith 5002bb7acecfSBarry Smith .seealso: `DMSetLabel()`, `DMSetField()`, `DMGetField()`, `PetscFE` 500344a7f3ddSMatthew G. Knepley @*/ 5004d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject disc) 5005d71ae5a4SJacob Faibussowitsch { 500644a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 500744a7f3ddSMatthew G. Knepley 500844a7f3ddSMatthew G. Knepley PetscFunctionBegin; 500944a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5010064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5011bb7acecfSBarry Smith PetscValidHeader(disc, 3); 50129566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, Nf + 1)); 501344a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 5014bb7acecfSBarry Smith dm->fields[Nf].disc = disc; 50159566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5016bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 5017bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, Nf, disc)); 50189566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 5019af122d2aSMatthew G Knepley PetscFunctionReturn(0); 5020af122d2aSMatthew G Knepley } 50216636e97aSMatthew G Knepley 5022e5e52638SMatthew G. Knepley /*@ 5023e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 5024e0b68406SMatthew Knepley 5025e0b68406SMatthew Knepley Logically collective on dm 5026e0b68406SMatthew Knepley 5027e0b68406SMatthew Knepley Input Parameters: 5028bb7acecfSBarry Smith + dm - The `DM` 5029e0b68406SMatthew Knepley . f - The field index 5030bb7acecfSBarry Smith - avoidTensor - `PETSC_TRUE` to skip defining the field on tensor cells 5031e0b68406SMatthew Knepley 5032e0b68406SMatthew Knepley Level: intermediate 5033e0b68406SMatthew Knepley 5034db781477SPatrick Sanan .seealso: `DMGetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5035e0b68406SMatthew Knepley @*/ 5036d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5037d71ae5a4SJacob Faibussowitsch { 5038e0b68406SMatthew Knepley PetscFunctionBegin; 503963a3b9bcSJacob 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); 5040e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 5041e0b68406SMatthew Knepley PetscFunctionReturn(0); 5042e0b68406SMatthew Knepley } 5043e0b68406SMatthew Knepley 5044e0b68406SMatthew Knepley /*@ 5045e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5046e0b68406SMatthew Knepley 5047bb7acecfSBarry Smith Not collective 5048e0b68406SMatthew Knepley 5049e0b68406SMatthew Knepley Input Parameters: 5050bb7acecfSBarry Smith + dm - The `DM` 5051e0b68406SMatthew Knepley - f - The field index 5052e0b68406SMatthew Knepley 5053e0b68406SMatthew Knepley Output Parameter: 5054e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5055e0b68406SMatthew Knepley 5056e0b68406SMatthew Knepley Level: intermediate 5057e0b68406SMatthew Knepley 5058bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMSetField()`, `DMGetField()`, `DMSetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5059e0b68406SMatthew Knepley @*/ 5060d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5061d71ae5a4SJacob Faibussowitsch { 5062e0b68406SMatthew Knepley PetscFunctionBegin; 506363a3b9bcSJacob 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); 5064e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 5065e0b68406SMatthew Knepley PetscFunctionReturn(0); 5066e0b68406SMatthew Knepley } 5067e0b68406SMatthew Knepley 5068e0b68406SMatthew Knepley /*@ 5069bb7acecfSBarry Smith DMCopyFields - Copy the discretizations for the `DM` into another `DM` 5070e5e52638SMatthew G. Knepley 5071d083f849SBarry Smith Collective on dm 5072e5e52638SMatthew G. Knepley 5073e5e52638SMatthew G. Knepley Input Parameter: 5074bb7acecfSBarry Smith . dm - The `DM` 5075e5e52638SMatthew G. Knepley 5076e5e52638SMatthew G. Knepley Output Parameter: 5077bb7acecfSBarry Smith . newdm - The `DM` 5078e5e52638SMatthew G. Knepley 5079e5e52638SMatthew G. Knepley Level: advanced 5080e5e52638SMatthew G. Knepley 5081db781477SPatrick Sanan .seealso: `DMGetField()`, `DMSetField()`, `DMAddField()`, `DMCopyDS()`, `DMGetDS()`, `DMGetCellDS()` 5082e5e52638SMatthew G. Knepley @*/ 5083d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyFields(DM dm, DM newdm) 5084d71ae5a4SJacob Faibussowitsch { 5085e5e52638SMatthew G. Knepley PetscInt Nf, f; 5086e5e52638SMatthew G. Knepley 5087e5e52638SMatthew G. Knepley PetscFunctionBegin; 5088e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 50899566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 50909566063dSJacob Faibussowitsch PetscCall(DMClearFields(newdm)); 5091e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5092e5e52638SMatthew G. Knepley DMLabel label; 5093e5e52638SMatthew G. Knepley PetscObject field; 509434aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5095e5e52638SMatthew G. Knepley 50969566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, &label, &field)); 50979566063dSJacob Faibussowitsch PetscCall(DMSetField(newdm, f, label, field)); 50989566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, f, &useCone, &useClosure)); 50999566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(newdm, f, useCone, useClosure)); 510034aa8a36SMatthew G. Knepley } 510134aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 510234aa8a36SMatthew G. Knepley } 510334aa8a36SMatthew G. Knepley 510434aa8a36SMatthew G. Knepley /*@ 510534aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 510634aa8a36SMatthew G. Knepley 510734aa8a36SMatthew G. Knepley Not collective 510834aa8a36SMatthew G. Knepley 510934aa8a36SMatthew G. Knepley Input Parameters: 511034aa8a36SMatthew G. Knepley + dm - The DM object 511134aa8a36SMatthew G. Knepley - f - The field number, or PETSC_DEFAULT for the default adjacency 511234aa8a36SMatthew G. Knepley 5113d8d19677SJose E. Roman Output Parameters: 511434aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 511534aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 511634aa8a36SMatthew G. Knepley 511734aa8a36SMatthew G. Knepley Notes: 511834aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 511934aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 512034aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5121979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 512234aa8a36SMatthew G. Knepley 512334aa8a36SMatthew G. Knepley Level: developer 512434aa8a36SMatthew G. Knepley 5125db781477SPatrick Sanan .seealso: `DMSetAdjacency()`, `DMGetField()`, `DMSetField()` 512634aa8a36SMatthew G. Knepley @*/ 5127d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 5128d71ae5a4SJacob Faibussowitsch { 512934aa8a36SMatthew G. Knepley PetscFunctionBegin; 513034aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5131534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 5132534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 513334aa8a36SMatthew G. Knepley if (f < 0) { 513434aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 513534aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 513634aa8a36SMatthew G. Knepley } else { 513734aa8a36SMatthew G. Knepley PetscInt Nf; 513834aa8a36SMatthew G. Knepley 51399566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51407a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 514134aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 514234aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 514334aa8a36SMatthew G. Knepley } 514434aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 514534aa8a36SMatthew G. Knepley } 514634aa8a36SMatthew G. Knepley 514734aa8a36SMatthew G. Knepley /*@ 514834aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 514934aa8a36SMatthew G. Knepley 515034aa8a36SMatthew G. Knepley Not collective 515134aa8a36SMatthew G. Knepley 515234aa8a36SMatthew G. Knepley Input Parameters: 515334aa8a36SMatthew G. Knepley + dm - The DM object 515434aa8a36SMatthew G. Knepley . f - The field number 515534aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 515634aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 515734aa8a36SMatthew G. Knepley 515834aa8a36SMatthew G. Knepley Notes: 515934aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 516034aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 516134aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5162979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 516334aa8a36SMatthew G. Knepley 516434aa8a36SMatthew G. Knepley Level: developer 516534aa8a36SMatthew G. Knepley 5166db781477SPatrick Sanan .seealso: `DMGetAdjacency()`, `DMGetField()`, `DMSetField()` 516734aa8a36SMatthew G. Knepley @*/ 5168d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 5169d71ae5a4SJacob Faibussowitsch { 517034aa8a36SMatthew G. Knepley PetscFunctionBegin; 517134aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 517234aa8a36SMatthew G. Knepley if (f < 0) { 517334aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 517434aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 517534aa8a36SMatthew G. Knepley } else { 517634aa8a36SMatthew G. Knepley PetscInt Nf; 517734aa8a36SMatthew G. Knepley 51789566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51797a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 518034aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 518134aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5182e5e52638SMatthew G. Knepley } 5183e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5184e5e52638SMatthew G. Knepley } 5185e5e52638SMatthew G. Knepley 5186b0441da4SMatthew G. Knepley /*@ 5187b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5188b0441da4SMatthew G. Knepley 5189b0441da4SMatthew G. Knepley Not collective 5190b0441da4SMatthew G. Knepley 5191f899ff85SJose E. Roman Input Parameter: 5192b0441da4SMatthew G. Knepley . dm - The DM object 5193b0441da4SMatthew G. Knepley 5194d8d19677SJose E. Roman Output Parameters: 5195b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5196b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5197b0441da4SMatthew G. Knepley 5198b0441da4SMatthew G. Knepley Notes: 5199b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5200b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5201b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5202b0441da4SMatthew G. Knepley 5203b0441da4SMatthew G. Knepley Level: developer 5204b0441da4SMatthew G. Knepley 5205db781477SPatrick Sanan .seealso: `DMSetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5206b0441da4SMatthew G. Knepley @*/ 5207d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5208d71ae5a4SJacob Faibussowitsch { 5209b0441da4SMatthew G. Knepley PetscInt Nf; 5210b0441da4SMatthew G. Knepley 5211b0441da4SMatthew G. Knepley PetscFunctionBegin; 5212b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5213064a246eSJacob Faibussowitsch if (useCone) PetscValidBoolPointer(useCone, 2); 5214064a246eSJacob Faibussowitsch if (useClosure) PetscValidBoolPointer(useClosure, 3); 52159566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5216b0441da4SMatthew G. Knepley if (!Nf) { 52179566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5218b0441da4SMatthew G. Knepley } else { 52199566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, 0, useCone, useClosure)); 5220b0441da4SMatthew G. Knepley } 5221b0441da4SMatthew G. Knepley PetscFunctionReturn(0); 5222b0441da4SMatthew G. Knepley } 5223b0441da4SMatthew G. Knepley 5224b0441da4SMatthew G. Knepley /*@ 5225b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5226b0441da4SMatthew G. Knepley 5227b0441da4SMatthew G. Knepley Not collective 5228b0441da4SMatthew G. Knepley 5229b0441da4SMatthew G. Knepley Input Parameters: 5230b0441da4SMatthew G. Knepley + dm - The DM object 5231b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5232b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5233b0441da4SMatthew G. Knepley 5234b0441da4SMatthew G. Knepley Notes: 5235b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5236b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5237b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5238b0441da4SMatthew G. Knepley 5239b0441da4SMatthew G. Knepley Level: developer 5240b0441da4SMatthew G. Knepley 5241db781477SPatrick Sanan .seealso: `DMGetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5242b0441da4SMatthew G. Knepley @*/ 5243d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5244d71ae5a4SJacob Faibussowitsch { 5245b0441da4SMatthew G. Knepley PetscInt Nf; 5246b0441da4SMatthew G. Knepley 5247b0441da4SMatthew G. Knepley PetscFunctionBegin; 5248b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52499566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5250b0441da4SMatthew G. Knepley if (!Nf) { 52519566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5252b0441da4SMatthew G. Knepley } else { 52539566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, 0, useCone, useClosure)); 5254e5e52638SMatthew G. Knepley } 5255e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5256e5e52638SMatthew G. Knepley } 5257e5e52638SMatthew G. Knepley 5258d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompleteBCLabels_Internal(DM dm) 5259d71ae5a4SJacob Faibussowitsch { 5260799db056SMatthew G. Knepley DM plex; 5261799db056SMatthew G. Knepley DMLabel *labels, *glabels; 5262799db056SMatthew G. Knepley const char **names; 5263799db056SMatthew G. Knepley char *sendNames, *recvNames; 5264799db056SMatthew G. Knepley PetscInt Nds, s, maxLabels = 0, maxLen = 0, gmaxLen, Nl = 0, gNl, l, gl, m; 5265799db056SMatthew G. Knepley size_t len; 5266799db056SMatthew G. Knepley MPI_Comm comm; 5267799db056SMatthew G. Knepley PetscMPIInt rank, size, p, *counts, *displs; 5268783e2ec8SMatthew G. Knepley 5269783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5270799db056SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5271799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 5272799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5273799db056SMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 5274799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5275799db056SMatthew G. Knepley PetscDS dsBC; 5276799db056SMatthew G. Knepley PetscInt numBd; 5277799db056SMatthew G. Knepley 5278799db056SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC)); 5279799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5280799db056SMatthew G. Knepley maxLabels += numBd; 5281799db056SMatthew G. Knepley } 5282799db056SMatthew G. Knepley PetscCall(PetscCalloc1(maxLabels, &labels)); 5283799db056SMatthew G. Knepley /* Get list of labels to be completed */ 5284799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5285799db056SMatthew G. Knepley PetscDS dsBC; 5286799db056SMatthew G. Knepley PetscInt numBd, bd; 5287799db056SMatthew G. Knepley 5288799db056SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC)); 5289799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5290799db056SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5291799db056SMatthew G. Knepley DMLabel label; 5292799db056SMatthew G. Knepley PetscInt field; 5293799db056SMatthew G. Knepley PetscObject obj; 5294799db056SMatthew G. Knepley PetscClassId id; 5295799db056SMatthew G. Knepley 5296799db056SMatthew G. Knepley PetscCall(PetscDSGetBoundary(dsBC, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 52979566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, field, NULL, &obj)); 52989566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(obj, &id)); 5299799db056SMatthew G. Knepley if (!(id == PETSCFE_CLASSID) || !label) continue; 53009371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 53019371c9d4SSatish Balay if (labels[l] == label) break; 5302799db056SMatthew G. Knepley if (l == Nl) labels[Nl++] = label; 5303783e2ec8SMatthew G. Knepley } 5304799db056SMatthew G. Knepley } 5305799db056SMatthew G. Knepley /* Get label names */ 5306799db056SMatthew G. Knepley PetscCall(PetscMalloc1(Nl, &names)); 5307799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscObjectGetName((PetscObject)labels[l], &names[l])); 53089371c9d4SSatish Balay for (l = 0; l < Nl; ++l) { 53099371c9d4SSatish Balay PetscCall(PetscStrlen(names[l], &len)); 53109371c9d4SSatish Balay maxLen = PetscMax(maxLen, (PetscInt)len + 2); 53119371c9d4SSatish Balay } 5312799db056SMatthew G. Knepley PetscCall(PetscFree(labels)); 5313799db056SMatthew G. Knepley PetscCallMPI(MPI_Allreduce(&maxLen, &gmaxLen, 1, MPIU_INT, MPI_MAX, comm)); 5314799db056SMatthew G. Knepley PetscCall(PetscCalloc1(Nl * gmaxLen, &sendNames)); 5315799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscStrcpy(&sendNames[gmaxLen * l], names[l])); 5316799db056SMatthew G. Knepley PetscCall(PetscFree(names)); 5317799db056SMatthew G. Knepley /* Put all names on all processes */ 5318799db056SMatthew G. Knepley PetscCall(PetscCalloc2(size, &counts, size + 1, &displs)); 5319799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgather(&Nl, 1, MPI_INT, counts, 1, MPI_INT, comm)); 5320799db056SMatthew G. Knepley for (p = 0; p < size; ++p) displs[p + 1] = displs[p] + counts[p]; 5321799db056SMatthew G. Knepley gNl = displs[size]; 53229371c9d4SSatish Balay for (p = 0; p < size; ++p) { 53239371c9d4SSatish Balay counts[p] *= gmaxLen; 53249371c9d4SSatish Balay displs[p] *= gmaxLen; 53259371c9d4SSatish Balay } 5326799db056SMatthew G. Knepley PetscCall(PetscCalloc2(gNl * gmaxLen, &recvNames, gNl, &glabels)); 5327799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgatherv(sendNames, counts[rank], MPI_CHAR, recvNames, counts, displs, MPI_CHAR, comm)); 5328799db056SMatthew G. Knepley PetscCall(PetscFree2(counts, displs)); 5329799db056SMatthew G. Knepley PetscCall(PetscFree(sendNames)); 5330799db056SMatthew G. Knepley for (l = 0, gl = 0; l < gNl; ++l) { 5331799db056SMatthew G. Knepley PetscCall(DMGetLabel(dm, &recvNames[l * gmaxLen], &glabels[gl])); 5332799db056SMatthew G. Knepley PetscCheck(glabels[gl], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Label %s missing on rank %d", &recvNames[l * gmaxLen], rank); 53339371c9d4SSatish Balay for (m = 0; m < gl; ++m) 53349371c9d4SSatish Balay if (glabels[m] == glabels[gl]) continue; 53359566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 5336799db056SMatthew G. Knepley PetscCall(DMPlexLabelComplete(plex, glabels[gl])); 53379566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5338799db056SMatthew G. Knepley ++gl; 5339783e2ec8SMatthew G. Knepley } 5340799db056SMatthew G. Knepley PetscCall(PetscFree2(recvNames, glabels)); 5341783e2ec8SMatthew G. Knepley PetscFunctionReturn(0); 5342783e2ec8SMatthew G. Knepley } 5343783e2ec8SMatthew G. Knepley 5344d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5345d71ae5a4SJacob Faibussowitsch { 5346e5e52638SMatthew G. Knepley DMSpace *tmpd; 5347e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5348e5e52638SMatthew G. Knepley 5349e5e52638SMatthew G. Knepley PetscFunctionBegin; 5350e5e52638SMatthew G. Knepley if (Nds >= NdsNew) PetscFunctionReturn(0); 53519566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NdsNew, &tmpd)); 5352e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 53539371c9d4SSatish Balay for (s = Nds; s < NdsNew; ++s) { 53549371c9d4SSatish Balay tmpd[s].ds = NULL; 53559371c9d4SSatish Balay tmpd[s].label = NULL; 53569371c9d4SSatish Balay tmpd[s].fields = NULL; 53579371c9d4SSatish Balay } 53589566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5359e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5360e5e52638SMatthew G. Knepley dm->probs = tmpd; 5361e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5362e5e52638SMatthew G. Knepley } 5363e5e52638SMatthew G. Knepley 5364e5e52638SMatthew G. Knepley /*@ 5365e5e52638SMatthew G. Knepley DMGetNumDS - Get the number of discrete systems in the DM 5366e5e52638SMatthew G. Knepley 5367e5e52638SMatthew G. Knepley Not collective 5368e5e52638SMatthew G. Knepley 5369e5e52638SMatthew G. Knepley Input Parameter: 5370e5e52638SMatthew G. Knepley . dm - The DM 5371e5e52638SMatthew G. Knepley 5372e5e52638SMatthew G. Knepley Output Parameter: 5373e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects 5374e5e52638SMatthew G. Knepley 5375e5e52638SMatthew G. Knepley Level: intermediate 5376e5e52638SMatthew G. Knepley 5377db781477SPatrick Sanan .seealso: `DMGetDS()`, `DMGetCellDS()` 5378e5e52638SMatthew G. Knepley @*/ 5379d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5380d71ae5a4SJacob Faibussowitsch { 5381e5e52638SMatthew G. Knepley PetscFunctionBegin; 5382e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5383534a8f05SLisandro Dalcin PetscValidIntPointer(Nds, 2); 5384e5e52638SMatthew G. Knepley *Nds = dm->Nds; 5385e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5386e5e52638SMatthew G. Knepley } 5387e5e52638SMatthew G. Knepley 5388e5e52638SMatthew G. Knepley /*@ 5389e5e52638SMatthew G. Knepley DMClearDS - Remove all discrete systems from the DM 5390e5e52638SMatthew G. Knepley 5391d083f849SBarry Smith Logically collective on dm 5392e5e52638SMatthew G. Knepley 5393e5e52638SMatthew G. Knepley Input Parameter: 5394e5e52638SMatthew G. Knepley . dm - The DM 5395e5e52638SMatthew G. Knepley 5396e5e52638SMatthew G. Knepley Level: intermediate 5397e5e52638SMatthew G. Knepley 5398db781477SPatrick Sanan .seealso: `DMGetNumDS()`, `DMGetDS()`, `DMSetField()` 5399e5e52638SMatthew G. Knepley @*/ 5400d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearDS(DM dm) 5401d71ae5a4SJacob Faibussowitsch { 5402e5e52638SMatthew G. Knepley PetscInt s; 5403e5e52638SMatthew G. Knepley 5404e5e52638SMatthew G. Knepley PetscFunctionBegin; 5405e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5406e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 54079566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 54089566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[s].label)); 54099566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[s].fields)); 5410e5e52638SMatthew G. Knepley } 54119566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5412e5e52638SMatthew G. Knepley dm->probs = NULL; 5413e5e52638SMatthew G. Knepley dm->Nds = 0; 5414e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5415e5e52638SMatthew G. Knepley } 5416e5e52638SMatthew G. Knepley 5417e5e52638SMatthew G. Knepley /*@ 5418e5e52638SMatthew G. Knepley DMGetDS - Get the default PetscDS 5419e5e52638SMatthew G. Knepley 5420e5e52638SMatthew G. Knepley Not collective 5421e5e52638SMatthew G. Knepley 5422e5e52638SMatthew G. Knepley Input Parameter: 5423e5e52638SMatthew G. Knepley . dm - The DM 5424e5e52638SMatthew G. Knepley 5425e5e52638SMatthew G. Knepley Output Parameter: 5426e5e52638SMatthew G. Knepley . prob - The default PetscDS 5427e5e52638SMatthew G. Knepley 5428e5e52638SMatthew G. Knepley Level: intermediate 5429e5e52638SMatthew G. Knepley 5430db781477SPatrick Sanan .seealso: `DMGetCellDS()`, `DMGetRegionDS()` 5431e5e52638SMatthew G. Knepley @*/ 5432d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 5433d71ae5a4SJacob Faibussowitsch { 5434e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5435e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5436e5e52638SMatthew G. Knepley PetscValidPointer(prob, 2); 5437b0143b4dSMatthew G. Knepley if (dm->Nds <= 0) { 5438b0143b4dSMatthew G. Knepley PetscDS ds; 5439b0143b4dSMatthew G. Knepley 54409566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 54419566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, NULL, NULL, ds)); 54429566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 5443b0143b4dSMatthew G. Knepley } 5444b0143b4dSMatthew G. Knepley *prob = dm->probs[0].ds; 5445e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5446e5e52638SMatthew G. Knepley } 5447e5e52638SMatthew G. Knepley 5448e5e52638SMatthew G. Knepley /*@ 5449e5e52638SMatthew G. Knepley DMGetCellDS - Get the PetscDS defined on a given cell 5450e5e52638SMatthew G. Knepley 5451e5e52638SMatthew G. Knepley Not collective 5452e5e52638SMatthew G. Knepley 5453e5e52638SMatthew G. Knepley Input Parameters: 5454e5e52638SMatthew G. Knepley + dm - The DM 5455e5e52638SMatthew G. Knepley - point - Cell for the DS 5456e5e52638SMatthew G. Knepley 5457e5e52638SMatthew G. Knepley Output Parameter: 5458e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell 5459e5e52638SMatthew G. Knepley 5460e5e52638SMatthew G. Knepley Level: developer 5461e5e52638SMatthew G. Knepley 5462db781477SPatrick Sanan .seealso: `DMGetDS()`, `DMSetRegionDS()` 5463e5e52638SMatthew G. Knepley @*/ 5464d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob) 5465d71ae5a4SJacob Faibussowitsch { 5466e5e52638SMatthew G. Knepley PetscDS probDef = NULL; 5467e5e52638SMatthew G. Knepley PetscInt s; 5468e5e52638SMatthew G. Knepley 5469e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5470e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5471e5e52638SMatthew G. Knepley PetscValidPointer(prob, 3); 547263a3b9bcSJacob Faibussowitsch PetscCheck(point >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %" PetscInt_FMT, point); 5473e5e52638SMatthew G. Knepley *prob = NULL; 5474e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5475e5e52638SMatthew G. Knepley PetscInt val; 5476e5e52638SMatthew G. Knepley 54779371c9d4SSatish Balay if (!dm->probs[s].label) { 54789371c9d4SSatish Balay probDef = dm->probs[s].ds; 54799371c9d4SSatish Balay } else { 54809566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dm->probs[s].label, point, &val)); 54819371c9d4SSatish Balay if (val >= 0) { 54829371c9d4SSatish Balay *prob = dm->probs[s].ds; 54839371c9d4SSatish Balay break; 54849371c9d4SSatish Balay } 5485e5e52638SMatthew G. Knepley } 5486e5e52638SMatthew G. Knepley } 5487e5e52638SMatthew G. Knepley if (!*prob) *prob = probDef; 5488e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5489e5e52638SMatthew G. Knepley } 5490e5e52638SMatthew G. Knepley 5491e5e52638SMatthew G. Knepley /*@ 5492e5e52638SMatthew G. Knepley DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel 5493e5e52638SMatthew G. Knepley 5494e5e52638SMatthew G. Knepley Not collective 5495e5e52638SMatthew G. Knepley 5496e5e52638SMatthew G. Knepley Input Parameters: 5497e5e52638SMatthew G. Knepley + dm - The DM 5498e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh 5499e5e52638SMatthew G. Knepley 5500b3cf3223SMatthew G. Knepley Output Parameters: 5501b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5502b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL 5503e5e52638SMatthew G. Knepley 5504154ca461SJed Brown Note: 5505154ca461SJed Brown If a non-NULL label is given, but there is no PetscDS on that specific label, 5506154ca461SJed Brown the PetscDS for the full domain (if present) is returned. Returns with 5507154ca461SJed Brown fields=NULL and prob=NULL if there is no PetscDS for the full domain. 5508e5e52638SMatthew G. Knepley 5509e5e52638SMatthew G. Knepley Level: advanced 5510e5e52638SMatthew G. Knepley 5511db781477SPatrick Sanan .seealso: `DMGetRegionNumDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5512e5e52638SMatthew G. Knepley @*/ 5513d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds) 5514d71ae5a4SJacob Faibussowitsch { 5515e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5516e5e52638SMatthew G. Knepley 5517e5e52638SMatthew G. Knepley PetscFunctionBegin; 5518e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5519e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 55209371c9d4SSatish Balay if (fields) { 55219371c9d4SSatish Balay PetscValidPointer(fields, 3); 55229371c9d4SSatish Balay *fields = NULL; 55239371c9d4SSatish Balay } 55249371c9d4SSatish Balay if (ds) { 55259371c9d4SSatish Balay PetscValidPointer(ds, 4); 55269371c9d4SSatish Balay *ds = NULL; 55279371c9d4SSatish Balay } 5528e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5529154ca461SJed Brown if (dm->probs[s].label == label || !dm->probs[s].label) { 5530b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5531b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 5532154ca461SJed Brown if (dm->probs[s].label) PetscFunctionReturn(0); 5533b3cf3223SMatthew G. Knepley } 5534e5e52638SMatthew G. Knepley } 55352df9ee95SMatthew G. Knepley PetscFunctionReturn(0); 5536e5e52638SMatthew G. Knepley } 5537e5e52638SMatthew G. Knepley 5538e5e52638SMatthew G. Knepley /*@ 5539bb7acecfSBarry Smith DMSetRegionDS - Set the `PetscDS` for a given mesh region, defined by a `DMLabel` 5540083401c6SMatthew G. Knepley 5541083401c6SMatthew G. Knepley Collective on dm 5542083401c6SMatthew G. Knepley 5543083401c6SMatthew G. Knepley Input Parameters: 5544bb7acecfSBarry Smith + dm - The `DM` 5545bb7acecfSBarry Smith . label - The `DMLabel` defining the mesh region, or NULL for the entire mesh 5546bb7acecfSBarry Smith . fields - The IS containing the `DM` field numbers for the fields in this `PetscDS`, or NULL for all fields 5547bb7acecfSBarry Smith - prob - The `PetscDS` defined on the given region 5548083401c6SMatthew G. Knepley 5549bb7acecfSBarry Smith Note: 5550bb7acecfSBarry 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, 5551083401c6SMatthew G. Knepley the fields argument is ignored. 5552083401c6SMatthew G. Knepley 5553083401c6SMatthew G. Knepley Level: advanced 5554083401c6SMatthew G. Knepley 5555db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionNumDS()`, `DMGetDS()`, `DMGetCellDS()` 5556083401c6SMatthew G. Knepley @*/ 5557d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds) 5558d71ae5a4SJacob Faibussowitsch { 5559083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5560083401c6SMatthew G. Knepley 5561083401c6SMatthew G. Knepley PetscFunctionBegin; 5562083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5563083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5564064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 5565083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5566083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 55679566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 5568083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 5569083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5570083401c6SMatthew G. Knepley } 5571083401c6SMatthew G. Knepley } 55729566063dSJacob Faibussowitsch PetscCall(DMDSEnlarge_Static(dm, Nds + 1)); 55739566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 55749566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 55759566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 5576083401c6SMatthew G. Knepley if (!label) { 5577083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5578083401c6SMatthew G. Knepley for (s = Nds - 1; s >= 0; --s) dm->probs[s + 1] = dm->probs[s]; 5579083401c6SMatthew G. Knepley Nds = 0; 5580083401c6SMatthew G. Knepley } 5581083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5582083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5583083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 5584083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5585083401c6SMatthew G. Knepley } 5586083401c6SMatthew G. Knepley 5587083401c6SMatthew G. Knepley /*@ 5588e5e52638SMatthew G. Knepley DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number 5589e5e52638SMatthew G. Knepley 5590e5e52638SMatthew G. Knepley Not collective 5591e5e52638SMatthew G. Knepley 5592e5e52638SMatthew G. Knepley Input Parameters: 5593e5e52638SMatthew G. Knepley + dm - The DM 5594e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5595e5e52638SMatthew G. Knepley 5596e5e52638SMatthew G. Knepley Output Parameters: 5597b3cf3223SMatthew G. Knepley + label - The region label, or NULL 5598b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5599083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL 5600e5e52638SMatthew G. Knepley 5601e5e52638SMatthew G. Knepley Level: advanced 5602e5e52638SMatthew G. Knepley 5603db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5604e5e52638SMatthew G. Knepley @*/ 5605d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds) 5606d71ae5a4SJacob Faibussowitsch { 5607e5e52638SMatthew G. Knepley PetscInt Nds; 5608e5e52638SMatthew G. Knepley 5609e5e52638SMatthew G. Knepley PetscFunctionBegin; 5610e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56119566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 561263a3b9bcSJacob 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); 5613e5e52638SMatthew G. Knepley if (label) { 5614e5e52638SMatthew G. Knepley PetscValidPointer(label, 3); 5615e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5616e5e52638SMatthew G. Knepley } 5617b3cf3223SMatthew G. Knepley if (fields) { 5618b3cf3223SMatthew G. Knepley PetscValidPointer(fields, 4); 5619b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5620b3cf3223SMatthew G. Knepley } 5621e5e52638SMatthew G. Knepley if (ds) { 5622b3cf3223SMatthew G. Knepley PetscValidPointer(ds, 5); 5623e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5624e5e52638SMatthew G. Knepley } 5625e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5626e5e52638SMatthew G. Knepley } 5627e5e52638SMatthew G. Knepley 5628e5e52638SMatthew G. Knepley /*@ 5629083401c6SMatthew G. Knepley DMSetRegionNumDS - Set the PetscDS for a given mesh region, defined by the region number 5630e5e52638SMatthew G. Knepley 5631083401c6SMatthew G. Knepley Not collective 5632e5e52638SMatthew G. Knepley 5633e5e52638SMatthew G. Knepley Input Parameters: 5634e5e52638SMatthew G. Knepley + dm - The DM 5635083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 5636083401c6SMatthew G. Knepley . label - The region label, or NULL 5637083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL to prevent setting 5638083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL to prevent setting 5639e5e52638SMatthew G. Knepley 5640e5e52638SMatthew G. Knepley Level: advanced 5641e5e52638SMatthew G. Knepley 5642db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5643e5e52638SMatthew G. Knepley @*/ 5644d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds) 5645d71ae5a4SJacob Faibussowitsch { 5646083401c6SMatthew G. Knepley PetscInt Nds; 5647e5e52638SMatthew G. Knepley 5648e5e52638SMatthew G. Knepley PetscFunctionBegin; 5649e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5650ad540459SPierre Jolivet if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 56519566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 565263a3b9bcSJacob 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); 56539566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 56549566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[num].label)); 5655083401c6SMatthew G. Knepley dm->probs[num].label = label; 5656083401c6SMatthew G. Knepley if (fields) { 5657083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 56589566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 56599566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[num].fields)); 5660083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5661e5e52638SMatthew G. Knepley } 5662083401c6SMatthew G. Knepley if (ds) { 5663083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 56649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 56659566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[num].ds)); 5666083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5667083401c6SMatthew G. Knepley } 5668e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5669e5e52638SMatthew G. Knepley } 5670e5e52638SMatthew G. Knepley 5671e5e52638SMatthew G. Knepley /*@ 56721d3af9e0SMatthew G. Knepley DMFindRegionNum - Find the region number for a given PetscDS, or -1 if it is not found. 56731d3af9e0SMatthew G. Knepley 56741d3af9e0SMatthew G. Knepley Not collective 56751d3af9e0SMatthew G. Knepley 56761d3af9e0SMatthew G. Knepley Input Parameters: 56771d3af9e0SMatthew G. Knepley + dm - The DM 56781d3af9e0SMatthew G. Knepley - ds - The PetscDS defined on the given region 56791d3af9e0SMatthew G. Knepley 56801d3af9e0SMatthew G. Knepley Output Parameter: 56811d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 56821d3af9e0SMatthew G. Knepley 56831d3af9e0SMatthew G. Knepley Level: advanced 56841d3af9e0SMatthew G. Knepley 5685db781477SPatrick Sanan .seealso: `DMGetRegionNumDS()`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 56861d3af9e0SMatthew G. Knepley @*/ 5687d71ae5a4SJacob Faibussowitsch PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 5688d71ae5a4SJacob Faibussowitsch { 56891d3af9e0SMatthew G. Knepley PetscInt Nds, n; 56901d3af9e0SMatthew G. Knepley 56911d3af9e0SMatthew G. Knepley PetscFunctionBegin; 56921d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56931d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 5694dadcf809SJacob Faibussowitsch PetscValidIntPointer(num, 3); 56959566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 56969371c9d4SSatish Balay for (n = 0; n < Nds; ++n) 56979371c9d4SSatish Balay if (ds == dm->probs[n].ds) break; 56981d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 56991d3af9e0SMatthew G. Knepley else *num = n; 57001d3af9e0SMatthew G. Knepley PetscFunctionReturn(0); 57011d3af9e0SMatthew G. Knepley } 57021d3af9e0SMatthew G. Knepley 57032df84da0SMatthew G. Knepley /*@C 5704bb7acecfSBarry Smith DMCreateFEDefault - Create a `PetscFE` based on the celltype for the mesh 57052df84da0SMatthew G. Knepley 57062df84da0SMatthew G. Knepley Not collective 57072df84da0SMatthew G. Knepley 5708f1a722f8SMatthew G. Knepley Input Parameters: 5709bb7acecfSBarry Smith + dm - The `DM` 57102df84da0SMatthew G. Knepley . Nc - The number of components for the field 5711bb7acecfSBarry Smith . prefix - The options prefix for the output `PetscFE`, or NULL 5712bb7acecfSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 57132df84da0SMatthew G. Knepley 57142df84da0SMatthew G. Knepley Output Parameter: 5715bb7acecfSBarry Smith . fem - The `PetscFE` 57162df84da0SMatthew G. Knepley 5717bb7acecfSBarry Smith Note: 5718bb7acecfSBarry Smith This is a convenience method that just calls `PetscFECreateByCell()` underneath. 57192df84da0SMatthew G. Knepley 57202df84da0SMatthew G. Knepley Level: intermediate 57212df84da0SMatthew G. Knepley 5722db781477SPatrick Sanan .seealso: `PetscFECreateByCell()`, `DMAddField()`, `DMCreateDS()`, `DMGetCellDS()`, `DMGetRegionDS()` 57232df84da0SMatthew G. Knepley @*/ 5724d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFEDefault(DM dm, PetscInt Nc, const char prefix[], PetscInt qorder, PetscFE *fem) 5725d71ae5a4SJacob Faibussowitsch { 57262df84da0SMatthew G. Knepley DMPolytopeType ct; 57272df84da0SMatthew G. Knepley PetscInt dim, cStart; 57282df84da0SMatthew G. Knepley 57292df84da0SMatthew G. Knepley PetscFunctionBegin; 57302df84da0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57312df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 2); 57322df84da0SMatthew G. Knepley if (prefix) PetscValidCharPointer(prefix, 3); 57332df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, qorder, 4); 57342df84da0SMatthew G. Knepley PetscValidPointer(fem, 5); 57359566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 57369566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 57379566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 57389566063dSJacob Faibussowitsch PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, Nc, ct, prefix, qorder, fem)); 57392df84da0SMatthew G. Knepley PetscFunctionReturn(0); 57402df84da0SMatthew G. Knepley } 57412df84da0SMatthew G. Knepley 57421d3af9e0SMatthew G. Knepley /*@ 5743bb7acecfSBarry Smith DMCreateDS - Create the discrete systems for the `DM` based upon the fields added to the `DM` 5744e5e52638SMatthew G. Knepley 5745d083f849SBarry Smith Collective on dm 5746e5e52638SMatthew G. Knepley 5747e5e52638SMatthew G. Knepley Input Parameter: 5748bb7acecfSBarry Smith . dm - The `DM` 5749e5e52638SMatthew G. Knepley 575045480ffeSMatthew G. Knepley Options Database Keys: 5751bb7acecfSBarry Smith . -dm_petscds_view - View all the `PetscDS` objects in this `DM` 575245480ffeSMatthew G. Knepley 5753bb7acecfSBarry Smith Note: 5754bb7acecfSBarry Smith If the label has a `PetscDS` defined, it will be replaced. Otherwise, it will be added to the `DM`. 5755e5e52638SMatthew G. Knepley 5756e5e52638SMatthew G. Knepley Level: intermediate 5757e5e52638SMatthew G. Knepley 5758db781477SPatrick Sanan .seealso: `DMSetField`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 5759e5e52638SMatthew G. Knepley @*/ 5760d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDS(DM dm) 5761d71ae5a4SJacob Faibussowitsch { 5762e5e52638SMatthew G. Knepley MPI_Comm comm; 5763083401c6SMatthew G. Knepley PetscDS dsDef; 5764083401c6SMatthew G. Knepley DMLabel *labelSet; 5765f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5766f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5767e5e52638SMatthew G. Knepley 5768e5e52638SMatthew G. Knepley PetscFunctionBegin; 5769e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5770e5e52638SMatthew G. Knepley if (!dm->fields) PetscFunctionReturn(0); 57719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 57729566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dE)); 5773083401c6SMatthew G. Knepley /* Determine how many regions we have */ 57749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &labelSet)); 5775083401c6SMatthew G. Knepley Nl = 0; 5776083401c6SMatthew G. Knepley Ndef = 0; 5777083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5778083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5779083401c6SMatthew G. Knepley PetscInt l; 5780083401c6SMatthew G. Knepley 5781f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5782f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5783f918ec44SMatthew G. Knepley { 5784f918ec44SMatthew G. Knepley PetscClassId id; 5785f918ec44SMatthew G. Knepley 57869566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(dm->fields[f].disc, &id)); 5787f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5788f918ec44SMatthew G. Knepley Ceed ceed; 5789f918ec44SMatthew G. Knepley 57909566063dSJacob Faibussowitsch PetscCall(DMGetCeed(dm, &ceed)); 57919566063dSJacob Faibussowitsch PetscCall(PetscFESetCeed((PetscFE)dm->fields[f].disc, ceed)); 5792f918ec44SMatthew G. Knepley } 5793f918ec44SMatthew G. Knepley } 5794f918ec44SMatthew G. Knepley #endif 57959371c9d4SSatish Balay if (!label) { 57969371c9d4SSatish Balay ++Ndef; 57979371c9d4SSatish Balay continue; 57989371c9d4SSatish Balay } 57999371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 58009371c9d4SSatish Balay if (label == labelSet[l]) break; 5801083401c6SMatthew G. Knepley if (l < Nl) continue; 5802083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5803083401c6SMatthew G. Knepley } 5804083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 58059566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef)); 5806083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5807b3cf3223SMatthew G. Knepley IS fields; 5808b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5809b3cf3223SMatthew G. Knepley 58109371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58119371c9d4SSatish Balay if (!dm->fields[f].label) ++nf; 58127a8be351SBarry Smith PetscCheck(nf, comm, PETSC_ERR_PLIB, "All fields have labels, but we are trying to create a default DS"); 58139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 58149371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58159371c9d4SSatish Balay if (!dm->fields[f].label) fld[nf++] = f; 58169566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 58179566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 58189566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 58199566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 582088f0c812SMatthew G. Knepley 58219566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 58229566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, NULL, fields, dsDef)); 58239566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 58249566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 58252df9ee95SMatthew G. Knepley } 58269566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef)); 58279566063dSJacob Faibussowitsch if (dsDef) PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 5828083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5829083401c6SMatthew G. Knepley if (Ndef && Nl) { 58300122748bSMatthew G. Knepley DM plex; 5831083401c6SMatthew G. Knepley DMLabel cellLabel; 5832083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5833083401c6SMatthew G. Knepley PetscInt *fields; 5834083401c6SMatthew G. Knepley const PetscInt *cells; 5835083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 58360122748bSMatthew G. Knepley 58379566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 58389566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(plex, &depth)); 58399566063dSJacob Faibussowitsch PetscCall(DMGetStratumIS(plex, "dim", depth, &allcellIS)); 58409566063dSJacob Faibussowitsch if (!allcellIS) PetscCall(DMGetStratumIS(plex, "depth", depth, &allcellIS)); 58415fedec97SMatthew G. Knepley /* TODO This looks like it only works for one label */ 5842083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5843083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5844083401c6SMatthew G. Knepley IS pointIS; 5845083401c6SMatthew G. Knepley 58469566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 58479566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, 1, &pointIS)); 58489566063dSJacob Faibussowitsch PetscCall(ISDifference(allcellIS, pointIS, &defcellIS)); 58499566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointIS)); 5850083401c6SMatthew G. Knepley } 58519566063dSJacob Faibussowitsch PetscCall(ISDestroy(&allcellIS)); 5852083401c6SMatthew G. Knepley 58539566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel)); 58549566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(defcellIS, &n)); 58559566063dSJacob Faibussowitsch PetscCall(ISGetIndices(defcellIS, &cells)); 58569566063dSJacob Faibussowitsch for (c = 0; c < n; ++c) PetscCall(DMLabelSetValue(cellLabel, cells[c], 1)); 58579566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(defcellIS, &cells)); 58589566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 58599566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(plex, cellLabel)); 5860083401c6SMatthew G. Knepley 58619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Ndef, &fields)); 58629371c9d4SSatish Balay for (f = 0; f < Nf; ++f) 58639371c9d4SSatish Balay if (!dm->fields[f].label) fields[nf++] = f; 58649566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fieldIS)); 58659566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fieldIS, "dm_fields_")); 58669566063dSJacob Faibussowitsch PetscCall(ISSetType(fieldIS, ISGENERAL)); 58679566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER)); 5868083401c6SMatthew G. Knepley 58699566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 58709566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, cellLabel, fieldIS, dsDef)); 58719566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 58729566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&cellLabel)); 58739566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 58749566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fieldIS)); 58759566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5876083401c6SMatthew G. Knepley } 5877083401c6SMatthew G. Knepley /* Create label DSes 5878083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5879083401c6SMatthew G. Knepley */ 5880083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5881083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5882083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5883083401c6SMatthew G. Knepley PetscDS ds; 5884083401c6SMatthew G. Knepley IS fields; 5885083401c6SMatthew G. Knepley PetscInt *fld, nf; 5886083401c6SMatthew G. Knepley 58879566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 58889371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58899371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 58909566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 58919371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58929371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 58939566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 58949566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 58959566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 58969566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 58979566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, label, fields, ds)); 58989566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 58999566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(ds, dE)); 5900083401c6SMatthew G. Knepley { 5901083401c6SMatthew G. Knepley DMPolytopeType ct; 5902083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 59035fedec97SMatthew G. Knepley PetscBool isCohesiveLocal = PETSC_FALSE, isCohesive; 59040122748bSMatthew G. Knepley 59059566063dSJacob Faibussowitsch PetscCall(DMLabelGetBounds(label, &lStart, &lEnd)); 5906665f567fSMatthew G. Knepley if (lStart >= 0) { 59079566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, lStart, &ct)); 5908412e9a14SMatthew G. Knepley switch (ct) { 5909412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5910412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5911412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5912d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5913d71ae5a4SJacob Faibussowitsch isCohesiveLocal = PETSC_TRUE; 5914d71ae5a4SJacob Faibussowitsch break; 5915d71ae5a4SJacob Faibussowitsch default: 5916d71ae5a4SJacob Faibussowitsch break; 5917412e9a14SMatthew G. Knepley } 5918665f567fSMatthew G. Knepley } 59199566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&isCohesiveLocal, &isCohesive, 1, MPIU_BOOL, MPI_LOR, comm)); 59205fedec97SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) { 59215fedec97SMatthew G. Knepley if (label == dm->fields[f].label || !dm->fields[f].label) { 59225fedec97SMatthew G. Knepley if (label == dm->fields[f].label) { 59239566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, nf, NULL)); 59249566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(ds, nf, isCohesive)); 59255fedec97SMatthew G. Knepley } 59265fedec97SMatthew G. Knepley ++nf; 59275fedec97SMatthew G. Knepley } 59285fedec97SMatthew G. Knepley } 5929e5e52638SMatthew G. Knepley } 59309566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 5931e5e52638SMatthew G. Knepley } 59329566063dSJacob Faibussowitsch PetscCall(PetscFree(labelSet)); 5933e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5934083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5935083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 5936083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5937083401c6SMatthew G. Knepley const PetscInt *fld; 59385fedec97SMatthew G. Knepley PetscInt nf, dsnf; 59395fedec97SMatthew G. Knepley PetscBool isCohesive; 5940e5e52638SMatthew G. Knepley 59419566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsnf)); 59429566063dSJacob Faibussowitsch PetscCall(PetscDSIsCohesive(ds, &isCohesive)); 59439566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(fields, &nf)); 59449566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fields, &fld)); 5945083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5946083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 59475fedec97SMatthew G. Knepley PetscBool isCohesiveField; 5948e5e52638SMatthew G. Knepley PetscClassId id; 5949e5e52638SMatthew G. Knepley 59505fedec97SMatthew G. Knepley /* Handle DS with no fields */ 59519566063dSJacob Faibussowitsch if (dsnf) PetscCall(PetscDSGetCohesive(ds, f, &isCohesiveField)); 59525fedec97SMatthew G. Knepley /* If this is a cohesive cell, then regular fields need the lower dimensional discretization */ 59539566063dSJacob Faibussowitsch if (isCohesive && !isCohesiveField) PetscCall(PetscFEGetHeightSubspace((PetscFE)disc, 1, (PetscFE *)&disc)); 59549566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, f, disc)); 5955083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 59569566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 5957e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 5958e5e52638SMatthew G. Knepley } 59599566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fields, &fld)); 5960e5e52638SMatthew G. Knepley } 5961f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 59629566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)dm)->prefix, "-dm_ds_jet_degree", &k, &flg)); 5963f9244615SMatthew G. Knepley if (flg) { 59643b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 59653b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 59663b4aee56SMatthew G. Knepley PetscInt Nf, f; 59673b4aee56SMatthew G. Knepley 59689566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 59699566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSSetJetDegree(ds, f, k)); 59703b4aee56SMatthew G. Knepley } 5971f9244615SMatthew G. Knepley } 5972e5e52638SMatthew G. Knepley /* Setup DSes */ 5973e5e52638SMatthew G. Knepley if (doSetup) { 59749566063dSJacob Faibussowitsch for (s = 0; s < dm->Nds; ++s) PetscCall(PetscDSSetUp(dm->probs[s].ds)); 5975e5e52638SMatthew G. Knepley } 5976e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5977e5e52638SMatthew G. Knepley } 5978e5e52638SMatthew G. Knepley 5979e5e52638SMatthew G. Knepley /*@ 5980bb7acecfSBarry Smith DMComputeExactSolution - Compute the exact solution for a given `DM`, using the `PetscDS` information. 59817f96f943SMatthew G. Knepley 5982bb7acecfSBarry Smith Collective on `DM` 5983f2cacb80SMatthew G. Knepley 59847f96f943SMatthew G. Knepley Input Parameters: 5985bb7acecfSBarry Smith + dm - The `DM` 59867f96f943SMatthew G. Knepley - time - The time 59877f96f943SMatthew G. Knepley 59887f96f943SMatthew G. Knepley Output Parameters: 5989f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5990f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 59917f96f943SMatthew G. Knepley 5992bb7acecfSBarry Smith Note: 5993bb7acecfSBarry Smith The user must call `PetscDSSetExactSolution()` before using this routine 59947f96f943SMatthew G. Knepley 59957f96f943SMatthew G. Knepley Level: developer 59967f96f943SMatthew G. Knepley 5997db781477SPatrick Sanan .seealso: `PetscDSSetExactSolution()` 59987f96f943SMatthew G. Knepley @*/ 5999d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 6000d71ae5a4SJacob Faibussowitsch { 60017f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 60027f96f943SMatthew G. Knepley void **ectxs; 60037f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 60047f96f943SMatthew G. Knepley 60057f96f943SMatthew G. Knepley PetscFunctionBegin; 6006f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6007f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 6008f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 60099566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 60109566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exacts, Nf, &ectxs)); 60119566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 60127f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 60137f96f943SMatthew G. Knepley PetscDS ds; 60147f96f943SMatthew G. Knepley DMLabel label; 60157f96f943SMatthew G. Knepley IS fieldIS; 60167f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 60177f96f943SMatthew G. Knepley PetscInt dsNf, f; 60187f96f943SMatthew G. Knepley 60199566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds)); 60209566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 60219566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fieldIS, &fields)); 60229566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 60239566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6024f2cacb80SMatthew G. Knepley if (u) { 60257f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 60267f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 60279566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field])); 60287f96f943SMatthew G. Knepley } 60299566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 60307f96f943SMatthew G. Knepley if (label) { 60319566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u)); 60327f96f943SMatthew G. Knepley } else { 60339566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u)); 60347f96f943SMatthew G. Knepley } 60357f96f943SMatthew G. Knepley } 6036f2cacb80SMatthew G. Knepley if (u_t) { 60379566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 60389566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6039f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 6040f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 60419566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field])); 6042f2cacb80SMatthew G. Knepley } 60439566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 6044f2cacb80SMatthew G. Knepley if (label) { 60459566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t)); 6046f2cacb80SMatthew G. Knepley } else { 60479566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t)); 6048f2cacb80SMatthew G. Knepley } 6049f2cacb80SMatthew G. Knepley } 6050f2cacb80SMatthew G. Knepley } 6051f2cacb80SMatthew G. Knepley if (u) { 60529566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution")); 60539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u, "exact_")); 6054f2cacb80SMatthew G. Knepley } 6055f2cacb80SMatthew G. Knepley if (u_t) { 60569566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution Time Derivative")); 60579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u_t, "exact_t_")); 6058f2cacb80SMatthew G. Knepley } 60599566063dSJacob Faibussowitsch PetscCall(PetscFree2(exacts, ectxs)); 60607f96f943SMatthew G. Knepley PetscFunctionReturn(0); 60617f96f943SMatthew G. Knepley } 60627f96f943SMatthew G. Knepley 6063d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscDS ds) 6064d71ae5a4SJacob Faibussowitsch { 606545480ffeSMatthew G. Knepley PetscDS dsNew; 606645480ffeSMatthew G. Knepley DSBoundary b; 60676a02485aSMatthew G. Knepley PetscInt cdim, Nf, f, d; 60685fedec97SMatthew G. Knepley PetscBool isCohesive; 606945480ffeSMatthew G. Knepley void *ctx; 607045480ffeSMatthew G. Knepley 607145480ffeSMatthew G. Knepley PetscFunctionBegin; 60729566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)ds), &dsNew)); 60739566063dSJacob Faibussowitsch PetscCall(PetscDSCopyConstants(ds, dsNew)); 60749566063dSJacob Faibussowitsch PetscCall(PetscDSCopyExactSolutions(ds, dsNew)); 60759566063dSJacob Faibussowitsch PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew)); 60769566063dSJacob Faibussowitsch PetscCall(PetscDSCopyEquations(ds, dsNew)); 60779566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 607845480ffeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 60799566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(ds, f, &ctx)); 60809566063dSJacob Faibussowitsch PetscCall(PetscDSSetContext(dsNew, f, ctx)); 60819566063dSJacob Faibussowitsch PetscCall(PetscDSGetCohesive(ds, f, &isCohesive)); 60829566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive)); 60836a02485aSMatthew G. Knepley PetscCall(PetscDSGetJetDegree(ds, f, &d)); 60846a02485aSMatthew G. Knepley PetscCall(PetscDSSetJetDegree(dsNew, f, d)); 608545480ffeSMatthew G. Knepley } 608645480ffeSMatthew G. Knepley if (Nf) { 60879566063dSJacob Faibussowitsch PetscCall(PetscDSGetCoordinateDimension(ds, &cdim)); 60889566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim)); 608945480ffeSMatthew G. Knepley } 60909566063dSJacob Faibussowitsch PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew)); 609145480ffeSMatthew G. Knepley for (b = dsNew->boundary; b; b = b->next) { 60929566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, b->lname, &b->label)); 609345480ffeSMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 60947a8be351SBarry Smith //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name); 609545480ffeSMatthew G. Knepley } 609645480ffeSMatthew G. Knepley 60979566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, label, fields, dsNew)); 60989566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsNew)); 609945480ffeSMatthew G. Knepley PetscFunctionReturn(0); 610045480ffeSMatthew G. Knepley } 610145480ffeSMatthew G. Knepley 61027f96f943SMatthew G. Knepley /*@ 6103bb7acecfSBarry Smith DMCopyDS - Copy the discrete systems for the `DM` into another `DM` 6104e5e52638SMatthew G. Knepley 6105d083f849SBarry Smith Collective on dm 6106e5e52638SMatthew G. Knepley 6107e5e52638SMatthew G. Knepley Input Parameter: 6108bb7acecfSBarry Smith . dm - The `DM` 6109e5e52638SMatthew G. Knepley 6110e5e52638SMatthew G. Knepley Output Parameter: 6111bb7acecfSBarry Smith . newdm - The `DM` 6112e5e52638SMatthew G. Knepley 6113e5e52638SMatthew G. Knepley Level: advanced 6114e5e52638SMatthew G. Knepley 6115db781477SPatrick Sanan .seealso: `DMCopyFields()`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 6116e5e52638SMatthew G. Knepley @*/ 6117d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDS(DM dm, DM newdm) 6118d71ae5a4SJacob Faibussowitsch { 6119e5e52638SMatthew G. Knepley PetscInt Nds, s; 6120e5e52638SMatthew G. Knepley 6121e5e52638SMatthew G. Knepley PetscFunctionBegin; 6122e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 61239566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 61249566063dSJacob Faibussowitsch PetscCall(DMClearDS(newdm)); 6125e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6126e5e52638SMatthew G. Knepley DMLabel label; 6127b3cf3223SMatthew G. Knepley IS fields; 612845480ffeSMatthew G. Knepley PetscDS ds, newds; 6129783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6130e5e52638SMatthew G. Knepley 61319566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fields, &ds)); 6132b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 61339566063dSJacob Faibussowitsch PetscCall(DMTransferDS_Internal(newdm, label, fields, ds)); 613445480ffeSMatthew G. Knepley /* Commplete new labels in the new DS */ 61359566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(newdm, label, NULL, &newds)); 61369566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumBoundary(newds, &Nbd)); 6137783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6138b8025e53SMatthew G. Knepley PetscWeakForm wf; 613945480ffeSMatthew G. Knepley DMLabel label; 6140783e2ec8SMatthew G. Knepley PetscInt field; 6141783e2ec8SMatthew G. Knepley 61429566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 61439566063dSJacob Faibussowitsch PetscCall(PetscWeakFormReplaceLabel(wf, label)); 6144783e2ec8SMatthew G. Knepley } 6145e5e52638SMatthew G. Knepley } 6146799db056SMatthew G. Knepley PetscCall(DMCompleteBCLabels_Internal(newdm)); 6147e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6148e5e52638SMatthew G. Knepley } 6149e5e52638SMatthew G. Knepley 6150e5e52638SMatthew G. Knepley /*@ 6151bb7acecfSBarry Smith DMCopyDisc - Copy the fields and discrete systems for the `DM` into another `DM` 6152e5e52638SMatthew G. Knepley 6153d083f849SBarry Smith Collective on dm 6154e5e52638SMatthew G. Knepley 6155e5e52638SMatthew G. Knepley Input Parameter: 6156bb7acecfSBarry Smith . dm - The `DM` 6157e5e52638SMatthew G. Knepley 6158e5e52638SMatthew G. Knepley Output Parameter: 6159bb7acecfSBarry Smith . newdm - The `DM` 6160e5e52638SMatthew G. Knepley 6161e5e52638SMatthew G. Knepley Level: advanced 6162e5e52638SMatthew G. Knepley 6163bb7acecfSBarry Smith Developer Note: 6164bb7acecfSBarry Smith Really ugly name, nothing in PETSc is called a `Disc` plus it is an ugly abbreviation 6165bb7acecfSBarry Smith 6166db781477SPatrick Sanan .seealso: `DMCopyFields()`, `DMCopyDS()` 6167e5e52638SMatthew G. Knepley @*/ 6168d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6169d71ae5a4SJacob Faibussowitsch { 6170e5e52638SMatthew G. Knepley PetscFunctionBegin; 61719566063dSJacob Faibussowitsch PetscCall(DMCopyFields(dm, newdm)); 61729566063dSJacob Faibussowitsch PetscCall(DMCopyDS(dm, newdm)); 6173e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6174e5e52638SMatthew G. Knepley } 6175e5e52638SMatthew G. Knepley 6176c73cfb54SMatthew G. Knepley /*@ 6177bb7acecfSBarry Smith DMGetDimension - Return the topological dimension of the `DM` 6178c73cfb54SMatthew G. Knepley 6179c73cfb54SMatthew G. Knepley Not collective 6180c73cfb54SMatthew G. Knepley 6181c73cfb54SMatthew G. Knepley Input Parameter: 6182bb7acecfSBarry Smith . dm - The `DM` 6183c73cfb54SMatthew G. Knepley 6184c73cfb54SMatthew G. Knepley Output Parameter: 6185c73cfb54SMatthew G. Knepley . dim - The topological dimension 6186c73cfb54SMatthew G. Knepley 6187c73cfb54SMatthew G. Knepley Level: beginner 6188c73cfb54SMatthew G. Knepley 6189db781477SPatrick Sanan .seealso: `DMSetDimension()`, `DMCreate()` 6190c73cfb54SMatthew G. Knepley @*/ 6191d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6192d71ae5a4SJacob Faibussowitsch { 6193c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6194c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6195534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 6196c73cfb54SMatthew G. Knepley *dim = dm->dim; 6197c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6198c73cfb54SMatthew G. Knepley } 6199c73cfb54SMatthew G. Knepley 6200c73cfb54SMatthew G. Knepley /*@ 6201bb7acecfSBarry Smith DMSetDimension - Set the topological dimension of the `DM` 6202c73cfb54SMatthew G. Knepley 6203c73cfb54SMatthew G. Knepley Collective on dm 6204c73cfb54SMatthew G. Knepley 6205c73cfb54SMatthew G. Knepley Input Parameters: 6206bb7acecfSBarry Smith + dm - The `DM` 6207c73cfb54SMatthew G. Knepley - dim - The topological dimension 6208c73cfb54SMatthew G. Knepley 6209c73cfb54SMatthew G. Knepley Level: beginner 6210c73cfb54SMatthew G. Knepley 6211db781477SPatrick Sanan .seealso: `DMGetDimension()`, `DMCreate()` 6212c73cfb54SMatthew G. Knepley @*/ 6213d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6214d71ae5a4SJacob Faibussowitsch { 6215e5e52638SMatthew G. Knepley PetscDS ds; 621645480ffeSMatthew G. Knepley PetscInt Nds, n; 6217f17e8794SMatthew G. Knepley 6218c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6219c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6220c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6221c73cfb54SMatthew G. Knepley dm->dim = dim; 6222d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 62239566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 622445480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 62259566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds)); 62269566063dSJacob Faibussowitsch if (ds->dimEmbed < 0) PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 622745480ffeSMatthew G. Knepley } 6228d17bd122SMatthew G. Knepley } 6229c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6230c73cfb54SMatthew G. Knepley } 6231c73cfb54SMatthew G. Knepley 6232793f3fe5SMatthew G. Knepley /*@ 6233793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6234793f3fe5SMatthew G. Knepley 6235d083f849SBarry Smith Collective on dm 6236793f3fe5SMatthew G. Knepley 6237793f3fe5SMatthew G. Knepley Input Parameters: 6238bb7acecfSBarry Smith + dm - the `DM` 6239793f3fe5SMatthew G. Knepley - dim - the dimension 6240793f3fe5SMatthew G. Knepley 6241793f3fe5SMatthew G. Knepley Output Parameters: 6242793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6243aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6244793f3fe5SMatthew G. Knepley 6245793f3fe5SMatthew G. Knepley Note: 6246793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6247a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6248793f3fe5SMatthew G. Knepley then the interval is empty. 6249793f3fe5SMatthew G. Knepley 6250793f3fe5SMatthew G. Knepley Level: intermediate 6251793f3fe5SMatthew G. Knepley 6252db781477SPatrick Sanan .seealso: `DMPLEX`, `DMPlexGetDepthStratum()`, `DMPlexGetHeightStratum()` 6253793f3fe5SMatthew G. Knepley @*/ 6254d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6255d71ae5a4SJacob Faibussowitsch { 6256793f3fe5SMatthew G. Knepley PetscInt d; 6257793f3fe5SMatthew G. Knepley 6258793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6259793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 62609566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &d)); 62617a8be351SBarry Smith PetscCheck((dim >= 0) && (dim <= d), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %" PetscInt_FMT, dim); 6262dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getdimpoints, dim, pStart, pEnd); 6263793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 6264793f3fe5SMatthew G. Knepley } 6265793f3fe5SMatthew G. Knepley 62666636e97aSMatthew G Knepley /*@ 6267bb7acecfSBarry Smith DMGetOutputDM - Retrieve the `DM` associated with the layout for output 6268f4d763aaSMatthew G. Knepley 62698f700142SStefano Zampini Collective on dm 62708f700142SStefano Zampini 6271f4d763aaSMatthew G. Knepley Input Parameter: 6272bb7acecfSBarry Smith . dm - The original `DM` 6273f4d763aaSMatthew G. Knepley 6274f4d763aaSMatthew G. Knepley Output Parameter: 6275bb7acecfSBarry Smith . odm - The `DM` which provides the layout for output 6276f4d763aaSMatthew G. Knepley 6277f4d763aaSMatthew G. Knepley Level: intermediate 6278f4d763aaSMatthew G. Knepley 6279bb7acecfSBarry Smith Note: 6280bb7acecfSBarry Smith In some situations the vector obtained with `DMCreateGlobalVector()` excludes points for degrees of freedom that are associated with fixed (Dirichelet) boundary 6281bb7acecfSBarry 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 6282bb7acecfSBarry Smith locations for those dof so that they can be output to a file or other viewer along with the unconstrained dof. 6283bb7acecfSBarry Smith 6284bb7acecfSBarry Smith .seealso: `VecView()`, `DMGetGlobalSection()`, `DMCreateGlobalVector()`, `PetscSectionHasConstraints()`, `DMSetGlobalSection()` 6285f4d763aaSMatthew G. Knepley @*/ 6286d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 6287d71ae5a4SJacob Faibussowitsch { 6288c26acbdeSMatthew G. Knepley PetscSection section; 62892d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 629014f150ffSMatthew G. Knepley 629114f150ffSMatthew G. Knepley PetscFunctionBegin; 629214f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 629314f150ffSMatthew G. Knepley PetscValidPointer(odm, 2); 62949566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 62959566063dSJacob Faibussowitsch PetscCall(PetscSectionHasConstraints(section, &hasConstraints)); 62969566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)dm))); 62972d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 6298c26acbdeSMatthew G. Knepley *odm = dm; 6299c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 6300c26acbdeSMatthew G. Knepley } 630114f150ffSMatthew G. Knepley if (!dm->dmBC) { 6302c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 630314f150ffSMatthew G. Knepley PetscSF sf; 630414f150ffSMatthew G. Knepley 63059566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->dmBC)); 63069566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, dm->dmBC)); 63079566063dSJacob Faibussowitsch PetscCall(PetscSectionClone(section, &newSection)); 63089566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm->dmBC, newSection)); 63099566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&newSection)); 63109566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm->dmBC, &sf)); 63119566063dSJacob Faibussowitsch PetscCall(PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection)); 63129566063dSJacob Faibussowitsch PetscCall(DMSetGlobalSection(dm->dmBC, gsection)); 63139566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&gsection)); 631414f150ffSMatthew G. Knepley } 631514f150ffSMatthew G. Knepley *odm = dm->dmBC; 631614f150ffSMatthew G. Knepley PetscFunctionReturn(0); 631714f150ffSMatthew G. Knepley } 6318f4d763aaSMatthew G. Knepley 6319f4d763aaSMatthew G. Knepley /*@ 6320cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 6321f4d763aaSMatthew G. Knepley 6322f4d763aaSMatthew G. Knepley Input Parameter: 6323bb7acecfSBarry Smith . dm - The original `DM` 6324f4d763aaSMatthew G. Knepley 6325cdb7a50dSMatthew G. Knepley Output Parameters: 6326cdb7a50dSMatthew G. Knepley + num - The output sequence number 6327cdb7a50dSMatthew G. Knepley - val - The output sequence value 6328f4d763aaSMatthew G. Knepley 6329f4d763aaSMatthew G. Knepley Level: intermediate 6330f4d763aaSMatthew G. Knepley 6331bb7acecfSBarry Smith Note: 6332bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6333bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6334bb7acecfSBarry Smith 6335bb7acecfSBarry Smith Developer Note: 6336bb7acecfSBarry Smith The `DM` serves as a convenient place to store the current iteration value. The iteration is not 6337bb7acecfSBarry Smith not directly related to the `DM`. 6338f4d763aaSMatthew G. Knepley 6339db781477SPatrick Sanan .seealso: `VecView()` 6340f4d763aaSMatthew G. Knepley @*/ 6341d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 6342d71ae5a4SJacob Faibussowitsch { 6343f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6344f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63459371c9d4SSatish Balay if (num) { 63469371c9d4SSatish Balay PetscValidIntPointer(num, 2); 63479371c9d4SSatish Balay *num = dm->outputSequenceNum; 63489371c9d4SSatish Balay } 63499371c9d4SSatish Balay if (val) { 63509371c9d4SSatish Balay PetscValidRealPointer(val, 3); 63519371c9d4SSatish Balay *val = dm->outputSequenceVal; 63529371c9d4SSatish Balay } 6353f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 6354f4d763aaSMatthew G. Knepley } 6355f4d763aaSMatthew G. Knepley 6356f4d763aaSMatthew G. Knepley /*@ 6357cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 6358f4d763aaSMatthew G. Knepley 6359f4d763aaSMatthew G. Knepley Input Parameters: 6360bb7acecfSBarry Smith + dm - The original `DM` 6361cdb7a50dSMatthew G. Knepley . num - The output sequence number 6362cdb7a50dSMatthew G. Knepley - val - The output sequence value 6363f4d763aaSMatthew G. Knepley 6364f4d763aaSMatthew G. Knepley Level: intermediate 6365f4d763aaSMatthew G. Knepley 6366bb7acecfSBarry Smith Note: 6367bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6368bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6369f4d763aaSMatthew G. Knepley 6370db781477SPatrick Sanan .seealso: `VecView()` 6371f4d763aaSMatthew G. Knepley @*/ 6372d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 6373d71ae5a4SJacob Faibussowitsch { 6374f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6375f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6376f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 6377cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 6378cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 6379cdb7a50dSMatthew G. Knepley } 6380cdb7a50dSMatthew G. Knepley 6381cdb7a50dSMatthew G. Knepley /*@C 6382bb7acecfSBarry Smith DMOutputSequenceLoad - Retrieve the sequence value from a `PetscViewer` 6383cdb7a50dSMatthew G. Knepley 6384cdb7a50dSMatthew G. Knepley Input Parameters: 6385bb7acecfSBarry Smith + dm - The original `DM` 6386cdb7a50dSMatthew G. Knepley . name - The sequence name 6387cdb7a50dSMatthew G. Knepley - num - The output sequence number 6388cdb7a50dSMatthew G. Knepley 6389cdb7a50dSMatthew G. Knepley Output Parameter: 6390cdb7a50dSMatthew G. Knepley . val - The output sequence value 6391cdb7a50dSMatthew G. Knepley 6392cdb7a50dSMatthew G. Knepley Level: intermediate 6393cdb7a50dSMatthew G. Knepley 6394bb7acecfSBarry Smith Note: 6395bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6396bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6397bb7acecfSBarry Smith 6398bb7acecfSBarry Smith Developer Note: 6399bb7acecfSBarry Smith It is unclear at the user API level why a `DM` is needed as input 6400cdb7a50dSMatthew G. Knepley 6401db781477SPatrick Sanan .seealso: `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6402cdb7a50dSMatthew G. Knepley @*/ 6403d71ae5a4SJacob Faibussowitsch PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 6404d71ae5a4SJacob Faibussowitsch { 6405cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 6406cdb7a50dSMatthew G. Knepley 6407cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 6408cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6409cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6410064a246eSJacob Faibussowitsch PetscValidRealPointer(val, 5); 64119566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6412cdb7a50dSMatthew G. Knepley if (ishdf5) { 6413cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6414cdb7a50dSMatthew G. Knepley PetscScalar value; 6415cdb7a50dSMatthew G. Knepley 64169566063dSJacob Faibussowitsch PetscCall(DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer)); 64174aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 6418cdb7a50dSMatthew G. Knepley #endif 6419cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 6420f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 6421f4d763aaSMatthew G. Knepley } 64228e4ac7eaSMatthew G. Knepley 64238e4ac7eaSMatthew G. Knepley /*@ 6424bb7acecfSBarry Smith DMGetUseNatural - Get the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 64258e4ac7eaSMatthew G. Knepley 64268e4ac7eaSMatthew G. Knepley Not collective 64278e4ac7eaSMatthew G. Knepley 64288e4ac7eaSMatthew G. Knepley Input Parameter: 6429bb7acecfSBarry Smith . dm - The `DM` 64308e4ac7eaSMatthew G. Knepley 64318e4ac7eaSMatthew G. Knepley Output Parameter: 6432bb7acecfSBarry Smith . useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 64338e4ac7eaSMatthew G. Knepley 64348e4ac7eaSMatthew G. Knepley Level: beginner 64358e4ac7eaSMatthew G. Knepley 6436db781477SPatrick Sanan .seealso: `DMSetUseNatural()`, `DMCreate()` 64378e4ac7eaSMatthew G. Knepley @*/ 6438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 6439d71ae5a4SJacob Faibussowitsch { 64408e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 64418e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6442534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 64438e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 64448e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 64458e4ac7eaSMatthew G. Knepley } 64468e4ac7eaSMatthew G. Knepley 64478e4ac7eaSMatthew G. Knepley /*@ 6448bb7acecfSBarry Smith DMSetUseNatural - Set the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 64498e4ac7eaSMatthew G. Knepley 64508e4ac7eaSMatthew G. Knepley Collective on dm 64518e4ac7eaSMatthew G. Knepley 64528e4ac7eaSMatthew G. Knepley Input Parameters: 6453bb7acecfSBarry Smith + dm - The `DM` 6454bb7acecfSBarry Smith - useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 64558e4ac7eaSMatthew G. Knepley 6456bb7acecfSBarry Smith Note: 6457bb7acecfSBarry Smith This also causes the map to be build after `DMCreateSubDM()` and `DMCreateSuperDM()` 64585d3b26e6SMatthew G. Knepley 64598e4ac7eaSMatthew G. Knepley Level: beginner 64608e4ac7eaSMatthew G. Knepley 6461db781477SPatrick Sanan .seealso: `DMGetUseNatural()`, `DMCreate()`, `DMPlexDistribute()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 64628e4ac7eaSMatthew G. Knepley @*/ 6463d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 6464d71ae5a4SJacob Faibussowitsch { 64658e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 64668e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64678833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 64688e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 64698e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 64708e4ac7eaSMatthew G. Knepley } 6471c58f1c22SToby Isaac 6472c58f1c22SToby Isaac /*@C 6473bb7acecfSBarry Smith DMCreateLabel - Create a label of the given name if it does not already exist in the `DM` 6474c58f1c22SToby Isaac 6475c58f1c22SToby Isaac Not Collective 6476c58f1c22SToby Isaac 6477c58f1c22SToby Isaac Input Parameters: 6478bb7acecfSBarry Smith + dm - The `DM` object 6479c58f1c22SToby Isaac - name - The label name 6480c58f1c22SToby Isaac 6481c58f1c22SToby Isaac Level: intermediate 6482c58f1c22SToby Isaac 6483db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6484c58f1c22SToby Isaac @*/ 6485d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabel(DM dm, const char name[]) 6486d71ae5a4SJacob Faibussowitsch { 64875d80c0bfSVaclav Hapla PetscBool flg; 64885d80c0bfSVaclav Hapla DMLabel label; 6489c58f1c22SToby Isaac 6490c58f1c22SToby Isaac PetscFunctionBegin; 6491c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6492c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 64939566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 6494c58f1c22SToby Isaac if (!flg) { 64959566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 64969566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 64979566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 6498c58f1c22SToby Isaac } 6499c58f1c22SToby Isaac PetscFunctionReturn(0); 6500c58f1c22SToby Isaac } 6501c58f1c22SToby Isaac 6502c58f1c22SToby Isaac /*@C 6503bb7acecfSBarry 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. 65040fdc7489SMatthew Knepley 65050fdc7489SMatthew Knepley Not Collective 65060fdc7489SMatthew Knepley 65070fdc7489SMatthew Knepley Input Parameters: 6508bb7acecfSBarry Smith + dm - The `DM` object 65090fdc7489SMatthew Knepley . l - The index for the label 65100fdc7489SMatthew Knepley - name - The label name 65110fdc7489SMatthew Knepley 65120fdc7489SMatthew Knepley Level: intermediate 65130fdc7489SMatthew Knepley 6514db781477SPatrick Sanan .seealso: `DMCreateLabel()`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 65150fdc7489SMatthew Knepley @*/ 6516d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 6517d71ae5a4SJacob Faibussowitsch { 65180fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 65190fdc7489SMatthew Knepley DMLabel label; 65200fdc7489SMatthew Knepley PetscInt Nl, m; 65210fdc7489SMatthew Knepley PetscBool flg, match; 65220fdc7489SMatthew Knepley const char *lname; 65230fdc7489SMatthew Knepley 65240fdc7489SMatthew Knepley PetscFunctionBegin; 65250fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6526064a246eSJacob Faibussowitsch PetscValidCharPointer(name, 3); 65279566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 65280fdc7489SMatthew Knepley if (!flg) { 65299566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 65309566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 65319566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 65320fdc7489SMatthew Knepley } 65339566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 653463a3b9bcSJacob Faibussowitsch PetscCheck(l < Nl, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", l, Nl); 65350fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 65369566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)orig->label, &lname)); 65379566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &match)); 65380fdc7489SMatthew Knepley if (match) break; 65390fdc7489SMatthew Knepley } 65400fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 65410fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 65420fdc7489SMatthew Knepley else prev->next = orig->next; 65430fdc7489SMatthew Knepley if (!l) { 65440fdc7489SMatthew Knepley orig->next = dm->labels; 65450fdc7489SMatthew Knepley dm->labels = orig; 65460fdc7489SMatthew Knepley } else { 65479371c9d4SSatish Balay for (m = 0, prev = dm->labels; m < l - 1; ++m, prev = prev->next) 65489371c9d4SSatish Balay ; 65490fdc7489SMatthew Knepley orig->next = prev->next; 65500fdc7489SMatthew Knepley prev->next = orig; 65510fdc7489SMatthew Knepley } 65520fdc7489SMatthew Knepley PetscFunctionReturn(0); 65530fdc7489SMatthew Knepley } 65540fdc7489SMatthew Knepley 65550fdc7489SMatthew Knepley /*@C 6556bb7acecfSBarry Smith DMGetLabelValue - Get the value in a `DMLabel` for the given point, with -1 as the default 6557c58f1c22SToby Isaac 6558c58f1c22SToby Isaac Not Collective 6559c58f1c22SToby Isaac 6560c58f1c22SToby Isaac Input Parameters: 6561bb7acecfSBarry Smith + dm - The `DM` object 6562c58f1c22SToby Isaac . name - The label name 6563c58f1c22SToby Isaac - point - The mesh point 6564c58f1c22SToby Isaac 6565c58f1c22SToby Isaac Output Parameter: 6566c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 6567c58f1c22SToby Isaac 6568c58f1c22SToby Isaac Level: beginner 6569c58f1c22SToby Isaac 6570db781477SPatrick Sanan .seealso: `DMLabelGetValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6571c58f1c22SToby Isaac @*/ 6572d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 6573d71ae5a4SJacob Faibussowitsch { 6574c58f1c22SToby Isaac DMLabel label; 6575c58f1c22SToby Isaac 6576c58f1c22SToby Isaac PetscFunctionBegin; 6577c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6578c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 65799566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 65807a8be351SBarry Smith PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 65819566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, point, value)); 6582c58f1c22SToby Isaac PetscFunctionReturn(0); 6583c58f1c22SToby Isaac } 6584c58f1c22SToby Isaac 6585c58f1c22SToby Isaac /*@C 6586bb7acecfSBarry Smith DMSetLabelValue - Add a point to a `DMLabel` with given value 6587c58f1c22SToby Isaac 6588c58f1c22SToby Isaac Not Collective 6589c58f1c22SToby Isaac 6590c58f1c22SToby Isaac Input Parameters: 6591bb7acecfSBarry Smith + dm - The `DM` object 6592c58f1c22SToby Isaac . name - The label name 6593c58f1c22SToby Isaac . point - The mesh point 6594c58f1c22SToby Isaac - value - The label value for this point 6595c58f1c22SToby Isaac 6596c58f1c22SToby Isaac Output Parameter: 6597c58f1c22SToby Isaac 6598c58f1c22SToby Isaac Level: beginner 6599c58f1c22SToby Isaac 6600db781477SPatrick Sanan .seealso: `DMLabelSetValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6601c58f1c22SToby Isaac @*/ 6602d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6603d71ae5a4SJacob Faibussowitsch { 6604c58f1c22SToby Isaac DMLabel label; 6605c58f1c22SToby Isaac 6606c58f1c22SToby Isaac PetscFunctionBegin; 6607c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6608c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 66099566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6610c58f1c22SToby Isaac if (!label) { 66119566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 66129566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6613c58f1c22SToby Isaac } 66149566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, point, value)); 6615c58f1c22SToby Isaac PetscFunctionReturn(0); 6616c58f1c22SToby Isaac } 6617c58f1c22SToby Isaac 6618c58f1c22SToby Isaac /*@C 6619bb7acecfSBarry Smith DMClearLabelValue - Remove a point from a `DMLabel` with given value 6620c58f1c22SToby Isaac 6621c58f1c22SToby Isaac Not Collective 6622c58f1c22SToby Isaac 6623c58f1c22SToby Isaac Input Parameters: 6624bb7acecfSBarry Smith + dm - The `DM` object 6625c58f1c22SToby Isaac . name - The label name 6626c58f1c22SToby Isaac . point - The mesh point 6627c58f1c22SToby Isaac - value - The label value for this point 6628c58f1c22SToby Isaac 6629c58f1c22SToby Isaac Level: beginner 6630c58f1c22SToby Isaac 6631db781477SPatrick Sanan .seealso: `DMLabelClearValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6632c58f1c22SToby Isaac @*/ 6633d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6634d71ae5a4SJacob Faibussowitsch { 6635c58f1c22SToby Isaac DMLabel label; 6636c58f1c22SToby Isaac 6637c58f1c22SToby Isaac PetscFunctionBegin; 6638c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6639c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 66409566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6641c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 66429566063dSJacob Faibussowitsch PetscCall(DMLabelClearValue(label, point, value)); 6643c58f1c22SToby Isaac PetscFunctionReturn(0); 6644c58f1c22SToby Isaac } 6645c58f1c22SToby Isaac 6646c58f1c22SToby Isaac /*@C 6647bb7acecfSBarry Smith DMGetLabelSize - Get the value of `DMLabelGetNumValues()` of a `DMLabel` in the `DM` 6648c58f1c22SToby Isaac 6649c58f1c22SToby Isaac Not Collective 6650c58f1c22SToby Isaac 6651c58f1c22SToby Isaac Input Parameters: 6652bb7acecfSBarry Smith + dm - The `DM` object 6653c58f1c22SToby Isaac - name - The label name 6654c58f1c22SToby Isaac 6655c58f1c22SToby Isaac Output Parameter: 6656c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 6657c58f1c22SToby Isaac 6658c58f1c22SToby Isaac Level: beginner 6659c58f1c22SToby Isaac 6660bb7acecfSBarry Smith Developer Note: 6661bb7acecfSBarry Smith This should be renamed to something like `DMGetLabelNumValues()` or removed. 6662bb7acecfSBarry Smith 6663bb7acecfSBarry Smith .seealso: `DMLabelGetNumValues()`, `DMSetLabelValue()`, `DMGetLabel()` 6664c58f1c22SToby Isaac @*/ 6665d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 6666d71ae5a4SJacob Faibussowitsch { 6667c58f1c22SToby Isaac DMLabel label; 6668c58f1c22SToby Isaac 6669c58f1c22SToby Isaac PetscFunctionBegin; 6670c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6671c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6672534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 66739566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6674c58f1c22SToby Isaac *size = 0; 6675c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 66769566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, size)); 6677c58f1c22SToby Isaac PetscFunctionReturn(0); 6678c58f1c22SToby Isaac } 6679c58f1c22SToby Isaac 6680c58f1c22SToby Isaac /*@C 6681bb7acecfSBarry Smith DMGetLabelIdIS - Get the `DMLabelGetValueIS()` from a `DMLabel` in the `DM` 6682c58f1c22SToby Isaac 6683c58f1c22SToby Isaac Not Collective 6684c58f1c22SToby Isaac 6685c58f1c22SToby Isaac Input Parameters: 6686bb7acecfSBarry Smith + mesh - The `DM` object 6687c58f1c22SToby Isaac - name - The label name 6688c58f1c22SToby Isaac 6689c58f1c22SToby Isaac Output Parameter: 6690c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 6691c58f1c22SToby Isaac 6692c58f1c22SToby Isaac Level: beginner 6693c58f1c22SToby Isaac 6694db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMGetLabelSize()` 6695c58f1c22SToby Isaac @*/ 6696d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 6697d71ae5a4SJacob Faibussowitsch { 6698c58f1c22SToby Isaac DMLabel label; 6699c58f1c22SToby Isaac 6700c58f1c22SToby Isaac PetscFunctionBegin; 6701c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6702c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6703c58f1c22SToby Isaac PetscValidPointer(ids, 3); 67049566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6705c58f1c22SToby Isaac *ids = NULL; 6706dab2e251SBlaise Bourdin if (label) { 67079566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, ids)); 6708dab2e251SBlaise Bourdin } else { 6709dab2e251SBlaise Bourdin /* returning an empty IS */ 67109566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 0, NULL, PETSC_USE_POINTER, ids)); 6711dab2e251SBlaise Bourdin } 6712c58f1c22SToby Isaac PetscFunctionReturn(0); 6713c58f1c22SToby Isaac } 6714c58f1c22SToby Isaac 6715c58f1c22SToby Isaac /*@C 6716c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 6717c58f1c22SToby Isaac 6718c58f1c22SToby Isaac Not Collective 6719c58f1c22SToby Isaac 6720c58f1c22SToby Isaac Input Parameters: 6721bb7acecfSBarry Smith + dm - The `DM` object 6722c58f1c22SToby Isaac . name - The label name 6723c58f1c22SToby Isaac - value - The stratum value 6724c58f1c22SToby Isaac 6725c58f1c22SToby Isaac Output Parameter: 6726bb7acecfSBarry Smith . size - The number of points, also called the stratum size 6727c58f1c22SToby Isaac 6728c58f1c22SToby Isaac Level: beginner 6729c58f1c22SToby Isaac 6730db781477SPatrick Sanan .seealso: `DMLabelGetStratumSize()`, `DMGetLabelSize()`, `DMGetLabelIds()` 6731c58f1c22SToby Isaac @*/ 6732d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 6733d71ae5a4SJacob Faibussowitsch { 6734c58f1c22SToby Isaac DMLabel label; 6735c58f1c22SToby Isaac 6736c58f1c22SToby Isaac PetscFunctionBegin; 6737c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6738c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6739534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 67409566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6741c58f1c22SToby Isaac *size = 0; 6742c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 67439566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, value, size)); 6744c58f1c22SToby Isaac PetscFunctionReturn(0); 6745c58f1c22SToby Isaac } 6746c58f1c22SToby Isaac 6747c58f1c22SToby Isaac /*@C 6748c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 6749c58f1c22SToby Isaac 6750c58f1c22SToby Isaac Not Collective 6751c58f1c22SToby Isaac 6752c58f1c22SToby Isaac Input Parameters: 6753bb7acecfSBarry Smith + dm - The `DM` object 6754c58f1c22SToby Isaac . name - The label name 6755c58f1c22SToby Isaac - value - The stratum value 6756c58f1c22SToby Isaac 6757c58f1c22SToby Isaac Output Parameter: 6758c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 6759c58f1c22SToby Isaac 6760c58f1c22SToby Isaac Level: beginner 6761c58f1c22SToby Isaac 6762db781477SPatrick Sanan .seealso: `DMLabelGetStratumIS()`, `DMGetStratumSize()` 6763c58f1c22SToby Isaac @*/ 6764d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 6765d71ae5a4SJacob Faibussowitsch { 6766c58f1c22SToby Isaac DMLabel label; 6767c58f1c22SToby Isaac 6768c58f1c22SToby Isaac PetscFunctionBegin; 6769c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6770c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6771c58f1c22SToby Isaac PetscValidPointer(points, 4); 67729566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6773c58f1c22SToby Isaac *points = NULL; 6774c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 67759566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, value, points)); 6776c58f1c22SToby Isaac PetscFunctionReturn(0); 6777c58f1c22SToby Isaac } 6778c58f1c22SToby Isaac 67794de306b1SToby Isaac /*@C 67809044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 67814de306b1SToby Isaac 67824de306b1SToby Isaac Not Collective 67834de306b1SToby Isaac 67844de306b1SToby Isaac Input Parameters: 6785bb7acecfSBarry Smith + dm - The `DM` object 67864de306b1SToby Isaac . name - The label name 67874de306b1SToby Isaac . value - The stratum value 67884de306b1SToby Isaac - points - The stratum points 67894de306b1SToby Isaac 67904de306b1SToby Isaac Level: beginner 67914de306b1SToby Isaac 6792bb7acecfSBarry Smith .seealso: `DMLabel`, `DMClearLabelStratum()`, `DMLabelClearStratum()`, `DMLabelSetStratumIS()`, `DMGetStratumSize()` 67934de306b1SToby Isaac @*/ 6794d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 6795d71ae5a4SJacob Faibussowitsch { 67964de306b1SToby Isaac DMLabel label; 67974de306b1SToby Isaac 67984de306b1SToby Isaac PetscFunctionBegin; 67994de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68004de306b1SToby Isaac PetscValidCharPointer(name, 2); 68014de306b1SToby Isaac PetscValidPointer(points, 4); 68029566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 68034de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 68049566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, points)); 68054de306b1SToby Isaac PetscFunctionReturn(0); 68064de306b1SToby Isaac } 68074de306b1SToby Isaac 6808c58f1c22SToby Isaac /*@C 6809bb7acecfSBarry Smith DMClearLabelStratum - Remove all points from a stratum from a `DMLabel` 6810c58f1c22SToby Isaac 6811c58f1c22SToby Isaac Not Collective 6812c58f1c22SToby Isaac 6813c58f1c22SToby Isaac Input Parameters: 6814bb7acecfSBarry Smith + dm - The `DM` object 6815c58f1c22SToby Isaac . name - The label name 6816c58f1c22SToby Isaac - value - The label value for this point 6817c58f1c22SToby Isaac 6818c58f1c22SToby Isaac Output Parameter: 6819c58f1c22SToby Isaac 6820c58f1c22SToby Isaac Level: beginner 6821c58f1c22SToby Isaac 6822bb7acecfSBarry Smith .seealso: `DMLabel`, `DMLabelClearStratum()`, `DMSetLabelValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6823c58f1c22SToby Isaac @*/ 6824d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 6825d71ae5a4SJacob Faibussowitsch { 6826c58f1c22SToby Isaac DMLabel label; 6827c58f1c22SToby Isaac 6828c58f1c22SToby Isaac PetscFunctionBegin; 6829c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6830c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 68319566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6832c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 68339566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 6834c58f1c22SToby Isaac PetscFunctionReturn(0); 6835c58f1c22SToby Isaac } 6836c58f1c22SToby Isaac 6837c58f1c22SToby Isaac /*@ 6838bb7acecfSBarry Smith DMGetNumLabels - Return the number of labels defined by on the `DM` 6839c58f1c22SToby Isaac 6840c58f1c22SToby Isaac Not Collective 6841c58f1c22SToby Isaac 6842c58f1c22SToby Isaac Input Parameter: 6843bb7acecfSBarry Smith . dm - The `DM` object 6844c58f1c22SToby Isaac 6845c58f1c22SToby Isaac Output Parameter: 6846c58f1c22SToby Isaac . numLabels - the number of Labels 6847c58f1c22SToby Isaac 6848c58f1c22SToby Isaac Level: intermediate 6849c58f1c22SToby Isaac 6850bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabelByNum()`, `DMGetLabelName()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6851c58f1c22SToby Isaac @*/ 6852d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 6853d71ae5a4SJacob Faibussowitsch { 68545d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6855c58f1c22SToby Isaac PetscInt n = 0; 6856c58f1c22SToby Isaac 6857c58f1c22SToby Isaac PetscFunctionBegin; 6858c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6859534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 68609371c9d4SSatish Balay while (next) { 68619371c9d4SSatish Balay ++n; 68629371c9d4SSatish Balay next = next->next; 68639371c9d4SSatish Balay } 6864c58f1c22SToby Isaac *numLabels = n; 6865c58f1c22SToby Isaac PetscFunctionReturn(0); 6866c58f1c22SToby Isaac } 6867c58f1c22SToby Isaac 6868c58f1c22SToby Isaac /*@C 6869c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 6870c58f1c22SToby Isaac 6871c58f1c22SToby Isaac Not Collective 6872c58f1c22SToby Isaac 6873c58f1c22SToby Isaac Input Parameters: 6874bb7acecfSBarry Smith + dm - The `DM` object 6875c58f1c22SToby Isaac - n - the label number 6876c58f1c22SToby Isaac 6877c58f1c22SToby Isaac Output Parameter: 6878c58f1c22SToby Isaac . name - the label name 6879c58f1c22SToby Isaac 6880c58f1c22SToby Isaac Level: intermediate 6881c58f1c22SToby Isaac 6882bb7acecfSBarry Smith Developer Note: 6883bb7acecfSBarry Smith Some of the functions that appropriate on labels using their number have the suffix ByNum, others do not. 6884bb7acecfSBarry Smith 6885bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabelByNum()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6886c58f1c22SToby Isaac @*/ 6887d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 6888d71ae5a4SJacob Faibussowitsch { 68895d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6890c58f1c22SToby Isaac PetscInt l = 0; 6891c58f1c22SToby Isaac 6892c58f1c22SToby Isaac PetscFunctionBegin; 6893c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6894c58f1c22SToby Isaac PetscValidPointer(name, 3); 6895c58f1c22SToby Isaac while (next) { 6896c58f1c22SToby Isaac if (l == n) { 68979566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, name)); 6898c58f1c22SToby Isaac PetscFunctionReturn(0); 6899c58f1c22SToby Isaac } 6900c58f1c22SToby Isaac ++l; 6901c58f1c22SToby Isaac next = next->next; 6902c58f1c22SToby Isaac } 690363a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 6904c58f1c22SToby Isaac } 6905c58f1c22SToby Isaac 6906c58f1c22SToby Isaac /*@C 6907bb7acecfSBarry Smith DMHasLabel - Determine whether the `DM` has a label of a given name 6908c58f1c22SToby Isaac 6909c58f1c22SToby Isaac Not Collective 6910c58f1c22SToby Isaac 6911c58f1c22SToby Isaac Input Parameters: 6912bb7acecfSBarry Smith + dm - The `DM` object 6913c58f1c22SToby Isaac - name - The label name 6914c58f1c22SToby Isaac 6915c58f1c22SToby Isaac Output Parameter: 6916bb7acecfSBarry Smith . hasLabel - `PETSC_TRUE` if the label is present 6917c58f1c22SToby Isaac 6918c58f1c22SToby Isaac Level: intermediate 6919c58f1c22SToby Isaac 6920bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabel()`, `DMGetLabelByNum()`, `DMCreateLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6921c58f1c22SToby Isaac @*/ 6922d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 6923d71ae5a4SJacob Faibussowitsch { 69245d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6925d67d17b1SMatthew G. Knepley const char *lname; 6926c58f1c22SToby Isaac 6927c58f1c22SToby Isaac PetscFunctionBegin; 6928c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6929c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6930534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 6931c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 6932c58f1c22SToby Isaac while (next) { 69339566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 69349566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, hasLabel)); 6935c58f1c22SToby Isaac if (*hasLabel) break; 6936c58f1c22SToby Isaac next = next->next; 6937c58f1c22SToby Isaac } 6938c58f1c22SToby Isaac PetscFunctionReturn(0); 6939c58f1c22SToby Isaac } 6940c58f1c22SToby Isaac 6941c58f1c22SToby Isaac /*@C 6942bb7acecfSBarry Smith DMGetLabel - Return the label of a given name, or NULL, from a `DM` 6943c58f1c22SToby Isaac 6944c58f1c22SToby Isaac Not Collective 6945c58f1c22SToby Isaac 6946c58f1c22SToby Isaac Input Parameters: 6947bb7acecfSBarry Smith + dm - The `DM` object 6948c58f1c22SToby Isaac - name - The label name 6949c58f1c22SToby Isaac 6950c58f1c22SToby Isaac Output Parameter: 6951bb7acecfSBarry Smith . label - The `DMLabel`, or NULL if the label is absent 6952c58f1c22SToby Isaac 6953bb7acecfSBarry Smith Default labels in a `DMPLEX`: 6954bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 6955bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 6956bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 6957bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 6958bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 6959bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 69606d7c9049SMatthew G. Knepley 6961c58f1c22SToby Isaac Level: intermediate 6962c58f1c22SToby Isaac 6963bb7acecfSBarry Smith .seealso: `DMLabel`, `DMHasLabel()`, `DMGetLabelByNum()`, `DMAddLabel()`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 6964c58f1c22SToby Isaac @*/ 6965d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 6966d71ae5a4SJacob Faibussowitsch { 69675d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6968c58f1c22SToby Isaac PetscBool hasLabel; 6969d67d17b1SMatthew G. Knepley const char *lname; 6970c58f1c22SToby Isaac 6971c58f1c22SToby Isaac PetscFunctionBegin; 6972c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6973c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6974c58f1c22SToby Isaac PetscValidPointer(label, 3); 6975c58f1c22SToby Isaac *label = NULL; 6976c58f1c22SToby Isaac while (next) { 69779566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 69789566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 6979c58f1c22SToby Isaac if (hasLabel) { 6980c58f1c22SToby Isaac *label = next->label; 6981c58f1c22SToby Isaac break; 6982c58f1c22SToby Isaac } 6983c58f1c22SToby Isaac next = next->next; 6984c58f1c22SToby Isaac } 6985c58f1c22SToby Isaac PetscFunctionReturn(0); 6986c58f1c22SToby Isaac } 6987c58f1c22SToby Isaac 6988c58f1c22SToby Isaac /*@C 6989bb7acecfSBarry Smith DMGetLabelByNum - Return the nth label on a `DM` 6990c58f1c22SToby Isaac 6991c58f1c22SToby Isaac Not Collective 6992c58f1c22SToby Isaac 6993c58f1c22SToby Isaac Input Parameters: 6994bb7acecfSBarry Smith + dm - The `DM` object 6995c58f1c22SToby Isaac - n - the label number 6996c58f1c22SToby Isaac 6997c58f1c22SToby Isaac Output Parameter: 6998c58f1c22SToby Isaac . label - the label 6999c58f1c22SToby Isaac 7000c58f1c22SToby Isaac Level: intermediate 7001c58f1c22SToby Isaac 7002bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7003c58f1c22SToby Isaac @*/ 7004d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7005d71ae5a4SJacob Faibussowitsch { 70065d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7007c58f1c22SToby Isaac PetscInt l = 0; 7008c58f1c22SToby Isaac 7009c58f1c22SToby Isaac PetscFunctionBegin; 7010c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7011c58f1c22SToby Isaac PetscValidPointer(label, 3); 7012c58f1c22SToby Isaac while (next) { 7013c58f1c22SToby Isaac if (l == n) { 7014c58f1c22SToby Isaac *label = next->label; 7015c58f1c22SToby Isaac PetscFunctionReturn(0); 7016c58f1c22SToby Isaac } 7017c58f1c22SToby Isaac ++l; 7018c58f1c22SToby Isaac next = next->next; 7019c58f1c22SToby Isaac } 702063a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7021c58f1c22SToby Isaac } 7022c58f1c22SToby Isaac 7023c58f1c22SToby Isaac /*@C 7024bb7acecfSBarry Smith DMAddLabel - Add the label to this `DM` 7025c58f1c22SToby Isaac 7026c58f1c22SToby Isaac Not Collective 7027c58f1c22SToby Isaac 7028c58f1c22SToby Isaac Input Parameters: 7029bb7acecfSBarry Smith + dm - The `DM` object 7030bb7acecfSBarry Smith - label - The `DMLabel` 7031c58f1c22SToby Isaac 7032c58f1c22SToby Isaac Level: developer 7033c58f1c22SToby Isaac 7034bb7acecfSBarry Smith .seealso: `DMLabel`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7035c58f1c22SToby Isaac @*/ 7036d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7037d71ae5a4SJacob Faibussowitsch { 70385d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7039c58f1c22SToby Isaac PetscBool hasLabel; 7040d67d17b1SMatthew G. Knepley const char *lname; 70415d80c0bfSVaclav Hapla PetscBool flg; 7042c58f1c22SToby Isaac 7043c58f1c22SToby Isaac PetscFunctionBegin; 7044c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70459566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 70469566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, lname, &hasLabel)); 70477a8be351SBarry Smith PetscCheck(!hasLabel, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 70489566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(1, &tmpLabel)); 7049c58f1c22SToby Isaac tmpLabel->label = label; 7050c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 70515d80c0bfSVaclav Hapla for (p = &dm->labels; (l = *p); p = &l->next) { } 70525d80c0bfSVaclav Hapla *p = tmpLabel; 70539566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 70549566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 70555d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 70569566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 7057ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 7058c58f1c22SToby Isaac PetscFunctionReturn(0); 7059c58f1c22SToby Isaac } 7060c58f1c22SToby Isaac 7061c58f1c22SToby Isaac /*@C 70624a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 70634a7ee7d0SMatthew G. Knepley 70644a7ee7d0SMatthew G. Knepley Not Collective 70654a7ee7d0SMatthew G. Knepley 70664a7ee7d0SMatthew G. Knepley Input Parameters: 7067bb7acecfSBarry Smith + dm - The `DM` object 7068bb7acecfSBarry Smith - label - The `DMLabel`, having the same name, to substitute 70694a7ee7d0SMatthew G. Knepley 7070bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7071bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7072bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7073bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7074bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7075bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7076bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 70774a7ee7d0SMatthew G. Knepley 70784a7ee7d0SMatthew G. Knepley Level: intermediate 70794a7ee7d0SMatthew G. Knepley 7080bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 70814a7ee7d0SMatthew G. Knepley @*/ 7082d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabel(DM dm, DMLabel label) 7083d71ae5a4SJacob Faibussowitsch { 70844a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 70854a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 70864a7ee7d0SMatthew G. Knepley const char *name, *lname; 70874a7ee7d0SMatthew G. Knepley 70884a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 70894a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70904a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 70919566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 70924a7ee7d0SMatthew G. Knepley while (next) { 70939566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 70949566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 70954a7ee7d0SMatthew G. Knepley if (hasLabel) { 70969566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 70979566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 70984a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 70999566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 71004a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 71019566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 71024a7ee7d0SMatthew G. Knepley next->label = label; 71034a7ee7d0SMatthew G. Knepley break; 71044a7ee7d0SMatthew G. Knepley } 71054a7ee7d0SMatthew G. Knepley next = next->next; 71064a7ee7d0SMatthew G. Knepley } 71074a7ee7d0SMatthew G. Knepley PetscFunctionReturn(0); 71084a7ee7d0SMatthew G. Knepley } 71094a7ee7d0SMatthew G. Knepley 71104a7ee7d0SMatthew G. Knepley /*@C 7111bb7acecfSBarry Smith DMRemoveLabel - Remove the label given by name from this `DM` 7112c58f1c22SToby Isaac 7113c58f1c22SToby Isaac Not Collective 7114c58f1c22SToby Isaac 7115c58f1c22SToby Isaac Input Parameters: 7116bb7acecfSBarry Smith + dm - The `DM` object 7117c58f1c22SToby Isaac - name - The label name 7118c58f1c22SToby Isaac 7119c58f1c22SToby Isaac Output Parameter: 7120bb7acecfSBarry Smith . label - The `DMLabel`, or NULL if the label is absent. Pass in NULL to call `DMLabelDestroy()` on the label, otherwise the 7121bb7acecfSBarry Smith caller is responsible for calling `DMLabelDestroy()`. 7122c58f1c22SToby Isaac 7123c58f1c22SToby Isaac Level: developer 7124c58f1c22SToby Isaac 7125bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabelBySelf()` 7126c58f1c22SToby Isaac @*/ 7127d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7128d71ae5a4SJacob Faibussowitsch { 712995d578d6SVaclav Hapla DMLabelLink link, *pnext; 7130c58f1c22SToby Isaac PetscBool hasLabel; 7131d67d17b1SMatthew G. Knepley const char *lname; 7132c58f1c22SToby Isaac 7133c58f1c22SToby Isaac PetscFunctionBegin; 7134c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7135e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 7136e5472504SVaclav Hapla if (label) { 7137e5472504SVaclav Hapla PetscValidPointer(label, 3); 7138c58f1c22SToby Isaac *label = NULL; 7139e5472504SVaclav Hapla } 71405d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 71419566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)link->label, &lname)); 71429566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7143c58f1c22SToby Isaac if (hasLabel) { 714495d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 71459566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &hasLabel)); 714695d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 71479566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &hasLabel)); 7148ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 714995d578d6SVaclav Hapla if (label) *label = link->label; 71509566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&link->label)); 71519566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7152c58f1c22SToby Isaac break; 7153c58f1c22SToby Isaac } 7154c58f1c22SToby Isaac } 7155c58f1c22SToby Isaac PetscFunctionReturn(0); 7156c58f1c22SToby Isaac } 7157c58f1c22SToby Isaac 7158306894acSVaclav Hapla /*@ 7159bb7acecfSBarry Smith DMRemoveLabelBySelf - Remove the label from this `DM` 7160306894acSVaclav Hapla 7161306894acSVaclav Hapla Not Collective 7162306894acSVaclav Hapla 7163306894acSVaclav Hapla Input Parameters: 7164bb7acecfSBarry Smith + dm - The `DM` object 7165bb7acecfSBarry Smith . label - The `DMLabel` to be removed from the `DM` 7166306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 7167306894acSVaclav Hapla 7168306894acSVaclav Hapla Level: developer 7169306894acSVaclav Hapla 7170bb7acecfSBarry Smith Note: 7171306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7172bb7acecfSBarry Smith If the `DM` has an exclusive reference to the label, the label gets destroyed and 7173306894acSVaclav Hapla *label nullified. 7174306894acSVaclav Hapla 7175bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()` `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabel()` 7176306894acSVaclav Hapla @*/ 7177d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7178d71ae5a4SJacob Faibussowitsch { 717943e45a93SVaclav Hapla DMLabelLink link, *pnext; 7180306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7181306894acSVaclav Hapla 7182306894acSVaclav Hapla PetscFunctionBegin; 7183306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7184306894acSVaclav Hapla PetscValidPointer(label, 2); 7185f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 7186306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7187306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm, failNotFound, 3); 71885d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 718943e45a93SVaclav Hapla if (*label == link->label) { 7190306894acSVaclav Hapla hasLabel = PETSC_TRUE; 719143e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7192306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7193ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 719443e45a93SVaclav Hapla if (((PetscObject)link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 71959566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&link->label)); 71969566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7197306894acSVaclav Hapla break; 7198306894acSVaclav Hapla } 7199306894acSVaclav Hapla } 72007a8be351SBarry Smith PetscCheck(hasLabel || !failNotFound, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 7201306894acSVaclav Hapla PetscFunctionReturn(0); 7202306894acSVaclav Hapla } 7203306894acSVaclav Hapla 7204c58f1c22SToby Isaac /*@C 7205c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7206c58f1c22SToby Isaac 7207c58f1c22SToby Isaac Not Collective 7208c58f1c22SToby Isaac 7209c58f1c22SToby Isaac Input Parameters: 7210bb7acecfSBarry Smith + dm - The `DM` object 7211c58f1c22SToby Isaac - name - The label name 7212c58f1c22SToby Isaac 7213c58f1c22SToby Isaac Output Parameter: 7214c58f1c22SToby Isaac . output - The flag for output 7215c58f1c22SToby Isaac 7216c58f1c22SToby Isaac Level: developer 7217c58f1c22SToby Isaac 7218bb7acecfSBarry Smith .seealso: `DMLabel`, `DMSetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7219c58f1c22SToby Isaac @*/ 7220d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7221d71ae5a4SJacob Faibussowitsch { 72225d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7223d67d17b1SMatthew G. Knepley const char *lname; 7224c58f1c22SToby Isaac 7225c58f1c22SToby Isaac PetscFunctionBegin; 7226c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7227dadcf809SJacob Faibussowitsch PetscValidCharPointer(name, 2); 7228dadcf809SJacob Faibussowitsch PetscValidBoolPointer(output, 3); 7229c58f1c22SToby Isaac while (next) { 7230c58f1c22SToby Isaac PetscBool flg; 7231c58f1c22SToby Isaac 72329566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 72339566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 72349371c9d4SSatish Balay if (flg) { 72359371c9d4SSatish Balay *output = next->output; 72369371c9d4SSatish Balay PetscFunctionReturn(0); 72379371c9d4SSatish Balay } 7238c58f1c22SToby Isaac next = next->next; 7239c58f1c22SToby Isaac } 724098921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7241c58f1c22SToby Isaac } 7242c58f1c22SToby Isaac 7243c58f1c22SToby Isaac /*@C 7244bb7acecfSBarry Smith DMSetLabelOutput - Set if a given label should be saved to a `PetscViewer` in calls to `DMView()` 7245c58f1c22SToby Isaac 7246c58f1c22SToby Isaac Not Collective 7247c58f1c22SToby Isaac 7248c58f1c22SToby Isaac Input Parameters: 7249bb7acecfSBarry Smith + dm - The `DM` object 7250c58f1c22SToby Isaac . name - The label name 7251bb7acecfSBarry Smith - output - `PETSC_TRUE` to save the label to the viewer 7252c58f1c22SToby Isaac 7253c58f1c22SToby Isaac Level: developer 7254c58f1c22SToby Isaac 7255bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetOutputFlag()`, `DMGetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7256c58f1c22SToby Isaac @*/ 7257d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7258d71ae5a4SJacob Faibussowitsch { 72595d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7260d67d17b1SMatthew G. Knepley const char *lname; 7261c58f1c22SToby Isaac 7262c58f1c22SToby Isaac PetscFunctionBegin; 7263c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7264534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 7265c58f1c22SToby Isaac while (next) { 7266c58f1c22SToby Isaac PetscBool flg; 7267c58f1c22SToby Isaac 72689566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 72699566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 72709371c9d4SSatish Balay if (flg) { 72719371c9d4SSatish Balay next->output = output; 72729371c9d4SSatish Balay PetscFunctionReturn(0); 72739371c9d4SSatish Balay } 7274c58f1c22SToby Isaac next = next->next; 7275c58f1c22SToby Isaac } 727698921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7277c58f1c22SToby Isaac } 7278c58f1c22SToby Isaac 7279c58f1c22SToby Isaac /*@ 7280bb7acecfSBarry Smith DMCopyLabels - Copy labels from one `DM` mesh to another `DM` with a superset of the points 7281c58f1c22SToby Isaac 7282d083f849SBarry Smith Collective on dmA 7283c58f1c22SToby Isaac 7284d8d19677SJose E. Roman Input Parameters: 7285bb7acecfSBarry Smith + dmA - The `DM` object with initial labels 7286bb7acecfSBarry Smith . dmB - The `DM` object to which labels are copied 7287bb7acecfSBarry Smith . mode - Copy labels by pointers (`PETSC_OWN_POINTER`) or duplicate them (`PETSC_COPY_VALUES`) 7288bb7acecfSBarry Smith . all - Copy all labels including "depth", "dim", and "celltype" (`PETSC_TRUE`) which are otherwise ignored (`PETSC_FALSE`) 7289bb7acecfSBarry Smith - emode - How to behave when a `DMLabel` in the source and destination `DM`s with the same name is encountered (see `DMCopyLabelsMode`) 7290c58f1c22SToby Isaac 7291c58f1c22SToby Isaac Level: intermediate 7292c58f1c22SToby Isaac 7293bb7acecfSBarry Smith Note: 72942cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 7295c58f1c22SToby Isaac 7296bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode` 7297c58f1c22SToby Isaac @*/ 7298d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 7299d71ae5a4SJacob Faibussowitsch { 73002cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 7301c58f1c22SToby Isaac const char *name; 7302c58f1c22SToby Isaac PetscBool flg; 73035d80c0bfSVaclav Hapla DMLabelLink link; 7304c58f1c22SToby Isaac 73055d80c0bfSVaclav Hapla PetscFunctionBegin; 73065d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 73075d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 73085d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode, 3); 73095d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 73107a8be351SBarry Smith PetscCheck(mode != PETSC_USE_POINTER, PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 73115d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 73125d80c0bfSVaclav Hapla for (link = dmA->labels; link; link = link->next) { 73135d80c0bfSVaclav Hapla label = link->label; 73149566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 73155d80c0bfSVaclav Hapla if (!all) { 73169566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &flg)); 7317c58f1c22SToby Isaac if (flg) continue; 73189566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "dim", &flg)); 73197d5acc75SStefano Zampini if (flg) continue; 73209566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &flg)); 7321ba2698f1SMatthew G. Knepley if (flg) continue; 73225d80c0bfSVaclav Hapla } 73239566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmB, name, &labelOld)); 73242cbb9b06SVaclav Hapla if (labelOld) { 73252cbb9b06SVaclav Hapla switch (emode) { 7326d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_KEEP: 7327d71ae5a4SJacob Faibussowitsch continue; 7328d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_REPLACE: 7329d71ae5a4SJacob Faibussowitsch PetscCall(DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE)); 7330d71ae5a4SJacob Faibussowitsch break; 7331d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_FAIL: 7332d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 7333d71ae5a4SJacob Faibussowitsch default: 7334d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", (int)emode); 73352cbb9b06SVaclav Hapla } 73362cbb9b06SVaclav Hapla } 73375d80c0bfSVaclav Hapla if (mode == PETSC_COPY_VALUES) { 73389566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, &labelNew)); 73395d80c0bfSVaclav Hapla } else { 73405d80c0bfSVaclav Hapla labelNew = label; 73415d80c0bfSVaclav Hapla } 73429566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmB, labelNew)); 73439566063dSJacob Faibussowitsch if (mode == PETSC_COPY_VALUES) PetscCall(DMLabelDestroy(&labelNew)); 7344c58f1c22SToby Isaac } 7345c58f1c22SToby Isaac PetscFunctionReturn(0); 7346c58f1c22SToby Isaac } 7347461a15a0SLisandro Dalcin 7348609dae6eSVaclav Hapla /*@C 7349bb7acecfSBarry Smith DMCompareLabels - Compare labels of two `DMPLEX` meshes 7350609dae6eSVaclav Hapla 73515efe38ccSVaclav Hapla Collective 7352609dae6eSVaclav Hapla 7353609dae6eSVaclav Hapla Input Parameters: 7354bb7acecfSBarry Smith + dm0 - First `DM` object 7355bb7acecfSBarry Smith - dm1 - Second `DM` object 7356609dae6eSVaclav Hapla 7357609dae6eSVaclav Hapla Output Parameters 73585efe38ccSVaclav Hapla + equal - (Optional) Flag whether labels of dm0 and dm1 are the same 7359609dae6eSVaclav Hapla - message - (Optional) Message describing the difference, or NULL if there is no difference 7360609dae6eSVaclav Hapla 7361609dae6eSVaclav Hapla Level: intermediate 7362609dae6eSVaclav Hapla 7363609dae6eSVaclav Hapla Notes: 7364bb7acecfSBarry Smith The output flag equal will be the same on all processes. 7365bb7acecfSBarry Smith 7366bb7acecfSBarry Smith If equal is passed as NULL and difference is found, an error is thrown on all processes. 7367bb7acecfSBarry Smith 7368bb7acecfSBarry Smith Make sure to pass equal is NULL on all processes or none of them. 7369609dae6eSVaclav Hapla 73705efe38ccSVaclav Hapla The output message is set independently on each rank. 7371bb7acecfSBarry Smith 7372bb7acecfSBarry Smith message must be freed with `PetscFree()` 7373bb7acecfSBarry Smith 7374bb7acecfSBarry Smith If message is passed as NULL and a difference is found, the difference description is printed to stderr in synchronized manner. 7375bb7acecfSBarry Smith 7376bb7acecfSBarry Smith Make sure to pass message as NULL on all processes or no processes. 7377609dae6eSVaclav Hapla 7378609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 7379bb7acecfSBarry Smith `DMLabelCompare()` is used to compare each pair of labels with the same name. 7380609dae6eSVaclav Hapla 7381bb7acecfSBarry Smith Fortran Note: 7382bb7acecfSBarry Smith This function is not available from Fortran. 7383609dae6eSVaclav Hapla 7384bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode`, `DMLabelCompare()` 7385609dae6eSVaclav Hapla @*/ 7386d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *equal, char **message) 7387d71ae5a4SJacob Faibussowitsch { 73885efe38ccSVaclav Hapla PetscInt n, i; 7389609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 73905efe38ccSVaclav Hapla PetscBool eq; 7391609dae6eSVaclav Hapla MPI_Comm comm; 73925efe38ccSVaclav Hapla PetscMPIInt rank; 7393609dae6eSVaclav Hapla 7394609dae6eSVaclav Hapla PetscFunctionBegin; 7395609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0, DM_CLASSID, 1); 7396609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1, DM_CLASSID, 2); 7397609dae6eSVaclav Hapla PetscCheckSameComm(dm0, 1, dm1, 2); 73985efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal, 3); 7399609dae6eSVaclav Hapla if (message) PetscValidPointer(message, 4); 74009566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm0, &comm)); 74019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 74025efe38ccSVaclav Hapla { 74035efe38ccSVaclav Hapla PetscInt n1; 74045efe38ccSVaclav Hapla 74059566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm0, &n)); 74069566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm1, &n1)); 74075efe38ccSVaclav Hapla eq = (PetscBool)(n == n1); 740848a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %" PetscInt_FMT " != %" PetscInt_FMT " = Number of labels in dm1", n, n1)); 74099566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 74105efe38ccSVaclav Hapla if (!eq) goto finish; 74115efe38ccSVaclav Hapla } 74125efe38ccSVaclav Hapla for (i = 0; i < n; i++) { 7413609dae6eSVaclav Hapla DMLabel l0, l1; 7414609dae6eSVaclav Hapla const char *name; 7415609dae6eSVaclav Hapla char *msgInner; 7416609dae6eSVaclav Hapla 7417609dae6eSVaclav Hapla /* Ignore label order */ 74189566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm0, i, &l0)); 74199566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name)); 74209566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm1, name, &l1)); 7421609dae6eSVaclav Hapla if (!l1) { 742263a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%" PetscInt_FMT " in dm0) not found in dm1", name, i)); 74235efe38ccSVaclav Hapla eq = PETSC_FALSE; 74245efe38ccSVaclav Hapla break; 7425609dae6eSVaclav Hapla } 74269566063dSJacob Faibussowitsch PetscCall(DMLabelCompare(comm, l0, l1, &eq, &msgInner)); 74279566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(msg, msgInner, sizeof(msg))); 74289566063dSJacob Faibussowitsch PetscCall(PetscFree(msgInner)); 74295efe38ccSVaclav Hapla if (!eq) break; 7430609dae6eSVaclav Hapla } 74319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 7432609dae6eSVaclav Hapla finish: 74335efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 7434609dae6eSVaclav Hapla if (message) { 7435609dae6eSVaclav Hapla *message = NULL; 743648a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 74375efe38ccSVaclav Hapla } else { 743848a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 74399566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 74405efe38ccSVaclav Hapla } 74415efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 74425efe38ccSVaclav Hapla if (equal) *equal = eq; 74437a8be351SBarry Smith else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels are not the same in dm0 and dm1"); 7444609dae6eSVaclav Hapla PetscFunctionReturn(0); 7445609dae6eSVaclav Hapla } 7446609dae6eSVaclav Hapla 7447d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 7448d71ae5a4SJacob Faibussowitsch { 7449461a15a0SLisandro Dalcin PetscFunctionBegin; 7450461a15a0SLisandro Dalcin PetscValidPointer(label, 2); 7451461a15a0SLisandro Dalcin if (!*label) { 74529566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 74539566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, label)); 7454461a15a0SLisandro Dalcin } 74559566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(*label, point, value)); 7456461a15a0SLisandro Dalcin PetscFunctionReturn(0); 7457461a15a0SLisandro Dalcin } 7458461a15a0SLisandro Dalcin 74590fdc7489SMatthew Knepley /* 74600fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 74610fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 74620fdc7489SMatthew Knepley (label, id) pair in the DM. 74630fdc7489SMatthew Knepley 74640fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 74650fdc7489SMatthew Knepley each label. 74660fdc7489SMatthew Knepley */ 7467d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 7468d71ae5a4SJacob Faibussowitsch { 74690fdc7489SMatthew Knepley DMUniversalLabel ul; 74700fdc7489SMatthew Knepley PetscBool *active; 74710fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 74720fdc7489SMatthew Knepley 74730fdc7489SMatthew Knepley PetscFunctionBegin; 74749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &ul)); 74759566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label)); 74769566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 74779566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nl, &active)); 74780fdc7489SMatthew Knepley ul->Nl = 0; 74790fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 74800fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 74810fdc7489SMatthew Knepley const char *name; 74820fdc7489SMatthew Knepley 74839566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 74849566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "depth", 6, &isdepth)); 74859566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "celltype", 9, &iscelltype)); 74860fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 74870fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 74880fdc7489SMatthew Knepley } 74899566063dSJacob 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)); 74900fdc7489SMatthew Knepley ul->Nv = 0; 74910fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 74920fdc7489SMatthew Knepley DMLabel label; 74930fdc7489SMatthew Knepley PetscInt nv; 74940fdc7489SMatthew Knepley const char *name; 74950fdc7489SMatthew Knepley 74960fdc7489SMatthew Knepley if (!active[l]) continue; 74979566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 74989566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 74999566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 75009566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &ul->names[m])); 75010fdc7489SMatthew Knepley ul->indices[m] = l; 75020fdc7489SMatthew Knepley ul->Nv += nv; 75030fdc7489SMatthew Knepley ul->offsets[m + 1] = nv; 75040fdc7489SMatthew Knepley ul->bits[m + 1] = PetscCeilReal(PetscLog2Real(nv + 1)); 75050fdc7489SMatthew Knepley ++m; 75060fdc7489SMatthew Knepley } 75070fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 75080fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l - 1] + ul->offsets[l]; 75090fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l - 1] + ul->bits[l]; 75100fdc7489SMatthew Knepley } 75110fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 75120fdc7489SMatthew Knepley PetscInt b; 75130fdc7489SMatthew Knepley 75140fdc7489SMatthew Knepley ul->masks[l] = 0; 75150fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l + 1]; ++b) ul->masks[l] |= 1 << b; 75160fdc7489SMatthew Knepley } 75179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ul->Nv, &ul->values)); 75180fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 75190fdc7489SMatthew Knepley DMLabel label; 75200fdc7489SMatthew Knepley IS valueIS; 75210fdc7489SMatthew Knepley const PetscInt *varr; 75220fdc7489SMatthew Knepley PetscInt nv, v; 75230fdc7489SMatthew Knepley 75240fdc7489SMatthew Knepley if (!active[l]) continue; 75259566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 75269566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 75279566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &valueIS)); 75289566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &varr)); 7529ad540459SPierre Jolivet for (v = 0; v < nv; ++v) ul->values[ul->offsets[m] + v] = varr[v]; 75309566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(valueIS, &varr)); 75319566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valueIS)); 75329566063dSJacob Faibussowitsch PetscCall(PetscSortInt(nv, &ul->values[ul->offsets[m]])); 75330fdc7489SMatthew Knepley ++m; 75340fdc7489SMatthew Knepley } 75359566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 75360fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 75370fdc7489SMatthew Knepley PetscInt uval = 0; 75380fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 75390fdc7489SMatthew Knepley 75400fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 75410fdc7489SMatthew Knepley DMLabel label; 75420649b39aSStefano Zampini PetscInt val, defval, loc, nv; 75430fdc7489SMatthew Knepley 75440fdc7489SMatthew Knepley if (!active[l]) continue; 75459566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 75469566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &val)); 75479566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &defval)); 75489371c9d4SSatish Balay if (val == defval) { 75499371c9d4SSatish Balay ++m; 75509371c9d4SSatish Balay continue; 75519371c9d4SSatish Balay } 75520649b39aSStefano Zampini nv = ul->offsets[m + 1] - ul->offsets[m]; 75530fdc7489SMatthew Knepley marked = PETSC_TRUE; 75549566063dSJacob Faibussowitsch PetscCall(PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc)); 755563a3b9bcSJacob Faibussowitsch PetscCheck(loc >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %" PetscInt_FMT " not found in compression array", val); 75560fdc7489SMatthew Knepley uval += (loc + 1) << ul->bits[m]; 75570fdc7489SMatthew Knepley ++m; 75580fdc7489SMatthew Knepley } 75599566063dSJacob Faibussowitsch if (marked) PetscCall(DMLabelSetValue(ul->label, p, uval)); 75600fdc7489SMatthew Knepley } 75619566063dSJacob Faibussowitsch PetscCall(PetscFree(active)); 75620fdc7489SMatthew Knepley *universal = ul; 75630fdc7489SMatthew Knepley PetscFunctionReturn(0); 75640fdc7489SMatthew Knepley } 75650fdc7489SMatthew Knepley 7566d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 7567d71ae5a4SJacob Faibussowitsch { 75680fdc7489SMatthew Knepley PetscInt l; 75690fdc7489SMatthew Knepley 75700fdc7489SMatthew Knepley PetscFunctionBegin; 75719566063dSJacob Faibussowitsch for (l = 0; l < (*universal)->Nl; ++l) PetscCall(PetscFree((*universal)->names[l])); 75729566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&(*universal)->label)); 75739566063dSJacob Faibussowitsch PetscCall(PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks)); 75749566063dSJacob Faibussowitsch PetscCall(PetscFree((*universal)->values)); 75759566063dSJacob Faibussowitsch PetscCall(PetscFree(*universal)); 75760fdc7489SMatthew Knepley *universal = NULL; 75770fdc7489SMatthew Knepley PetscFunctionReturn(0); 75780fdc7489SMatthew Knepley } 75790fdc7489SMatthew Knepley 7580d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 7581d71ae5a4SJacob Faibussowitsch { 75820fdc7489SMatthew Knepley PetscFunctionBegin; 75830fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 75840fdc7489SMatthew Knepley *ulabel = ul->label; 75850fdc7489SMatthew Knepley PetscFunctionReturn(0); 75860fdc7489SMatthew Knepley } 75870fdc7489SMatthew Knepley 7588d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 7589d71ae5a4SJacob Faibussowitsch { 75900fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 75910fdc7489SMatthew Knepley 75920fdc7489SMatthew Knepley PetscFunctionBegin; 7593064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 75940fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 75959566063dSJacob Faibussowitsch if (preserveOrder) PetscCall(DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l])); 75969566063dSJacob Faibussowitsch else PetscCall(DMCreateLabel(dm, ul->names[l])); 75970fdc7489SMatthew Knepley } 75980fdc7489SMatthew Knepley if (preserveOrder) { 75990fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 76000fdc7489SMatthew Knepley const char *name; 76010fdc7489SMatthew Knepley PetscBool match; 76020fdc7489SMatthew Knepley 76039566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, ul->indices[l], &name)); 76049566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, ul->names[l], &match)); 760563a3b9bcSJacob 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]); 76060fdc7489SMatthew Knepley } 76070fdc7489SMatthew Knepley } 76080fdc7489SMatthew Knepley PetscFunctionReturn(0); 76090fdc7489SMatthew Knepley } 76100fdc7489SMatthew Knepley 7611d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 7612d71ae5a4SJacob Faibussowitsch { 76130fdc7489SMatthew Knepley PetscInt l; 76140fdc7489SMatthew Knepley 76150fdc7489SMatthew Knepley PetscFunctionBegin; 76160fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 76170fdc7489SMatthew Knepley DMLabel label; 76180fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 76190fdc7489SMatthew Knepley 76200fdc7489SMatthew Knepley if (lval) { 76219566063dSJacob Faibussowitsch if (useIndex) PetscCall(DMGetLabelByNum(dm, ul->indices[l], &label)); 76229566063dSJacob Faibussowitsch else PetscCall(DMGetLabel(dm, ul->names[l], &label)); 76239566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, p, ul->values[ul->offsets[l] + lval - 1])); 76240fdc7489SMatthew Knepley } 76250fdc7489SMatthew Knepley } 76260fdc7489SMatthew Knepley PetscFunctionReturn(0); 76270fdc7489SMatthew Knepley } 7628a8fb8f29SToby Isaac 7629a8fb8f29SToby Isaac /*@ 7630bb7acecfSBarry Smith DMGetCoarseDM - Get the coarse `DM`from which this `DM` was obtained by refinement 7631bb7acecfSBarry Smith 7632bb7acecfSBarry Smith Not collective 7633a8fb8f29SToby Isaac 7634a8fb8f29SToby Isaac Input Parameter: 7635bb7acecfSBarry Smith . dm - The `DM` object 7636a8fb8f29SToby Isaac 7637a8fb8f29SToby Isaac Output Parameter: 7638bb7acecfSBarry Smith . cdm - The coarse `DM` 7639a8fb8f29SToby Isaac 7640a8fb8f29SToby Isaac Level: intermediate 7641a8fb8f29SToby Isaac 7642bb7acecfSBarry Smith .seealso: `DMSetCoarseDM()`, `DMCoarsen()` 7643a8fb8f29SToby Isaac @*/ 7644d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 7645d71ae5a4SJacob Faibussowitsch { 7646a8fb8f29SToby Isaac PetscFunctionBegin; 7647a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7648a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 7649a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 7650a8fb8f29SToby Isaac PetscFunctionReturn(0); 7651a8fb8f29SToby Isaac } 7652a8fb8f29SToby Isaac 7653a8fb8f29SToby Isaac /*@ 7654bb7acecfSBarry Smith DMSetCoarseDM - Set the coarse `DM` from which this `DM` was obtained by refinement 7655a8fb8f29SToby Isaac 7656a8fb8f29SToby Isaac Input Parameters: 7657bb7acecfSBarry Smith + dm - The `DM` object 7658bb7acecfSBarry Smith - cdm - The coarse `DM` 7659a8fb8f29SToby Isaac 7660a8fb8f29SToby Isaac Level: intermediate 7661a8fb8f29SToby Isaac 7662bb7acecfSBarry Smith Note: 7663bb7acecfSBarry Smith Normally this is set automatically by `DMRefine()` 7664bb7acecfSBarry Smith 7665bb7acecfSBarry Smith .seealso: `DMGetCoarseDM()`, `DMCoarsen()`, `DMSetRefine()`, `DMSetFineDM()` 7666a8fb8f29SToby Isaac @*/ 7667d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 7668d71ae5a4SJacob Faibussowitsch { 7669a8fb8f29SToby Isaac PetscFunctionBegin; 7670a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7671a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 767289d734beSBarry Smith if (dm == cdm) cdm = NULL; 76739566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cdm)); 76749566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->coarseMesh)); 7675a8fb8f29SToby Isaac dm->coarseMesh = cdm; 7676a8fb8f29SToby Isaac PetscFunctionReturn(0); 7677a8fb8f29SToby Isaac } 7678a8fb8f29SToby Isaac 767988bdff64SToby Isaac /*@ 7680bb7acecfSBarry Smith DMGetFineDM - Get the fine mesh from which this `DM` was obtained by coarsening 768188bdff64SToby Isaac 768288bdff64SToby Isaac Input Parameter: 7683bb7acecfSBarry Smith . dm - The `DM` object 768488bdff64SToby Isaac 768588bdff64SToby Isaac Output Parameter: 7686bb7acecfSBarry Smith . fdm - The fine `DM` 768788bdff64SToby Isaac 768888bdff64SToby Isaac Level: intermediate 768988bdff64SToby Isaac 7690bb7acecfSBarry Smith .seealso: `DMSetFineDM()`, `DMCoarsen()`, `DMRefine()` 769188bdff64SToby Isaac @*/ 7692d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 7693d71ae5a4SJacob Faibussowitsch { 769488bdff64SToby Isaac PetscFunctionBegin; 769588bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 769688bdff64SToby Isaac PetscValidPointer(fdm, 2); 769788bdff64SToby Isaac *fdm = dm->fineMesh; 769888bdff64SToby Isaac PetscFunctionReturn(0); 769988bdff64SToby Isaac } 770088bdff64SToby Isaac 770188bdff64SToby Isaac /*@ 7702bb7acecfSBarry Smith DMSetFineDM - Set the fine mesh from which this was obtained by coarsening 770388bdff64SToby Isaac 770488bdff64SToby Isaac Input Parameters: 7705bb7acecfSBarry Smith + dm - The `DM` object 7706bb7acecfSBarry Smith - fdm - The fine `DM` 770788bdff64SToby Isaac 7708bb7acecfSBarry Smith Level: developer 770988bdff64SToby Isaac 7710bb7acecfSBarry Smith Note: 7711bb7acecfSBarry Smith Normally this is set automatically by `DMCoarsen()` 7712bb7acecfSBarry Smith 7713bb7acecfSBarry Smith .seealso: `DMGetFineDM()`, `DMCoarsen()`, `DMRefine()` 771488bdff64SToby Isaac @*/ 7715d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFineDM(DM dm, DM fdm) 7716d71ae5a4SJacob Faibussowitsch { 771788bdff64SToby Isaac PetscFunctionBegin; 771888bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 771988bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 772089d734beSBarry Smith if (dm == fdm) fdm = NULL; 77219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fdm)); 77229566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->fineMesh)); 772388bdff64SToby Isaac dm->fineMesh = fdm; 772488bdff64SToby Isaac PetscFunctionReturn(0); 772588bdff64SToby Isaac } 772688bdff64SToby Isaac 7727a6ba4734SToby Isaac /*@C 7728bb7acecfSBarry Smith DMAddBoundary - Add a boundary condition to a model represented by a `DM` 7729a6ba4734SToby Isaac 7730783e2ec8SMatthew G. Knepley Collective on dm 7731783e2ec8SMatthew G. Knepley 7732a6ba4734SToby Isaac Input Parameters: 7733bb7acecfSBarry Smith + dm - The `DM`, with a `PetscDS` that matches the problem being constrained 7734bb7acecfSBarry Smith . type - The type of condition, e.g. `DM_BC_ESSENTIAL_ANALYTIC`, `DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann) 7735a6ba4734SToby Isaac . name - The BC name 773645480ffeSMatthew G. Knepley . label - The label defining constrained points 7737bb7acecfSBarry Smith . Nv - The number of `DMLabel` values for constrained points 773845480ffeSMatthew G. Knepley . values - An array of values for constrained points 7739a6ba4734SToby Isaac . field - The field to constrain 774045480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 7741a6ba4734SToby Isaac . comps - An array of constrained component numbers 7742a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 774356cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 7744a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 7745a6ba4734SToby Isaac 774645480ffeSMatthew G. Knepley Output Parameter: 774745480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 774845480ffeSMatthew G. Knepley 7749a6ba4734SToby Isaac Options Database Keys: 7750a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 7751a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 7752a6ba4734SToby Isaac 7753bb7acecfSBarry Smith Notes: 7754bb7acecfSBarry 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: 775556cf3b9cSMatthew G. Knepley 775656cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 775756cf3b9cSMatthew G. Knepley 7758bb7acecfSBarry Smith If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is: 775956cf3b9cSMatthew G. Knepley 776056cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 776156cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 776256cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 776356cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 776456cf3b9cSMatthew G. Knepley 776556cf3b9cSMatthew G. Knepley + dim - the spatial dimension 776656cf3b9cSMatthew G. Knepley . Nf - the number of fields 776756cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 776856cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 776956cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 777056cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 777156cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 777256cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 777356cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 777456cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 777556cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 777656cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 777756cf3b9cSMatthew G. Knepley . t - current time 777856cf3b9cSMatthew G. Knepley . x - coordinates of the current point 777956cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 778056cf3b9cSMatthew G. Knepley . constants - constant parameters 778156cf3b9cSMatthew G. Knepley - bcval - output values at the current point 778256cf3b9cSMatthew G. Knepley 7783ed808b8fSJed Brown Level: intermediate 7784a6ba4734SToby Isaac 7785db781477SPatrick Sanan .seealso: `DSGetBoundary()`, `PetscDSAddBoundary()` 7786a6ba4734SToby Isaac @*/ 7787d71ae5a4SJacob 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) 7788d71ae5a4SJacob Faibussowitsch { 7789e5e52638SMatthew G. Knepley PetscDS ds; 7790a6ba4734SToby Isaac 7791a6ba4734SToby Isaac PetscFunctionBegin; 7792a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7793783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 779445480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 779545480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 779645480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 779745480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 779801a5d20dSJed Brown PetscCheck(!dm->localSection, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot add boundary to DM after creating local section"); 77999566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7800799db056SMatthew G. Knepley /* Complete label */ 7801799db056SMatthew G. Knepley if (label) { 7802799db056SMatthew G. Knepley PetscObject obj; 7803799db056SMatthew G. Knepley PetscClassId id; 7804799db056SMatthew G. Knepley 7805799db056SMatthew G. Knepley PetscCall(DMGetField(dm, field, NULL, &obj)); 7806799db056SMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 7807799db056SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 7808799db056SMatthew G. Knepley DM plex; 7809799db056SMatthew G. Knepley 7810799db056SMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 7811799db056SMatthew G. Knepley if (plex) PetscCall(DMPlexLabelComplete(plex, label)); 7812799db056SMatthew G. Knepley PetscCall(DMDestroy(&plex)); 7813799db056SMatthew G. Knepley } 7814799db056SMatthew G. Knepley } 78159566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd)); 7816a6ba4734SToby Isaac PetscFunctionReturn(0); 7817a6ba4734SToby Isaac } 7818a6ba4734SToby Isaac 781945480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 7820d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPopulateBoundary(DM dm) 7821d71ae5a4SJacob Faibussowitsch { 7822e5e52638SMatthew G. Knepley PetscDS ds; 7823dff059c6SToby Isaac DMBoundary *lastnext; 7824e6f8dbb6SToby Isaac DSBoundary dsbound; 7825e6f8dbb6SToby Isaac 7826e6f8dbb6SToby Isaac PetscFunctionBegin; 78279566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7828e5e52638SMatthew G. Knepley dsbound = ds->boundary; 782947a1f5adSToby Isaac if (dm->boundary) { 783047a1f5adSToby Isaac DMBoundary next = dm->boundary; 783147a1f5adSToby Isaac 783247a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 783347a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 783447a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 783547a1f5adSToby Isaac while (next) { 783647a1f5adSToby Isaac DMBoundary b = next; 783747a1f5adSToby Isaac 783847a1f5adSToby Isaac next = b->next; 78399566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 7840a6ba4734SToby Isaac } 784147a1f5adSToby Isaac dm->boundary = NULL; 7842a6ba4734SToby Isaac } 784347a1f5adSToby Isaac 7844dff059c6SToby Isaac lastnext = &(dm->boundary); 7845e6f8dbb6SToby Isaac while (dsbound) { 7846e6f8dbb6SToby Isaac DMBoundary dmbound; 7847e6f8dbb6SToby Isaac 78489566063dSJacob Faibussowitsch PetscCall(PetscNew(&dmbound)); 7849e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 785045480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 785147a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 7852dff059c6SToby Isaac *lastnext = dmbound; 7853dff059c6SToby Isaac lastnext = &(dmbound->next); 7854dff059c6SToby Isaac dsbound = dsbound->next; 7855a6ba4734SToby Isaac } 7856a6ba4734SToby Isaac PetscFunctionReturn(0); 7857a6ba4734SToby Isaac } 7858a6ba4734SToby Isaac 7859bb7acecfSBarry Smith /* TODO: missing manual page */ 7860d71ae5a4SJacob Faibussowitsch PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 7861d71ae5a4SJacob Faibussowitsch { 7862b95f2879SToby Isaac DMBoundary b; 7863a6ba4734SToby Isaac 7864a6ba4734SToby Isaac PetscFunctionBegin; 7865a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7866534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 7867a6ba4734SToby Isaac *isBd = PETSC_FALSE; 78689566063dSJacob Faibussowitsch PetscCall(DMPopulateBoundary(dm)); 7869b95f2879SToby Isaac b = dm->boundary; 7870a6ba4734SToby Isaac while (b && !(*isBd)) { 7871e6f8dbb6SToby Isaac DMLabel label = b->label; 7872e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 7873a6ba4734SToby Isaac PetscInt i; 7874a6ba4734SToby Isaac 787545480ffeSMatthew G. Knepley if (label) { 78769566063dSJacob Faibussowitsch for (i = 0; i < dsb->Nv && !(*isBd); ++i) PetscCall(DMLabelStratumHasPoint(label, dsb->values[i], point, isBd)); 7877a6ba4734SToby Isaac } 7878a6ba4734SToby Isaac b = b->next; 7879a6ba4734SToby Isaac } 7880a6ba4734SToby Isaac PetscFunctionReturn(0); 7881a6ba4734SToby Isaac } 78824d6f44ffSToby Isaac 78834d6f44ffSToby Isaac /*@C 7884bb7acecfSBarry Smith DMProjectFunction - This projects the given function into the function space provided by a `DM`, putting the coefficients in a global vector. 7885a6e0b375SMatthew G. Knepley 7886bb7acecfSBarry Smith Collective on dm 78874d6f44ffSToby Isaac 78884d6f44ffSToby Isaac Input Parameters: 7889bb7acecfSBarry Smith + dm - The `DM` 78900709b2feSToby Isaac . time - The time 78914d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 78924d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 78934d6f44ffSToby Isaac - mode - The insertion mode for values 78944d6f44ffSToby Isaac 78954d6f44ffSToby Isaac Output Parameter: 78964d6f44ffSToby Isaac . X - vector 78974d6f44ffSToby Isaac 78984d6f44ffSToby Isaac Calling sequence of func: 789977b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 79004d6f44ffSToby Isaac 79014d6f44ffSToby Isaac + dim - The spatial dimension 79028ec8862eSJed Brown . time - The time at which to sample 79034d6f44ffSToby Isaac . x - The coordinates 790477b739a6SMatthew Knepley . Nc - The number of components 79054d6f44ffSToby Isaac . u - The output field values 79064d6f44ffSToby Isaac - ctx - optional user-defined function context 79074d6f44ffSToby Isaac 79084d6f44ffSToby Isaac Level: developer 79094d6f44ffSToby Isaac 7910bb7acecfSBarry Smith Developer Notes: 7911bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7912bb7acecfSBarry Smith 7913bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7914bb7acecfSBarry Smith 7915db781477SPatrick Sanan .seealso: `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 79164d6f44ffSToby Isaac @*/ 7917d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 7918d71ae5a4SJacob Faibussowitsch { 79194d6f44ffSToby Isaac Vec localX; 79204d6f44ffSToby Isaac 79214d6f44ffSToby Isaac PetscFunctionBegin; 79224d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 79239566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 79249566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX)); 79259566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 79269566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 79279566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 79284d6f44ffSToby Isaac PetscFunctionReturn(0); 79294d6f44ffSToby Isaac } 79304d6f44ffSToby Isaac 7931a6e0b375SMatthew G. Knepley /*@C 7932bb7acecfSBarry Smith DMProjectFunctionLocal - This projects the given function into the function space provided by a `DM`, putting the coefficients in a local vector. 7933a6e0b375SMatthew G. Knepley 7934a6e0b375SMatthew G. Knepley Not collective 7935a6e0b375SMatthew G. Knepley 7936a6e0b375SMatthew G. Knepley Input Parameters: 7937bb7acecfSBarry Smith + dm - The `DM` 7938a6e0b375SMatthew G. Knepley . time - The time 7939a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 7940a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 7941a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 7942a6e0b375SMatthew G. Knepley 7943a6e0b375SMatthew G. Knepley Output Parameter: 7944a6e0b375SMatthew G. Knepley . localX - vector 7945a6e0b375SMatthew G. Knepley 7946a6e0b375SMatthew G. Knepley Calling sequence of func: 794777b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 7948a6e0b375SMatthew G. Knepley 7949a6e0b375SMatthew G. Knepley + dim - The spatial dimension 7950a6e0b375SMatthew G. Knepley . x - The coordinates 795177b739a6SMatthew Knepley . Nc - The number of components 7952a6e0b375SMatthew G. Knepley . u - The output field values 7953a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 7954a6e0b375SMatthew G. Knepley 7955a6e0b375SMatthew G. Knepley Level: developer 7956a6e0b375SMatthew G. Knepley 7957bb7acecfSBarry Smith Developer Notes: 7958bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7959bb7acecfSBarry Smith 7960bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7961bb7acecfSBarry Smith 7962db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 7963a6e0b375SMatthew G. Knepley @*/ 7964d71ae5a4SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 7965d71ae5a4SJacob Faibussowitsch { 79664d6f44ffSToby Isaac PetscFunctionBegin; 79674d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7968064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 79699566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlocal)(dm, time, funcs, ctxs, mode, localX)); 79704d6f44ffSToby Isaac PetscFunctionReturn(0); 79714d6f44ffSToby Isaac } 79724d6f44ffSToby Isaac 7973a6e0b375SMatthew G. Knepley /*@C 7974bb7acecfSBarry 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. 7975a6e0b375SMatthew G. Knepley 7976bb7acecfSBarry Smith Collective on dm 7977a6e0b375SMatthew G. Knepley 7978a6e0b375SMatthew G. Knepley Input Parameters: 7979bb7acecfSBarry Smith + dm - The `DM` 7980a6e0b375SMatthew G. Knepley . time - The time 7981bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 7982a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 7983bb7acecfSBarry Smith . ctxs - Optional array of contexts to pass to each coordinate function. ctxs may be null. 7984a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 7985a6e0b375SMatthew G. Knepley 7986a6e0b375SMatthew G. Knepley Output Parameter: 7987a6e0b375SMatthew G. Knepley . X - vector 7988a6e0b375SMatthew G. Knepley 7989a6e0b375SMatthew G. Knepley Calling sequence of func: 799077b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 7991a6e0b375SMatthew G. Knepley 7992a6e0b375SMatthew G. Knepley + dim - The spatial dimension 7993a6e0b375SMatthew G. Knepley . x - The coordinates 799477b739a6SMatthew Knepley . Nc - The number of components 7995a6e0b375SMatthew G. Knepley . u - The output field values 7996a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 7997a6e0b375SMatthew G. Knepley 7998a6e0b375SMatthew G. Knepley Level: developer 7999a6e0b375SMatthew G. Knepley 8000bb7acecfSBarry Smith Developer Notes: 8001bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8002bb7acecfSBarry Smith 8003bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8004bb7acecfSBarry Smith 8005db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabelLocal()`, `DMComputeL2Diff()` 8006a6e0b375SMatthew G. Knepley @*/ 8007d71ae5a4SJacob 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) 8008d71ae5a4SJacob Faibussowitsch { 80092c53366bSMatthew G. Knepley Vec localX; 80102c53366bSMatthew G. Knepley 80112c53366bSMatthew G. Knepley PetscFunctionBegin; 80122c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 80139566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 80149566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 80159566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 80169566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 80179566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 80182c53366bSMatthew G. Knepley PetscFunctionReturn(0); 80192c53366bSMatthew G. Knepley } 80202c53366bSMatthew G. Knepley 8021a6e0b375SMatthew G. Knepley /*@C 8022bb7acecfSBarry 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. 8023a6e0b375SMatthew G. Knepley 8024a6e0b375SMatthew G. Knepley Not collective 8025a6e0b375SMatthew G. Knepley 8026a6e0b375SMatthew G. Knepley Input Parameters: 8027bb7acecfSBarry Smith + dm - The `DM` 8028a6e0b375SMatthew G. Knepley . time - The time 8029bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8030a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8031a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8032a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8033a6e0b375SMatthew G. Knepley 8034a6e0b375SMatthew G. Knepley Output Parameter: 8035a6e0b375SMatthew G. Knepley . localX - vector 8036a6e0b375SMatthew G. Knepley 8037a6e0b375SMatthew G. Knepley Calling sequence of func: 803877b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 8039a6e0b375SMatthew G. Knepley 8040a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8041a6e0b375SMatthew G. Knepley . x - The coordinates 804277b739a6SMatthew Knepley . Nc - The number of components 8043a6e0b375SMatthew G. Knepley . u - The output field values 8044a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8045a6e0b375SMatthew G. Knepley 8046a6e0b375SMatthew G. Knepley Level: developer 8047a6e0b375SMatthew G. Knepley 8048bb7acecfSBarry Smith Developer Notes: 8049bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8050bb7acecfSBarry Smith 8051bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8052bb7acecfSBarry Smith 8053db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8054a6e0b375SMatthew G. Knepley @*/ 8055d71ae5a4SJacob 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) 8056d71ae5a4SJacob Faibussowitsch { 80574d6f44ffSToby Isaac PetscFunctionBegin; 80584d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8059064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 80609566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlabellocal)(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 80614d6f44ffSToby Isaac PetscFunctionReturn(0); 80624d6f44ffSToby Isaac } 80632716604bSToby Isaac 8064a6e0b375SMatthew G. Knepley /*@C 8065bb7acecfSBarry 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. 8066a6e0b375SMatthew G. Knepley 8067a6e0b375SMatthew G. Knepley Not collective 8068a6e0b375SMatthew G. Knepley 8069a6e0b375SMatthew G. Knepley Input Parameters: 8070bb7acecfSBarry Smith + dm - The `DM` 8071a6e0b375SMatthew G. Knepley . time - The time 8072a6e0b375SMatthew G. Knepley . localU - The input field vector 8073a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8074a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8075a6e0b375SMatthew G. Knepley 8076a6e0b375SMatthew G. Knepley Output Parameter: 8077a6e0b375SMatthew G. Knepley . localX - The output vector 8078a6e0b375SMatthew G. Knepley 8079a6e0b375SMatthew G. Knepley Calling sequence of func: 8080a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8081a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8082a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8083a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8084a6e0b375SMatthew G. Knepley 8085a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8086a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8087a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8088a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8089a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8090a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8091a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8092a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8093a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8094a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8095a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8096a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8097a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8098a6e0b375SMatthew G. Knepley . t - The current time 8099a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8100a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8101a6e0b375SMatthew G. Knepley . constants - The value of each constant 8102a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8103a6e0b375SMatthew G. Knepley 8104bb7acecfSBarry Smith Note: 8105bb7acecfSBarry 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. 8106bb7acecfSBarry 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 8107bb7acecfSBarry 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 8108a6e0b375SMatthew 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. 8109a6e0b375SMatthew G. Knepley 8110a6e0b375SMatthew G. Knepley Level: intermediate 8111a6e0b375SMatthew G. Knepley 8112bb7acecfSBarry Smith Developer Notes: 8113bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8114bb7acecfSBarry Smith 8115bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8116bb7acecfSBarry Smith 8117db781477SPatrick Sanan .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8118a6e0b375SMatthew G. Knepley @*/ 8119d71ae5a4SJacob 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) 8120d71ae5a4SJacob Faibussowitsch { 81218c6c5593SMatthew G. Knepley PetscFunctionBegin; 81228c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 81238c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU, VEC_CLASSID, 3); 81248c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 81259566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlocal)(dm, time, localU, funcs, mode, localX)); 81268c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 81278c6c5593SMatthew G. Knepley } 81288c6c5593SMatthew G. Knepley 8129a6e0b375SMatthew G. Knepley /*@C 8130a6e0b375SMatthew 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. 8131a6e0b375SMatthew G. Knepley 8132a6e0b375SMatthew G. Knepley Not collective 8133a6e0b375SMatthew G. Knepley 8134a6e0b375SMatthew G. Knepley Input Parameters: 8135bb7acecfSBarry Smith + dm - The `DM` 8136a6e0b375SMatthew G. Knepley . time - The time 8137bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8138a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8139a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8140bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8141a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8142a6e0b375SMatthew G. Knepley . localU - The input field vector 8143a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8144a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8145a6e0b375SMatthew G. Knepley 8146a6e0b375SMatthew G. Knepley Output Parameter: 8147a6e0b375SMatthew G. Knepley . localX - The output vector 8148a6e0b375SMatthew G. Knepley 8149a6e0b375SMatthew G. Knepley Calling sequence of func: 8150a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8151a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8152a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8153a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8154a6e0b375SMatthew G. Knepley 8155a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8156a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8157a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8158a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8159a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8160a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8161a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8162a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8163a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8164a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8165a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8166a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8167a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8168a6e0b375SMatthew G. Knepley . t - The current time 8169a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8170a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8171a6e0b375SMatthew G. Knepley . constants - The value of each constant 8172a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8173a6e0b375SMatthew G. Knepley 8174bb7acecfSBarry Smith Note: 8175bb7acecfSBarry 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. 8176bb7acecfSBarry 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 8177bb7acecfSBarry 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 8178a6e0b375SMatthew 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. 8179a6e0b375SMatthew G. Knepley 8180a6e0b375SMatthew G. Knepley Level: intermediate 8181a6e0b375SMatthew G. Knepley 8182bb7acecfSBarry Smith Developer Notes: 8183bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8184bb7acecfSBarry Smith 8185bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8186bb7acecfSBarry Smith 8187d29d7c6eSMatthew G. Knepley .seealso: `DMProjectField()`, `DMProjectFieldLabel()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8188a6e0b375SMatthew G. Knepley @*/ 8189d71ae5a4SJacob 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) 8190d71ae5a4SJacob Faibussowitsch { 81918c6c5593SMatthew G. Knepley PetscFunctionBegin; 81928c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8193064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8194064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 81959566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 81968c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 81978c6c5593SMatthew G. Knepley } 81988c6c5593SMatthew G. Knepley 81992716604bSToby Isaac /*@C 8200d29d7c6eSMatthew 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. 8201d29d7c6eSMatthew G. Knepley 8202d29d7c6eSMatthew G. Knepley Not collective 8203d29d7c6eSMatthew G. Knepley 8204d29d7c6eSMatthew G. Knepley Input Parameters: 8205bb7acecfSBarry Smith + dm - The `DM` 8206d29d7c6eSMatthew G. Knepley . time - The time 8207bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8208d29d7c6eSMatthew G. Knepley . numIds - The number of label ids to use 8209d29d7c6eSMatthew G. Knepley . ids - The label ids to use for marking 8210bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8211d29d7c6eSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8212d29d7c6eSMatthew G. Knepley . U - The input field vector 8213d29d7c6eSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8214d29d7c6eSMatthew G. Knepley - mode - The insertion mode for values 8215d29d7c6eSMatthew G. Knepley 8216d29d7c6eSMatthew G. Knepley Output Parameter: 8217d29d7c6eSMatthew G. Knepley . X - The output vector 8218d29d7c6eSMatthew G. Knepley 8219d29d7c6eSMatthew G. Knepley Calling sequence of func: 8220d29d7c6eSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8221d29d7c6eSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8222d29d7c6eSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8223d29d7c6eSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8224d29d7c6eSMatthew G. Knepley 8225d29d7c6eSMatthew G. Knepley + dim - The spatial dimension 8226d29d7c6eSMatthew G. Knepley . Nf - The number of input fields 8227d29d7c6eSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8228d29d7c6eSMatthew G. Knepley . uOff - The offset of each field in u[] 8229d29d7c6eSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8230d29d7c6eSMatthew G. Knepley . u - The field values at this point in space 8231d29d7c6eSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8232d29d7c6eSMatthew G. Knepley . u_x - The field derivatives at this point in space 8233d29d7c6eSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8234d29d7c6eSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8235d29d7c6eSMatthew G. Knepley . a - The auxiliary field values at this point in space 8236d29d7c6eSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8237d29d7c6eSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8238d29d7c6eSMatthew G. Knepley . t - The current time 8239d29d7c6eSMatthew G. Knepley . x - The coordinates of this point 8240d29d7c6eSMatthew G. Knepley . numConstants - The number of constants 8241d29d7c6eSMatthew G. Knepley . constants - The value of each constant 8242d29d7c6eSMatthew G. Knepley - f - The value of the function at this point in space 8243d29d7c6eSMatthew G. Knepley 8244bb7acecfSBarry Smith Note: 8245bb7acecfSBarry 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. 8246bb7acecfSBarry 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 8247bb7acecfSBarry 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 8248d29d7c6eSMatthew 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. 8249d29d7c6eSMatthew G. Knepley 8250d29d7c6eSMatthew G. Knepley Level: intermediate 8251d29d7c6eSMatthew G. Knepley 8252bb7acecfSBarry Smith Developer Notes: 8253bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8254bb7acecfSBarry Smith 8255bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8256bb7acecfSBarry Smith 8257d29d7c6eSMatthew G. Knepley .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8258d29d7c6eSMatthew G. Knepley @*/ 8259d71ae5a4SJacob 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) 8260d71ae5a4SJacob Faibussowitsch { 8261d29d7c6eSMatthew G. Knepley DM dmIn; 8262d29d7c6eSMatthew G. Knepley Vec localU, localX; 8263d29d7c6eSMatthew G. Knepley 8264d29d7c6eSMatthew G. Knepley PetscFunctionBegin; 8265d29d7c6eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8266d29d7c6eSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn)); 8267d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dmIn, &localU)); 8268d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &localX)); 826972fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dmIn, U, mode, localU)); 827072fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dmIn, U, mode, localU)); 8271d29d7c6eSMatthew G. Knepley PetscCall(DMProjectFieldLabelLocal(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8272d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 8273d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 8274d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &localX)); 8275d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dmIn, &localU)); 8276d29d7c6eSMatthew G. Knepley PetscFunctionReturn(0); 8277d29d7c6eSMatthew G. Knepley } 8278d29d7c6eSMatthew G. Knepley 8279d29d7c6eSMatthew G. Knepley /*@C 8280ece3a9fcSMatthew 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. 8281ece3a9fcSMatthew G. Knepley 8282ece3a9fcSMatthew G. Knepley Not collective 8283ece3a9fcSMatthew G. Knepley 8284ece3a9fcSMatthew G. Knepley Input Parameters: 8285bb7acecfSBarry Smith + dm - The `DM` 8286ece3a9fcSMatthew G. Knepley . time - The time 8287bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain boundary to output 8288ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8289ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8290bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8291ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8292ece3a9fcSMatthew G. Knepley . localU - The input field vector 8293ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8294ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8295ece3a9fcSMatthew G. Knepley 8296ece3a9fcSMatthew G. Knepley Output Parameter: 8297ece3a9fcSMatthew G. Knepley . localX - The output vector 8298ece3a9fcSMatthew G. Knepley 8299ece3a9fcSMatthew G. Knepley Calling sequence of func: 8300ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8301ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8302ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8303ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8304ece3a9fcSMatthew G. Knepley 8305ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8306ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8307ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8308ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8309ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8310ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8311ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8312ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8313ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8314ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8315ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8316ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8317ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8318ece3a9fcSMatthew G. Knepley . t - The current time 8319ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8320ece3a9fcSMatthew G. Knepley . n - The face normal 8321ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8322ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8323ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8324ece3a9fcSMatthew G. Knepley 8325ece3a9fcSMatthew G. Knepley Note: 8326bb7acecfSBarry 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. 8327bb7acecfSBarry 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 8328bb7acecfSBarry 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 8329ece3a9fcSMatthew 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. 8330ece3a9fcSMatthew G. Knepley 8331ece3a9fcSMatthew G. Knepley Level: intermediate 8332ece3a9fcSMatthew G. Knepley 8333bb7acecfSBarry Smith Developer Notes: 8334bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8335bb7acecfSBarry Smith 8336bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8337bb7acecfSBarry Smith 8338db781477SPatrick Sanan .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8339ece3a9fcSMatthew G. Knepley @*/ 8340d71ae5a4SJacob 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) 8341d71ae5a4SJacob Faibussowitsch { 8342ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8343ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8344064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8345064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 83469566063dSJacob Faibussowitsch PetscCall((dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8347ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 8348ece3a9fcSMatthew G. Knepley } 8349ece3a9fcSMatthew G. Knepley 8350ece3a9fcSMatthew G. Knepley /*@C 83512716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 83522716604bSToby Isaac 8353bb7acecfSBarry Smith Collective on dm 8354bb7acecfSBarry Smith 83552716604bSToby Isaac Input Parameters: 8356bb7acecfSBarry Smith + dm - The `DM` 83570709b2feSToby Isaac . time - The time 83582716604bSToby Isaac . funcs - The functions to evaluate for each field component 83592716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8360574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 83612716604bSToby Isaac 83622716604bSToby Isaac Output Parameter: 83632716604bSToby Isaac . diff - The diff ||u - u_h||_2 83642716604bSToby Isaac 83652716604bSToby Isaac Level: developer 83662716604bSToby Isaac 8367bb7acecfSBarry Smith Developer Notes: 8368bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8369bb7acecfSBarry Smith 8370bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8371bb7acecfSBarry Smith 8372db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 83732716604bSToby Isaac @*/ 8374d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 8375d71ae5a4SJacob Faibussowitsch { 83762716604bSToby Isaac PetscFunctionBegin; 83772716604bSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8378b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 83799566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2diff)(dm, time, funcs, ctxs, X, diff)); 83802716604bSToby Isaac PetscFunctionReturn(0); 83812716604bSToby Isaac } 8382b698f381SToby Isaac 8383b698f381SToby Isaac /*@C 8384b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8385b698f381SToby Isaac 8386d083f849SBarry Smith Collective on dm 8387d083f849SBarry Smith 8388b698f381SToby Isaac Input Parameters: 8389bb7acecfSBarry Smith + dm - The `DM` 8390b698f381SToby Isaac , time - The time 8391b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8392b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8393574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8394b698f381SToby Isaac - n - The vector to project along 8395b698f381SToby Isaac 8396b698f381SToby Isaac Output Parameter: 8397b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8398b698f381SToby Isaac 8399b698f381SToby Isaac Level: developer 8400b698f381SToby Isaac 8401bb7acecfSBarry Smith Developer Notes: 8402bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8403bb7acecfSBarry Smith 8404bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8405bb7acecfSBarry Smith 8406bb7acecfSBarry Smith .seealso: `DMProjectFunction()`, `DMComputeL2Diff()`, `DMComputeL2FieldDiff()` 8407b698f381SToby Isaac @*/ 8408d71ae5a4SJacob 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) 8409d71ae5a4SJacob Faibussowitsch { 8410b698f381SToby Isaac PetscFunctionBegin; 8411b698f381SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8412b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 84139566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2gradientdiff)(dm, time, funcs, ctxs, X, n, diff)); 8414b698f381SToby Isaac PetscFunctionReturn(0); 8415b698f381SToby Isaac } 8416b698f381SToby Isaac 84172a16baeaSToby Isaac /*@C 84182a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 84192a16baeaSToby Isaac 8420d083f849SBarry Smith Collective on dm 8421d083f849SBarry Smith 84222a16baeaSToby Isaac Input Parameters: 8423bb7acecfSBarry Smith + dm - The `DM` 84242a16baeaSToby Isaac . time - The time 84252a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 84262a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8427574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 84282a16baeaSToby Isaac 84292a16baeaSToby Isaac Output Parameter: 84302a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 84312a16baeaSToby Isaac 84322a16baeaSToby Isaac Level: developer 84332a16baeaSToby Isaac 8434bb7acecfSBarry Smith Developer Notes: 8435bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8436bb7acecfSBarry Smith 8437bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8438bb7acecfSBarry Smith 8439db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 84402a16baeaSToby Isaac @*/ 8441d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 8442d71ae5a4SJacob Faibussowitsch { 84432a16baeaSToby Isaac PetscFunctionBegin; 84442a16baeaSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 84452a16baeaSToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 84469566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2fielddiff)(dm, time, funcs, ctxs, X, diff)); 84472a16baeaSToby Isaac PetscFunctionReturn(0); 84482a16baeaSToby Isaac } 84492a16baeaSToby Isaac 8450df0b854cSToby Isaac /*@C 8451bb7acecfSBarry Smith DMGetNeighbors - Gets an array containing the MPI ranks of all the processes neighbors 8452502a2867SDave May 8453502a2867SDave May Not Collective 8454502a2867SDave May 8455502a2867SDave May Input Parameter: 8456bb7acecfSBarry Smith . dm - The `DM` 8457502a2867SDave May 84580a19bb7dSprj- Output Parameters: 84590a19bb7dSprj- + nranks - the number of neighbours 84600a19bb7dSprj- - ranks - the neighbors ranks 8461502a2867SDave May 8462bb7acecfSBarry Smith Note: 8463bb7acecfSBarry Smith Do not free the array, it is freed when the `DM` is destroyed. 8464502a2867SDave May 8465502a2867SDave May Level: beginner 8466502a2867SDave May 8467db781477SPatrick Sanan .seealso: `DMDAGetNeighbors()`, `PetscSFGetRootRanks()` 8468502a2867SDave May @*/ 8469d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNeighbors(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 8470d71ae5a4SJacob Faibussowitsch { 8471502a2867SDave May PetscFunctionBegin; 8472502a2867SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 84739566063dSJacob Faibussowitsch PetscCall((dm->ops->getneighbors)(dm, nranks, ranks)); 8474502a2867SDave May PetscFunctionReturn(0); 8475502a2867SDave May } 8476502a2867SDave May 8477531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 8478531c7667SBarry Smith 8479531c7667SBarry Smith /* 8480531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 8481531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 8482531c7667SBarry Smith */ 8483d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringApply_AIJDM(Mat J, MatFDColoring coloring, Vec x1, void *sctx) 8484d71ae5a4SJacob Faibussowitsch { 8485531c7667SBarry Smith PetscFunctionBegin; 8486531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8487531c7667SBarry Smith Vec x1local; 8488531c7667SBarry Smith DM dm; 84899566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 84907a8be351SBarry Smith PetscCheck(dm, PetscObjectComm((PetscObject)J), PETSC_ERR_ARG_INCOMP, "IS_COLORING_LOCAL requires a DM"); 84919566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &x1local)); 84929566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, x1, INSERT_VALUES, x1local)); 84939566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, x1, INSERT_VALUES, x1local)); 8494531c7667SBarry Smith x1 = x1local; 8495531c7667SBarry Smith } 84969566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply_AIJ(J, coloring, x1, sctx)); 8497531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8498531c7667SBarry Smith DM dm; 84999566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 85009566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &x1)); 8501531c7667SBarry Smith } 8502531c7667SBarry Smith PetscFunctionReturn(0); 8503531c7667SBarry Smith } 8504531c7667SBarry Smith 8505531c7667SBarry Smith /*@ 8506bb7acecfSBarry Smith MatFDColoringUseDM - allows a `MatFDColoring` object to use the `DM` associated with the matrix to compute a `IS_COLORING_LOCAL` coloring 8507531c7667SBarry Smith 8508531c7667SBarry Smith Input Parameter: 8509bb7acecfSBarry Smith . coloring - the `MatFDColoring` object 8510531c7667SBarry Smith 8511bb7acecfSBarry Smith Developer Note: 8512bb7acecfSBarry Smith this routine exists because the PETSc `Mat` library does not know about the `DM` objects 8513531c7667SBarry Smith 85141b266c99SBarry Smith Level: advanced 85151b266c99SBarry Smith 8516db781477SPatrick Sanan .seealso: `MatFDColoring`, `MatFDColoringCreate()`, `ISColoringType` 8517531c7667SBarry Smith @*/ 8518d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringUseDM(Mat coloring, MatFDColoring fdcoloring) 8519d71ae5a4SJacob Faibussowitsch { 8520531c7667SBarry Smith PetscFunctionBegin; 8521531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 8522531c7667SBarry Smith PetscFunctionReturn(0); 8523531c7667SBarry Smith } 85248320bc6fSPatrick Sanan 85258320bc6fSPatrick Sanan /*@ 8526bb7acecfSBarry Smith DMGetCompatibility - determine if two `DM`s are compatible 85278320bc6fSPatrick Sanan 85288320bc6fSPatrick Sanan Collective 85298320bc6fSPatrick Sanan 85308320bc6fSPatrick Sanan Input Parameters: 8531bb7acecfSBarry Smith + dm1 - the first `DM` 8532bb7acecfSBarry Smith - dm2 - the second `DM` 85338320bc6fSPatrick Sanan 85348320bc6fSPatrick Sanan Output Parameters: 8535bb7acecfSBarry Smith + compatible - whether or not the two `DM`s are compatible 8536bb7acecfSBarry Smith - set - whether or not the compatible value was actually determined and set 85378320bc6fSPatrick Sanan 85388320bc6fSPatrick Sanan Notes: 8539bb7acecfSBarry Smith Two `DM`s are deemed compatible if they represent the same parallel decomposition 85403d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 85418320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 8542bb7acecfSBarry Smith Loosely speaking, compatible `DM`s represent the same domain and parallel 85433d862458SPatrick Sanan decomposition, but hold different data. 85448320bc6fSPatrick Sanan 85458320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 8546bb7acecfSBarry Smith over a pair of vectors obtained from different `DM`s. 85478320bc6fSPatrick Sanan 8548bb7acecfSBarry Smith For example, two `DMDA` objects are compatible if they have the same local 85498320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 85508320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 8551bb7acecfSBarry Smith either `DM` in bounds for a loop over vectors derived from either `DM`. 85528320bc6fSPatrick Sanan 8553bb7acecfSBarry Smith Consider the operation of summing data living on a 2-dof `DMDA` to data living 8554bb7acecfSBarry Smith on a 1-dof `DMDA`, which should be compatible, as in the following snippet. 85558320bc6fSPatrick Sanan .vb 85568320bc6fSPatrick Sanan ... 85579566063dSJacob Faibussowitsch PetscCall(DMGetCompatibility(da1,da2,&compatible,&set)); 85588320bc6fSPatrick Sanan if (set && compatible) { 85599566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1)); 85609566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2)); 85619566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL)); 85628320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 85638320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 85648320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 85658320bc6fSPatrick Sanan } 85668320bc6fSPatrick Sanan } 85679566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1)); 85689566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2)); 85698320bc6fSPatrick Sanan } else { 85708320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 85718320bc6fSPatrick Sanan } 85728320bc6fSPatrick Sanan ... 85738320bc6fSPatrick Sanan .ve 85748320bc6fSPatrick Sanan 8575bb7acecfSBarry Smith Checking compatibility might be expensive for a given implementation of `DM`, 85768320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 85778320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 85788320bc6fSPatrick Sanan always check the "set" output parameter. 85798320bc6fSPatrick Sanan 8580bb7acecfSBarry Smith A `DM` is always compatible with itself. 85818320bc6fSPatrick Sanan 8582bb7acecfSBarry Smith In the current implementation, `DM`s which live on "unequal" communicators 85838320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 85848320bc6fSPatrick Sanan incompatible. 85858320bc6fSPatrick Sanan 85868320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 8587bb7acecfSBarry Smith is required on each rank. However, in `DM` implementations which store all this 85888320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 85898320bc6fSPatrick Sanan 8590bb7acecfSBarry Smith Developer Note: 8591bb7acecfSBarry Smith Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B 85923d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 8593a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 8594bb7acecfSBarry Smith compatibility. It is left to `DM` implementers to ensure that symmetry is 85958320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 85963d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 8597bb7acecfSBarry Smith of other `DM` types and let *set = PETSC_FALSE if found. 85988320bc6fSPatrick Sanan 85998320bc6fSPatrick Sanan Level: advanced 86008320bc6fSPatrick Sanan 8601db781477SPatrick Sanan .seealso: `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()` 86028320bc6fSPatrick Sanan @*/ 8603d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCompatibility(DM dm1, DM dm2, PetscBool *compatible, PetscBool *set) 8604d71ae5a4SJacob Faibussowitsch { 86058320bc6fSPatrick Sanan PetscMPIInt compareResult; 86068320bc6fSPatrick Sanan DMType type, type2; 86078320bc6fSPatrick Sanan PetscBool sameType; 86088320bc6fSPatrick Sanan 86098320bc6fSPatrick Sanan PetscFunctionBegin; 8610a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 86118320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 86128320bc6fSPatrick Sanan 86138320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 8614a5bc1bf3SBarry Smith if (dm1 == dm2) { 86158320bc6fSPatrick Sanan *set = PETSC_TRUE; 86168320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 86178320bc6fSPatrick Sanan PetscFunctionReturn(0); 86188320bc6fSPatrick Sanan } 86198320bc6fSPatrick Sanan 86208320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 86218320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 86228320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 86238320bc6fSPatrick Sanan determined by the implementation-specific logic */ 86249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)dm1), PetscObjectComm((PetscObject)dm2), &compareResult)); 86258320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 86268320bc6fSPatrick Sanan *set = PETSC_TRUE; 86278320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 86288320bc6fSPatrick Sanan PetscFunctionReturn(0); 86298320bc6fSPatrick Sanan } 86308320bc6fSPatrick Sanan 86318320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 8632a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 8633dbbe0bcdSBarry Smith PetscUseTypeMethod(dm1, getcompatibility, dm2, compatible, set); 8634b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 86358320bc6fSPatrick Sanan } 86368320bc6fSPatrick Sanan 8637a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 86388320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 86399566063dSJacob Faibussowitsch PetscCall(DMGetType(dm1, &type)); 86409566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2, &type2)); 86419566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, type2, &sameType)); 86428320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 8643dbbe0bcdSBarry Smith PetscUseTypeMethod(dm2, getcompatibility, dm1, compatible, set); /* Note argument order */ 86448320bc6fSPatrick Sanan } else { 86458320bc6fSPatrick Sanan *set = PETSC_FALSE; 86468320bc6fSPatrick Sanan } 86478320bc6fSPatrick Sanan PetscFunctionReturn(0); 86488320bc6fSPatrick Sanan } 8649c0f0dcc3SMatthew G. Knepley 8650c0f0dcc3SMatthew G. Knepley /*@C 8651bb7acecfSBarry Smith DMMonitorSet - Sets an additional monitor function that is to be used after a solve to monitor discretization performance. 8652c0f0dcc3SMatthew G. Knepley 8653bb7acecfSBarry Smith Logically Collective on dm 8654c0f0dcc3SMatthew G. Knepley 8655c0f0dcc3SMatthew G. Knepley Input Parameters: 8656bb7acecfSBarry Smith + DM - the `DM` 8657c0f0dcc3SMatthew G. Knepley . f - the monitor function 8658c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 8659c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 8660c0f0dcc3SMatthew G. Knepley 8661c0f0dcc3SMatthew G. Knepley Options Database Keys: 8662bb7acecfSBarry Smith - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `DMMonitorSet()`, but 8663c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 8664c0f0dcc3SMatthew G. Knepley 8665bb7acecfSBarry Smith Note: 8666c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 8667bb7acecfSBarry Smith `DMMonitorSet()` multiple times or with `DMMonitorSetFromOptions()`; all will be called in the 8668c0f0dcc3SMatthew G. Knepley order in which they were set. 8669c0f0dcc3SMatthew G. Knepley 8670bb7acecfSBarry Smith Fortran Note: 8671bb7acecfSBarry Smith Only a single monitor function can be set for each `DM` object 8672bb7acecfSBarry Smith 8673bb7acecfSBarry Smith Developer Note: 8674bb7acecfSBarry Smith This API has a generic name but seems specific to a very particular aspect of the use of `DM` 8675c0f0dcc3SMatthew G. Knepley 8676c0f0dcc3SMatthew G. Knepley Level: intermediate 8677c0f0dcc3SMatthew G. Knepley 8678bb7acecfSBarry Smith .seealso: `DMMonitorCancel()`,`DMMonitorSetFromOptions()`, `DMMonitor()` 8679c0f0dcc3SMatthew G. Knepley @*/ 8680d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 8681d71ae5a4SJacob Faibussowitsch { 8682c0f0dcc3SMatthew G. Knepley PetscInt m; 8683c0f0dcc3SMatthew G. Knepley 8684c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8685c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8686c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 8687c0f0dcc3SMatthew G. Knepley PetscBool identical; 8688c0f0dcc3SMatthew G. Knepley 86899566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical)); 8690c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 8691c0f0dcc3SMatthew G. Knepley } 86927a8be351SBarry Smith PetscCheck(dm->numbermonitors < MAXDMMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 8693c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 8694c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 8695c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *)mctx; 8696c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8697c0f0dcc3SMatthew G. Knepley } 8698c0f0dcc3SMatthew G. Knepley 8699c0f0dcc3SMatthew G. Knepley /*@ 8700bb7acecfSBarry Smith DMMonitorCancel - Clears all the monitor functions for a `DM` object. 8701c0f0dcc3SMatthew G. Knepley 8702bb7acecfSBarry Smith Logically Collective on dm 8703c0f0dcc3SMatthew G. Knepley 8704c0f0dcc3SMatthew G. Knepley Input Parameter: 8705c0f0dcc3SMatthew G. Knepley . dm - the DM 8706c0f0dcc3SMatthew G. Knepley 8707c0f0dcc3SMatthew G. Knepley Options Database Key: 8708c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 8709bb7acecfSBarry Smith into a code by calls to `DMonitorSet()`, but does not cancel those 8710c0f0dcc3SMatthew G. Knepley set via the options database 8711c0f0dcc3SMatthew G. Knepley 8712bb7acecfSBarry Smith Note: 8713bb7acecfSBarry Smith There is no way to clear one specific monitor from a `DM` object. 8714c0f0dcc3SMatthew G. Knepley 8715c0f0dcc3SMatthew G. Knepley Level: intermediate 8716c0f0dcc3SMatthew G. Knepley 8717bb7acecfSBarry Smith .seealso: `DMMonitorSet()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8718c0f0dcc3SMatthew G. Knepley @*/ 8719d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorCancel(DM dm) 8720d71ae5a4SJacob Faibussowitsch { 8721c0f0dcc3SMatthew G. Knepley PetscInt m; 8722c0f0dcc3SMatthew G. Knepley 8723c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8724c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8725c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 87269566063dSJacob Faibussowitsch if (dm->monitordestroy[m]) PetscCall((*dm->monitordestroy[m])(&dm->monitorcontext[m])); 8727c0f0dcc3SMatthew G. Knepley } 8728c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 8729c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8730c0f0dcc3SMatthew G. Knepley } 8731c0f0dcc3SMatthew G. Knepley 8732c0f0dcc3SMatthew G. Knepley /*@C 8733c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 8734c0f0dcc3SMatthew G. Knepley 8735bb7acecfSBarry Smith Collective on dm 8736c0f0dcc3SMatthew G. Knepley 8737c0f0dcc3SMatthew G. Knepley Input Parameters: 8738bb7acecfSBarry Smith + dm - `DM` object you wish to monitor 8739c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 8740c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 8741c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 8742c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 8743bb7acecfSBarry 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 8744c0f0dcc3SMatthew G. Knepley 8745c0f0dcc3SMatthew G. Knepley Output Parameter: 8746c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 8747c0f0dcc3SMatthew G. Knepley 8748c0f0dcc3SMatthew G. Knepley Level: developer 8749c0f0dcc3SMatthew G. Knepley 8750db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 8751db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 8752db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 8753db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 8754c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 8755db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 8756bb7acecfSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `DMMonitor()`, `DMMonitorSet()` 8757c0f0dcc3SMatthew G. Knepley @*/ 8758d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 8759d71ae5a4SJacob Faibussowitsch { 8760c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 8761c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 8762c0f0dcc3SMatthew G. Knepley 8763c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8764c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 87659566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)dm), ((PetscObject)dm)->options, ((PetscObject)dm)->prefix, name, &viewer, &format, flg)); 8766c0f0dcc3SMatthew G. Knepley if (*flg) { 8767c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 8768c0f0dcc3SMatthew G. Knepley 87699566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 87709566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 87719566063dSJacob Faibussowitsch if (monitorsetup) PetscCall((*monitorsetup)(dm, vf)); 87729566063dSJacob Faibussowitsch PetscCall(DMMonitorSet(dm, (PetscErrorCode(*)(DM, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 8773c0f0dcc3SMatthew G. Knepley } 8774c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8775c0f0dcc3SMatthew G. Knepley } 8776c0f0dcc3SMatthew G. Knepley 8777c0f0dcc3SMatthew G. Knepley /*@ 8778c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 8779c0f0dcc3SMatthew G. Knepley 8780bb7acecfSBarry Smith Collective on dm 8781c0f0dcc3SMatthew G. Knepley 8782c0f0dcc3SMatthew G. Knepley Input Parameters: 8783bb7acecfSBarry Smith . dm - The `DM` 8784c0f0dcc3SMatthew G. Knepley 8785c0f0dcc3SMatthew G. Knepley Level: developer 8786c0f0dcc3SMatthew G. Knepley 8787bb7acecfSBarry Smith Question: 8788bb7acecfSBarry 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 8789bb7acecfSBarry Smith since some `DM` have no concept of discretization 8790bb7acecfSBarry Smith 8791bb7acecfSBarry Smith .seealso: `DMMonitorSet()`, `DMMonitorSetFromOptions()` 8792c0f0dcc3SMatthew G. Knepley @*/ 8793d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitor(DM dm) 8794d71ae5a4SJacob Faibussowitsch { 8795c0f0dcc3SMatthew G. Knepley PetscInt m; 8796c0f0dcc3SMatthew G. Knepley 8797c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8798c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 8799c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 880048a46eb9SPierre Jolivet for (m = 0; m < dm->numbermonitors; ++m) PetscCall((*dm->monitor[m])(dm, dm->monitorcontext[m])); 8801c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8802c0f0dcc3SMatthew G. Knepley } 88032e4af2aeSMatthew G. Knepley 88042e4af2aeSMatthew G. Knepley /*@ 8805bb7acecfSBarry Smith DMComputeError - Computes the error assuming the user has provided the exact solution functions 88062e4af2aeSMatthew G. Knepley 8807bb7acecfSBarry Smith Collective on dm 88082e4af2aeSMatthew G. Knepley 88092e4af2aeSMatthew G. Knepley Input Parameters: 8810bb7acecfSBarry Smith + dm - The `DM` 88116b867d5aSJose E. Roman - sol - The solution vector 88122e4af2aeSMatthew G. Knepley 88136b867d5aSJose E. Roman Input/Output Parameter: 88146b867d5aSJose E. Roman . errors - An array of length Nf, the number of fields, or NULL for no output; on output 88156b867d5aSJose E. Roman contains the error in each field 88166b867d5aSJose E. Roman 88176b867d5aSJose E. Roman Output Parameter: 88186b867d5aSJose E. Roman . errorVec - A vector to hold the cellwise error (may be NULL) 88192e4af2aeSMatthew G. Knepley 8820bb7acecfSBarry Smith Note: 8821bb7acecfSBarry Smith The exact solutions come from the `PetscDS` object, and the time comes from `DMGetOutputSequenceNumber()`. 88222e4af2aeSMatthew G. Knepley 88232e4af2aeSMatthew G. Knepley Level: developer 88242e4af2aeSMatthew G. Knepley 8825db781477SPatrick Sanan .seealso: `DMMonitorSet()`, `DMGetRegionNumDS()`, `PetscDSGetExactSolution()`, `DMGetOutputSequenceNumber()` 88262e4af2aeSMatthew G. Knepley @*/ 8827d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 8828d71ae5a4SJacob Faibussowitsch { 88292e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 88302e4af2aeSMatthew G. Knepley void **ctxs; 88312e4af2aeSMatthew G. Knepley PetscReal time; 88322e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 88332e4af2aeSMatthew G. Knepley 88342e4af2aeSMatthew G. Knepley PetscFunctionBegin; 88359566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 88369566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nf, &exactSol, Nf, &ctxs)); 88379566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 88382e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 88392e4af2aeSMatthew G. Knepley PetscDS ds; 88402e4af2aeSMatthew G. Knepley DMLabel label; 88412e4af2aeSMatthew G. Knepley IS fieldIS; 88422e4af2aeSMatthew G. Knepley const PetscInt *fields; 88432e4af2aeSMatthew G. Knepley PetscInt dsNf; 88442e4af2aeSMatthew G. Knepley 88459566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds)); 88469566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 88479566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISGetIndices(fieldIS, &fields)); 88482e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 88492e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 88509566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field])); 88512e4af2aeSMatthew G. Knepley } 88529566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISRestoreIndices(fieldIS, &fields)); 88532e4af2aeSMatthew G. Knepley } 8854ad540459SPierre 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); 88559566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, NULL, &time)); 88569566063dSJacob Faibussowitsch if (errors) PetscCall(DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors)); 88572e4af2aeSMatthew G. Knepley if (errorVec) { 88582e4af2aeSMatthew G. Knepley DM edm; 88592e4af2aeSMatthew G. Knepley DMPolytopeType ct; 88602e4af2aeSMatthew G. Knepley PetscBool simplex; 88612e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 88622e4af2aeSMatthew G. Knepley 88639566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &edm)); 88649566063dSJacob Faibussowitsch PetscCall(DMGetDimension(edm, &dim)); 88659566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 88669566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 88672e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 88689566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 88692e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 88702e4af2aeSMatthew G. Knepley PetscFE fe, efe; 88712e4af2aeSMatthew G. Knepley PetscQuadrature q; 88722e4af2aeSMatthew G. Knepley const char *name; 88732e4af2aeSMatthew G. Knepley 88749566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, (PetscObject *)&fe)); 88759566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe)); 88769566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 88779566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)efe, name)); 88789566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 88799566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(efe, q)); 88809566063dSJacob Faibussowitsch PetscCall(DMSetField(edm, f, NULL, (PetscObject)efe)); 88819566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&efe)); 88822e4af2aeSMatthew G. Knepley } 88839566063dSJacob Faibussowitsch PetscCall(DMCreateDS(edm)); 88842e4af2aeSMatthew G. Knepley 88859566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(edm, errorVec)); 88869566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*errorVec, "Error")); 88879566063dSJacob Faibussowitsch PetscCall(DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec)); 88889566063dSJacob Faibussowitsch PetscCall(DMDestroy(&edm)); 88892e4af2aeSMatthew G. Knepley } 88909566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, ctxs)); 88912e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 88922e4af2aeSMatthew G. Knepley } 88939a2a23afSMatthew G. Knepley 88949a2a23afSMatthew G. Knepley /*@ 8895bb7acecfSBarry Smith DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this `DM` 88969a2a23afSMatthew G. Knepley 88979a2a23afSMatthew G. Knepley Not collective 88989a2a23afSMatthew G. Knepley 88999a2a23afSMatthew G. Knepley Input Parameter: 8900bb7acecfSBarry Smith . dm - The `DM` 89019a2a23afSMatthew G. Knepley 89029a2a23afSMatthew G. Knepley Output Parameter: 8903a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 89049a2a23afSMatthew G. Knepley 89059a2a23afSMatthew G. Knepley Level: advanced 89069a2a23afSMatthew G. Knepley 8907bb7acecfSBarry Smith .seealso: `DMSetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 89089a2a23afSMatthew G. Knepley @*/ 8909d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 8910d71ae5a4SJacob Faibussowitsch { 89119a2a23afSMatthew G. Knepley PetscFunctionBegin; 89129a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89139566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize(dm->auxData, numAux)); 89149a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89159a2a23afSMatthew G. Knepley } 89169a2a23afSMatthew G. Knepley 89179a2a23afSMatthew G. Knepley /*@ 8918ac17215fSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value, and equation part 89199a2a23afSMatthew G. Knepley 89209a2a23afSMatthew G. Knepley Not collective 89219a2a23afSMatthew G. Knepley 89229a2a23afSMatthew G. Knepley Input Parameters: 8923bb7acecfSBarry Smith + dm - The `DM` 8924bb7acecfSBarry Smith . label - The `DMLabel` 8925ac17215fSMatthew G. Knepley . value - The label value indicating the region 8926ac17215fSMatthew G. Knepley - part - The equation part, or 0 if unused 89279a2a23afSMatthew G. Knepley 89289a2a23afSMatthew G. Knepley Output Parameter: 8929bb7acecfSBarry Smith . aux - The `Vec` holding auxiliary field data 89309a2a23afSMatthew G. Knepley 8931bb7acecfSBarry Smith Note: 8932bb7acecfSBarry Smith If no auxiliary vector is found for this (label, value), (NULL, 0, 0) is checked as well. 893304c51a94SMatthew G. Knepley 89349a2a23afSMatthew G. Knepley Level: advanced 89359a2a23afSMatthew G. Knepley 8936bb7acecfSBarry Smith .seealso: `DMSetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryLabels()` 89379a2a23afSMatthew G. Knepley @*/ 8938d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec *aux) 8939d71ae5a4SJacob Faibussowitsch { 8940ac17215fSMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0, 0}; 894104c51a94SMatthew G. Knepley PetscBool has; 89429a2a23afSMatthew G. Knepley 89439a2a23afSMatthew G. Knepley PetscFunctionBegin; 89449a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89459a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 89469a2a23afSMatthew G. Knepley key.label = label; 89479a2a23afSMatthew G. Knepley key.value = value; 8948ac17215fSMatthew G. Knepley key.part = part; 89499566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxHas(dm->auxData, key, &has)); 89509566063dSJacob Faibussowitsch if (has) PetscCall(PetscHMapAuxGet(dm->auxData, key, aux)); 89519566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxGet(dm->auxData, wild, aux)); 89529a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89539a2a23afSMatthew G. Knepley } 89549a2a23afSMatthew G. Knepley 89559a2a23afSMatthew G. Knepley /*@ 8956bb7acecfSBarry Smith DMSetAuxiliaryVec - Set an auxiliary vector for region specified by the given label and value, and equation part 89579a2a23afSMatthew G. Knepley 8958bb7acecfSBarry Smith Not collective because auxilary vectors are not parallel 89599a2a23afSMatthew G. Knepley 89609a2a23afSMatthew G. Knepley Input Parameters: 8961bb7acecfSBarry Smith + dm - The `DM` 8962bb7acecfSBarry Smith . label - The `DMLabel` 89639a2a23afSMatthew G. Knepley . value - The label value indicating the region 8964ac17215fSMatthew G. Knepley . part - The equation part, or 0 if unused 8965bb7acecfSBarry Smith - aux - The `Vec` holding auxiliary field data 89669a2a23afSMatthew G. Knepley 89679a2a23afSMatthew G. Knepley Level: advanced 89689a2a23afSMatthew G. Knepley 8969bb7acecfSBarry Smith .seealso: `DMGetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMCopyAuxiliaryVec()` 89709a2a23afSMatthew G. Knepley @*/ 8971d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec aux) 8972d71ae5a4SJacob Faibussowitsch { 89739a2a23afSMatthew G. Knepley Vec old; 89749a2a23afSMatthew G. Knepley PetscHashAuxKey key; 89759a2a23afSMatthew G. Knepley 89769a2a23afSMatthew G. Knepley PetscFunctionBegin; 89779a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89789a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 89799a2a23afSMatthew G. Knepley key.label = label; 89809a2a23afSMatthew G. Knepley key.value = value; 8981ac17215fSMatthew G. Knepley key.part = part; 89829566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGet(dm->auxData, key, &old)); 89839566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)aux)); 89849566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)old)); 89859566063dSJacob Faibussowitsch if (!aux) PetscCall(PetscHMapAuxDel(dm->auxData, key)); 89869566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxSet(dm->auxData, key, aux)); 89879a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89889a2a23afSMatthew G. Knepley } 89899a2a23afSMatthew G. Knepley 89909a2a23afSMatthew G. Knepley /*@C 8991bb7acecfSBarry Smith DMGetAuxiliaryLabels - Get the labels, values, and parts for all auxiliary vectors in this `DM` 89929a2a23afSMatthew G. Knepley 89939a2a23afSMatthew G. Knepley Not collective 89949a2a23afSMatthew G. Knepley 89959a2a23afSMatthew G. Knepley Input Parameter: 8996bb7acecfSBarry Smith . dm - The `DM` 89979a2a23afSMatthew G. Knepley 89989a2a23afSMatthew G. Knepley Output Parameters: 8999bb7acecfSBarry Smith + labels - The `DMLabel`s for each `Vec` 9000bb7acecfSBarry Smith . values - The label values for each `Vec` 9001bb7acecfSBarry Smith - parts - The equation parts for each `Vec` 90029a2a23afSMatthew G. Knepley 9003bb7acecfSBarry Smith Note: 9004bb7acecfSBarry Smith The arrays passed in must be at least as large as `DMGetNumAuxiliaryVec()`. 90059a2a23afSMatthew G. Knepley 90069a2a23afSMatthew G. Knepley Level: advanced 90079a2a23afSMatthew G. Knepley 9008bb7acecfSBarry Smith .seealso: `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMSetAuxiliaryVec()`, DMCopyAuxiliaryVec()` 90099a2a23afSMatthew G. Knepley @*/ 9010d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[], PetscInt parts[]) 9011d71ae5a4SJacob Faibussowitsch { 90129a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 90139a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 90149a2a23afSMatthew G. Knepley 90159a2a23afSMatthew G. Knepley PetscFunctionBegin; 90169a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90179a2a23afSMatthew G. Knepley PetscValidPointer(labels, 2); 9018dadcf809SJacob Faibussowitsch PetscValidIntPointer(values, 3); 9019dadcf809SJacob Faibussowitsch PetscValidIntPointer(parts, 4); 90209566063dSJacob Faibussowitsch PetscCall(DMGetNumAuxiliaryVec(dm, &n)); 90219566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &keys)); 90229566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetKeys(dm->auxData, &off, keys)); 90239371c9d4SSatish Balay for (i = 0; i < n; ++i) { 90249371c9d4SSatish Balay labels[i] = keys[i].label; 90259371c9d4SSatish Balay values[i] = keys[i].value; 90269371c9d4SSatish Balay parts[i] = keys[i].part; 90279371c9d4SSatish Balay } 90289566063dSJacob Faibussowitsch PetscCall(PetscFree(keys)); 90299a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 90309a2a23afSMatthew G. Knepley } 90319a2a23afSMatthew G. Knepley 90329a2a23afSMatthew G. Knepley /*@ 9033bb7acecfSBarry Smith DMCopyAuxiliaryVec - Copy the auxiliary vector data on a `DM` to a new `DM` 90349a2a23afSMatthew G. Knepley 90359a2a23afSMatthew G. Knepley Not collective 90369a2a23afSMatthew G. Knepley 90379a2a23afSMatthew G. Knepley Input Parameter: 9038bb7acecfSBarry Smith . dm - The `DM` 90399a2a23afSMatthew G. Knepley 90409a2a23afSMatthew G. Knepley Output Parameter: 9041bb7acecfSBarry Smith . dmNew - The new `DM`, now with the same auxiliary data 90429a2a23afSMatthew G. Knepley 90439a2a23afSMatthew G. Knepley Level: advanced 90449a2a23afSMatthew G. Knepley 9045bb7acecfSBarry Smith Note: 9046bb7acecfSBarry Smith This is a shallow copy of the auxiliary vectors 9047bb7acecfSBarry Smith 9048db781477SPatrick Sanan .seealso: `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 90499a2a23afSMatthew G. Knepley @*/ 9050d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 9051d71ae5a4SJacob Faibussowitsch { 90529a2a23afSMatthew G. Knepley PetscFunctionBegin; 90539a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90549566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&dmNew->auxData)); 90559566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData)); 90569a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 90579a2a23afSMatthew G. Knepley } 9058b5a892a1SMatthew G. Knepley 9059b5a892a1SMatthew G. Knepley /*@C 9060bb7acecfSBarry Smith DMPolytopeMatchOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9061b5a892a1SMatthew G. Knepley 9062b5a892a1SMatthew G. Knepley Not collective 9063b5a892a1SMatthew G. Knepley 9064b5a892a1SMatthew G. Knepley Input Parameters: 9065bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9066b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9067b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9068b5a892a1SMatthew G. Knepley 9069b5a892a1SMatthew G. Knepley Output Parameters: 9070bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9071b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9072b5a892a1SMatthew G. Knepley 9073b5a892a1SMatthew G. Knepley Level: advanced 9074b5a892a1SMatthew G. Knepley 9075bb7acecfSBarry Smith Note: 9076bb7acecfSBarry Smith An arrangement is a face order combined with an orientation for each face 9077bb7acecfSBarry Smith 9078bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9079bb7acecfSBarry Smith that labels each arrangement (face ordering plus orientation for each face). 9080bb7acecfSBarry Smith 9081bb7acecfSBarry Smith See `DMPolytopeMatchVertexOrientation()` to find a new vertex orientation that takes the source vertex arrangement to the target vertex arrangement 9082bb7acecfSBarry Smith 9083bb7acecfSBarry Smith .seealso: `DMPolytopeGetOrientation()`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetVertexOrientation()` 9084b5a892a1SMatthew G. Knepley @*/ 9085d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9086d71ae5a4SJacob Faibussowitsch { 9087b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 9088b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct) / 2; 9089b5a892a1SMatthew G. Knepley PetscInt o, c; 9090b5a892a1SMatthew G. Knepley 9091b5a892a1SMatthew G. Knepley PetscFunctionBegin; 90929371c9d4SSatish Balay if (!nO) { 90939371c9d4SSatish Balay *ornt = 0; 90949371c9d4SSatish Balay *found = PETSC_TRUE; 90959371c9d4SSatish Balay PetscFunctionReturn(0); 90969371c9d4SSatish Balay } 9097b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9098b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 9099b5a892a1SMatthew G. Knepley 91009371c9d4SSatish Balay for (c = 0; c < cS; ++c) 91019371c9d4SSatish Balay if (sourceCone[arr[c * 2]] != targetCone[c]) break; 91029371c9d4SSatish Balay if (c == cS) { 91039371c9d4SSatish Balay *ornt = o; 91049371c9d4SSatish Balay break; 91059371c9d4SSatish Balay } 9106b5a892a1SMatthew G. Knepley } 9107b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 9108b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9109b5a892a1SMatthew G. Knepley } 9110b5a892a1SMatthew G. Knepley 9111b5a892a1SMatthew G. Knepley /*@C 9112bb7acecfSBarry Smith DMPolytopeGetOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9113b5a892a1SMatthew G. Knepley 9114b5a892a1SMatthew G. Knepley Not collective 9115b5a892a1SMatthew G. Knepley 9116b5a892a1SMatthew G. Knepley Input Parameters: 9117bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9118b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9119b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9120b5a892a1SMatthew G. Knepley 9121b5a892a1SMatthew G. Knepley Output Parameters: 9122bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9123b5a892a1SMatthew G. Knepley 9124b5a892a1SMatthew G. Knepley Level: advanced 9125b5a892a1SMatthew G. Knepley 9126bb7acecfSBarry Smith Note: 9127bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchOrientation()` except it will generate an error if no suitable orientation can be found. 9128bb7acecfSBarry Smith 9129bb7acecfSBarry Smith Developer Note: 9130bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchOrientation()` and error if none is found 9131bb7acecfSBarry Smith 9132bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeMatchOrientation()`, `DMPolytopeGetVertexOrientation()`, `DMPolytopeMatchVertexOrientation()` 9133b5a892a1SMatthew G. Knepley @*/ 9134d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9135d71ae5a4SJacob Faibussowitsch { 9136b5a892a1SMatthew G. Knepley PetscBool found; 9137b5a892a1SMatthew G. Knepley 9138b5a892a1SMatthew G. Knepley PetscFunctionBegin; 91399566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found)); 91407a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 9141b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9142b5a892a1SMatthew G. Knepley } 9143b5a892a1SMatthew G. Knepley 9144b5a892a1SMatthew G. Knepley /*@C 9145bb7acecfSBarry Smith DMPolytopeMatchVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9146b5a892a1SMatthew G. Knepley 9147b5a892a1SMatthew G. Knepley Not collective 9148b5a892a1SMatthew G. Knepley 9149b5a892a1SMatthew G. Knepley Input Parameters: 9150bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9151b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 9152b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 9153b5a892a1SMatthew G. Knepley 9154b5a892a1SMatthew G. Knepley Output Parameters: 9155bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9156b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9157b5a892a1SMatthew G. Knepley 9158b5a892a1SMatthew G. Knepley Level: advanced 9159b5a892a1SMatthew G. Knepley 9160bb7acecfSBarry Smith Note: 9161bb7acecfSBarry Smith An arrangement is a vertex order 9162bb7acecfSBarry Smith 9163bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9164bb7acecfSBarry Smith that labels each arrangement (vertex ordering). 9165bb7acecfSBarry Smith 9166bb7acecfSBarry Smith See `DMPolytopeMatchOrientation()` to find a new face orientation that takes the source face arrangement to the target face arrangement 9167bb7acecfSBarry Smith 9168bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchOrientation()`, `DMPolytopeTypeGetNumVertices()`, `DMPolytopeTypeGetVertexArrangment()` 9169b5a892a1SMatthew G. Knepley @*/ 9170d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 9171d71ae5a4SJacob Faibussowitsch { 9172b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 9173b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct) / 2; 9174b5a892a1SMatthew G. Knepley PetscInt o, c; 9175b5a892a1SMatthew G. Knepley 9176b5a892a1SMatthew G. Knepley PetscFunctionBegin; 91779371c9d4SSatish Balay if (!nO) { 91789371c9d4SSatish Balay *ornt = 0; 91799371c9d4SSatish Balay *found = PETSC_TRUE; 91809371c9d4SSatish Balay PetscFunctionReturn(0); 91819371c9d4SSatish Balay } 9182b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9183b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangment(ct, o); 9184b5a892a1SMatthew G. Knepley 91859371c9d4SSatish Balay for (c = 0; c < cS; ++c) 91869371c9d4SSatish Balay if (sourceVert[arr[c]] != targetVert[c]) break; 91879371c9d4SSatish Balay if (c == cS) { 91889371c9d4SSatish Balay *ornt = o; 91899371c9d4SSatish Balay break; 91909371c9d4SSatish Balay } 9191b5a892a1SMatthew G. Knepley } 9192b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 9193b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9194b5a892a1SMatthew G. Knepley } 9195b5a892a1SMatthew G. Knepley 9196b5a892a1SMatthew G. Knepley /*@C 9197bb7acecfSBarry Smith DMPolytopeGetVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9198b5a892a1SMatthew G. Knepley 9199b5a892a1SMatthew G. Knepley Not collective 9200b5a892a1SMatthew G. Knepley 9201b5a892a1SMatthew G. Knepley Input Parameters: 9202bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9203b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 9204b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 9205b5a892a1SMatthew G. Knepley 9206b5a892a1SMatthew G. Knepley Output Parameters: 9207bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9208b5a892a1SMatthew G. Knepley 9209b5a892a1SMatthew G. Knepley Level: advanced 9210b5a892a1SMatthew G. Knepley 9211bb7acecfSBarry Smith Note: 9212bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchVertexOrientation()` except it errors if not orientation is possible. 9213bb7acecfSBarry Smith 9214bb7acecfSBarry Smith Developer Note: 9215bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchVertexOrientation()` and error if none is found 9216bb7acecfSBarry Smith 9217bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetOrientation()` 9218b5a892a1SMatthew G. Knepley @*/ 9219d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9220d71ae5a4SJacob Faibussowitsch { 9221b5a892a1SMatthew G. Knepley PetscBool found; 9222b5a892a1SMatthew G. Knepley 9223b5a892a1SMatthew G. Knepley PetscFunctionBegin; 92249566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found)); 92257a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 9226b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9227b5a892a1SMatthew G. Knepley } 9228012bc364SMatthew G. Knepley 9229012bc364SMatthew G. Knepley /*@C 9230012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 9231012bc364SMatthew G. Knepley 9232012bc364SMatthew G. Knepley Not collective 9233012bc364SMatthew G. Knepley 9234012bc364SMatthew G. Knepley Input Parameters: 9235bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9236012bc364SMatthew G. Knepley - point - Coordinates of the point 9237012bc364SMatthew G. Knepley 9238012bc364SMatthew G. Knepley Output Parameters: 9239012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 9240012bc364SMatthew G. Knepley 9241012bc364SMatthew G. Knepley Level: advanced 9242012bc364SMatthew G. Knepley 9243bb7acecfSBarry Smith .seealso: `DM`, `DMPolytopeType`, `DMLocatePoints()` 9244012bc364SMatthew G. Knepley @*/ 9245d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 9246d71ae5a4SJacob Faibussowitsch { 9247012bc364SMatthew G. Knepley PetscReal sum = 0.0; 9248012bc364SMatthew G. Knepley PetscInt d; 9249012bc364SMatthew G. Knepley 9250012bc364SMatthew G. Knepley PetscFunctionBegin; 9251012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 9252012bc364SMatthew G. Knepley switch (ct) { 9253012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 9254012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 9255012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 92569371c9d4SSatish Balay if (point[d] < -1.0) { 92579371c9d4SSatish Balay *inside = PETSC_FALSE; 92589371c9d4SSatish Balay break; 92599371c9d4SSatish Balay } 9260012bc364SMatthew G. Knepley sum += point[d]; 9261012bc364SMatthew G. Knepley } 92629371c9d4SSatish Balay if (sum > PETSC_SMALL) { 92639371c9d4SSatish Balay *inside = PETSC_FALSE; 92649371c9d4SSatish Balay break; 92659371c9d4SSatish Balay } 9266012bc364SMatthew G. Knepley break; 9267012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 9268012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 9269012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 92709371c9d4SSatish Balay if (PetscAbsReal(point[d]) > 1. + PETSC_SMALL) { 92719371c9d4SSatish Balay *inside = PETSC_FALSE; 9272012bc364SMatthew G. Knepley break; 92739371c9d4SSatish Balay } 92749371c9d4SSatish Balay break; 9275d71ae5a4SJacob Faibussowitsch default: 9276d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 9277012bc364SMatthew G. Knepley } 9278012bc364SMatthew G. Knepley PetscFunctionReturn(0); 9279012bc364SMatthew G. Knepley } 9280