1d0295fc0SJunchao Zhang #include <petscvec.h> 2af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 3c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 4e6f8dbb6SToby Isaac #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/ 53e922f36SToby Isaac #include <petscdmplex.h> 6d2b2dc1eSMatthew G. Knepley #include <petscdmceed.h> 7f19dbd58SToby Isaac #include <petscdmfield.h> 80c312b8eSJed Brown #include <petscsf.h> 92764a2aaSMatthew G. Knepley #include <petscds.h> 1047c6ae99SBarry Smith 11f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 12f918ec44SMatthew G. Knepley #include <petscfeceed.h> 13f918ec44SMatthew G. Knepley #endif 14f918ec44SMatthew G. Knepley 15cea3dcb8SSatish Balay #if !defined(PETSC_HAVE_WINDOWS_COMPILERS) 16cea3dcb8SSatish Balay #include <petsc/private/valgrind/memcheck.h> 1700d952a4SJed Brown #endif 1800d952a4SJed Brown 19732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 20d67d17b1SMatthew G. Knepley PetscClassId DMLABEL_CLASSID; 21708be2fdSJed Brown 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, DM_ProjectFunction; 2267a56275SMatthew G Knepley 23ea78f98cSLisandro Dalcin const char *const DMBoundaryTypes[] = {"NONE", "GHOSTED", "MIRROR", "PERIODIC", "TWIST", "DMBoundaryType", "DM_BOUNDARY_", NULL}; 24d1b3049bSMatthew 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}; 250e762ea3SJed Brown const char *const DMBlockingTypes[] = {"TOPOLOGICAL_POINT", "FIELD_NODE", "DMBlockingType", "DM_BLOCKING_", NULL}; 26*476787b7SMatthew G. Knepley const char *const DMPolytopeTypes[] = 27*476787b7SMatthew G. Knepley {"vertex", "segment", "tensor_segment", "triangle", "quadrilateral", "tensor_quad", "tetrahedron", "hexahedron", "triangular_prism", "tensor_triangular_prism", "tensor_quadrilateral_prism", "pyramid", "FV_ghost_cell", "interior_ghost_cell", 28*476787b7SMatthew G. Knepley "unknown", "unknown_cell", "unknown_face", "invalid", "DMPolytopeType", "DM_POLYTOPE_", NULL}; 292cbb9b06SVaclav Hapla const char *const DMCopyLabelsModes[] = {"replace", "keep", "fail", "DMCopyLabelsMode", "DM_COPY_LABELS_", NULL}; 3060c22052SBarry Smith 31a4121054SBarry Smith /*@ 32bb7acecfSBarry Smith DMCreate - Creates an empty `DM` object. `DM`s are the abstract objects in PETSc that mediate between meshes and discretizations and the 33bb7acecfSBarry Smith algebraic solvers, time integrators, and optimization algorithms. 34a4121054SBarry Smith 35d083f849SBarry Smith Collective 36a4121054SBarry Smith 37a4121054SBarry Smith Input Parameter: 38bb7acecfSBarry Smith . comm - The communicator for the `DM` object 39a4121054SBarry Smith 40a4121054SBarry Smith Output Parameter: 41bb7acecfSBarry Smith . dm - The `DM` object 42a4121054SBarry Smith 43a4121054SBarry Smith Level: beginner 44a4121054SBarry Smith 45bb7acecfSBarry Smith Notes: 46bb7acecfSBarry Smith See `DMType` for a brief summary of available `DM`. 47bb7acecfSBarry Smith 48bb7acecfSBarry Smith The type must then be set with `DMSetType()`. If you never call `DMSetType()` it will generate an 49bb7acecfSBarry Smith error when you try to use the dm. 50bb7acecfSBarry Smith 511cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetType()`, `DMType`, `DMDACreate()`, `DMDA`, `DMSLICED`, `DMCOMPOSITE`, `DMPLEX`, `DMMOAB`, `DMNETWORK` 52a4121054SBarry Smith @*/ 53d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreate(MPI_Comm comm, DM *dm) 54d71ae5a4SJacob Faibussowitsch { 55a4121054SBarry Smith DM v; 56e5e52638SMatthew G. Knepley PetscDS ds; 57a4121054SBarry Smith 58a4121054SBarry Smith PetscFunctionBegin; 594f572ea9SToby Isaac PetscAssertPointer(dm, 2); 600298fd71SBarry Smith *dm = NULL; 619566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 62a4121054SBarry Smith 639566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView)); 64e7c4fc90SDmitry Karpeev 6562e5d2d2SJDBetteridge ((PetscObject)v)->non_cyclic_references = &DMCountNonCyclicReferences; 6662e5d2d2SJDBetteridge 6749be4549SMatthew G. Knepley v->setupcalled = PETSC_FALSE; 6849be4549SMatthew G. Knepley v->setfromoptionscalled = PETSC_FALSE; 690298fd71SBarry Smith v->ltogmap = NULL; 70a4ea9b21SRichard Tran Mills v->bind_below = 0; 711411c6eeSJed Brown v->bs = 1; 72171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 739566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sf)); 749566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sectionSF)); 75c58f1c22SToby Isaac v->labels = NULL; 7634aa8a36SMatthew G. Knepley v->adjacency[0] = PETSC_FALSE; 7734aa8a36SMatthew G. Knepley v->adjacency[1] = PETSC_TRUE; 78c58f1c22SToby Isaac v->depthLabel = NULL; 79ba2698f1SMatthew G. Knepley v->celltypeLabel = NULL; 801bb6d2a8SBarry Smith v->localSection = NULL; 811bb6d2a8SBarry Smith v->globalSection = NULL; 823b8ba7d1SJed Brown v->defaultConstraint.section = NULL; 833b8ba7d1SJed Brown v->defaultConstraint.mat = NULL; 8479769bd5SJed Brown v->defaultConstraint.bias = NULL; 856858538eSMatthew G. Knepley v->coordinates[0].dim = PETSC_DEFAULT; 866858538eSMatthew G. Knepley v->coordinates[1].dim = PETSC_DEFAULT; 876858538eSMatthew G. Knepley v->sparseLocalize = PETSC_TRUE; 8896173672SStefano Zampini v->dim = PETSC_DETERMINE; 89435a35e8SMatthew G Knepley { 90435a35e8SMatthew G Knepley PetscInt i; 91435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 920298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 93f9d4088aSMatthew G. Knepley v->nearnullspaceConstructors[i] = NULL; 94435a35e8SMatthew G Knepley } 95435a35e8SMatthew G Knepley } 969566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 9707218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(v, NULL, NULL, ds, NULL)); 989566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 999566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxCreate(&v->auxData)); 10014f150ffSMatthew G. Knepley v->dmBC = NULL; 101a8fb8f29SToby Isaac v->coarseMesh = NULL; 102f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 103cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 1049566063dSJacob Faibussowitsch PetscCall(DMSetVecType(v, VECSTANDARD)); 1059566063dSJacob Faibussowitsch PetscCall(DMSetMatType(v, MATAIJ)); 1064a7a4c06SLawrence Mitchell 1071411c6eeSJed Brown *dm = v; 1083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 109a4121054SBarry Smith } 110a4121054SBarry Smith 11138221697SMatthew G. Knepley /*@ 112bb7acecfSBarry Smith DMClone - Creates a `DM` object with the same topology as the original. 11338221697SMatthew G. Knepley 114d083f849SBarry Smith Collective 11538221697SMatthew G. Knepley 11638221697SMatthew G. Knepley Input Parameter: 117bb7acecfSBarry Smith . dm - The original `DM` object 11838221697SMatthew G. Knepley 11938221697SMatthew G. Knepley Output Parameter: 120bb7acecfSBarry Smith . newdm - The new `DM` object 12138221697SMatthew G. Knepley 12238221697SMatthew G. Knepley Level: beginner 12338221697SMatthew G. Knepley 1241cb8cacdSPatrick Sanan Notes: 125bb7acecfSBarry Smith For some `DM` implementations this is a shallow clone, the result of which may share (reference counted) information with its parent. For example, 126bb7acecfSBarry Smith `DMClone()` applied to a `DMPLEX` object will result in a new `DMPLEX` that shares the topology with the original `DMPLEX`. It does not 127bb7acecfSBarry Smith share the `PetscSection` of the original `DM`. 1281bb6d2a8SBarry Smith 129bb7acecfSBarry Smith The clone is considered set up if the original has been set up. 13089706ed2SPatrick Sanan 131bb7acecfSBarry Smith Use `DMConvert()` for a general way to create new `DM` from a given `DM` 132bb7acecfSBarry Smith 13360225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMSetType()`, `DMSetLocalSection()`, `DMSetGlobalSection()`, `DMPLEX`, `DMConvert()` 13438221697SMatthew G. Knepley @*/ 135d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClone(DM dm, DM *newdm) 136d71ae5a4SJacob Faibussowitsch { 13738221697SMatthew G. Knepley PetscSF sf; 13838221697SMatthew G. Knepley Vec coords; 13938221697SMatthew G. Knepley void *ctx; 1406858538eSMatthew G. Knepley PetscInt dim, cdim, i; 14138221697SMatthew G. Knepley 14238221697SMatthew G. Knepley PetscFunctionBegin; 14338221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1444f572ea9SToby Isaac PetscAssertPointer(newdm, 2); 1459566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), newdm)); 1469566063dSJacob Faibussowitsch PetscCall(DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE, DM_COPY_LABELS_FAIL)); 147ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 148ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 149c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 150fc214432SJed Brown (*newdm)->prealloc_skip = dm->prealloc_skip; 1519566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->vectype)); 1529566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*newdm)->vectype)); 1539566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->mattype)); 1549566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*newdm)->mattype)); 1559566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1569566063dSJacob Faibussowitsch PetscCall(DMSetDimension(*newdm, dim)); 157dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, clone, newdm); 1583f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 1599566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm, &sf)); 1609566063dSJacob Faibussowitsch PetscCall(DMSetPointSF(*newdm, sf)); 1619566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dm, &ctx)); 1629566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(*newdm, ctx)); 1636858538eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 1646858538eSMatthew G. Knepley if (dm->coordinates[i].dm) { 165be4c1c3eSMatthew G. Knepley DM ncdm; 166be4c1c3eSMatthew G. Knepley PetscSection cs; 1675a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 168be4c1c3eSMatthew G. Knepley 1696858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm->coordinates[i].dm, &cs)); 1709566063dSJacob Faibussowitsch if (cs) PetscCall(PetscSectionGetChart(cs, NULL, &pEnd)); 171712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&pEnd, &pEndMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 1725a0206caSToby Isaac if (pEndMax >= 0) { 1736858538eSMatthew G. Knepley PetscCall(DMClone(dm->coordinates[i].dm, &ncdm)); 1746858538eSMatthew G. Knepley PetscCall(DMCopyDisc(dm->coordinates[i].dm, ncdm)); 1759566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(ncdm, cs)); 1766858538eSMatthew G. Knepley if (i) PetscCall(DMSetCellCoordinateDM(*newdm, ncdm)); 1776858538eSMatthew G. Knepley else PetscCall(DMSetCoordinateDM(*newdm, ncdm)); 1789566063dSJacob Faibussowitsch PetscCall(DMDestroy(&ncdm)); 179be4c1c3eSMatthew G. Knepley } 180be4c1c3eSMatthew G. Knepley } 1816858538eSMatthew G. Knepley } 1829566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 1839566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateDim(*newdm, cdim)); 1849566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coords)); 18538221697SMatthew G. Knepley if (coords) { 1869566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(*newdm, coords)); 18738221697SMatthew G. Knepley } else { 1889566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm, &coords)); 1899566063dSJacob Faibussowitsch if (coords) PetscCall(DMSetCoordinates(*newdm, coords)); 19038221697SMatthew G. Knepley } 1916858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coords)); 1926858538eSMatthew G. Knepley if (coords) { 1936858538eSMatthew G. Knepley PetscCall(DMSetCellCoordinatesLocal(*newdm, coords)); 1946858538eSMatthew G. Knepley } else { 1956858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinates(dm, &coords)); 1966858538eSMatthew G. Knepley if (coords) PetscCall(DMSetCellCoordinates(*newdm, coords)); 1976858538eSMatthew G. Knepley } 19890b157c4SStefano Zampini { 1994fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 2006858538eSMatthew G. Knepley 2014fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 2024fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*newdm, maxCell, Lstart, L)); 203c6b900c6SMatthew G. Knepley } 20434aa8a36SMatthew G. Knepley { 20534aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 20634aa8a36SMatthew G. Knepley 2079566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure)); 2089566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure)); 20934aa8a36SMatthew G. Knepley } 2103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21138221697SMatthew G. Knepley } 21238221697SMatthew G. Knepley 2139a42bb27SBarry Smith /*@C 214bb7acecfSBarry Smith DMSetVecType - Sets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 2159a42bb27SBarry Smith 21620f4b53cSBarry Smith Logically Collective 2179a42bb27SBarry Smith 218147403d9SBarry Smith Input Parameters: 2199a42bb27SBarry Smith + da - initial distributed array 220bb7acecfSBarry Smith - ctype - the vector type, for example `VECSTANDARD`, `VECCUDA`, or `VECVIENNACL` 2219a42bb27SBarry Smith 22220f4b53cSBarry Smith Options Database Key: 223147403d9SBarry Smith . -dm_vec_type ctype - the type of vector to create 2249a42bb27SBarry Smith 2259a42bb27SBarry Smith Level: intermediate 2269a42bb27SBarry Smith 22760225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMDestroy()`, `DMDAInterpolationType`, `VecType`, `DMGetVecType()`, `DMSetMatType()`, `DMGetMatType()`, 228bb7acecfSBarry Smith `VECSTANDARD`, `VECCUDA`, `VECVIENNACL`, `DMCreateLocalVector()`, `DMCreateGlobalVector()` 2299a42bb27SBarry Smith @*/ 230d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVecType(DM da, VecType ctype) 231d71ae5a4SJacob Faibussowitsch { 2329a42bb27SBarry Smith PetscFunctionBegin; 2339a42bb27SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 2349566063dSJacob Faibussowitsch PetscCall(PetscFree(da->vectype)); 2359566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype, (char **)&da->vectype)); 2363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2379a42bb27SBarry Smith } 2389a42bb27SBarry Smith 239c0dedaeaSBarry Smith /*@C 240bb7acecfSBarry Smith DMGetVecType - Gets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 241c0dedaeaSBarry Smith 24220f4b53cSBarry Smith Logically Collective 243c0dedaeaSBarry Smith 244c0dedaeaSBarry Smith Input Parameter: 245c0dedaeaSBarry Smith . da - initial distributed array 246c0dedaeaSBarry Smith 247c0dedaeaSBarry Smith Output Parameter: 248c0dedaeaSBarry Smith . ctype - the vector type 249c0dedaeaSBarry Smith 250c0dedaeaSBarry Smith Level: intermediate 251c0dedaeaSBarry Smith 25260225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMDestroy()`, `DMDAInterpolationType`, `VecType`, `DMSetMatType()`, `DMGetMatType()`, `DMSetVecType()` 253c0dedaeaSBarry Smith @*/ 254d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetVecType(DM da, VecType *ctype) 255d71ae5a4SJacob Faibussowitsch { 256c0dedaeaSBarry Smith PetscFunctionBegin; 257c0dedaeaSBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 258c0dedaeaSBarry Smith *ctype = da->vectype; 2593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 260c0dedaeaSBarry Smith } 261c0dedaeaSBarry Smith 2625f1ad066SMatthew G Knepley /*@ 263bb7acecfSBarry Smith VecGetDM - Gets the `DM` defining the data layout of the vector 2645f1ad066SMatthew G Knepley 26520f4b53cSBarry Smith Not Collective 2665f1ad066SMatthew G Knepley 2675f1ad066SMatthew G Knepley Input Parameter: 268bb7acecfSBarry Smith . v - The `Vec` 2695f1ad066SMatthew G Knepley 2705f1ad066SMatthew G Knepley Output Parameter: 271bb7acecfSBarry Smith . dm - The `DM` 2725f1ad066SMatthew G Knepley 2735f1ad066SMatthew G Knepley Level: intermediate 2745f1ad066SMatthew G Knepley 275bb7acecfSBarry Smith Note: 276bb7acecfSBarry Smith A `Vec` may not have a `DM` associated with it. 277bb7acecfSBarry Smith 2781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecSetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 2795f1ad066SMatthew G Knepley @*/ 280d71ae5a4SJacob Faibussowitsch PetscErrorCode VecGetDM(Vec v, DM *dm) 281d71ae5a4SJacob Faibussowitsch { 2825f1ad066SMatthew G Knepley PetscFunctionBegin; 2835f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 2844f572ea9SToby Isaac PetscAssertPointer(dm, 2); 2859566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)v, "__PETSc_dm", (PetscObject *)dm)); 2863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2875f1ad066SMatthew G Knepley } 2885f1ad066SMatthew G Knepley 2895f1ad066SMatthew G Knepley /*@ 290bb7acecfSBarry Smith VecSetDM - Sets the `DM` defining the data layout of the vector. 2915f1ad066SMatthew G Knepley 29220f4b53cSBarry Smith Not Collective 2935f1ad066SMatthew G Knepley 2945f1ad066SMatthew G Knepley Input Parameters: 295bb7acecfSBarry Smith + v - The `Vec` 296bb7acecfSBarry Smith - dm - The `DM` 2975f1ad066SMatthew G Knepley 29820f4b53cSBarry Smith Level: developer 29920f4b53cSBarry Smith 300bb7acecfSBarry Smith Note: 301bb7acecfSBarry Smith This is rarely used, generally one uses `DMGetLocalVector()` or `DMGetGlobalVector()` to create a vector associated with a given `DM` 302d9805387SMatthew G. Knepley 303bb7acecfSBarry 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. 304bb7acecfSBarry Smith 3051cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecGetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 3065f1ad066SMatthew G Knepley @*/ 307d71ae5a4SJacob Faibussowitsch PetscErrorCode VecSetDM(Vec v, DM dm) 308d71ae5a4SJacob Faibussowitsch { 3095f1ad066SMatthew G Knepley PetscFunctionBegin; 3105f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 311d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 3129566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)v, "__PETSc_dm", (PetscObject)dm)); 3133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3145f1ad066SMatthew G Knepley } 3155f1ad066SMatthew G Knepley 316521d9a4cSLisandro Dalcin /*@C 317bb7acecfSBarry Smith DMSetISColoringType - Sets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 3188f1509bcSBarry Smith 31920f4b53cSBarry Smith Logically Collective 3208f1509bcSBarry Smith 3218f1509bcSBarry Smith Input Parameters: 322bb7acecfSBarry Smith + dm - the `DM` context 3238f1509bcSBarry Smith - ctype - the matrix type 3248f1509bcSBarry Smith 32520f4b53cSBarry Smith Options Database Key: 3268f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3278f1509bcSBarry Smith 3288f1509bcSBarry Smith Level: intermediate 3298f1509bcSBarry Smith 3301cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 331bb7acecfSBarry Smith `DMGetISColoringType()`, `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3328f1509bcSBarry Smith @*/ 333d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetISColoringType(DM dm, ISColoringType ctype) 334d71ae5a4SJacob Faibussowitsch { 3358f1509bcSBarry Smith PetscFunctionBegin; 3368f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3378f1509bcSBarry Smith dm->coloringtype = ctype; 3383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3398f1509bcSBarry Smith } 3408f1509bcSBarry Smith 3418f1509bcSBarry Smith /*@C 342bb7acecfSBarry Smith DMGetISColoringType - Gets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 343521d9a4cSLisandro Dalcin 34420f4b53cSBarry Smith Logically Collective 345521d9a4cSLisandro Dalcin 346521d9a4cSLisandro Dalcin Input Parameter: 347bb7acecfSBarry Smith . dm - the `DM` context 3488f1509bcSBarry Smith 3498f1509bcSBarry Smith Output Parameter: 3508f1509bcSBarry Smith . ctype - the matrix type 3518f1509bcSBarry Smith 35220f4b53cSBarry Smith Options Database Key: 3538f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3548f1509bcSBarry Smith 3558f1509bcSBarry Smith Level: intermediate 3568f1509bcSBarry Smith 3571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 35842747ad1SJacob Faibussowitsch `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3598f1509bcSBarry Smith @*/ 360d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetISColoringType(DM dm, ISColoringType *ctype) 361d71ae5a4SJacob Faibussowitsch { 3628f1509bcSBarry Smith PetscFunctionBegin; 3638f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3648f1509bcSBarry Smith *ctype = dm->coloringtype; 3653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3668f1509bcSBarry Smith } 3678f1509bcSBarry Smith 3688f1509bcSBarry Smith /*@C 369bb7acecfSBarry Smith DMSetMatType - Sets the type of matrix created with `DMCreateMatrix()` 3708f1509bcSBarry Smith 37120f4b53cSBarry Smith Logically Collective 3728f1509bcSBarry Smith 3738f1509bcSBarry Smith Input Parameters: 374bb7acecfSBarry Smith + dm - the `DM` context 375bb7acecfSBarry Smith - ctype - the matrix type, for example `MATMPIAIJ` 376521d9a4cSLisandro Dalcin 37720f4b53cSBarry Smith Options Database Key: 378bb7acecfSBarry Smith . -dm_mat_type ctype - the type of the matrix to create, for example mpiaij 379521d9a4cSLisandro Dalcin 380521d9a4cSLisandro Dalcin Level: intermediate 381521d9a4cSLisandro Dalcin 38242747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `MatType`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMGetMatType()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()` 383521d9a4cSLisandro Dalcin @*/ 384d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatType(DM dm, MatType ctype) 385d71ae5a4SJacob Faibussowitsch { 386521d9a4cSLisandro Dalcin PetscFunctionBegin; 387521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3889566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->mattype)); 3899566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype, (char **)&dm->mattype)); 3903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 391521d9a4cSLisandro Dalcin } 392521d9a4cSLisandro Dalcin 393c0dedaeaSBarry Smith /*@C 39420f4b53cSBarry Smith DMGetMatType - Gets the type of matrix that would be created with `DMCreateMatrix()` 395c0dedaeaSBarry Smith 39620f4b53cSBarry Smith Logically Collective 397c0dedaeaSBarry Smith 398c0dedaeaSBarry Smith Input Parameter: 399bb7acecfSBarry Smith . dm - the `DM` context 400c0dedaeaSBarry Smith 401c0dedaeaSBarry Smith Output Parameter: 402c0dedaeaSBarry Smith . ctype - the matrix type 403c0dedaeaSBarry Smith 404c0dedaeaSBarry Smith Level: intermediate 405c0dedaeaSBarry Smith 40642747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMSetMatType()` 407c0dedaeaSBarry Smith @*/ 408d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetMatType(DM dm, MatType *ctype) 409d71ae5a4SJacob Faibussowitsch { 410c0dedaeaSBarry Smith PetscFunctionBegin; 411c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 412c0dedaeaSBarry Smith *ctype = dm->mattype; 4133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 414c0dedaeaSBarry Smith } 415c0dedaeaSBarry Smith 416c688c046SMatthew G Knepley /*@ 417bb7acecfSBarry Smith MatGetDM - Gets the `DM` defining the data layout of the matrix 418c688c046SMatthew G Knepley 41920f4b53cSBarry Smith Not Collective 420c688c046SMatthew G Knepley 421c688c046SMatthew G Knepley Input Parameter: 422bb7acecfSBarry Smith . A - The `Mat` 423c688c046SMatthew G Knepley 424c688c046SMatthew G Knepley Output Parameter: 425bb7acecfSBarry Smith . dm - The `DM` 426c688c046SMatthew G Knepley 427c688c046SMatthew G Knepley Level: intermediate 428c688c046SMatthew G Knepley 429bb7acecfSBarry Smith Note: 430bb7acecfSBarry Smith A matrix may not have a `DM` associated with it 431bb7acecfSBarry Smith 43260225df5SJacob Faibussowitsch Developer Notes: 433bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with the `Mat` through a `PetscObjectCompose()` operation 4348f1509bcSBarry Smith 4351cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatSetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 436c688c046SMatthew G Knepley @*/ 437d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetDM(Mat A, DM *dm) 438d71ae5a4SJacob Faibussowitsch { 439c688c046SMatthew G Knepley PetscFunctionBegin; 440c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4414f572ea9SToby Isaac PetscAssertPointer(dm, 2); 4429566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_dm", (PetscObject *)dm)); 4433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 444c688c046SMatthew G Knepley } 445c688c046SMatthew G Knepley 446c688c046SMatthew G Knepley /*@ 447bb7acecfSBarry Smith MatSetDM - Sets the `DM` defining the data layout of the matrix 448c688c046SMatthew G Knepley 44920f4b53cSBarry Smith Not Collective 450c688c046SMatthew G Knepley 451c688c046SMatthew G Knepley Input Parameters: 45220f4b53cSBarry Smith + A - The `Mat` 45320f4b53cSBarry Smith - dm - The `DM` 454c688c046SMatthew G Knepley 455bb7acecfSBarry Smith Level: developer 456c688c046SMatthew G Knepley 457bb7acecfSBarry Smith Note: 458bb7acecfSBarry Smith This is rarely used in practice, rather `DMCreateMatrix()` is used to create a matrix associated with a particular `DM` 459bb7acecfSBarry Smith 46060225df5SJacob Faibussowitsch Developer Notes: 461bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with 462bb7acecfSBarry Smith the `Mat` through a `PetscObjectCompose()` operation 4638f1509bcSBarry Smith 4641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatGetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 465c688c046SMatthew G Knepley @*/ 466d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetDM(Mat A, DM dm) 467d71ae5a4SJacob Faibussowitsch { 468c688c046SMatthew G Knepley PetscFunctionBegin; 469c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4708865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 4719566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_dm", (PetscObject)dm)); 4723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 473c688c046SMatthew G Knepley } 474c688c046SMatthew G Knepley 4759a42bb27SBarry Smith /*@C 476bb7acecfSBarry Smith DMSetOptionsPrefix - Sets the prefix prepended to all option names when searching through the options database 4779a42bb27SBarry Smith 47820f4b53cSBarry Smith Logically Collective 4799a42bb27SBarry Smith 480d8d19677SJose E. Roman Input Parameters: 48160225df5SJacob Faibussowitsch + dm - the `DM` context 482bb7acecfSBarry Smith - prefix - the prefix to prepend 4839a42bb27SBarry Smith 48420f4b53cSBarry Smith Level: advanced 48520f4b53cSBarry Smith 48620f4b53cSBarry Smith Note: 4879a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 4889a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 4899a42bb27SBarry Smith 4901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscObjectSetOptionsPrefix()`, `DMSetFromOptions()` 4919a42bb27SBarry Smith @*/ 492d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOptionsPrefix(DM dm, const char prefix[]) 493d71ae5a4SJacob Faibussowitsch { 4949a42bb27SBarry Smith PetscFunctionBegin; 4959a42bb27SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4969566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm, prefix)); 4971baa6e33SBarry Smith if (dm->sf) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sf, prefix)); 4981baa6e33SBarry Smith if (dm->sectionSF) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF, prefix)); 4993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5009a42bb27SBarry Smith } 5019a42bb27SBarry Smith 50231697293SDave May /*@C 503da81f932SPierre Jolivet DMAppendOptionsPrefix - Appends an additional string to an already existing prefix used for searching for 504bb7acecfSBarry Smith `DM` options in the options database. 50531697293SDave May 50620f4b53cSBarry Smith Logically Collective 50731697293SDave May 50831697293SDave May Input Parameters: 509bb7acecfSBarry Smith + dm - the `DM` context 510bb7acecfSBarry Smith - prefix - the string to append to the current prefix 51131697293SDave May 51220f4b53cSBarry Smith Level: advanced 51320f4b53cSBarry Smith 51420f4b53cSBarry Smith Note: 515bb7acecfSBarry 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. 51631697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 51731697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 51831697293SDave May 5191cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetOptionsPrefix()`, `DMGetOptionsPrefix()`, `PetscObjectAppendOptionsPrefix()`, `DMSetFromOptions()` 52031697293SDave May @*/ 521d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAppendOptionsPrefix(DM dm, const char prefix[]) 522d71ae5a4SJacob Faibussowitsch { 52331697293SDave May PetscFunctionBegin; 52431697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5259566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)dm, prefix)); 5263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 52731697293SDave May } 52831697293SDave May 52931697293SDave May /*@C 53031697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 531bb7acecfSBarry Smith DM options in the options database. 53231697293SDave May 53331697293SDave May Not Collective 53431697293SDave May 5352fe279fdSBarry Smith Input Parameter: 536bb7acecfSBarry Smith . dm - the `DM` context 53731697293SDave May 5382fe279fdSBarry Smith Output Parameter: 53931697293SDave May . prefix - pointer to the prefix string used is returned 54031697293SDave May 54131697293SDave May Level: advanced 54231697293SDave May 54360225df5SJacob Faibussowitsch Fortran Notes: 54420f4b53cSBarry Smith Pass in a string 'prefix' of 54520f4b53cSBarry Smith sufficient length to hold the prefix. 54620f4b53cSBarry Smith 5471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetOptionsPrefix()`, `DMAppendOptionsPrefix()`, `DMSetFromOptions()` 54831697293SDave May @*/ 549d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOptionsPrefix(DM dm, const char *prefix[]) 550d71ae5a4SJacob Faibussowitsch { 55131697293SDave May PetscFunctionBegin; 55231697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5539566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, prefix)); 5543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55531697293SDave May } 55631697293SDave May 55762e5d2d2SJDBetteridge static PetscErrorCode DMCountNonCyclicReferences_Internal(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 558d71ae5a4SJacob Faibussowitsch { 5596eb26441SStefano Zampini PetscInt refct = ((PetscObject)dm)->refct; 56088bdff64SToby Isaac 56188bdff64SToby Isaac PetscFunctionBegin; 562aab5bcd8SJed Brown *ncrefct = 0; 56388bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 56488bdff64SToby Isaac refct--; 56588bdff64SToby Isaac if (recurseCoarse) { 56688bdff64SToby Isaac PetscInt coarseCount; 56788bdff64SToby Isaac 56862e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE, &coarseCount)); 56988bdff64SToby Isaac refct += coarseCount; 57088bdff64SToby Isaac } 57188bdff64SToby Isaac } 57288bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 57388bdff64SToby Isaac refct--; 57488bdff64SToby Isaac if (recurseFine) { 57588bdff64SToby Isaac PetscInt fineCount; 57688bdff64SToby Isaac 57762e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->fineMesh, PETSC_FALSE, PETSC_TRUE, &fineCount)); 57888bdff64SToby Isaac refct += fineCount; 57988bdff64SToby Isaac } 58088bdff64SToby Isaac } 58188bdff64SToby Isaac *ncrefct = refct; 5823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58388bdff64SToby Isaac } 58488bdff64SToby Isaac 58562e5d2d2SJDBetteridge /* Generic wrapper for DMCountNonCyclicReferences_Internal() */ 58662e5d2d2SJDBetteridge PetscErrorCode DMCountNonCyclicReferences(PetscObject dm, PetscInt *ncrefct) 58762e5d2d2SJDBetteridge { 58862e5d2d2SJDBetteridge PetscFunctionBegin; 58962e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal((DM)dm, PETSC_TRUE, PETSC_TRUE, ncrefct)); 5903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 59162e5d2d2SJDBetteridge } 59262e5d2d2SJDBetteridge 593d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 594d71ae5a4SJacob Faibussowitsch { 5955d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 596354557abSToby Isaac 597354557abSToby Isaac PetscFunctionBegin; 598354557abSToby Isaac /* destroy the labels */ 599354557abSToby Isaac while (next) { 600354557abSToby Isaac DMLabelLink tmp = next->next; 601354557abSToby Isaac 6025d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 603ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 6049566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 6059566063dSJacob Faibussowitsch PetscCall(PetscFree(next)); 606354557abSToby Isaac next = tmp; 607354557abSToby Isaac } 6085d80c0bfSVaclav Hapla dm->labels = NULL; 6093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 610354557abSToby Isaac } 611354557abSToby Isaac 61266976f2fSJacob Faibussowitsch static PetscErrorCode DMDestroyCoordinates_Private(DMCoordinates *c) 613d71ae5a4SJacob Faibussowitsch { 6146858538eSMatthew G. Knepley PetscFunctionBegin; 6156858538eSMatthew G. Knepley c->dim = PETSC_DEFAULT; 6166858538eSMatthew G. Knepley PetscCall(DMDestroy(&c->dm)); 6176858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->x)); 6186858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->xl)); 6196858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&c->field)); 6203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6216858538eSMatthew G. Knepley } 6226858538eSMatthew G. Knepley 6231fb7b255SJunchao Zhang /*@C 624bb7acecfSBarry Smith DMDestroy - Destroys a `DM`. 62547c6ae99SBarry Smith 62620f4b53cSBarry Smith Collective 62747c6ae99SBarry Smith 62847c6ae99SBarry Smith Input Parameter: 629bb7acecfSBarry Smith . dm - the `DM` object to destroy 63047c6ae99SBarry Smith 63147c6ae99SBarry Smith Level: developer 63247c6ae99SBarry Smith 6331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMType`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 63447c6ae99SBarry Smith @*/ 635d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroy(DM *dm) 636d71ae5a4SJacob Faibussowitsch { 6376eb26441SStefano Zampini PetscInt cnt; 63847c6ae99SBarry Smith 63947c6ae99SBarry Smith PetscFunctionBegin; 6403ba16761SJacob Faibussowitsch if (!*dm) PetscFunctionReturn(PETSC_SUCCESS); 6416bf464f9SBarry Smith PetscValidHeaderSpecific((*dm), DM_CLASSID, 1); 64287e657c6SBarry Smith 64388bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 64462e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(*dm, PETSC_TRUE, PETSC_TRUE, &cnt)); 64588bdff64SToby Isaac --((PetscObject)(*dm))->refct; 6469371c9d4SSatish Balay if (--cnt > 0) { 6479371c9d4SSatish Balay *dm = NULL; 6483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6499371c9d4SSatish Balay } 6503ba16761SJacob Faibussowitsch if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(PETSC_SUCCESS); 6516bf464f9SBarry Smith ((PetscObject)(*dm))->refct = 0; 6526eb26441SStefano Zampini 6539566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(*dm)); 6549566063dSJacob Faibussowitsch PetscCall(DMClearLocalVectors(*dm)); 655974ca4ecSStefano Zampini PetscCall(DMClearNamedGlobalVectors(*dm)); 656974ca4ecSStefano Zampini PetscCall(DMClearNamedLocalVectors(*dm)); 6572348bcf4SPeter Brune 658b17ce1afSJed Brown /* Destroy the list of hooks */ 659c833c3b5SJed Brown { 660c833c3b5SJed Brown DMCoarsenHookLink link, next; 661b17ce1afSJed Brown for (link = (*dm)->coarsenhook; link; link = next) { 662b17ce1afSJed Brown next = link->next; 6639566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 664b17ce1afSJed Brown } 6650298fd71SBarry Smith (*dm)->coarsenhook = NULL; 666c833c3b5SJed Brown } 667c833c3b5SJed Brown { 668c833c3b5SJed Brown DMRefineHookLink link, next; 669c833c3b5SJed Brown for (link = (*dm)->refinehook; link; link = next) { 670c833c3b5SJed Brown next = link->next; 6719566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 672c833c3b5SJed Brown } 6730298fd71SBarry Smith (*dm)->refinehook = NULL; 674c833c3b5SJed Brown } 675be081cd6SPeter Brune { 676be081cd6SPeter Brune DMSubDomainHookLink link, next; 677be081cd6SPeter Brune for (link = (*dm)->subdomainhook; link; link = next) { 678be081cd6SPeter Brune next = link->next; 6799566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 680be081cd6SPeter Brune } 6810298fd71SBarry Smith (*dm)->subdomainhook = NULL; 682be081cd6SPeter Brune } 683baf369e7SPeter Brune { 684baf369e7SPeter Brune DMGlobalToLocalHookLink link, next; 685baf369e7SPeter Brune for (link = (*dm)->gtolhook; link; link = next) { 686baf369e7SPeter Brune next = link->next; 6879566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 688baf369e7SPeter Brune } 6890298fd71SBarry Smith (*dm)->gtolhook = NULL; 690baf369e7SPeter Brune } 691d4d07f1eSToby Isaac { 692d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, next; 693d4d07f1eSToby Isaac for (link = (*dm)->ltoghook; link; link = next) { 694d4d07f1eSToby Isaac next = link->next; 6959566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 696d4d07f1eSToby Isaac } 697d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 698d4d07f1eSToby Isaac } 699aa1993deSMatthew G Knepley /* Destroy the work arrays */ 700aa1993deSMatthew G Knepley { 701aa1993deSMatthew G Knepley DMWorkLink link, next; 702936381afSPierre Jolivet PetscCheck(!(*dm)->workout, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Work array still checked out %p %p", (void *)(*dm)->workout, (void *)(*dm)->workout->mem); 703aa1993deSMatthew G Knepley for (link = (*dm)->workin; link; link = next) { 704aa1993deSMatthew G Knepley next = link->next; 7059566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 7069566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 707aa1993deSMatthew G Knepley } 7080298fd71SBarry Smith (*dm)->workin = NULL; 709aa1993deSMatthew G Knepley } 710c58f1c22SToby Isaac /* destroy the labels */ 7119566063dSJacob Faibussowitsch PetscCall(DMDestroyLabelLinkList_Internal(*dm)); 712f4cdcedcSVaclav Hapla /* destroy the fields */ 7139566063dSJacob Faibussowitsch PetscCall(DMClearFields(*dm)); 714f4cdcedcSVaclav Hapla /* destroy the boundaries */ 715e6f8dbb6SToby Isaac { 716e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 717e6f8dbb6SToby Isaac while (next) { 718e6f8dbb6SToby Isaac DMBoundary b = next; 719e6f8dbb6SToby Isaac 720e6f8dbb6SToby Isaac next = b->next; 7219566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 722e6f8dbb6SToby Isaac } 723e6f8dbb6SToby Isaac } 724b17ce1afSJed Brown 7259566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmksp)); 7269566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmsnes)); 7279566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmts)); 72852536dc3SBarry Smith 72948a46eb9SPierre Jolivet if ((*dm)->ctx && (*dm)->ctxdestroy) PetscCall((*(*dm)->ctxdestroy)(&(*dm)->ctx)); 7309566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&(*dm)->fd)); 7319566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap)); 7329566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->vectype)); 7339566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->mattype)); 73488ed4aceSMatthew G Knepley 7359566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->localSection)); 7369566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->globalSection)); 7379566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&(*dm)->map)); 7389566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->defaultConstraint.section)); 7399566063dSJacob Faibussowitsch PetscCall(MatDestroy(&(*dm)->defaultConstraint.mat)); 7409566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sf)); 7419566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sectionSF)); 74248a46eb9SPierre Jolivet if ((*dm)->sfNatural) PetscCall(PetscSFDestroy(&(*dm)->sfNatural)); 7439566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)(*dm)->sfMigration)); 7449a2a23afSMatthew G. Knepley { 7459a2a23afSMatthew G. Knepley Vec *auxData; 7469a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 7479a2a23afSMatthew G. Knepley 7489566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize((*dm)->auxData, &n)); 7499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &auxData)); 7509566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetVals((*dm)->auxData, &off, auxData)); 7519566063dSJacob Faibussowitsch for (i = 0; i < n; ++i) PetscCall(VecDestroy(&auxData[i])); 7529566063dSJacob Faibussowitsch PetscCall(PetscFree(auxData)); 7539566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&(*dm)->auxData)); 7549a2a23afSMatthew G. Knepley } 75548a46eb9SPierre Jolivet if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) PetscCall(DMSetFineDM((*dm)->coarseMesh, NULL)); 7566eb26441SStefano Zampini 7579566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->coarseMesh)); 75848a46eb9SPierre Jolivet if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) PetscCall(DMSetCoarseDM((*dm)->fineMesh, NULL)); 7599566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->fineMesh)); 7604fb89dddSMatthew G. Knepley PetscCall(PetscFree((*dm)->Lstart)); 7619566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->L)); 7629566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->maxCell)); 7636858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[0])); 7646858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[1])); 7659566063dSJacob Faibussowitsch if ((*dm)->transformDestroy) PetscCall((*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx)); 7669566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->transformDM)); 7679566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*dm)->transform)); 7686725e60dSJed Brown PetscCall(VecScatterDestroy(&(*dm)->periodic.affine_to_local)); 7696725e60dSJed Brown PetscCall(VecDestroy(&(*dm)->periodic.affine)); 7706636e97aSMatthew G Knepley 7719566063dSJacob Faibussowitsch PetscCall(DMClearDS(*dm)); 7729566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->dmBC)); 773e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 7749566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*dm)); 775732e2eb9SMatthew G Knepley 77648a46eb9SPierre Jolivet if ((*dm)->ops->destroy) PetscCall((*(*dm)->ops->destroy)(*dm)); 7779566063dSJacob Faibussowitsch PetscCall(DMMonitorCancel(*dm)); 778d2b2dc1eSMatthew G. Knepley PetscCall(DMCeedDestroy(&(*dm)->dmceed)); 779f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 7809566063dSJacob Faibussowitsch PetscCallCEED(CeedElemRestrictionDestroy(&(*dm)->ceedERestrict)); 7819566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*dm)->ceed)); 782f918ec44SMatthew G. Knepley #endif 783435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 7849566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(dm)); 7853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78647c6ae99SBarry Smith } 78747c6ae99SBarry Smith 788d7bf68aeSBarry Smith /*@ 789bb7acecfSBarry Smith DMSetUp - sets up the data structures inside a `DM` object 790d7bf68aeSBarry Smith 79120f4b53cSBarry Smith Collective 792d7bf68aeSBarry Smith 793d7bf68aeSBarry Smith Input Parameter: 794bb7acecfSBarry Smith . dm - the `DM` object to setup 795d7bf68aeSBarry Smith 796bb7acecfSBarry Smith Level: intermediate 797d7bf68aeSBarry Smith 798bb7acecfSBarry Smith Note: 799bb7acecfSBarry Smith This is usually called after various parameter setting operations and `DMSetFromOptions()` are called on the `DM` 800bb7acecfSBarry Smith 8011cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 802d7bf68aeSBarry Smith @*/ 803d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUp(DM dm) 804d71ae5a4SJacob Faibussowitsch { 805d7bf68aeSBarry Smith PetscFunctionBegin; 806171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8073ba16761SJacob Faibussowitsch if (dm->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 808dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setup); 8098387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 8103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 811d7bf68aeSBarry Smith } 812d7bf68aeSBarry Smith 813d7bf68aeSBarry Smith /*@ 814bb7acecfSBarry Smith DMSetFromOptions - sets parameters in a `DM` from the options database 815d7bf68aeSBarry Smith 81620f4b53cSBarry Smith Collective 817d7bf68aeSBarry Smith 818d7bf68aeSBarry Smith Input Parameter: 819bb7acecfSBarry Smith . dm - the `DM` object to set options for 820d7bf68aeSBarry Smith 82120f4b53cSBarry Smith Options Database Keys: 822bb7acecfSBarry Smith + -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 823bb7acecfSBarry Smith . -dm_vec_type <type> - type of vector to create inside `DM` 824bb7acecfSBarry Smith . -dm_mat_type <type> - type of matrix to create inside `DM` 825a4ea9b21SRichard Tran Mills . -dm_is_coloring_type - <global or local> 82620f4b53cSBarry 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` 82720f4b53cSBarry Smith . -dm_plex_filename <str> - File containing a mesh 8289318fe57SMatthew G. Knepley . -dm_plex_boundary_filename <str> - File containing a mesh boundary 829cd7e8a5eSksagiyam . -dm_plex_name <str> - Name of the mesh in the file 8305dca41c3SJed Brown . -dm_plex_shape <shape> - The domain shape, such as `BOX`, `SPHERE`, etc. 8319318fe57SMatthew G. Knepley . -dm_plex_cell <ct> - Cell shape 8329318fe57SMatthew G. Knepley . -dm_plex_reference_cell_domain <bool> - Use a reference cell domain 8339318fe57SMatthew G. Knepley . -dm_plex_dim <dim> - Set the topological dimension 834bb7acecfSBarry Smith . -dm_plex_simplex <bool> - `PETSC_TRUE` for simplex elements, `PETSC_FALSE` for tensor elements 835bb7acecfSBarry Smith . -dm_plex_interpolate <bool> - `PETSC_TRUE` turns on topological interpolation (creating edges and faces) 8369318fe57SMatthew G. Knepley . -dm_plex_scale <sc> - Scale factor for mesh coordinates 8379318fe57SMatthew G. Knepley . -dm_plex_box_faces <m,n,p> - Number of faces along each dimension 8389318fe57SMatthew G. Knepley . -dm_plex_box_lower <x,y,z> - Specify lower-left-bottom coordinates for the box 8399318fe57SMatthew G. Knepley . -dm_plex_box_upper <x,y,z> - Specify upper-right-top coordinates for the box 840bb7acecfSBarry Smith . -dm_plex_box_bd <bx,by,bz> - Specify the `DMBoundaryType` for each direction 8419318fe57SMatthew G. Knepley . -dm_plex_sphere_radius <r> - The sphere radius 8429318fe57SMatthew G. Knepley . -dm_plex_ball_radius <r> - Radius of the ball 8439318fe57SMatthew G. Knepley . -dm_plex_cylinder_bd <bz> - Boundary type in the z direction 8449318fe57SMatthew G. Knepley . -dm_plex_cylinder_num_wedges <n> - Number of wedges around the cylinder 845bdf63967SMatthew G. Knepley . -dm_plex_reorder <order> - Reorder the mesh using the specified algorithm 8469318fe57SMatthew G. Knepley . -dm_refine_pre <n> - The number of refinements before distribution 8479318fe57SMatthew G. Knepley . -dm_refine_uniform_pre <bool> - Flag for uniform refinement before distribution 8489318fe57SMatthew G. Knepley . -dm_refine_volume_limit_pre <v> - The maximum cell volume after refinement before distribution 8499318fe57SMatthew G. Knepley . -dm_refine <n> - The number of refinements after distribution 850bdf63967SMatthew G. Knepley . -dm_extrude <l> - Activate extrusion and specify the number of layers to extrude 851d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers 852d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding 853d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface 854d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction 855d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer 856909dfd52SMatthew G. Knepley . -dm_plex_create_fv_ghost_cells - Flag to create finite volume ghost cells on the boundary 857909dfd52SMatthew G. Knepley . -dm_plex_fv_ghost_cells_label <name> - Label name for ghost cells boundary 8589318fe57SMatthew G. Knepley . -dm_distribute <bool> - Flag to redistribute a mesh among processes 8599318fe57SMatthew G. Knepley . -dm_distribute_overlap <n> - The size of the overlap halo 8609318fe57SMatthew G. Knepley . -dm_plex_adj_cone <bool> - Set adjacency direction 86120f4b53cSBarry Smith . -dm_plex_adj_closure <bool> - Set adjacency size 862d2b2dc1eSMatthew G. Knepley . -dm_plex_use_ceed <bool> - Use LibCEED as the FEM backend 86320f4b53cSBarry Smith . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - `DMPlexCheckSymmetry()` 864bb7acecfSBarry Smith . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - `DMPlexCheckSkeleton()` 865bb7acecfSBarry 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()` 866bb7acecfSBarry Smith . -dm_plex_check_geometry - Check that cells have positive volume - `DMPlexCheckGeometry()` 867bb7acecfSBarry Smith . -dm_plex_check_pointsf - Check some necessary conditions for `PointSF` - `DMPlexCheckPointSF()` 868bb7acecfSBarry Smith . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - `DMPlexCheckInterfaceCones()` 869384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 870d7bf68aeSBarry Smith 87195eb5ee5SVaclav Hapla Level: intermediate 87295eb5ee5SVaclav Hapla 8731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 874bb7acecfSBarry Smith `DMPlexCheckSymmetry()`, `DMPlexCheckSkeleton()`, `DMPlexCheckFaces()`, `DMPlexCheckGeometry()`, `DMPlexCheckPointSF()`, `DMPlexCheckInterfaceCones()`, 87560225df5SJacob Faibussowitsch `DMSetOptionsPrefix()`, `DMType`, `DMPLEX`, `DMDA` 876d7bf68aeSBarry Smith @*/ 877d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFromOptions(DM dm) 878d71ae5a4SJacob Faibussowitsch { 8797781c08eSBarry Smith char typeName[256]; 880ca266f36SBarry Smith PetscBool flg; 881d7bf68aeSBarry Smith 882d7bf68aeSBarry Smith PetscFunctionBegin; 883171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 88449be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 8859566063dSJacob Faibussowitsch if (dm->sf) PetscCall(PetscSFSetFromOptions(dm->sf)); 8869566063dSJacob Faibussowitsch if (dm->sectionSF) PetscCall(PetscSFSetFromOptions(dm->sectionSF)); 887dd4c3f67SMatthew G. Knepley if (dm->coordinates[0].dm) PetscCall(DMSetFromOptions(dm->coordinates[0].dm)); 888d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)dm); 8899566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-dm_preallocate_only", "only preallocate matrix, but do not set column indices", "DMSetMatrixPreallocateOnly", dm->prealloc_only, &dm->prealloc_only, NULL)); 8909566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_vec_type", "Vector type used for created vectors", "DMSetVecType", VecList, dm->vectype, typeName, 256, &flg)); 8911baa6e33SBarry Smith if (flg) PetscCall(DMSetVecType(dm, typeName)); 8929566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_mat_type", "Matrix type used for created matrices", "DMSetMatType", MatList, dm->mattype ? dm->mattype : typeName, typeName, sizeof(typeName), &flg)); 8931baa6e33SBarry Smith if (flg) PetscCall(DMSetMatType(dm, typeName)); 894863027abSJed Brown PetscCall(PetscOptionsEnum("-dm_blocking_type", "Topological point or field node blocking", "DMSetBlockingType", DMBlockingTypes, (PetscEnum)dm->blocking_type, (PetscEnum *)&dm->blocking_type, NULL)); 8959566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-dm_is_coloring_type", "Global or local coloring of Jacobian", "DMSetISColoringType", ISColoringTypes, (PetscEnum)dm->coloringtype, (PetscEnum *)&dm->coloringtype, NULL)); 8969566063dSJacob 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)); 897dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setfromoptions, PetscOptionsObject); 898f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 899dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)dm, PetscOptionsObject)); 900d0609cedSBarry Smith PetscOptionsEnd(); 9013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 902d7bf68aeSBarry Smith } 903d7bf68aeSBarry Smith 904fc9bc008SSatish Balay /*@C 905bb7acecfSBarry Smith DMViewFromOptions - View a `DM` in a particular way based on a request in the options database 906fe2efc57SMark 90720f4b53cSBarry Smith Collective 908fe2efc57SMark 909fe2efc57SMark Input Parameters: 910bb7acecfSBarry Smith + dm - the `DM` object 91120f4b53cSBarry Smith . obj - optional object that provides the prefix for the options database (if `NULL` then the prefix in obj is used) 91260225df5SJacob Faibussowitsch - name - option string that is used to activate viewing 913fe2efc57SMark 914fe2efc57SMark Level: intermediate 915bb7acecfSBarry Smith 916bb7acecfSBarry Smith Note: 917bb7acecfSBarry Smith See `PetscObjectViewFromOptions()` for a list of values that can be provided in the options database to determine how the `DM` is viewed 918bb7acecfSBarry Smith 91960225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `PetscObjectViewFromOptions()`, `DMCreate()` 920fe2efc57SMark @*/ 921d71ae5a4SJacob Faibussowitsch PetscErrorCode DMViewFromOptions(DM dm, PetscObject obj, const char name[]) 922d71ae5a4SJacob Faibussowitsch { 923fe2efc57SMark PetscFunctionBegin; 924fe2efc57SMark PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9259566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)dm, obj, name)); 9263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 927fe2efc57SMark } 928fe2efc57SMark 929fe2efc57SMark /*@C 930bb7acecfSBarry 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 931bb7acecfSBarry Smith save the `DM` in a binary file to be loaded later or create a visualization of the `DM` 93247c6ae99SBarry Smith 93320f4b53cSBarry Smith Collective 93447c6ae99SBarry Smith 935d8d19677SJose E. Roman Input Parameters: 936bb7acecfSBarry Smith + dm - the `DM` object to view 93747c6ae99SBarry Smith - v - the viewer 93847c6ae99SBarry Smith 93920f4b53cSBarry Smith Level: beginner 94020f4b53cSBarry Smith 941cd7e8a5eSksagiyam Notes: 942bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` as the `PetscViewerFormat` one can save multiple `DMPLEX` 943bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 944bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 945cd7e8a5eSksagiyam 9461cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewer`, `PetscViewerFormat`, `PetscViewerSetFormat()`, `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMLoad()`, `PetscObjectSetName()` 94747c6ae99SBarry Smith @*/ 948d71ae5a4SJacob Faibussowitsch PetscErrorCode DMView(DM dm, PetscViewer v) 949d71ae5a4SJacob Faibussowitsch { 95032c0f0efSBarry Smith PetscBool isbinary; 95176a8abe0SBarry Smith PetscMPIInt size; 95276a8abe0SBarry Smith PetscViewerFormat format; 95347c6ae99SBarry Smith 95447c6ae99SBarry Smith PetscFunctionBegin; 955171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95648a46eb9SPierre Jolivet if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm), &v)); 957b1b135c8SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 95874903a4fSStefano Zampini /* Ideally, we would like to have this test on. 95974903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 96074903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 96174903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 96274903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 96374903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 96474903a4fSStefano Zampini in an error here */ 96574903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9669566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckWritable(v)); 967b1b135c8SBarry Smith 9689566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(v, &format)); 9699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 9703ba16761SJacob Faibussowitsch if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS); 9719566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)dm, v)); 9729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERBINARY, &isbinary)); 97332c0f0efSBarry Smith if (isbinary) { 97455849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 97532c0f0efSBarry Smith char type[256]; 97632c0f0efSBarry Smith 9779566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, &classid, 1, PETSC_INT)); 978c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(type, ((PetscObject)dm)->type_name, sizeof(type))); 9799566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, type, 256, PETSC_CHAR)); 98032c0f0efSBarry Smith } 981dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, view, v); 9823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98347c6ae99SBarry Smith } 98447c6ae99SBarry Smith 98547c6ae99SBarry Smith /*@ 986bb7acecfSBarry 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, 987bb7acecfSBarry Smith that is it has no ghost locations. 98847c6ae99SBarry Smith 98920f4b53cSBarry Smith Collective 99047c6ae99SBarry Smith 99147c6ae99SBarry Smith Input Parameter: 992bb7acecfSBarry Smith . dm - the `DM` object 99347c6ae99SBarry Smith 99447c6ae99SBarry Smith Output Parameter: 99547c6ae99SBarry Smith . vec - the global vector 99647c6ae99SBarry Smith 997073dac72SJed Brown Level: beginner 99847c6ae99SBarry Smith 9991cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1000bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 100147c6ae99SBarry Smith @*/ 1002d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector(DM dm, Vec *vec) 1003d71ae5a4SJacob Faibussowitsch { 100447c6ae99SBarry Smith PetscFunctionBegin; 1005171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10064f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1007dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createglobalvector, vec); 100876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1009c6b011d8SStefano Zampini DM vdm; 1010c6b011d8SStefano Zampini 10119566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10127a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1013c6b011d8SStefano Zampini } 10143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 101547c6ae99SBarry Smith } 101647c6ae99SBarry Smith 101747c6ae99SBarry Smith /*@ 1018bb7acecfSBarry Smith DMCreateLocalVector - Creates a local vector from a `DM` object. 101947c6ae99SBarry Smith 102047c6ae99SBarry Smith Not Collective 102147c6ae99SBarry Smith 102247c6ae99SBarry Smith Input Parameter: 1023bb7acecfSBarry Smith . dm - the `DM` object 102447c6ae99SBarry Smith 102547c6ae99SBarry Smith Output Parameter: 102647c6ae99SBarry Smith . vec - the local vector 102747c6ae99SBarry Smith 1028073dac72SJed Brown Level: beginner 102947c6ae99SBarry Smith 103020f4b53cSBarry Smith Note: 1031bb7acecfSBarry 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. 1032bb7acecfSBarry Smith 10331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateGlobalVector()`, `DMGetLocalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 1034bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 103547c6ae99SBarry Smith @*/ 1036d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector(DM dm, Vec *vec) 1037d71ae5a4SJacob Faibussowitsch { 103847c6ae99SBarry Smith PetscFunctionBegin; 1039171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10404f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1041dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalvector, vec); 104276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1043c6b011d8SStefano Zampini DM vdm; 1044c6b011d8SStefano Zampini 10459566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10467a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_LIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1047c6b011d8SStefano Zampini } 10483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 104947c6ae99SBarry Smith } 105047c6ae99SBarry Smith 10511411c6eeSJed Brown /*@ 1052bb7acecfSBarry Smith DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a `DM`. 10531411c6eeSJed Brown 105420f4b53cSBarry Smith Collective 10551411c6eeSJed Brown 10561411c6eeSJed Brown Input Parameter: 1057bb7acecfSBarry Smith . dm - the `DM` that provides the mapping 10581411c6eeSJed Brown 10591411c6eeSJed Brown Output Parameter: 10601411c6eeSJed Brown . ltog - the mapping 10611411c6eeSJed Brown 1062bb7acecfSBarry Smith Level: advanced 10631411c6eeSJed Brown 10641411c6eeSJed Brown Notes: 1065bb7acecfSBarry Smith The global to local mapping allows one to set values into the global vector or matrix using `VecSetValuesLocal()` and `MatSetValuesLocal()` 10661411c6eeSJed Brown 1067bb7acecfSBarry Smith Vectors obtained with `DMCreateGlobalVector()` and matrices obtained with `DMCreateMatrix()` already contain the global mapping so you do 1068bb7acecfSBarry Smith need to use this function with those objects. 1069bb7acecfSBarry Smith 1070bb7acecfSBarry Smith This mapping can then be used by `VecSetLocalToGlobalMapping()` or `MatSetLocalToGlobalMapping()`. 1071bb7acecfSBarry Smith 107260225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `VecSetLocalToGlobalMapping()`, `MatSetLocalToGlobalMapping()`, 1073bb7acecfSBarry Smith `DMCreateMatrix()` 10741411c6eeSJed Brown @*/ 1075d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalToGlobalMapping(DM dm, ISLocalToGlobalMapping *ltog) 1076d71ae5a4SJacob Faibussowitsch { 10770be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 10781411c6eeSJed Brown 10791411c6eeSJed Brown PetscFunctionBegin; 10801411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10814f572ea9SToby Isaac PetscAssertPointer(ltog, 2); 10821411c6eeSJed Brown if (!dm->ltogmap) { 108337d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 108437d0c07bSMatthew G Knepley 10859566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 108637d0c07bSMatthew G Knepley if (section) { 1087a974ec88SMatthew G. Knepley const PetscInt *cdofs; 108837d0c07bSMatthew G Knepley PetscInt *ltog; 1089ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 109037d0c07bSMatthew G Knepley 10919566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 10929566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 10939566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(section, &n)); 10949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, <og)); /* We want the local+overlap size */ 109537d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1096e6befd46SJed Brown PetscInt bdof, cdof, dof, off, c, cind; 109737d0c07bSMatthew G Knepley 109837d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 10999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(section, p, &dof)); 11009566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(section, p, &cdof)); 11019566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(section, p, &cdofs)); 11029566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &off)); 11031a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 11041a7dc684SMatthew G. Knepley bdof = cdof && (dof - cdof) ? 1 : dof; 1105ad540459SPierre Jolivet if (dof) bs = bs < 0 ? bdof : PetscGCD(bs, bdof); 11065227eafbSStefano Zampini 1107e6befd46SJed Brown for (c = 0, cind = 0; c < dof; ++c, ++l) { 11085227eafbSStefano Zampini if (cind < cdof && c == cdofs[cind]) { 1109e6befd46SJed Brown ltog[l] = off < 0 ? off - c : -(off + c + 1); 1110e6befd46SJed Brown cind++; 1111e6befd46SJed Brown } else { 11125227eafbSStefano Zampini ltog[l] = (off < 0 ? -(off + 1) : off) + c - cind; 1113e6befd46SJed Brown } 111437d0c07bSMatthew G Knepley } 111537d0c07bSMatthew G Knepley } 1116bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 11179371c9d4SSatish Balay bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; 11189371c9d4SSatish Balay bsLocal[1] = bs; 11199566063dSJacob Faibussowitsch PetscCall(PetscGlobalMinMaxInt(PetscObjectComm((PetscObject)dm), bsLocal, bsMinMax)); 11209371c9d4SSatish Balay if (bsMinMax[0] != bsMinMax[1]) { 11219371c9d4SSatish Balay bs = 1; 11229371c9d4SSatish Balay } else { 11239371c9d4SSatish Balay bs = bsMinMax[0]; 11249371c9d4SSatish Balay } 11257591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 11267591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1127ccf3bd66SMatthew G. Knepley if (bs > 1) { 1128ca469d19SJed Brown for (l = 0, k = 0; l < n; l += bs, ++k) { 1129ca469d19SJed Brown // Integer division of negative values truncates toward zero(!), not toward negative infinity 1130ca469d19SJed Brown ltog[k] = ltog[l] >= 0 ? ltog[l] / bs : -(-(ltog[l] + 1) / bs + 1); 1131ca469d19SJed Brown } 1132ccf3bd66SMatthew G. Knepley n /= bs; 1133ccf3bd66SMatthew G. Knepley } 11349566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap)); 1135dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, getlocaltoglobalmapping); 113637d0c07bSMatthew G Knepley } 11371411c6eeSJed Brown *ltog = dm->ltogmap; 11383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11391411c6eeSJed Brown } 11401411c6eeSJed Brown 11411411c6eeSJed Brown /*@ 1142bb7acecfSBarry Smith DMGetBlockSize - Gets the inherent block size associated with a `DM` 11431411c6eeSJed Brown 11441411c6eeSJed Brown Not Collective 11451411c6eeSJed Brown 11461411c6eeSJed Brown Input Parameter: 1147bb7acecfSBarry Smith . dm - the `DM` with block structure 11481411c6eeSJed Brown 11491411c6eeSJed Brown Output Parameter: 11501411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11511411c6eeSJed Brown 11521411c6eeSJed Brown Level: intermediate 11531411c6eeSJed Brown 1154bb7acecfSBarry Smith Note: 1155bb7acecfSBarry Smith This might be the number of degrees of freedom at each grid point for a structured grid. 1156bb7acecfSBarry Smith 1157bb7acecfSBarry Smith Complex `DM` that represent multiphysics or staggered grids or mixed-methods do not generally have a single inherent block size, but 1158bb7acecfSBarry Smith rather different locations in the vectors may have a different block size. 1159bb7acecfSBarry Smith 11601cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISCreateBlock()`, `VecSetBlockSize()`, `MatSetBlockSize()`, `DMGetLocalToGlobalMapping()` 11611411c6eeSJed Brown @*/ 1162d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBlockSize(DM dm, PetscInt *bs) 1163d71ae5a4SJacob Faibussowitsch { 11641411c6eeSJed Brown PetscFunctionBegin; 11651411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11664f572ea9SToby Isaac PetscAssertPointer(bs, 2); 11677a8be351SBarry Smith PetscCheck(dm->bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM does not have enough information to provide a block size yet"); 11681411c6eeSJed Brown *bs = dm->bs; 11693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11701411c6eeSJed Brown } 11711411c6eeSJed Brown 117248eeb7c8SBarry Smith /*@C 1173bb7acecfSBarry Smith DMCreateInterpolation - Gets the interpolation matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1174bb7acecfSBarry Smith `DMCreateGlobalVector()` on the coarse `DM` to similar vectors on the fine grid `DM`. 117547c6ae99SBarry Smith 117620f4b53cSBarry Smith Collective 117747c6ae99SBarry Smith 1178d8d19677SJose E. Roman Input Parameters: 1179bb7acecfSBarry Smith + dmc - the `DM` object 1180bb7acecfSBarry Smith - dmf - the second, finer `DM` object 118147c6ae99SBarry Smith 1182d8d19677SJose E. Roman Output Parameters: 118347c6ae99SBarry Smith + mat - the interpolation 1184bb7acecfSBarry Smith - vec - the scaling (optional), see `DMCreateInterpolationScale()` 118547c6ae99SBarry Smith 118647c6ae99SBarry Smith Level: developer 118747c6ae99SBarry Smith 118895452b02SPatrick Sanan Notes: 1189bb7acecfSBarry 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 1190bb7acecfSBarry Smith DMCoarsen(). The coordinates set into the `DMDA` are completely ignored in computing the interpolation. 1191d52bd9f3SBarry Smith 1192bb7acecfSBarry Smith For `DMDA` objects you can use this interpolation (more precisely the interpolation from the `DMGetCoordinateDM()`) to interpolate the mesh coordinate 1193bb7acecfSBarry Smith vectors EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 119485afcc9aSBarry Smith 11951cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolationScale()` 119647c6ae99SBarry Smith @*/ 1197d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolation(DM dmc, DM dmf, Mat *mat, Vec *vec) 1198d71ae5a4SJacob Faibussowitsch { 119947c6ae99SBarry Smith PetscFunctionBegin; 1200a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1201a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 12024f572ea9SToby Isaac PetscAssertPointer(mat, 3); 12039566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInterpolation, dmc, dmf, 0, 0)); 1204dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createinterpolation, dmf, mat, vec); 12059566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInterpolation, dmc, dmf, 0, 0)); 12063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 120747c6ae99SBarry Smith } 120847c6ae99SBarry Smith 12093ad4599aSBarry Smith /*@ 1210a4e35b19SJacob Faibussowitsch DMCreateInterpolationScale - Forms L = 1/(R*1) where 1 is the vector of all ones, and R is 1211a4e35b19SJacob Faibussowitsch the transpose of the interpolation between the `DM`. 12122ed6491fSPatrick Sanan 12132ed6491fSPatrick Sanan Input Parameters: 1214bb7acecfSBarry Smith + dac - `DM` that defines a coarse mesh 1215bb7acecfSBarry Smith . daf - `DM` that defines a fine mesh 12162ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 12172ed6491fSPatrick Sanan 12182ed6491fSPatrick Sanan Output Parameter: 12192ed6491fSPatrick Sanan . scale - the scaled vector 12202ed6491fSPatrick Sanan 1221bb7acecfSBarry Smith Level: advanced 12222ed6491fSPatrick Sanan 1223a4e35b19SJacob Faibussowitsch Notes: 1224a4e35b19SJacob Faibussowitsch xcoarse = diag(L)*R*xfine preserves scale and is thus suitable for state (versus residual) 1225a4e35b19SJacob Faibussowitsch restriction. In other words xcoarse is the coarse representation of xfine. 1226a4e35b19SJacob Faibussowitsch 122760225df5SJacob Faibussowitsch Developer Notes: 1228bb7acecfSBarry Smith If the fine-scale `DMDA` has the -dm_bind_below option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 1229e9c74fd6SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 1230e9c74fd6SRichard Tran Mills 123160225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `MatRestrict()`, `MatInterpolate()`, `DMCreateInterpolation()`, `DMCreateRestriction()`, `DMCreateGlobalVector()` 12322ed6491fSPatrick Sanan @*/ 1233d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolationScale(DM dac, DM daf, Mat mat, Vec *scale) 1234d71ae5a4SJacob Faibussowitsch { 12352ed6491fSPatrick Sanan Vec fine; 12362ed6491fSPatrick Sanan PetscScalar one = 1.0; 12379704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 1238e9c74fd6SRichard Tran Mills PetscBool bindingpropagates, isbound; 12399704db99SRichard Tran Mills #endif 12402ed6491fSPatrick Sanan 12412ed6491fSPatrick Sanan PetscFunctionBegin; 12429566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(daf, &fine)); 12439566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dac, scale)); 12449566063dSJacob Faibussowitsch PetscCall(VecSet(fine, one)); 12459704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 12469704db99SRichard Tran Mills /* If the 'fine' Vec is bound to the CPU, it makes sense to bind 'mat' as well. 12479704db99SRichard Tran Mills * Note that we only do this for the CUDA case, right now, but if we add support for MatMultTranspose() via ViennaCL, 12489704db99SRichard Tran Mills * we'll need to do it for that case, too.*/ 12499566063dSJacob Faibussowitsch PetscCall(VecGetBindingPropagates(fine, &bindingpropagates)); 1250e9c74fd6SRichard Tran Mills if (bindingpropagates) { 12519566063dSJacob Faibussowitsch PetscCall(MatSetBindingPropagates(mat, PETSC_TRUE)); 12529566063dSJacob Faibussowitsch PetscCall(VecBoundToCPU(fine, &isbound)); 12539566063dSJacob Faibussowitsch PetscCall(MatBindToCPU(mat, isbound)); 125483aa49f4SRichard Tran Mills } 12559704db99SRichard Tran Mills #endif 12569566063dSJacob Faibussowitsch PetscCall(MatRestrict(mat, fine, *scale)); 12579566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fine)); 12589566063dSJacob Faibussowitsch PetscCall(VecReciprocal(*scale)); 12593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12602ed6491fSPatrick Sanan } 12612ed6491fSPatrick Sanan 12622ed6491fSPatrick Sanan /*@ 1263bb7acecfSBarry Smith DMCreateRestriction - Gets restriction matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1264bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine `DM` to similar vectors on the coarse grid `DM`. 12653ad4599aSBarry Smith 126620f4b53cSBarry Smith Collective 12673ad4599aSBarry Smith 1268d8d19677SJose E. Roman Input Parameters: 1269bb7acecfSBarry Smith + dmc - the `DM` object 1270bb7acecfSBarry Smith - dmf - the second, finer `DM` object 12713ad4599aSBarry Smith 12723ad4599aSBarry Smith Output Parameter: 12733ad4599aSBarry Smith . mat - the restriction 12743ad4599aSBarry Smith 12753ad4599aSBarry Smith Level: developer 12763ad4599aSBarry Smith 1277bb7acecfSBarry Smith Note: 1278bb7acecfSBarry Smith This only works for `DMSTAG`. For many situations either the transpose of the operator obtained with `DMCreateInterpolation()` or that 1279bb7acecfSBarry Smith matrix multiplied by the vector obtained with `DMCreateInterpolationScale()` provides the desired object. 12803ad4599aSBarry Smith 12811cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRestrict()`, `DMInterpolate()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateInterpolation()` 12823ad4599aSBarry Smith @*/ 1283d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateRestriction(DM dmc, DM dmf, Mat *mat) 1284d71ae5a4SJacob Faibussowitsch { 12853ad4599aSBarry Smith PetscFunctionBegin; 1286a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1287a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 12884f572ea9SToby Isaac PetscAssertPointer(mat, 3); 12899566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateRestriction, dmc, dmf, 0, 0)); 1290dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createrestriction, dmf, mat); 12919566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateRestriction, dmc, dmf, 0, 0)); 12923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12933ad4599aSBarry Smith } 12943ad4599aSBarry Smith 129547c6ae99SBarry Smith /*@ 1296a4e35b19SJacob Faibussowitsch DMCreateInjection - Gets injection matrix between two `DM` objects. 129747c6ae99SBarry Smith 129820f4b53cSBarry Smith Collective 129947c6ae99SBarry Smith 1300d8d19677SJose E. Roman Input Parameters: 1301bb7acecfSBarry Smith + dac - the `DM` object 1302bb7acecfSBarry Smith - daf - the second, finer `DM` object 130347c6ae99SBarry Smith 130447c6ae99SBarry Smith Output Parameter: 13056dbf9973SLawrence Mitchell . mat - the injection 130647c6ae99SBarry Smith 130747c6ae99SBarry Smith Level: developer 130847c6ae99SBarry Smith 1309a4e35b19SJacob Faibussowitsch Notes: 1310a4e35b19SJacob Faibussowitsch This is an operator that applied to a vector obtained with `DMCreateGlobalVector()` on the 1311a4e35b19SJacob Faibussowitsch fine grid maps the values to a vector on the vector on the coarse `DM` by simply selecting 1312a4e35b19SJacob Faibussowitsch the values on the coarse grid points. This compares to the operator obtained by 1313a4e35b19SJacob Faibussowitsch `DMCreateRestriction()` or the transpose of the operator obtained by 1314a4e35b19SJacob Faibussowitsch `DMCreateInterpolation()` that uses a "local weighted average" of the values around the 1315a4e35b19SJacob Faibussowitsch coarse grid point as the coarse grid value. 1316a4e35b19SJacob Faibussowitsch 1317bb7acecfSBarry 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 1318bb7acecfSBarry Smith `DMCoarsen()`. The coordinates set into the `DMDA` are completely ignored in computing the injection. 131985afcc9aSBarry Smith 13201cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateInterpolation()`, 1321bb7acecfSBarry Smith `DMCreateRestriction()`, `MatRestrict()`, `MatInterpolate()` 132247c6ae99SBarry Smith @*/ 1323d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInjection(DM dac, DM daf, Mat *mat) 1324d71ae5a4SJacob Faibussowitsch { 132547c6ae99SBarry Smith PetscFunctionBegin; 1326a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac, DM_CLASSID, 1); 1327a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf, DM_CLASSID, 2); 13284f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13299566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInjection, dac, daf, 0, 0)); 1330dbbe0bcdSBarry Smith PetscUseTypeMethod(dac, createinjection, daf, mat); 13319566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInjection, dac, daf, 0, 0)); 13323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 133347c6ae99SBarry Smith } 133447c6ae99SBarry Smith 1335b412c318SBarry Smith /*@ 1336bb7acecfSBarry 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 1337bb7acecfSBarry Smith a Galerkin finite element model on the `DM` 1338bd041c0cSMatthew G. Knepley 133920f4b53cSBarry Smith Collective 1340bd041c0cSMatthew G. Knepley 1341d8d19677SJose E. Roman Input Parameters: 1342bb7acecfSBarry Smith + dmc - the target `DM` object 1343bb7acecfSBarry Smith - dmf - the source `DM` object 1344bd041c0cSMatthew G. Knepley 1345bd041c0cSMatthew G. Knepley Output Parameter: 1346b4937a87SMatthew G. Knepley . mat - the mass matrix 1347bd041c0cSMatthew G. Knepley 1348bd041c0cSMatthew G. Knepley Level: developer 1349bd041c0cSMatthew G. Knepley 1350bb7acecfSBarry Smith Notes: 1351bb7acecfSBarry Smith For `DMPLEX` the finite element model for the `DM` must have been already provided. 1352bb7acecfSBarry Smith 135320f4b53cSBarry 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()` 1354bb7acecfSBarry Smith 135542747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrixLumped()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1356bd041c0cSMatthew G. Knepley @*/ 1357d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrix(DM dmc, DM dmf, Mat *mat) 1358d71ae5a4SJacob Faibussowitsch { 1359bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1360b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1361b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13624f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13635b8ffe73SMark Adams PetscCall(PetscLogEventBegin(DM_CreateMassMatrix, 0, 0, 0, 0)); 1364dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createmassmatrix, dmf, mat); 13655b8ffe73SMark Adams PetscCall(PetscLogEventEnd(DM_CreateMassMatrix, 0, 0, 0, 0)); 13663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1367b4937a87SMatthew G. Knepley } 1368b4937a87SMatthew G. Knepley 1369b4937a87SMatthew G. Knepley /*@ 1370bb7acecfSBarry Smith DMCreateMassMatrixLumped - Gets the lumped mass matrix for a given `DM` 1371b4937a87SMatthew G. Knepley 137220f4b53cSBarry Smith Collective 1373b4937a87SMatthew G. Knepley 1374b4937a87SMatthew G. Knepley Input Parameter: 1375bb7acecfSBarry Smith . dm - the `DM` object 1376b4937a87SMatthew G. Knepley 1377b4937a87SMatthew G. Knepley Output Parameter: 1378bb7acecfSBarry Smith . lm - the lumped mass matrix, which is a diagonal matrix, represented as a vector 1379b4937a87SMatthew G. Knepley 1380b4937a87SMatthew G. Knepley Level: developer 1381b4937a87SMatthew G. Knepley 1382bb7acecfSBarry Smith Note: 1383bb7acecfSBarry Smith See `DMCreateMassMatrix()` for how to create the non-lumped version of the mass matrix. 1384bb7acecfSBarry Smith 138560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrix()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1386b4937a87SMatthew G. Knepley @*/ 1387d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrixLumped(DM dm, Vec *lm) 1388d71ae5a4SJacob Faibussowitsch { 1389b4937a87SMatthew G. Knepley PetscFunctionBegin; 1390b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 13914f572ea9SToby Isaac PetscAssertPointer(lm, 2); 1392dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createmassmatrixlumped, lm); 13933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1394bd041c0cSMatthew G. Knepley } 1395bd041c0cSMatthew G. Knepley 1396bd041c0cSMatthew G. Knepley /*@ 1397bb7acecfSBarry Smith DMCreateColoring - Gets coloring of a graph associated with the `DM`. Often the graph represents the operator matrix associated with the discretization 1398bb7acecfSBarry Smith of a PDE on the `DM`. 139947c6ae99SBarry Smith 140020f4b53cSBarry Smith Collective 140147c6ae99SBarry Smith 1402d8d19677SJose E. Roman Input Parameters: 1403bb7acecfSBarry Smith + dm - the `DM` object 1404bb7acecfSBarry Smith - ctype - `IS_COLORING_LOCAL` or `IS_COLORING_GLOBAL` 140547c6ae99SBarry Smith 140647c6ae99SBarry Smith Output Parameter: 140747c6ae99SBarry Smith . coloring - the coloring 140847c6ae99SBarry Smith 14091bf8429eSBarry Smith Level: developer 14101bf8429eSBarry Smith 1411ec5066bdSBarry Smith Notes: 1412bb7acecfSBarry 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 1413bb7acecfSBarry Smith matrix comes from (what this function provides). In general using the mesh produces a more optimal coloring (fewer colors). 1414ec5066bdSBarry Smith 1415bb7acecfSBarry Smith This produces a coloring with the distance of 2, see `MatSetColoringDistance()` which can be used for efficiently computing Jacobians with `MatFDColoringCreate()` 14161bf8429eSBarry Smith For `DMDA` in three dimensions with periodic boundary conditions the number of grid points in each dimension must be divisible by 2*stencil_width + 1, 14171bf8429eSBarry Smith otherwise an error will be generated. 1418ec5066bdSBarry Smith 14191cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISColoring`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatType()`, `MatColoring`, `MatFDColoringCreate()` 1420aab9d709SJed Brown @*/ 1421d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateColoring(DM dm, ISColoringType ctype, ISColoring *coloring) 1422d71ae5a4SJacob Faibussowitsch { 142347c6ae99SBarry Smith PetscFunctionBegin; 1424171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14254f572ea9SToby Isaac PetscAssertPointer(coloring, 3); 1426dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getcoloring, ctype, coloring); 14273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 142847c6ae99SBarry Smith } 142947c6ae99SBarry Smith 1430b412c318SBarry Smith /*@ 1431bb7acecfSBarry Smith DMCreateMatrix - Gets an empty matrix for a `DM` that is most commonly used to store the Jacobian of a discrete PDE operator. 143247c6ae99SBarry Smith 143320f4b53cSBarry Smith Collective 143447c6ae99SBarry Smith 143547c6ae99SBarry Smith Input Parameter: 1436bb7acecfSBarry Smith . dm - the `DM` object 143747c6ae99SBarry Smith 143847c6ae99SBarry Smith Output Parameter: 143947c6ae99SBarry Smith . mat - the empty Jacobian 144047c6ae99SBarry Smith 144120f4b53cSBarry Smith Options Database Key: 1442bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 1443f27dd7c6SMatthew G. Knepley 144420f4b53cSBarry Smith Level: beginner 144520f4b53cSBarry Smith 144695452b02SPatrick Sanan Notes: 144795452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 144894013140SBarry Smith do not need to do it yourself. 144994013140SBarry Smith 145094013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 1451bb7acecfSBarry Smith the nonzero pattern call `DMSetMatrixPreallocateOnly()` 145294013140SBarry Smith 1453bb7acecfSBarry Smith For `DMDA`, when you call `MatView()` on this matrix it is displayed using the global natural ordering, NOT in the ordering used 145494013140SBarry Smith internally by PETSc. 145594013140SBarry Smith 1456bb7acecfSBarry Smith For `DMDA`, in general it is easiest to use `MatSetValuesStencil()` or `MatSetValuesLocal()` to put values into the matrix because 1457bb7acecfSBarry Smith `MatSetValues()` requires the indices for the global numbering for the `DMDA` which is complic`ated to compute 145894013140SBarry Smith 14591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMSetMatType()`, `DMCreateMassMatrix()` 1460aab9d709SJed Brown @*/ 1461d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMatrix(DM dm, Mat *mat) 1462d71ae5a4SJacob Faibussowitsch { 146347c6ae99SBarry Smith PetscFunctionBegin; 1464171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14654f572ea9SToby Isaac PetscAssertPointer(mat, 2); 14669566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 14679566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateMatrix, 0, 0, 0, 0)); 1468dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, creatematrix, mat); 146976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1470c6b011d8SStefano Zampini DM mdm; 1471c6b011d8SStefano Zampini 14729566063dSJacob Faibussowitsch PetscCall(MatGetDM(*mat, &mdm)); 14737a8be351SBarry Smith PetscCheck(mdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the matrix", ((PetscObject)dm)->type_name); 1474c6b011d8SStefano Zampini } 1475e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1476e5e52638SMatthew G. Knepley if (dm->Nf) { 1477e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1478649ef022SMatthew Knepley PetscInt Nf, f; 1479e571a35bSMatthew G. Knepley 14809566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1481649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1482649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 14839566063dSJacob Faibussowitsch PetscCall((*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace)); 14849566063dSJacob Faibussowitsch PetscCall(MatSetNullSpace(*mat, nullSpace)); 14859566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1486649ef022SMatthew Knepley break; 1487e571a35bSMatthew G. Knepley } 1488649ef022SMatthew Knepley } 1489649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1490649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 14919566063dSJacob Faibussowitsch PetscCall((*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace)); 14929566063dSJacob Faibussowitsch PetscCall(MatSetNearNullSpace(*mat, nullSpace)); 14939566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1494e571a35bSMatthew G. Knepley } 1495e571a35bSMatthew G. Knepley } 1496e571a35bSMatthew G. Knepley } 14979566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateMatrix, 0, 0, 0, 0)); 14983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 149947c6ae99SBarry Smith } 150047c6ae99SBarry Smith 1501732e2eb9SMatthew G Knepley /*@ 1502a4e35b19SJacob Faibussowitsch DMSetMatrixPreallocateSkip - When `DMCreateMatrix()` is called the matrix sizes and 1503a4e35b19SJacob Faibussowitsch `ISLocalToGlobalMapping` will be properly set, but the data structures to store values in the 1504a4e35b19SJacob Faibussowitsch matrices will not be preallocated. 1505aa0f6e3cSJed Brown 150620f4b53cSBarry Smith Logically Collective 1507aa0f6e3cSJed Brown 1508aa0f6e3cSJed Brown Input Parameters: 1509bb7acecfSBarry Smith + dm - the `DM` 1510bb7acecfSBarry Smith - skip - `PETSC_TRUE` to skip preallocation 1511aa0f6e3cSJed Brown 1512aa0f6e3cSJed Brown Level: developer 1513aa0f6e3cSJed Brown 1514a4e35b19SJacob Faibussowitsch Notes: 1515a4e35b19SJacob Faibussowitsch This is most useful to reduce initialization costs when `MatSetPreallocationCOO()` and 1516a4e35b19SJacob Faibussowitsch `MatSetValuesCOO()` will be used. 1517a4e35b19SJacob Faibussowitsch 15181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateOnly()` 1519aa0f6e3cSJed Brown @*/ 1520d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateSkip(DM dm, PetscBool skip) 1521d71ae5a4SJacob Faibussowitsch { 1522aa0f6e3cSJed Brown PetscFunctionBegin; 1523aa0f6e3cSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1524aa0f6e3cSJed Brown dm->prealloc_skip = skip; 15253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1526aa0f6e3cSJed Brown } 1527aa0f6e3cSJed Brown 1528aa0f6e3cSJed Brown /*@ 1529bb7acecfSBarry Smith DMSetMatrixPreallocateOnly - When `DMCreateMatrix()` is called the matrix will be properly 1530732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1531732e2eb9SMatthew G Knepley 153220f4b53cSBarry Smith Logically Collective 1533732e2eb9SMatthew G Knepley 1534d8d19677SJose E. Roman Input Parameters: 1535bb7acecfSBarry Smith + dm - the `DM` 1536bb7acecfSBarry Smith - only - `PETSC_TRUE` if only want preallocation 1537732e2eb9SMatthew G Knepley 153820f4b53cSBarry Smith Options Database Key: 1539bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()`, `DMCreateMassMatrix()`, but do not fill it with zeros 1540f27dd7c6SMatthew G. Knepley 154120f4b53cSBarry Smith Level: developer 154220f4b53cSBarry Smith 15431cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateSkip()` 1544732e2eb9SMatthew G Knepley @*/ 1545d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1546d71ae5a4SJacob Faibussowitsch { 1547732e2eb9SMatthew G Knepley PetscFunctionBegin; 1548732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1549732e2eb9SMatthew G Knepley dm->prealloc_only = only; 15503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1551732e2eb9SMatthew G Knepley } 1552732e2eb9SMatthew G Knepley 1553b06ff27eSHong Zhang /*@ 1554bb7acecfSBarry Smith DMSetMatrixStructureOnly - When `DMCreateMatrix()` is called, the matrix structure will be created 1555bb7acecfSBarry Smith but the array for numerical values will not be allocated. 1556b06ff27eSHong Zhang 155720f4b53cSBarry Smith Logically Collective 1558b06ff27eSHong Zhang 1559d8d19677SJose E. Roman Input Parameters: 1560bb7acecfSBarry Smith + dm - the `DM` 1561da81f932SPierre Jolivet - only - `PETSC_TRUE` if you only want matrix structure 1562b06ff27eSHong Zhang 1563b06ff27eSHong Zhang Level: developer 1564bb7acecfSBarry Smith 15651cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMSetMatrixPreallocateSkip()` 1566b06ff27eSHong Zhang @*/ 1567d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1568d71ae5a4SJacob Faibussowitsch { 1569b06ff27eSHong Zhang PetscFunctionBegin; 1570b06ff27eSHong Zhang PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1571b06ff27eSHong Zhang dm->structure_only = only; 15723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1573b06ff27eSHong Zhang } 1574b06ff27eSHong Zhang 1575863027abSJed Brown /*@ 1576863027abSJed Brown DMSetBlockingType - set the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1577863027abSJed Brown 157820f4b53cSBarry Smith Logically Collective 1579863027abSJed Brown 1580863027abSJed Brown Input Parameters: 1581863027abSJed Brown + dm - the `DM` 1582863027abSJed Brown - btype - block by topological point or field node 1583863027abSJed Brown 158420f4b53cSBarry Smith Options Database Key: 15850e762ea3SJed Brown . -dm_blocking_type [topological_point, field_node] - use topological point blocking or field node blocking 1586863027abSJed Brown 158720f4b53cSBarry Smith Level: advanced 158820f4b53cSBarry Smith 15891cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1590863027abSJed Brown @*/ 1591863027abSJed Brown PetscErrorCode DMSetBlockingType(DM dm, DMBlockingType btype) 1592863027abSJed Brown { 1593863027abSJed Brown PetscFunctionBegin; 1594863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1595863027abSJed Brown dm->blocking_type = btype; 15963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1597863027abSJed Brown } 1598863027abSJed Brown 1599863027abSJed Brown /*@ 1600863027abSJed Brown DMGetBlockingType - get the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1601863027abSJed Brown 1602863027abSJed Brown Not Collective 1603863027abSJed Brown 16042fe279fdSBarry Smith Input Parameter: 1605863027abSJed Brown . dm - the `DM` 1606863027abSJed Brown 16072fe279fdSBarry Smith Output Parameter: 1608863027abSJed Brown . btype - block by topological point or field node 1609863027abSJed Brown 1610863027abSJed Brown Level: advanced 1611863027abSJed Brown 16121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1613863027abSJed Brown @*/ 1614863027abSJed Brown PetscErrorCode DMGetBlockingType(DM dm, DMBlockingType *btype) 1615863027abSJed Brown { 1616863027abSJed Brown PetscFunctionBegin; 1617863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16184f572ea9SToby Isaac PetscAssertPointer(btype, 2); 1619863027abSJed Brown *btype = dm->blocking_type; 16203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1621863027abSJed Brown } 1622863027abSJed Brown 1623a89ea682SMatthew G Knepley /*@C 1624bb7acecfSBarry Smith DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with `DMRestoreWorkArray()` 1625a89ea682SMatthew G Knepley 1626a89ea682SMatthew G Knepley Not Collective 1627a89ea682SMatthew G Knepley 1628a89ea682SMatthew G Knepley Input Parameters: 1629bb7acecfSBarry Smith + dm - the `DM` object 1630a5b23f4aSJose E. Roman . count - The minimum size 163120f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, or `MPIU_INT`) 1632a89ea682SMatthew G Knepley 1633a89ea682SMatthew G Knepley Output Parameter: 163460225df5SJacob Faibussowitsch . mem - the work array 1635a89ea682SMatthew G Knepley 1636a89ea682SMatthew G Knepley Level: developer 1637a89ea682SMatthew G Knepley 1638bb7acecfSBarry Smith Note: 1639da81f932SPierre Jolivet A `DM` may stash the array between instantiations so using this routine may be more efficient than calling `PetscMalloc()` 1640bb7acecfSBarry Smith 1641bb7acecfSBarry Smith The array may contain nonzero values 1642bb7acecfSBarry Smith 16431cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMRestoreWorkArray()`, `PetscMalloc()` 1644a89ea682SMatthew G Knepley @*/ 1645d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1646d71ae5a4SJacob Faibussowitsch { 1647aa1993deSMatthew G Knepley DMWorkLink link; 164869291d52SBarry Smith PetscMPIInt dsize; 1649a89ea682SMatthew G Knepley 1650a89ea682SMatthew G Knepley PetscFunctionBegin; 1651a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16524f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1653442f3b32SStefano Zampini if (!count) { 1654442f3b32SStefano Zampini *(void **)mem = NULL; 1655442f3b32SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 1656442f3b32SStefano Zampini } 1657aa1993deSMatthew G Knepley if (dm->workin) { 1658aa1993deSMatthew G Knepley link = dm->workin; 1659aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1660aa1993deSMatthew G Knepley } else { 16614dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&link)); 1662a89ea682SMatthew G Knepley } 1663b77fa653SStefano Zampini /* Avoid MPI_Type_size for most used datatypes 1664b77fa653SStefano Zampini Get size directly */ 1665b77fa653SStefano Zampini if (dtype == MPIU_INT) dsize = sizeof(PetscInt); 1666b77fa653SStefano Zampini else if (dtype == MPIU_REAL) dsize = sizeof(PetscReal); 1667b77fa653SStefano Zampini #if defined(PETSC_USE_64BIT_INDICES) 1668b77fa653SStefano Zampini else if (dtype == MPI_INT) dsize = sizeof(int); 1669b77fa653SStefano Zampini #endif 1670b77fa653SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1671b77fa653SStefano Zampini else if (dtype == MPIU_SCALAR) dsize = sizeof(PetscScalar); 1672b77fa653SStefano Zampini #endif 1673b77fa653SStefano Zampini else PetscCallMPI(MPI_Type_size(dtype, &dsize)); 1674b77fa653SStefano Zampini 16755056fcd2SBarry Smith if (((size_t)dsize * count) > link->bytes) { 16769566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 16779566063dSJacob Faibussowitsch PetscCall(PetscMalloc(dsize * count, &link->mem)); 1678854ce69bSBarry Smith link->bytes = dsize * count; 1679aa1993deSMatthew G Knepley } 1680aa1993deSMatthew G Knepley link->next = dm->workout; 1681aa1993deSMatthew G Knepley dm->workout = link; 1682cea3dcb8SSatish Balay #if defined(__MEMCHECK_H) && (defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) || defined(PLAT_amd64_darwin)) 168300d952a4SJed Brown VALGRIND_MAKE_MEM_NOACCESS((char *)link->mem + (size_t)dsize * count, link->bytes - (size_t)dsize * count); 168400d952a4SJed Brown VALGRIND_MAKE_MEM_UNDEFINED(link->mem, (size_t)dsize * count); 168500d952a4SJed Brown #endif 1686aa1993deSMatthew G Knepley *(void **)mem = link->mem; 16873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1688a89ea682SMatthew G Knepley } 1689a89ea682SMatthew G Knepley 1690aa1993deSMatthew G Knepley /*@C 1691bb7acecfSBarry Smith DMRestoreWorkArray - Restores a work array obtained with `DMCreateWorkArray()` 1692aa1993deSMatthew G Knepley 1693aa1993deSMatthew G Knepley Not Collective 1694aa1993deSMatthew G Knepley 1695aa1993deSMatthew G Knepley Input Parameters: 1696bb7acecfSBarry Smith + dm - the `DM` object 1697a5b23f4aSJose E. Roman . count - The minimum size 169820f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_INT` 1699aa1993deSMatthew G Knepley 1700aa1993deSMatthew G Knepley Output Parameter: 170160225df5SJacob Faibussowitsch . mem - the work array 1702aa1993deSMatthew G Knepley 1703aa1993deSMatthew G Knepley Level: developer 1704aa1993deSMatthew G Knepley 170560225df5SJacob Faibussowitsch Developer Notes: 1706bb7acecfSBarry Smith count and dtype are ignored, they are only needed for `DMGetWorkArray()` 1707147403d9SBarry Smith 17081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMGetWorkArray()` 1709aa1993deSMatthew G Knepley @*/ 1710d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1711d71ae5a4SJacob Faibussowitsch { 1712aa1993deSMatthew G Knepley DMWorkLink *p, link; 1713aa1993deSMatthew G Knepley 1714aa1993deSMatthew G Knepley PetscFunctionBegin; 1715aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17164f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1717a4e35b19SJacob Faibussowitsch (void)count; 1718a4e35b19SJacob Faibussowitsch (void)dtype; 1719442f3b32SStefano Zampini if (!*(void **)mem) PetscFunctionReturn(PETSC_SUCCESS); 1720aa1993deSMatthew G Knepley for (p = &dm->workout; (link = *p); p = &link->next) { 1721aa1993deSMatthew G Knepley if (link->mem == *(void **)mem) { 1722aa1993deSMatthew G Knepley *p = link->next; 1723aa1993deSMatthew G Knepley link->next = dm->workin; 1724aa1993deSMatthew G Knepley dm->workin = link; 17250298fd71SBarry Smith *(void **)mem = NULL; 17263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1727aa1993deSMatthew G Knepley } 1728aa1993deSMatthew G Knepley } 1729aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Array was not checked out"); 1730aa1993deSMatthew G Knepley } 1731e7c4fc90SDmitry Karpeev 17328cda7954SMatthew G. Knepley /*@C 1733bb7acecfSBarry Smith DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field, defined with `DMAddField()`, when function spaces 1734bb7acecfSBarry Smith are joined or split, such as in `DMCreateSubDM()` 17358cda7954SMatthew G. Knepley 173620f4b53cSBarry Smith Logically Collective; No Fortran Support 17378cda7954SMatthew G. Knepley 17388cda7954SMatthew G. Knepley Input Parameters: 1739bb7acecfSBarry Smith + dm - The `DM` 17408cda7954SMatthew G. Knepley . field - The field number for the nullspace 17418cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 17428cda7954SMatthew G. Knepley 174320f4b53cSBarry Smith Calling sequence of `nullsp`: 1744bb7acecfSBarry Smith + dm - The present `DM` 1745bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1746147403d9SBarry Smith . field - The field number in dm 1747147403d9SBarry Smith - nullSpace - The nullspace for the given field 17488cda7954SMatthew G. Knepley 174949762cbcSSatish Balay Level: intermediate 175049762cbcSSatish Balay 17511cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1752147403d9SBarry Smith @*/ 1753a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1754d71ae5a4SJacob Faibussowitsch { 1755435a35e8SMatthew G Knepley PetscFunctionBegin; 1756435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17577a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1758435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 17593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1760435a35e8SMatthew G Knepley } 1761435a35e8SMatthew G Knepley 17628cda7954SMatthew G. Knepley /*@C 1763bb7acecfSBarry Smith DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, defined with `DMAddField()` 17648cda7954SMatthew G. Knepley 176520f4b53cSBarry Smith Not Collective; No Fortran Support 17668cda7954SMatthew G. Knepley 17678cda7954SMatthew G. Knepley Input Parameters: 1768bb7acecfSBarry Smith + dm - The `DM` 17698cda7954SMatthew G. Knepley - field - The field number for the nullspace 17708cda7954SMatthew G. Knepley 17718cda7954SMatthew G. Knepley Output Parameter: 17728cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 17738cda7954SMatthew G. Knepley 177420f4b53cSBarry Smith Calling sequence of `nullsp`: 1775147403d9SBarry Smith + dm - The present DM 1776147403d9SBarry Smith . origField - The field number given above, in the original DM 1777147403d9SBarry Smith . field - The field number in dm 1778147403d9SBarry Smith - nullSpace - The nullspace for the given field 17798cda7954SMatthew G. Knepley 178049762cbcSSatish Balay Level: intermediate 178149762cbcSSatish Balay 17821cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1783147403d9SBarry Smith @*/ 1784a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1785d71ae5a4SJacob Faibussowitsch { 17860a50eb56SMatthew G. Knepley PetscFunctionBegin; 17870a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17884f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 17897a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 17900a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 17913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17920a50eb56SMatthew G. Knepley } 17930a50eb56SMatthew G. Knepley 17948cda7954SMatthew G. Knepley /*@C 1795bb7acecfSBarry Smith DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 17968cda7954SMatthew G. Knepley 179720f4b53cSBarry Smith Logically Collective; No Fortran Support 17988cda7954SMatthew G. Knepley 17998cda7954SMatthew G. Knepley Input Parameters: 1800bb7acecfSBarry Smith + dm - The `DM` 18018cda7954SMatthew G. Knepley . field - The field number for the nullspace 18028cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 18038cda7954SMatthew G. Knepley 180420f4b53cSBarry Smith Calling sequence of `nullsp`: 1805bb7acecfSBarry Smith + dm - The present `DM` 1806bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1807147403d9SBarry Smith . field - The field number in dm 1808147403d9SBarry Smith - nullSpace - The nullspace for the given field 18098cda7954SMatthew G. Knepley 181049762cbcSSatish Balay Level: intermediate 181149762cbcSSatish Balay 18121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()`, 1813bb7acecfSBarry Smith `MatNullSpace` 1814147403d9SBarry Smith @*/ 1815a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1816d71ae5a4SJacob Faibussowitsch { 1817f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1818f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18197a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1820f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 18213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1822f9d4088aSMatthew G. Knepley } 1823f9d4088aSMatthew G. Knepley 18248cda7954SMatthew G. Knepley /*@C 1825bb7acecfSBarry Smith DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 18268cda7954SMatthew G. Knepley 182720f4b53cSBarry Smith Not Collective; No Fortran Support 18288cda7954SMatthew G. Knepley 18298cda7954SMatthew G. Knepley Input Parameters: 1830bb7acecfSBarry Smith + dm - The `DM` 18318cda7954SMatthew G. Knepley - field - The field number for the nullspace 18328cda7954SMatthew G. Knepley 18338cda7954SMatthew G. Knepley Output Parameter: 18348cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 18358cda7954SMatthew G. Knepley 183620f4b53cSBarry Smith Calling sequence of `nullsp`: 1837bb7acecfSBarry Smith + dm - The present `DM` 1838bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1839147403d9SBarry Smith . field - The field number in dm 1840147403d9SBarry Smith - nullSpace - The nullspace for the given field 18418cda7954SMatthew G. Knepley 184249762cbcSSatish Balay Level: intermediate 184349762cbcSSatish Balay 18441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, 1845bb7acecfSBarry Smith `MatNullSpace`, `DMCreateSuperDM()` 1846147403d9SBarry Smith @*/ 1847a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1848d71ae5a4SJacob Faibussowitsch { 1849f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1850f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18514f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 18527a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1853f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 18543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1855f9d4088aSMatthew G. Knepley } 1856f9d4088aSMatthew G. Knepley 18574f3b5142SJed Brown /*@C 1858bb7acecfSBarry Smith DMCreateFieldIS - Creates a set of `IS` objects with the global indices of dofs for each field defined with `DMAddField()` 18594d343eeaSMatthew G Knepley 186020f4b53cSBarry Smith Not Collective; No Fortran Support 18614d343eeaSMatthew G Knepley 18624d343eeaSMatthew G Knepley Input Parameter: 1863bb7acecfSBarry Smith . dm - the `DM` object 18644d343eeaSMatthew G Knepley 18654d343eeaSMatthew G Knepley Output Parameters: 186620f4b53cSBarry Smith + numFields - The number of fields (or `NULL` if not requested) 186720f4b53cSBarry Smith . fieldNames - The number of each field (or `NULL` if not requested) 186820f4b53cSBarry Smith - fields - The global indices for each field (or `NULL` if not requested) 18694d343eeaSMatthew G Knepley 18704d343eeaSMatthew G Knepley Level: intermediate 18714d343eeaSMatthew G Knepley 1872bb7acecfSBarry Smith Note: 187321c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1874bb7acecfSBarry Smith `PetscFree()`, every entry of fields should be destroyed with `ISDestroy()`, and both arrays should be freed with 1875bb7acecfSBarry Smith `PetscFree()`. 187621c9b008SJed Brown 187760225df5SJacob Faibussowitsch Developer Notes: 1878bb7acecfSBarry Smith It is not clear why both this function and `DMCreateFieldDecomposition()` exist. Having two seems redundant and confusing. This function should 1879bb7acecfSBarry Smith likely be removed. 1880bb7acecfSBarry Smith 18811cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1882bb7acecfSBarry Smith `DMCreateFieldDecomposition()` 18834d343eeaSMatthew G Knepley @*/ 1884d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 1885d71ae5a4SJacob Faibussowitsch { 188637d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 18874d343eeaSMatthew G Knepley 18884d343eeaSMatthew G Knepley PetscFunctionBegin; 18894d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 189069ca1f37SDmitry Karpeev if (numFields) { 18914f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 189269ca1f37SDmitry Karpeev *numFields = 0; 189369ca1f37SDmitry Karpeev } 189437d0c07bSMatthew G Knepley if (fieldNames) { 18954f572ea9SToby Isaac PetscAssertPointer(fieldNames, 3); 18960298fd71SBarry Smith *fieldNames = NULL; 189769ca1f37SDmitry Karpeev } 189869ca1f37SDmitry Karpeev if (fields) { 18994f572ea9SToby Isaac PetscAssertPointer(fields, 4); 19000298fd71SBarry Smith *fields = NULL; 190169ca1f37SDmitry Karpeev } 19029566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 190337d0c07bSMatthew G Knepley if (section) { 19043a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 190537d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 190637d0c07bSMatthew G Knepley 19079566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 19089566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nF)); 19099566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nF, &fieldSizes, nF, &fieldNc, nF, &fieldIndices)); 19109566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(sectionGlobal, &pStart, &pEnd)); 191137d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 191237d0c07bSMatthew G Knepley fieldSizes[f] = 0; 19139566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(section, f, &fieldNc[f])); 191437d0c07bSMatthew G Knepley } 191537d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 191637d0c07bSMatthew G Knepley PetscInt gdof; 191737d0c07bSMatthew G Knepley 19189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 191937d0c07bSMatthew G Knepley if (gdof > 0) { 192037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19213a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 192237d0c07bSMatthew G Knepley 19239566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19249566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 19253a544194SStefano Zampini fpdof = fdof - fcdof; 19263a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 19273a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 19283a544194SStefano Zampini fieldNc[f] = 1; 19293a544194SStefano Zampini } 19303a544194SStefano Zampini fieldSizes[f] += fpdof; 193137d0c07bSMatthew G Knepley } 193237d0c07bSMatthew G Knepley } 193337d0c07bSMatthew G Knepley } 193437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fieldSizes[f], &fieldIndices[f])); 193637d0c07bSMatthew G Knepley fieldSizes[f] = 0; 193737d0c07bSMatthew G Knepley } 193837d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 193937d0c07bSMatthew G Knepley PetscInt gdof, goff; 194037d0c07bSMatthew G Knepley 19419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 194237d0c07bSMatthew G Knepley if (gdof > 0) { 19439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &goff)); 194437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 194537d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 194637d0c07bSMatthew G Knepley 19479566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19489566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 1949ad540459SPierre Jolivet for (fc = 0; fc < fdof - fcdof; ++fc, ++fieldSizes[f]) fieldIndices[f][fieldSizes[f]] = goff++; 195037d0c07bSMatthew G Knepley } 195137d0c07bSMatthew G Knepley } 195237d0c07bSMatthew G Knepley } 19538865f1eaSKarl Rupp if (numFields) *numFields = nF; 195437d0c07bSMatthew G Knepley if (fieldNames) { 19559566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fieldNames)); 195637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 195737d0c07bSMatthew G Knepley const char *fieldName; 195837d0c07bSMatthew G Knepley 19599566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 19609566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char **)&(*fieldNames)[f])); 196137d0c07bSMatthew G Knepley } 196237d0c07bSMatthew G Knepley } 196337d0c07bSMatthew G Knepley if (fields) { 19649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fields)); 196537d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19663a544194SStefano Zampini PetscInt bs, in[2], out[2]; 19673a544194SStefano Zampini 19689566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f])); 19693a544194SStefano Zampini in[0] = -fieldNc[f]; 19703a544194SStefano Zampini in[1] = fieldNc[f]; 19711c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 19723a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 19739566063dSJacob Faibussowitsch PetscCall(ISSetBlockSize((*fields)[f], bs)); 197437d0c07bSMatthew G Knepley } 197537d0c07bSMatthew G Knepley } 19769566063dSJacob Faibussowitsch PetscCall(PetscFree3(fieldSizes, fieldNc, fieldIndices)); 1977dbbe0bcdSBarry Smith } else PetscTryTypeMethod(dm, createfieldis, numFields, fieldNames, fields); 19783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19794d343eeaSMatthew G Knepley } 19804d343eeaSMatthew G Knepley 198116621825SDmitry Karpeev /*@C 1982bb7acecfSBarry Smith DMCreateFieldDecomposition - Returns a list of `IS` objects defining a decomposition of a problem into subproblems 1983a4e35b19SJacob Faibussowitsch corresponding to different fields. 1984e7c4fc90SDmitry Karpeev 198520f4b53cSBarry Smith Not Collective; No Fortran Support 1986e7c4fc90SDmitry Karpeev 1987e7c4fc90SDmitry Karpeev Input Parameter: 1988bb7acecfSBarry Smith . dm - the `DM` object 1989e7c4fc90SDmitry Karpeev 1990e7c4fc90SDmitry Karpeev Output Parameters: 199120f4b53cSBarry Smith + len - The number of fields (or `NULL` if not requested) 199220f4b53cSBarry Smith . namelist - The name for each field (or `NULL` if not requested) 199320f4b53cSBarry Smith . islist - The global indices for each field (or `NULL` if not requested) 199420f4b53cSBarry Smith - dmlist - The `DM`s for each field subproblem (or `NULL`, if not requested; if `NULL` is returned, no `DM`s are defined) 1995e7c4fc90SDmitry Karpeev 1996e7c4fc90SDmitry Karpeev Level: intermediate 1997e7c4fc90SDmitry Karpeev 1998a4e35b19SJacob Faibussowitsch Notes: 1999a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding field, defined by 2000a4e35b19SJacob Faibussowitsch `DMAddField()`. The optional list of `DM`s define the `DM` for each subproblem. 2001a4e35b19SJacob Faibussowitsch 2002a4e35b19SJacob Faibussowitsch The same as `DMCreateFieldIS()` but also returns a `DM` for each field. 2003a4e35b19SJacob Faibussowitsch 2004e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 2005bb7acecfSBarry Smith `PetscFree()`, every entry of is should be destroyed with `ISDestroy()`, every entry of dm should be destroyed with `DMDestroy()`, 2006bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 2007e7c4fc90SDmitry Karpeev 200860225df5SJacob Faibussowitsch Developer Notes: 2009bb7acecfSBarry Smith It is not clear why this function and `DMCreateFieldIS()` exist. Having two seems redundant and confusing. 2010bb7acecfSBarry Smith 201160225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMCreateFieldIS()`, `DMCreateSubDM()`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 2012e7c4fc90SDmitry Karpeev @*/ 2013d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 2014d71ae5a4SJacob Faibussowitsch { 2015e7c4fc90SDmitry Karpeev PetscFunctionBegin; 2016e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20178865f1eaSKarl Rupp if (len) { 20184f572ea9SToby Isaac PetscAssertPointer(len, 2); 20198865f1eaSKarl Rupp *len = 0; 20208865f1eaSKarl Rupp } 20218865f1eaSKarl Rupp if (namelist) { 20224f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 2023ea78f98cSLisandro Dalcin *namelist = NULL; 20248865f1eaSKarl Rupp } 20258865f1eaSKarl Rupp if (islist) { 20264f572ea9SToby Isaac PetscAssertPointer(islist, 4); 2027ea78f98cSLisandro Dalcin *islist = NULL; 20288865f1eaSKarl Rupp } 20298865f1eaSKarl Rupp if (dmlist) { 20304f572ea9SToby Isaac PetscAssertPointer(dmlist, 5); 2031ea78f98cSLisandro Dalcin *dmlist = NULL; 20328865f1eaSKarl Rupp } 2033f3f0edfdSDmitry Karpeev /* 2034f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2035f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2036f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2037f3f0edfdSDmitry Karpeev */ 20387a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 203916621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 2040435a35e8SMatthew G Knepley PetscSection section; 2041435a35e8SMatthew G Knepley PetscInt numFields, f; 2042435a35e8SMatthew G Knepley 20439566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 20449566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(section, &numFields)); 2045435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 2046f25d98f1SMatthew G. Knepley if (len) *len = numFields; 20479566063dSJacob Faibussowitsch if (namelist) PetscCall(PetscMalloc1(numFields, namelist)); 20489566063dSJacob Faibussowitsch if (islist) PetscCall(PetscMalloc1(numFields, islist)); 20499566063dSJacob Faibussowitsch if (dmlist) PetscCall(PetscMalloc1(numFields, dmlist)); 2050435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 2051435a35e8SMatthew G Knepley const char *fieldName; 2052435a35e8SMatthew G Knepley 20539566063dSJacob Faibussowitsch PetscCall(DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL)); 205403dc3394SMatthew G. Knepley if (namelist) { 20559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 20569566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char **)&(*namelist)[f])); 2057435a35e8SMatthew G Knepley } 205803dc3394SMatthew G. Knepley } 2059435a35e8SMatthew G Knepley } else { 20609566063dSJacob Faibussowitsch PetscCall(DMCreateFieldIS(dm, len, namelist, islist)); 2061e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 20620298fd71SBarry Smith if (dmlist) *dmlist = NULL; 2063e7c4fc90SDmitry Karpeev } 2064dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, createfielddecomposition, len, namelist, islist, dmlist); 20653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 206616621825SDmitry Karpeev } 206716621825SDmitry Karpeev 2068412a4547SAlexis Marboeuf /*@C 206920f4b53cSBarry Smith DMCreateSubDM - Returns an `IS` and `DM` encapsulating a subproblem defined by the fields passed in. 207020f4b53cSBarry Smith The fields are defined by `DMCreateFieldIS()`. 2071435a35e8SMatthew G Knepley 2072435a35e8SMatthew G Knepley Not collective 2073435a35e8SMatthew G Knepley 2074435a35e8SMatthew G Knepley Input Parameters: 2075bb7acecfSBarry Smith + dm - The `DM` object 2076bb7acecfSBarry Smith . numFields - The number of fields to select 20772adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 2078435a35e8SMatthew G Knepley 2079435a35e8SMatthew G Knepley Output Parameters: 2080bb7acecfSBarry Smith + is - The global indices for all the degrees of freedom in the new sub `DM` 2081bb7acecfSBarry Smith - subdm - The `DM` for the subproblem 2082435a35e8SMatthew G Knepley 208320f4b53cSBarry Smith Level: intermediate 208420f4b53cSBarry Smith 2085bb7acecfSBarry Smith Note: 2086bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 20875d3b26e6SMatthew G. Knepley 208860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateFieldIS()`, `DMCreateFieldDecomposition()`, `DMAddField()`, `DMCreateSuperDM()`, `IS`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 2089435a35e8SMatthew G Knepley @*/ 2090d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2091d71ae5a4SJacob Faibussowitsch { 2092435a35e8SMatthew G Knepley PetscFunctionBegin; 2093435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20944f572ea9SToby Isaac PetscAssertPointer(fields, 3); 20954f572ea9SToby Isaac if (is) PetscAssertPointer(is, 4); 20964f572ea9SToby Isaac if (subdm) PetscAssertPointer(subdm, 5); 2097dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createsubdm, numFields, fields, is, subdm); 20983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2099435a35e8SMatthew G Knepley } 2100435a35e8SMatthew G Knepley 21012adcc780SMatthew G. Knepley /*@C 2102bb7acecfSBarry Smith DMCreateSuperDM - Returns an arrays of `IS` and `DM` encapsulating a superproblem defined by multiple `DM`s passed in. 21032adcc780SMatthew G. Knepley 21042adcc780SMatthew G. Knepley Not collective 21052adcc780SMatthew G. Knepley 2106d8d19677SJose E. Roman Input Parameters: 2107bb7acecfSBarry Smith + dms - The `DM` objects 2108bb7acecfSBarry Smith - n - The number of `DM`s 21092adcc780SMatthew G. Knepley 21102adcc780SMatthew G. Knepley Output Parameters: 2111bb7acecfSBarry Smith + is - The global indices for each of subproblem within the super `DM`, or NULL 2112bb7acecfSBarry Smith - superdm - The `DM` for the superproblem 21132adcc780SMatthew G. Knepley 211420f4b53cSBarry Smith Level: intermediate 211520f4b53cSBarry Smith 2116bb7acecfSBarry Smith Note: 2117bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 21185d3b26e6SMatthew G. Knepley 21191cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateSubDM()`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 21202adcc780SMatthew G. Knepley @*/ 2121d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt n, IS **is, DM *superdm) 2122d71ae5a4SJacob Faibussowitsch { 21232adcc780SMatthew G. Knepley PetscInt i; 21242adcc780SMatthew G. Knepley 21252adcc780SMatthew G. Knepley PetscFunctionBegin; 21264f572ea9SToby Isaac PetscAssertPointer(dms, 1); 2127ad540459SPierre Jolivet for (i = 0; i < n; ++i) PetscValidHeaderSpecific(dms[i], DM_CLASSID, 1); 21284f572ea9SToby Isaac if (is) PetscAssertPointer(is, 3); 21294f572ea9SToby Isaac PetscAssertPointer(superdm, 4); 2130bb7acecfSBarry Smith PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %" PetscInt_FMT, n); 2131bb7acecfSBarry Smith if (n) { 2132b9d85ea2SLisandro Dalcin DM dm = dms[0]; 2133dbbe0bcdSBarry Smith PetscCall((*dm->ops->createsuperdm)(dms, n, is, superdm)); 21342adcc780SMatthew G. Knepley } 21353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21362adcc780SMatthew G. Knepley } 21372adcc780SMatthew G. Knepley 213816621825SDmitry Karpeev /*@C 2139a4e35b19SJacob Faibussowitsch DMCreateDomainDecomposition - Returns lists of `IS` objects defining a decomposition of a 2140a4e35b19SJacob Faibussowitsch problem into subproblems corresponding to restrictions to pairs of nested subdomains. 214116621825SDmitry Karpeev 214220f4b53cSBarry Smith Not Collective 214316621825SDmitry Karpeev 214416621825SDmitry Karpeev Input Parameter: 2145bb7acecfSBarry Smith . dm - the `DM` object 214616621825SDmitry Karpeev 214716621825SDmitry Karpeev Output Parameters: 214820f4b53cSBarry Smith + n - The number of subproblems in the domain decomposition (or `NULL` if not requested) 214920f4b53cSBarry Smith . namelist - The name for each subdomain (or `NULL` if not requested) 21500298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 21510298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 215220f4b53cSBarry Smith - dmlist - The `DM`s for each subdomain subproblem (or NULL, if not requested; if `NULL` is returned, no `DM`s are defined) 215316621825SDmitry Karpeev 215416621825SDmitry Karpeev Level: intermediate 215516621825SDmitry Karpeev 2156bb7acecfSBarry Smith Note: 2157a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding subdomains with in the 2158a4e35b19SJacob Faibussowitsch dofs of the original `DM`. The inner subdomains conceptually define a nonoverlapping 2159a4e35b19SJacob Faibussowitsch covering, while outer subdomains can overlap. 2160a4e35b19SJacob Faibussowitsch 2161a4e35b19SJacob Faibussowitsch The optional list of `DM`s define a `DM` for each subproblem. 2162a4e35b19SJacob Faibussowitsch 216316621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 2164bb7acecfSBarry Smith `PetscFree()`, every entry of is should be destroyed with `ISDestroy()`, every entry of dm should be destroyed with `DMDestroy()`, 2165bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 216616621825SDmitry Karpeev 2167a4e35b19SJacob Faibussowitsch Developer Notes: 216820f4b53cSBarry Smith The `dmlist` is for the inner subdomains or the outer subdomains or all subdomains? 2169bb7acecfSBarry Smith 217060225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateFieldDecomposition()`, `DMDestroy()`, `DMCreateDomainDecompositionScatters()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 217116621825SDmitry Karpeev @*/ 2172d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *n, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 2173d71ae5a4SJacob Faibussowitsch { 2174be081cd6SPeter Brune DMSubDomainHookLink link; 2175be081cd6SPeter Brune PetscInt i, l; 217616621825SDmitry Karpeev 217716621825SDmitry Karpeev PetscFunctionBegin; 217816621825SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21799371c9d4SSatish Balay if (n) { 21804f572ea9SToby Isaac PetscAssertPointer(n, 2); 21819371c9d4SSatish Balay *n = 0; 21829371c9d4SSatish Balay } 21839371c9d4SSatish Balay if (namelist) { 21844f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 21859371c9d4SSatish Balay *namelist = NULL; 21869371c9d4SSatish Balay } 21879371c9d4SSatish Balay if (innerislist) { 21884f572ea9SToby Isaac PetscAssertPointer(innerislist, 4); 21899371c9d4SSatish Balay *innerislist = NULL; 21909371c9d4SSatish Balay } 21919371c9d4SSatish Balay if (outerislist) { 21924f572ea9SToby Isaac PetscAssertPointer(outerislist, 5); 21939371c9d4SSatish Balay *outerislist = NULL; 21949371c9d4SSatish Balay } 21959371c9d4SSatish Balay if (dmlist) { 21964f572ea9SToby Isaac PetscAssertPointer(dmlist, 6); 21979371c9d4SSatish Balay *dmlist = NULL; 21989371c9d4SSatish Balay } 2199f3f0edfdSDmitry Karpeev /* 2200f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2201f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2202f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2203f3f0edfdSDmitry Karpeev */ 22047a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 220516621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 2206dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createdomaindecomposition, &l, namelist, innerislist, outerislist, dmlist); 220714a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 2208f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2209be081cd6SPeter Brune for (i = 0; i < l; i++) { 2210be081cd6SPeter Brune for (link = dm->subdomainhook; link; link = link->next) { 22119566063dSJacob Faibussowitsch if (link->ddhook) PetscCall((*link->ddhook)(dm, (*dmlist)[i], link->ctx)); 2212be081cd6SPeter Brune } 2213648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2214e7c4fc90SDmitry Karpeev } 221514a18fd3SPeter Brune } 2216bb7acecfSBarry Smith if (n) *n = l; 221714a18fd3SPeter Brune } 22183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2219e30e807fSPeter Brune } 2220e30e807fSPeter Brune 2221e30e807fSPeter Brune /*@C 2222e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 2223e30e807fSPeter Brune 222420f4b53cSBarry Smith Not Collective 2225e30e807fSPeter Brune 2226e30e807fSPeter Brune Input Parameters: 2227bb7acecfSBarry Smith + dm - the `DM` object 2228e30e807fSPeter Brune . n - the number of subdomain scatters 2229e30e807fSPeter Brune - subdms - the local subdomains 2230e30e807fSPeter Brune 2231e30e807fSPeter Brune Output Parameters: 22326b867d5aSJose E. Roman + iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2233e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2234e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2235e30e807fSPeter Brune 223620f4b53cSBarry Smith Level: developer 223720f4b53cSBarry Smith 2238bb7acecfSBarry Smith Note: 2239bb7acecfSBarry Smith This is an alternative to the iis and ois arguments in `DMCreateDomainDecomposition()` that allow for the solution 2240e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2241e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2242e30e807fSPeter Brune solution and residual data. 2243e30e807fSPeter Brune 2244a4e35b19SJacob Faibussowitsch Developer Notes: 2245a4e35b19SJacob Faibussowitsch Can the subdms input be anything or are they exactly the `DM` obtained from 2246a4e35b19SJacob Faibussowitsch `DMCreateDomainDecomposition()`? 2247bb7acecfSBarry Smith 22481cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2249e30e807fSPeter Brune @*/ 2250d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDomainDecompositionScatters(DM dm, PetscInt n, DM *subdms, VecScatter **iscat, VecScatter **oscat, VecScatter **gscat) 2251d71ae5a4SJacob Faibussowitsch { 2252e30e807fSPeter Brune PetscFunctionBegin; 2253e30e807fSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22544f572ea9SToby Isaac PetscAssertPointer(subdms, 3); 2255dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createddscatters, n, subdms, iscat, oscat, gscat); 22563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2257e7c4fc90SDmitry Karpeev } 2258e7c4fc90SDmitry Karpeev 225947c6ae99SBarry Smith /*@ 2260bb7acecfSBarry Smith DMRefine - Refines a `DM` object using a standard nonadaptive refinement of the underlying mesh 226147c6ae99SBarry Smith 226220f4b53cSBarry Smith Collective 226347c6ae99SBarry Smith 2264d8d19677SJose E. Roman Input Parameters: 2265bb7acecfSBarry Smith + dm - the `DM` object 2266bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 226747c6ae99SBarry Smith 226847c6ae99SBarry Smith Output Parameter: 226920f4b53cSBarry Smith . dmf - the refined `DM`, or `NULL` 2270ae0a1c52SMatthew G Knepley 227120f4b53cSBarry Smith Options Database Key: 2272412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2273412e9a14SMatthew G. Knepley 227447c6ae99SBarry Smith Level: developer 227547c6ae99SBarry Smith 227620f4b53cSBarry Smith Note: 227720f4b53cSBarry Smith If no refinement was done, the return value is `NULL` 227820f4b53cSBarry Smith 22791cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 228047c6ae99SBarry Smith @*/ 2281d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine(DM dm, MPI_Comm comm, DM *dmf) 2282d71ae5a4SJacob Faibussowitsch { 2283c833c3b5SJed Brown DMRefineHookLink link; 228447c6ae99SBarry Smith 228547c6ae99SBarry Smith PetscFunctionBegin; 2286732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22879566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Refine, dm, 0, 0, 0)); 2288dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refine, comm, dmf); 22894057135bSMatthew G Knepley if (*dmf) { 229043842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 22918865f1eaSKarl Rupp 22929566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmf)); 22938865f1eaSKarl Rupp 2294644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 22950598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2296656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 22978865f1eaSKarl Rupp 22989566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmf, dm->mattype)); 2299c833c3b5SJed Brown for (link = dm->refinehook; link; link = link->next) { 23001baa6e33SBarry Smith if (link->refinehook) PetscCall((*link->refinehook)(dm, *dmf, link->ctx)); 2301c833c3b5SJed Brown } 2302c833c3b5SJed Brown } 23039566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Refine, dm, 0, 0, 0)); 23043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2305c833c3b5SJed Brown } 2306c833c3b5SJed Brown 2307bb9467b5SJed Brown /*@C 2308c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2309c833c3b5SJed Brown 231020f4b53cSBarry Smith Logically Collective; No Fortran Support 2311c833c3b5SJed Brown 23124165533cSJose E. Roman Input Parameters: 2313bb7acecfSBarry Smith + coarse - `DM` on which to run a hook when interpolating to a finer level 2314bb7acecfSBarry Smith . refinehook - function to run when setting up the finer level 2315f826b5fcSPierre Jolivet . interphook - function to run to update data on finer levels (once per `SNESSolve()`) 231620f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2317c833c3b5SJed Brown 231820f4b53cSBarry Smith Calling sequence of `refinehook`: 2319bb7acecfSBarry Smith + coarse - coarse level `DM` 2320bb7acecfSBarry Smith . fine - fine level `DM` to interpolate problem to 2321c833c3b5SJed Brown - ctx - optional user-defined function context 2322c833c3b5SJed Brown 232320f4b53cSBarry Smith Calling sequence of `interphook`: 2324bb7acecfSBarry Smith + coarse - coarse level `DM` 2325c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2326bb7acecfSBarry Smith . fine - fine level `DM` to update 2327c833c3b5SJed Brown - ctx - optional user-defined function context 2328c833c3b5SJed Brown 2329c833c3b5SJed Brown Level: advanced 2330c833c3b5SJed Brown 2331c833c3b5SJed Brown Notes: 2332bb7acecfSBarry Smith This function is only needed if auxiliary data that is attached to the `DM`s via, for example, `PetscObjectCompose()`, needs to be 2333bb7acecfSBarry Smith passed to fine grids while grid sequencing. 2334bb7acecfSBarry Smith 2335bb7acecfSBarry Smith The actual interpolation is done when `DMInterpolate()` is called. 2336c833c3b5SJed Brown 2337c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2338c833c3b5SJed Brown 23391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2340c833c3b5SJed Brown @*/ 2341a4e35b19SJacob Faibussowitsch PetscErrorCode DMRefineHookAdd(DM coarse, PetscErrorCode (*refinehook)(DM coarse, DM fine, void *ctx), PetscErrorCode (*interphook)(DM coarse, Mat interp, DM fine, void *ctx), void *ctx) 2342d71ae5a4SJacob Faibussowitsch { 2343c833c3b5SJed Brown DMRefineHookLink link, *p; 2344c833c3b5SJed Brown 2345c833c3b5SJed Brown PetscFunctionBegin; 2346c833c3b5SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 23473d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 23483ba16761SJacob Faibussowitsch if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 23493d8e3701SJed Brown } 23509566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2351c833c3b5SJed Brown link->refinehook = refinehook; 2352c833c3b5SJed Brown link->interphook = interphook; 2353c833c3b5SJed Brown link->ctx = ctx; 23540298fd71SBarry Smith link->next = NULL; 2355c833c3b5SJed Brown *p = link; 23563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2357c833c3b5SJed Brown } 2358c833c3b5SJed Brown 23593d8e3701SJed Brown /*@C 2360bb7acecfSBarry Smith DMRefineHookRemove - remove a callback from the list of hooks, that have been set with `DMRefineHookAdd()`, to be run when interpolating 2361bb7acecfSBarry Smith a nonlinear problem to a finer grid 23623d8e3701SJed Brown 236320f4b53cSBarry Smith Logically Collective; No Fortran Support 23643d8e3701SJed Brown 23654165533cSJose E. Roman Input Parameters: 2366bb7acecfSBarry Smith + coarse - the `DM` on which to run a hook when restricting to a coarser level 2367bb7acecfSBarry Smith . refinehook - function to run when setting up a finer level 2368bb7acecfSBarry Smith . interphook - function to run to update data on finer levels 236920f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 23703d8e3701SJed Brown 23713d8e3701SJed Brown Level: advanced 23723d8e3701SJed Brown 2373bb7acecfSBarry Smith Note: 23743d8e3701SJed Brown This function does nothing if the hook is not in the list. 23753d8e3701SJed Brown 23761cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `DMCoarsenHookRemove()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 23773d8e3701SJed Brown @*/ 2378d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHookRemove(DM coarse, PetscErrorCode (*refinehook)(DM, DM, void *), PetscErrorCode (*interphook)(DM, Mat, DM, void *), void *ctx) 2379d71ae5a4SJacob Faibussowitsch { 23803d8e3701SJed Brown DMRefineHookLink link, *p; 23813d8e3701SJed Brown 23823d8e3701SJed Brown PetscFunctionBegin; 23833d8e3701SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 23843d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 23853d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 23863d8e3701SJed Brown link = *p; 23873d8e3701SJed Brown *p = link->next; 23889566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 23893d8e3701SJed Brown break; 23903d8e3701SJed Brown } 23913d8e3701SJed Brown } 23923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23933d8e3701SJed Brown } 23943d8e3701SJed Brown 2395c833c3b5SJed Brown /*@ 2396bb7acecfSBarry Smith DMInterpolate - interpolates user-defined problem data attached to a `DM` to a finer `DM` by running hooks registered by `DMRefineHookAdd()` 2397c833c3b5SJed Brown 2398c833c3b5SJed Brown Collective if any hooks are 2399c833c3b5SJed Brown 24004165533cSJose E. Roman Input Parameters: 2401bb7acecfSBarry Smith + coarse - coarser `DM` to use as a base 2402bb7acecfSBarry Smith . interp - interpolation matrix, apply using `MatInterpolate()` 2403bb7acecfSBarry Smith - fine - finer `DM` to update 2404c833c3b5SJed Brown 2405c833c3b5SJed Brown Level: developer 2406c833c3b5SJed Brown 240760225df5SJacob Faibussowitsch Developer Notes: 2408bb7acecfSBarry Smith This routine is called `DMInterpolate()` while the hook is called `DMRefineHookAdd()`. It would be better to have an 2409bb7acecfSBarry Smith an API with consistent terminology. 2410bb7acecfSBarry Smith 24111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `MatInterpolate()` 2412c833c3b5SJed Brown @*/ 2413d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolate(DM coarse, Mat interp, DM fine) 2414d71ae5a4SJacob Faibussowitsch { 2415c833c3b5SJed Brown DMRefineHookLink link; 2416c833c3b5SJed Brown 2417c833c3b5SJed Brown PetscFunctionBegin; 2418c833c3b5SJed Brown for (link = fine->refinehook; link; link = link->next) { 24191baa6e33SBarry Smith if (link->interphook) PetscCall((*link->interphook)(coarse, interp, fine, link->ctx)); 24204057135bSMatthew G Knepley } 24213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 242247c6ae99SBarry Smith } 242347c6ae99SBarry Smith 2424eb3f98d2SBarry Smith /*@ 24251f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 24261f3379b2SToby Isaac 242720f4b53cSBarry Smith Collective 24281f3379b2SToby Isaac 24294165533cSJose E. Roman Input Parameters: 2430bb7acecfSBarry Smith + coarse - coarse `DM` 2431bb7acecfSBarry Smith . fine - fine `DM` 2432bb7acecfSBarry Smith . interp - (optional) the matrix computed by `DMCreateInterpolation()`. Implementations may not need this, but if it 2433bb7acecfSBarry Smith is available it can avoid some recomputation. If it is provided, `MatInterpolate()` will be used if 2434bb7acecfSBarry Smith the coarse `DM` does not have a specialized implementation. 24351f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 24361f3379b2SToby Isaac 24374165533cSJose E. Roman Output Parameter: 24381f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 24391f3379b2SToby Isaac 24401f3379b2SToby Isaac Level: developer 24411f3379b2SToby Isaac 2442bb7acecfSBarry Smith Note: 2443bb7acecfSBarry Smith This function exists because the interpolation of a solution vector between meshes is not always a linear 24441f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 24451f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 24461f3379b2SToby Isaac slope-limiting reconstruction. 24471f3379b2SToby Isaac 244860225df5SJacob Faibussowitsch Developer Notes: 2449bb7acecfSBarry Smith This doesn't just interpolate "solutions" so its API name is questionable. 2450bb7acecfSBarry Smith 24511cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMInterpolate()`, `DMCreateInterpolation()` 24521f3379b2SToby Isaac @*/ 2453d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 2454d71ae5a4SJacob Faibussowitsch { 24551f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM, DM, Mat, Vec, Vec) = NULL; 24561f3379b2SToby Isaac 24571f3379b2SToby Isaac PetscFunctionBegin; 24581f3379b2SToby Isaac PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 24591f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp, MAT_CLASSID, 3); 24601f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol, VEC_CLASSID, 4); 24611f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol, VEC_CLASSID, 5); 24621f3379b2SToby Isaac 24639566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)coarse, "DMInterpolateSolution_C", &interpsol)); 24641f3379b2SToby Isaac if (interpsol) { 24659566063dSJacob Faibussowitsch PetscCall((*interpsol)(coarse, fine, interp, coarseSol, fineSol)); 24661f3379b2SToby Isaac } else if (interp) { 24679566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, coarseSol, fineSol)); 246898921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 24693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24701f3379b2SToby Isaac } 24711f3379b2SToby Isaac 24721f3379b2SToby Isaac /*@ 2473bb7acecfSBarry Smith DMGetRefineLevel - Gets the number of refinements that have generated this `DM` from some initial `DM`. 2474eb3f98d2SBarry Smith 2475eb3f98d2SBarry Smith Not Collective 2476eb3f98d2SBarry Smith 2477eb3f98d2SBarry Smith Input Parameter: 2478bb7acecfSBarry Smith . dm - the `DM` object 2479eb3f98d2SBarry Smith 2480eb3f98d2SBarry Smith Output Parameter: 2481eb3f98d2SBarry Smith . level - number of refinements 2482eb3f98d2SBarry Smith 2483eb3f98d2SBarry Smith Level: developer 2484eb3f98d2SBarry Smith 2485bb7acecfSBarry Smith Note: 2486bb7acecfSBarry Smith This can be used, by example, to set the number of coarser levels associated with this `DM` for a multigrid solver. 2487bb7acecfSBarry Smith 24881cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2489eb3f98d2SBarry Smith @*/ 2490d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRefineLevel(DM dm, PetscInt *level) 2491d71ae5a4SJacob Faibussowitsch { 2492eb3f98d2SBarry Smith PetscFunctionBegin; 2493eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2494eb3f98d2SBarry Smith *level = dm->levelup; 24953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2496eb3f98d2SBarry Smith } 2497eb3f98d2SBarry Smith 2498fef3a512SBarry Smith /*@ 2499bb7acecfSBarry Smith DMSetRefineLevel - Sets the number of refinements that have generated this `DM`. 2500fef3a512SBarry Smith 2501fef3a512SBarry Smith Not Collective 2502fef3a512SBarry Smith 2503d8d19677SJose E. Roman Input Parameters: 2504bb7acecfSBarry Smith + dm - the `DM` object 2505fef3a512SBarry Smith - level - number of refinements 2506fef3a512SBarry Smith 2507fef3a512SBarry Smith Level: advanced 2508fef3a512SBarry Smith 250995452b02SPatrick Sanan Notes: 2510bb7acecfSBarry Smith This value is used by `PCMG` to determine how many multigrid levels to use 2511fef3a512SBarry Smith 2512bb7acecfSBarry Smith The values are usually set automatically by the process that is causing the refinements of an initial `DM` by calling this routine. 2513bb7acecfSBarry Smith 25141cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRefineLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2515fef3a512SBarry Smith @*/ 2516d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRefineLevel(DM dm, PetscInt level) 2517d71ae5a4SJacob Faibussowitsch { 2518fef3a512SBarry Smith PetscFunctionBegin; 2519fef3a512SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2520fef3a512SBarry Smith dm->levelup = level; 25213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2522fef3a512SBarry Smith } 2523fef3a512SBarry Smith 2524d410b0cfSMatthew G. Knepley /*@ 2525bb7acecfSBarry Smith DMExtrude - Extrude a `DM` object from a surface 2526d410b0cfSMatthew G. Knepley 252720f4b53cSBarry Smith Collective 2528d410b0cfSMatthew G. Knepley 2529f1a722f8SMatthew G. Knepley Input Parameters: 2530bb7acecfSBarry Smith + dm - the `DM` object 2531d410b0cfSMatthew G. Knepley - layers - the number of extruded cell layers 2532d410b0cfSMatthew G. Knepley 2533d410b0cfSMatthew G. Knepley Output Parameter: 253420f4b53cSBarry Smith . dme - the extruded `DM`, or `NULL` 2535d410b0cfSMatthew G. Knepley 2536d410b0cfSMatthew G. Knepley Level: developer 2537d410b0cfSMatthew G. Knepley 253820f4b53cSBarry Smith Note: 253920f4b53cSBarry Smith If no extrusion was done, the return value is `NULL` 254020f4b53cSBarry Smith 25411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()` 2542d410b0cfSMatthew G. Knepley @*/ 2543d71ae5a4SJacob Faibussowitsch PetscErrorCode DMExtrude(DM dm, PetscInt layers, DM *dme) 2544d71ae5a4SJacob Faibussowitsch { 2545d410b0cfSMatthew G. Knepley PetscFunctionBegin; 2546d410b0cfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2547dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, extrude, layers, dme); 2548d410b0cfSMatthew G. Knepley if (*dme) { 2549d410b0cfSMatthew G. Knepley (*dme)->ops->creatematrix = dm->ops->creatematrix; 25509566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dme)); 2551d410b0cfSMatthew G. Knepley (*dme)->ctx = dm->ctx; 25529566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dme, dm->mattype)); 2553d410b0cfSMatthew G. Knepley } 25543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2555d410b0cfSMatthew G. Knepley } 2556d410b0cfSMatthew G. Knepley 2557d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2558d71ae5a4SJacob Faibussowitsch { 2559ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2560ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 25614f572ea9SToby Isaac PetscAssertPointer(tdm, 2); 2562ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 25633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2564ca3d3a14SMatthew G. Knepley } 2565ca3d3a14SMatthew G. Knepley 2566d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2567d71ae5a4SJacob Faibussowitsch { 2568ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2569ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 25704f572ea9SToby Isaac PetscAssertPointer(tv, 2); 2571ca3d3a14SMatthew G. Knepley *tv = dm->transform; 25723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2573ca3d3a14SMatthew G. Knepley } 2574ca3d3a14SMatthew G. Knepley 2575ca3d3a14SMatthew G. Knepley /*@ 2576bb7acecfSBarry Smith DMHasBasisTransform - Whether the `DM` employs a basis transformation from functions in global vectors to functions in local vectors 2577ca3d3a14SMatthew G. Knepley 2578ca3d3a14SMatthew G. Knepley Input Parameter: 257920f4b53cSBarry Smith . dm - The `DM` 2580ca3d3a14SMatthew G. Knepley 2581ca3d3a14SMatthew G. Knepley Output Parameter: 258220f4b53cSBarry Smith . flg - `PETSC_TRUE` if a basis transformation should be done 2583ca3d3a14SMatthew G. Knepley 2584ca3d3a14SMatthew G. Knepley Level: developer 2585ca3d3a14SMatthew G. Knepley 25861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPlexGlobalToLocalBasis()`, `DMPlexLocalToGlobalBasis()`, `DMPlexCreateBasisRotation()` 2587ca3d3a14SMatthew G. Knepley @*/ 2588d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2589d71ae5a4SJacob Faibussowitsch { 2590ca3d3a14SMatthew G. Knepley Vec tv; 2591ca3d3a14SMatthew G. Knepley 2592ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2593ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 25944f572ea9SToby Isaac PetscAssertPointer(flg, 2); 25959566063dSJacob Faibussowitsch PetscCall(DMGetBasisTransformVec_Internal(dm, &tv)); 2596ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 25973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2598ca3d3a14SMatthew G. Knepley } 2599ca3d3a14SMatthew G. Knepley 2600d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2601d71ae5a4SJacob Faibussowitsch { 2602ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2603ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2604ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2605ca3d3a14SMatthew G. Knepley 2606ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 26079566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 26089566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 26099566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 26109566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 26119566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->transformDM)); 26129566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm->transformDM, &ts)); 26139566063dSJacob Faibussowitsch PetscCall(PetscSectionSetNumFields(ts, Nf)); 26149566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(ts, pStart, pEnd)); 2615ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26169566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(s, f, &Nc)); 2617ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2618ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2619ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 26209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &dof)); 2621ca3d3a14SMatthew G. Knepley if (!dof) continue; 26229566063dSJacob Faibussowitsch PetscCall(PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim))); 26239566063dSJacob Faibussowitsch PetscCall(PetscSectionAddDof(ts, p, PetscSqr(cdim))); 2624ca3d3a14SMatthew G. Knepley } 2625ca3d3a14SMatthew G. Knepley } 26269566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(ts)); 26279566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dm->transformDM, &dm->transform)); 26289566063dSJacob Faibussowitsch PetscCall(VecGetArray(dm->transform, &ta)); 2629ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2630ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(ts, p, f, &dof)); 2632ca3d3a14SMatthew G. Knepley if (dof) { 2633ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2634ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2635ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2636ca3d3a14SMatthew G. Knepley 2637ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 26389566063dSJacob Faibussowitsch PetscCall((*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx)); 26399566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *)&tva)); 26409566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tva, A, PetscSqr(cdim))); 2641ca3d3a14SMatthew G. Knepley } 2642ca3d3a14SMatthew G. Knepley } 2643ca3d3a14SMatthew G. Knepley } 26449566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(dm->transform, &ta)); 26453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2646ca3d3a14SMatthew G. Knepley } 2647ca3d3a14SMatthew G. Knepley 2648d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2649d71ae5a4SJacob Faibussowitsch { 2650ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2651ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2652ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2653ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2654ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2655ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2656ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 26579566063dSJacob Faibussowitsch if (newdm->transformSetUp) PetscCall(DMConstructBasisTransform_Internal(newdm)); 26583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2659ca3d3a14SMatthew G. Knepley } 2660ca3d3a14SMatthew G. Knepley 2661bb9467b5SJed Brown /*@C 2662bb7acecfSBarry Smith DMGlobalToLocalHookAdd - adds a callback to be run when `DMGlobalToLocal()` is called 2663baf369e7SPeter Brune 266420f4b53cSBarry Smith Logically Collective 2665baf369e7SPeter Brune 26664165533cSJose E. Roman Input Parameters: 2667bb7acecfSBarry Smith + dm - the `DM` 2668bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMGlobalToLocalBegin()` 2669bb7acecfSBarry Smith . endhook - function to run after `DMGlobalToLocalEnd()` has completed 267020f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2671baf369e7SPeter Brune 267220f4b53cSBarry Smith Calling sequence of `beginhook`: 2673a4e35b19SJacob Faibussowitsch + dm - global `DM` 2674baf369e7SPeter Brune . g - global vector 2675baf369e7SPeter Brune . mode - mode 2676baf369e7SPeter Brune . l - local vector 2677baf369e7SPeter Brune - ctx - optional user-defined function context 2678baf369e7SPeter Brune 267920f4b53cSBarry Smith Calling sequence of `endhook`: 2680a4e35b19SJacob Faibussowitsch + dm - global `DM` 2681a4e35b19SJacob Faibussowitsch . g - global vector 2682a4e35b19SJacob Faibussowitsch . mode - mode 2683a4e35b19SJacob Faibussowitsch . l - local vector 2684baf369e7SPeter Brune - ctx - optional user-defined function context 2685baf369e7SPeter Brune 2686baf369e7SPeter Brune Level: advanced 2687baf369e7SPeter Brune 2688bb7acecfSBarry Smith Note: 2689bb7acecfSBarry 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. 2690bb7acecfSBarry Smith 26911cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocal()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2692baf369e7SPeter Brune @*/ 2693a4e35b19SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalHookAdd(DM dm, PetscErrorCode (*beginhook)(DM dm, Vec g, InsertMode mode, Vec l, void *ctx), PetscErrorCode (*endhook)(DM dm, Vec g, InsertMode mode, Vec l, void *ctx), void *ctx) 2694d71ae5a4SJacob Faibussowitsch { 2695baf369e7SPeter Brune DMGlobalToLocalHookLink link, *p; 2696baf369e7SPeter Brune 2697baf369e7SPeter Brune PetscFunctionBegin; 2698baf369e7SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2699baf369e7SPeter Brune for (p = &dm->gtolhook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 27009566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2701baf369e7SPeter Brune link->beginhook = beginhook; 2702baf369e7SPeter Brune link->endhook = endhook; 2703baf369e7SPeter Brune link->ctx = ctx; 27040298fd71SBarry Smith link->next = NULL; 2705baf369e7SPeter Brune *p = link; 27063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2707baf369e7SPeter Brune } 2708baf369e7SPeter Brune 2709d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 2710d71ae5a4SJacob Faibussowitsch { 27114c274da1SToby Isaac Mat cMat; 271279769bd5SJed Brown Vec cVec, cBias; 27134c274da1SToby Isaac PetscSection section, cSec; 27144c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 27154c274da1SToby Isaac 27164c274da1SToby Isaac PetscFunctionBegin; 2717a4e35b19SJacob Faibussowitsch (void)g; 2718a4e35b19SJacob Faibussowitsch (void)ctx; 27194c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 27209566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, &cBias)); 27214c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 27225db9a05bSToby Isaac PetscInt nRows; 27235db9a05bSToby Isaac 27249566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 27253ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 27269566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 27279566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 27289566063dSJacob Faibussowitsch PetscCall(MatMult(cMat, l, cVec)); 27299566063dSJacob Faibussowitsch if (cBias) PetscCall(VecAXPY(cVec, 1., cBias)); 27309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 27314c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 27329566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 27334c274da1SToby Isaac if (dof) { 27344c274da1SToby Isaac PetscScalar *vals; 27359566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(cVec, cSec, p, &vals)); 27369566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(l, section, p, vals, INSERT_ALL_VALUES)); 27374c274da1SToby Isaac } 27384c274da1SToby Isaac } 27399566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 27404c274da1SToby Isaac } 27413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27424c274da1SToby Isaac } 27434c274da1SToby Isaac 274447c6ae99SBarry Smith /*@ 274501729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 274601729b5cSPatrick Sanan 274720f4b53cSBarry Smith Neighbor-wise Collective 274801729b5cSPatrick Sanan 274901729b5cSPatrick Sanan Input Parameters: 2750bb7acecfSBarry Smith + dm - the `DM` object 275101729b5cSPatrick Sanan . g - the global vector 2752bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 275301729b5cSPatrick Sanan - l - the local vector 275401729b5cSPatrick Sanan 275520f4b53cSBarry Smith Level: beginner 275620f4b53cSBarry Smith 275701729b5cSPatrick Sanan Notes: 2758bb7acecfSBarry Smith The communication involved in this update can be overlapped with computation by instead using 2759bb7acecfSBarry Smith `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. 2760bb7acecfSBarry Smith 2761bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 276201729b5cSPatrick Sanan 27631cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocalHookAdd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, 276460225df5SJacob Faibussowitsch `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, 2765bb7acecfSBarry Smith `DMGlobalToLocalBegin()` `DMGlobalToLocalEnd()` 276601729b5cSPatrick Sanan @*/ 2767d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocal(DM dm, Vec g, InsertMode mode, Vec l) 2768d71ae5a4SJacob Faibussowitsch { 276901729b5cSPatrick Sanan PetscFunctionBegin; 27709566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, g, mode, l)); 27719566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, g, mode, l)); 27723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 277301729b5cSPatrick Sanan } 277401729b5cSPatrick Sanan 277501729b5cSPatrick Sanan /*@ 277647c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 277747c6ae99SBarry Smith 277820f4b53cSBarry Smith Neighbor-wise Collective 277947c6ae99SBarry Smith 278047c6ae99SBarry Smith Input Parameters: 2781bb7acecfSBarry Smith + dm - the `DM` object 278247c6ae99SBarry Smith . g - the global vector 2783bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 278447c6ae99SBarry Smith - l - the local vector 278547c6ae99SBarry Smith 278601729b5cSPatrick Sanan Level: intermediate 278747c6ae99SBarry Smith 2788bb7acecfSBarry Smith Notes: 2789bb7acecfSBarry Smith The operation is completed with `DMGlobalToLocalEnd()` 2790bb7acecfSBarry Smith 2791bb7acecfSBarry Smith One can perform local computations between the `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to overlap communication and computation 2792bb7acecfSBarry Smith 2793bb7acecfSBarry Smith `DMGlobalToLocal()` is a short form of `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` 2794bb7acecfSBarry Smith 2795bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 2796bb7acecfSBarry Smith 279760225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 279847c6ae99SBarry Smith @*/ 2799d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 2800d71ae5a4SJacob Faibussowitsch { 28017128ae9fSMatthew G Knepley PetscSF sf; 2802baf369e7SPeter Brune DMGlobalToLocalHookLink link; 280347c6ae99SBarry Smith 280447c6ae99SBarry Smith PetscFunctionBegin; 2805171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2806baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 28071baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, g, mode, l, link->ctx)); 2808baf369e7SPeter Brune } 28099566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28107128ae9fSMatthew G Knepley if (sf) { 2811ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2812ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2813d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 28147128ae9fSMatthew G Knepley 28157a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28169566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28179566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28189566063dSJacob Faibussowitsch PetscCall(PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE)); 28199566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28217128ae9fSMatthew G Knepley } else { 28229566063dSJacob Faibussowitsch PetscCall((*dm->ops->globaltolocalbegin)(dm, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l)); 28237128ae9fSMatthew G Knepley } 28243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 282547c6ae99SBarry Smith } 282647c6ae99SBarry Smith 282747c6ae99SBarry Smith /*@ 282847c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 282947c6ae99SBarry Smith 283020f4b53cSBarry Smith Neighbor-wise Collective 283147c6ae99SBarry Smith 283247c6ae99SBarry Smith Input Parameters: 2833bb7acecfSBarry Smith + dm - the `DM` object 283447c6ae99SBarry Smith . g - the global vector 2835bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 283647c6ae99SBarry Smith - l - the local vector 283747c6ae99SBarry Smith 283801729b5cSPatrick Sanan Level: intermediate 283947c6ae99SBarry Smith 2840bb7acecfSBarry Smith Note: 2841bb7acecfSBarry Smith See `DMGlobalToLocalBegin()` for details. 2842bb7acecfSBarry Smith 284360225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 284447c6ae99SBarry Smith @*/ 2845d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 2846d71ae5a4SJacob Faibussowitsch { 28477128ae9fSMatthew G Knepley PetscSF sf; 2848ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2849ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2850ca3d3a14SMatthew G. Knepley PetscBool transform; 2851baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2852d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 285347c6ae99SBarry Smith 285447c6ae99SBarry Smith PetscFunctionBegin; 2855171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 28569566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28579566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 28587128ae9fSMatthew G Knepley if (sf) { 28597a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28607128ae9fSMatthew G Knepley 28619566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28629566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28639566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray, MPI_REPLACE)); 28649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28659566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28669566063dSJacob Faibussowitsch if (transform) PetscCall(DMPlexGlobalToLocalBasis(dm, l)); 28677128ae9fSMatthew G Knepley } else { 28689566063dSJacob Faibussowitsch PetscCall((*dm->ops->globaltolocalend)(dm, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l)); 28697128ae9fSMatthew G Knepley } 28709566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalHook_Constraints(dm, g, mode, l, NULL)); 2871baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 28729566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 2873baf369e7SPeter Brune } 28743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 287547c6ae99SBarry Smith } 287647c6ae99SBarry Smith 2877d4d07f1eSToby Isaac /*@C 2878d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2879d4d07f1eSToby Isaac 288020f4b53cSBarry Smith Logically Collective 2881d4d07f1eSToby Isaac 28824165533cSJose E. Roman Input Parameters: 2883bb7acecfSBarry Smith + dm - the `DM` 2884bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMLocalToGlobalBegin()` 2885bb7acecfSBarry Smith . endhook - function to run after `DMLocalToGlobalEnd()` has completed 288620f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2887d4d07f1eSToby Isaac 288820f4b53cSBarry Smith Calling sequence of `beginhook`: 2889a4e35b19SJacob Faibussowitsch + global - global `DM` 2890d4d07f1eSToby Isaac . l - local vector 2891d4d07f1eSToby Isaac . mode - mode 2892d4d07f1eSToby Isaac . g - global vector 2893d4d07f1eSToby Isaac - ctx - optional user-defined function context 2894d4d07f1eSToby Isaac 289520f4b53cSBarry Smith Calling sequence of `endhook`: 2896bb7acecfSBarry Smith + global - global `DM` 2897d4d07f1eSToby Isaac . l - local vector 2898d4d07f1eSToby Isaac . mode - mode 2899d4d07f1eSToby Isaac . g - global vector 2900d4d07f1eSToby Isaac - ctx - optional user-defined function context 2901d4d07f1eSToby Isaac 2902d4d07f1eSToby Isaac Level: advanced 2903d4d07f1eSToby Isaac 29041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMRefineHookAdd()`, `DMGlobalToLocalHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2905d4d07f1eSToby Isaac @*/ 2906a4e35b19SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalHookAdd(DM dm, PetscErrorCode (*beginhook)(DM global, Vec l, InsertMode mode, Vec g, void *ctx), PetscErrorCode (*endhook)(DM global, Vec l, InsertMode mode, Vec g, void *ctx), void *ctx) 2907d71ae5a4SJacob Faibussowitsch { 2908d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, *p; 2909d4d07f1eSToby Isaac 2910d4d07f1eSToby Isaac PetscFunctionBegin; 2911d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2912d4d07f1eSToby Isaac for (p = &dm->ltoghook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 29139566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2914d4d07f1eSToby Isaac link->beginhook = beginhook; 2915d4d07f1eSToby Isaac link->endhook = endhook; 2916d4d07f1eSToby Isaac link->ctx = ctx; 2917d4d07f1eSToby Isaac link->next = NULL; 2918d4d07f1eSToby Isaac *p = link; 29193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2920d4d07f1eSToby Isaac } 2921d4d07f1eSToby Isaac 2922d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 2923d71ae5a4SJacob Faibussowitsch { 29244c274da1SToby Isaac Mat cMat; 29254c274da1SToby Isaac Vec cVec; 29264c274da1SToby Isaac PetscSection section, cSec; 29274c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 29284c274da1SToby Isaac 29294c274da1SToby Isaac PetscFunctionBegin; 2930a4e35b19SJacob Faibussowitsch (void)g; 2931a4e35b19SJacob Faibussowitsch (void)ctx; 29324c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29339566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, NULL)); 29344c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 29355db9a05bSToby Isaac PetscInt nRows; 29365db9a05bSToby Isaac 29379566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 29383ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 29399566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 29409566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 29419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 29424c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 29439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 29444c274da1SToby Isaac if (dof) { 29454c274da1SToby Isaac PetscInt d; 29464c274da1SToby Isaac PetscScalar *vals; 29479566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(l, section, p, &vals)); 29489566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(cVec, cSec, p, vals, mode)); 29494c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 29504c274da1SToby Isaac * we just extracted */ 2951ad540459SPierre Jolivet for (d = 0; d < dof; d++) vals[d] = 0.; 29524c274da1SToby Isaac } 29534c274da1SToby Isaac } 29549566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd(cMat, cVec, l, l)); 29559566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 29564c274da1SToby Isaac } 29573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29584c274da1SToby Isaac } 295901729b5cSPatrick Sanan /*@ 296001729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 296101729b5cSPatrick Sanan 296220f4b53cSBarry Smith Neighbor-wise Collective 296301729b5cSPatrick Sanan 296401729b5cSPatrick Sanan Input Parameters: 2965bb7acecfSBarry Smith + dm - the `DM` object 296601729b5cSPatrick Sanan . l - the local vector 2967bb7acecfSBarry 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. 296801729b5cSPatrick Sanan - g - the global vector 296901729b5cSPatrick Sanan 297020f4b53cSBarry Smith Level: beginner 297120f4b53cSBarry Smith 297201729b5cSPatrick Sanan Notes: 297301729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 2974bb7acecfSBarry Smith `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. 297501729b5cSPatrick Sanan 2976bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 2977bb7acecfSBarry Smith 2978bb7acecfSBarry 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. 2979bb7acecfSBarry Smith 2980bb7acecfSBarry Smith Use `DMLocalToGlobalHookAdd()` to add additional operations that are performed on the data during the update process 298101729b5cSPatrick Sanan 29821cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalHookAdd()`, `DMGlobaToLocallHookAdd()` 298301729b5cSPatrick Sanan @*/ 2984d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobal(DM dm, Vec l, InsertMode mode, Vec g) 2985d71ae5a4SJacob Faibussowitsch { 298601729b5cSPatrick Sanan PetscFunctionBegin; 29879566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, l, mode, g)); 29889566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, l, mode, g)); 29893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 299001729b5cSPatrick Sanan } 29914c274da1SToby Isaac 299247c6ae99SBarry Smith /*@ 299301729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 29949a42bb27SBarry Smith 299520f4b53cSBarry Smith Neighbor-wise Collective 29969a42bb27SBarry Smith 29979a42bb27SBarry Smith Input Parameters: 2998bb7acecfSBarry Smith + dm - the `DM` object 2999f6813fd5SJed Brown . l - the local vector 3000aa624791SPierre Jolivet . mode - if `INSERT_VALUES` then no parallel communication is used, if `ADD_VALUES` then all ghost points from the same base point accumulate into that base point. 30011eb28f2eSBarry Smith - g - the global vector 30029a42bb27SBarry Smith 300320f4b53cSBarry Smith Level: intermediate 300420f4b53cSBarry Smith 300595452b02SPatrick Sanan Notes: 3006bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 3007bb7acecfSBarry Smith 3008bb7acecfSBarry 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. 3009bb7acecfSBarry Smith 3010bb7acecfSBarry Smith Use `DMLocalToGlobalEnd()` to complete the communication process. 3011bb7acecfSBarry Smith 3012bb7acecfSBarry Smith `DMLocalToGlobal()` is a short form of `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()` 3013bb7acecfSBarry Smith 3014bb7acecfSBarry Smith `DMLocalToGlobalHookAdd()` may be used to provide additional operations that are performed during the update process. 30159a42bb27SBarry Smith 30161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()` 30179a42bb27SBarry Smith @*/ 3018d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBegin(DM dm, Vec l, InsertMode mode, Vec g) 3019d71ae5a4SJacob Faibussowitsch { 30207128ae9fSMatthew G Knepley PetscSF sf; 302184330215SMatthew G. Knepley PetscSection s, gs; 3022d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3023ca3d3a14SMatthew G. Knepley Vec tmpl; 3024ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3025ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3026fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 3027d0295fc0SJunchao Zhang PetscMemType lmtype = PETSC_MEMTYPE_HOST, gmtype = PETSC_MEMTYPE_HOST; 30289a42bb27SBarry Smith 30299a42bb27SBarry Smith PetscFunctionBegin; 3030171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3031d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 30321baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, l, mode, g, link->ctx)); 3033d4d07f1eSToby Isaac } 30349566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalHook_Constraints(dm, l, mode, g, NULL)); 30359566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 30369566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 30377128ae9fSMatthew G Knepley switch (mode) { 30387128ae9fSMatthew G Knepley case INSERT_VALUES: 30397128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 3040d71ae5a4SJacob Faibussowitsch case INSERT_BC_VALUES: 3041d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3042d71ae5a4SJacob Faibussowitsch break; 30437128ae9fSMatthew G Knepley case ADD_VALUES: 30447128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 3045d71ae5a4SJacob Faibussowitsch case ADD_BC_VALUES: 3046d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3047d71ae5a4SJacob Faibussowitsch break; 3048d71ae5a4SJacob Faibussowitsch default: 3049d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 30507128ae9fSMatthew G Knepley } 3051ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 30529566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3053ca3d3a14SMatthew G. Knepley if (transform) { 30549566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 30559566063dSJacob Faibussowitsch PetscCall(VecCopy(l, tmpl)); 30569566063dSJacob Faibussowitsch PetscCall(DMPlexLocalToGlobalBasis(dm, tmpl)); 30579566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3058fa88e482SJed Brown } else if (isInsert) { 30599566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(l, &lArray)); 3060fa88e482SJed Brown } else { 30619566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, &lmtype)); 3062fa88e482SJed Brown l_inplace = PETSC_TRUE; 3063ca3d3a14SMatthew G. Knepley } 3064fa88e482SJed Brown if (s && isInsert) { 30659566063dSJacob Faibussowitsch PetscCall(VecGetArray(g, &gArray)); 3066fa88e482SJed Brown } else { 30679566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, &gmtype)); 3068fa88e482SJed Brown g_inplace = PETSC_TRUE; 3069fa88e482SJed Brown } 3070ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 30719566063dSJacob Faibussowitsch PetscCall(PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM)); 307284330215SMatthew G. Knepley } else if (s && isInsert) { 307384330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 307484330215SMatthew G. Knepley 30759566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 30769566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 30779566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g, &gStart, NULL)); 307884330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3079b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 308084330215SMatthew G. Knepley 30819566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 30829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(gs, p, &gdof)); 30839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 30849566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(gs, p, &gcdof)); 30859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(s, p, &off)); 30869566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(gs, p, &goff)); 3087b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 308803442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 30897a8be351SBarry 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); 3090b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 3091b3b16f48SMatthew G. Knepley if (!gcdof) { 309284330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff - gStart + d] = lArray[off + d]; 3093b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 3094b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 309584330215SMatthew G. Knepley const PetscInt *cdofs; 309684330215SMatthew G. Knepley PetscInt cind = 0; 309784330215SMatthew G. Knepley 30989566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(s, p, &cdofs)); 3099b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 31009371c9d4SSatish Balay if ((cind < cdof) && (d == cdofs[cind])) { 31019371c9d4SSatish Balay ++cind; 31029371c9d4SSatish Balay continue; 31039371c9d4SSatish Balay } 3104b3b16f48SMatthew G. Knepley gArray[goff - gStart + e++] = lArray[off + d]; 310584330215SMatthew G. Knepley } 31067a8be351SBarry 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); 310784330215SMatthew G. Knepley } 3108ca3d3a14SMatthew G. Knepley } 3109fa88e482SJed Brown if (g_inplace) { 31109566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 3111fa88e482SJed Brown } else { 31129566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(g, &gArray)); 3113fa88e482SJed Brown } 3114ca3d3a14SMatthew G. Knepley if (transform) { 31159566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31169566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3117fa88e482SJed Brown } else if (l_inplace) { 31189566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3119ca3d3a14SMatthew G. Knepley } else { 31209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(l, &lArray)); 3121ca3d3a14SMatthew G. Knepley } 31227128ae9fSMatthew G Knepley } else { 31239566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtoglobalbegin)(dm, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g)); 31247128ae9fSMatthew G Knepley } 31253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31269a42bb27SBarry Smith } 31279a42bb27SBarry Smith 31289a42bb27SBarry Smith /*@ 31299a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 313047c6ae99SBarry Smith 313120f4b53cSBarry Smith Neighbor-wise Collective 313247c6ae99SBarry Smith 313347c6ae99SBarry Smith Input Parameters: 3134bb7acecfSBarry Smith + dm - the `DM` object 3135f6813fd5SJed Brown . l - the local vector 3136bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 3137f6813fd5SJed Brown - g - the global vector 313847c6ae99SBarry Smith 313901729b5cSPatrick Sanan Level: intermediate 314047c6ae99SBarry Smith 3141bb7acecfSBarry Smith Note: 3142bb7acecfSBarry Smith See `DMLocalToGlobalBegin()` for full details 3143bb7acecfSBarry Smith 314460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()` 314547c6ae99SBarry Smith @*/ 3146d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEnd(DM dm, Vec l, InsertMode mode, Vec g) 3147d71ae5a4SJacob Faibussowitsch { 31487128ae9fSMatthew G Knepley PetscSF sf; 314984330215SMatthew G. Knepley PetscSection s; 3150d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3151ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 315247c6ae99SBarry Smith 315347c6ae99SBarry Smith PetscFunctionBegin; 3154171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 31559566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 31569566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 31577128ae9fSMatthew G Knepley switch (mode) { 31587128ae9fSMatthew G Knepley case INSERT_VALUES: 3159d71ae5a4SJacob Faibussowitsch case INSERT_ALL_VALUES: 3160d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3161d71ae5a4SJacob Faibussowitsch break; 31627128ae9fSMatthew G Knepley case ADD_VALUES: 3163d71ae5a4SJacob Faibussowitsch case ADD_ALL_VALUES: 3164d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3165d71ae5a4SJacob Faibussowitsch break; 3166d71ae5a4SJacob Faibussowitsch default: 3167d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 31687128ae9fSMatthew G Knepley } 316984330215SMatthew G. Knepley if (sf && !isInsert) { 3170ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3171ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3172ca3d3a14SMatthew G. Knepley Vec tmpl; 317384330215SMatthew G. Knepley 31749566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3175ca3d3a14SMatthew G. Knepley if (transform) { 31769566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 31779566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3178ca3d3a14SMatthew G. Knepley } else { 31799566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, NULL)); 3180ca3d3a14SMatthew G. Knepley } 31819566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, NULL)); 31829566063dSJacob Faibussowitsch PetscCall(PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM)); 3183ca3d3a14SMatthew G. Knepley if (transform) { 31849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31859566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3186ca3d3a14SMatthew G. Knepley } else { 31879566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3188ca3d3a14SMatthew G. Knepley } 31899566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 319084330215SMatthew G. Knepley } else if (s && isInsert) { 31917128ae9fSMatthew G Knepley } else { 31929566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtoglobalend)(dm, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g)); 31937128ae9fSMatthew G Knepley } 3194d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 31959566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 3196d4d07f1eSToby Isaac } 31973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 319847c6ae99SBarry Smith } 319947c6ae99SBarry Smith 3200f089877aSRichard Tran Mills /*@ 3201a4e35b19SJacob Faibussowitsch DMLocalToLocalBegin - Begins the process of mapping values from a local vector (that include 3202a4e35b19SJacob Faibussowitsch ghost points that contain irrelevant values) to another local vector where the ghost points 3203a4e35b19SJacob Faibussowitsch in the second are set correctly from values on other MPI ranks. 3204f089877aSRichard Tran Mills 320520f4b53cSBarry Smith Neighbor-wise Collective 3206f089877aSRichard Tran Mills 3207f089877aSRichard Tran Mills Input Parameters: 3208bb7acecfSBarry Smith + dm - the `DM` object 3209bc0a1609SRichard Tran Mills . g - the original local vector 3210bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3211f089877aSRichard Tran Mills 3212bc0a1609SRichard Tran Mills Output Parameter: 3213bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3214f089877aSRichard Tran Mills 3215f089877aSRichard Tran Mills Level: intermediate 3216f089877aSRichard Tran Mills 3217a4e35b19SJacob Faibussowitsch Notes: 3218a4e35b19SJacob Faibussowitsch Must be followed by `DMLocalToLocalEnd()`. 3219a4e35b19SJacob Faibussowitsch 322060225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3221f089877aSRichard Tran Mills @*/ 3222d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 3223d71ae5a4SJacob Faibussowitsch { 3224f089877aSRichard Tran Mills PetscFunctionBegin; 3225f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32269f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 32279f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 32289f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 32293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3230f089877aSRichard Tran Mills } 3231f089877aSRichard Tran Mills 3232f089877aSRichard Tran Mills /*@ 3233bb7acecfSBarry Smith DMLocalToLocalEnd - Maps from a local vector to another local vector where the ghost 3234bb7acecfSBarry Smith points in the second are set correctly. Must be preceded by `DMLocalToLocalBegin()`. 3235f089877aSRichard Tran Mills 323620f4b53cSBarry Smith Neighbor-wise Collective 3237f089877aSRichard Tran Mills 3238f089877aSRichard Tran Mills Input Parameters: 323960225df5SJacob Faibussowitsch + dm - the `DM` object 3240bc0a1609SRichard Tran Mills . g - the original local vector 3241bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3242f089877aSRichard Tran Mills 3243bc0a1609SRichard Tran Mills Output Parameter: 3244bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3245f089877aSRichard Tran Mills 3246f089877aSRichard Tran Mills Level: intermediate 3247f089877aSRichard Tran Mills 324860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3249f089877aSRichard Tran Mills @*/ 3250d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 3251d71ae5a4SJacob Faibussowitsch { 3252f089877aSRichard Tran Mills PetscFunctionBegin; 3253f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32549f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 32559f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 32569f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 32573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3258f089877aSRichard Tran Mills } 3259f089877aSRichard Tran Mills 326047c6ae99SBarry Smith /*@ 3261bb7acecfSBarry Smith DMCoarsen - Coarsens a `DM` object using a standard, non-adaptive coarsening of the underlying mesh 326247c6ae99SBarry Smith 326320f4b53cSBarry Smith Collective 326447c6ae99SBarry Smith 3265d8d19677SJose E. Roman Input Parameters: 3266bb7acecfSBarry Smith + dm - the `DM` object 326720f4b53cSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 326847c6ae99SBarry Smith 326947c6ae99SBarry Smith Output Parameter: 3270bb7acecfSBarry Smith . dmc - the coarsened `DM` 327147c6ae99SBarry Smith 327247c6ae99SBarry Smith Level: developer 327347c6ae99SBarry Smith 32741cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 327547c6ae99SBarry Smith @*/ 3276d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 3277d71ae5a4SJacob Faibussowitsch { 3278b17ce1afSJed Brown DMCoarsenHookLink link; 327947c6ae99SBarry Smith 328047c6ae99SBarry Smith PetscFunctionBegin; 3281171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32829566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Coarsen, dm, 0, 0, 0)); 3283dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsen, comm, dmc); 3284b9d85ea2SLisandro Dalcin if (*dmc) { 3285a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 32869566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm, *dmc)); 328743842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 32889566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmc)); 3289644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 32900598a293SJed Brown (*dmc)->levelup = dm->levelup; 3291656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 32929566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmc, dm->mattype)); 3293b17ce1afSJed Brown for (link = dm->coarsenhook; link; link = link->next) { 32949566063dSJacob Faibussowitsch if (link->coarsenhook) PetscCall((*link->coarsenhook)(dm, *dmc, link->ctx)); 3295b17ce1afSJed Brown } 3296b9d85ea2SLisandro Dalcin } 32979566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Coarsen, dm, 0, 0, 0)); 32987a8be351SBarry Smith PetscCheck(*dmc, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 32993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3300b17ce1afSJed Brown } 3301b17ce1afSJed Brown 3302bb9467b5SJed Brown /*@C 3303b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3304b17ce1afSJed Brown 330520f4b53cSBarry Smith Logically Collective; No Fortran Support 3306b17ce1afSJed Brown 33074165533cSJose E. Roman Input Parameters: 3308bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3309b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3310bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels (called once per `SNESSolve()`) 331120f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3312b17ce1afSJed Brown 331320f4b53cSBarry Smith Calling sequence of `coarsenhook`: 3314bb7acecfSBarry Smith + fine - fine level `DM` 3315bb7acecfSBarry Smith . coarse - coarse level `DM` to restrict problem to 3316b17ce1afSJed Brown - ctx - optional user-defined function context 3317b17ce1afSJed Brown 331820f4b53cSBarry Smith Calling sequence of `restricthook`: 3319bb7acecfSBarry Smith + fine - fine level `DM` 3320bb7acecfSBarry Smith . mrestrict - matrix restricting a fine-level solution to the coarse grid, usually the transpose of the interpolation 3321c833c3b5SJed Brown . rscale - scaling vector for restriction 3322c833c3b5SJed Brown . inject - matrix restricting by injection 3323b17ce1afSJed Brown . coarse - coarse level DM to update 3324b17ce1afSJed Brown - ctx - optional user-defined function context 3325b17ce1afSJed Brown 3326b17ce1afSJed Brown Level: advanced 3327b17ce1afSJed Brown 3328b17ce1afSJed Brown Notes: 3329bb7acecfSBarry 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`. 3330b17ce1afSJed Brown 3331b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3332b17ce1afSJed Brown 3333b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3334bb7acecfSBarry Smith extract the finest level information from its context (instead of from the `SNES`). 3335b17ce1afSJed Brown 3336bb7acecfSBarry Smith The hooks are automatically called by `DMRestrict()` 3337bb7acecfSBarry Smith 33381cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3339b17ce1afSJed Brown @*/ 3340a4e35b19SJacob Faibussowitsch PetscErrorCode DMCoarsenHookAdd(DM fine, PetscErrorCode (*coarsenhook)(DM fine, DM coarse, void *ctx), PetscErrorCode (*restricthook)(DM fine, Mat mrestrict, Vec rscale, Mat inject, DM coarse, void *ctx), void *ctx) 3341d71ae5a4SJacob Faibussowitsch { 3342b17ce1afSJed Brown DMCoarsenHookLink link, *p; 3343b17ce1afSJed Brown 3344b17ce1afSJed Brown PetscFunctionBegin; 3345b17ce1afSJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 33461e3d8eccSJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 33473ba16761SJacob Faibussowitsch if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 33481e3d8eccSJed Brown } 33499566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3350b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3351b17ce1afSJed Brown link->restricthook = restricthook; 3352b17ce1afSJed Brown link->ctx = ctx; 33530298fd71SBarry Smith link->next = NULL; 3354b17ce1afSJed Brown *p = link; 33553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3356b17ce1afSJed Brown } 3357b17ce1afSJed Brown 3358dc822a44SJed Brown /*@C 3359bb7acecfSBarry Smith DMCoarsenHookRemove - remove a callback set with `DMCoarsenHookAdd()` 3360dc822a44SJed Brown 336120f4b53cSBarry Smith Logically Collective; No Fortran Support 3362dc822a44SJed Brown 33634165533cSJose E. Roman Input Parameters: 3364bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3365dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3366bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels 336720f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3368dc822a44SJed Brown 3369dc822a44SJed Brown Level: advanced 3370dc822a44SJed Brown 3371bb7acecfSBarry Smith Note: 3372dc822a44SJed Brown This function does nothing if the hook is not in the list. 3373dc822a44SJed Brown 33741cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `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 } 33903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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()` 340320f4b53cSBarry Smith - coarse - coarser `DM` to update 3404b17ce1afSJed Brown 3405b17ce1afSJed Brown Level: developer 3406b17ce1afSJed Brown 340760225df5SJacob Faibussowitsch Developer Notes: 3408bb7acecfSBarry Smith Though this routine is called `DMRestrict()` the hooks are added with `DMCoarsenHookAdd()`, a consistent terminology would be better 3409bb7acecfSBarry Smith 34101cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `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 } 34203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 342620f4b53cSBarry Smith Logically Collective; No Fortran Support 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) 343220f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 34335dbd56e3SPeter Brune 343420f4b53cSBarry Smith Calling sequence of `ddhook`: 3435bb7acecfSBarry Smith + global - global `DM` 3436bb7acecfSBarry Smith . block - block `DM` 3437ec4806b8SPeter Brune - ctx - optional user-defined function context 3438ec4806b8SPeter Brune 343920f4b53cSBarry Smith Calling sequence of `restricthook`: 3440bb7acecfSBarry Smith + global - global `DM` 34415dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 34425dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 3443bb7acecfSBarry Smith . block - block `DM` 34445dbd56e3SPeter Brune - ctx - optional user-defined function context 34455dbd56e3SPeter Brune 34465dbd56e3SPeter Brune Level: advanced 34475dbd56e3SPeter Brune 34485dbd56e3SPeter Brune Notes: 3449bb7acecfSBarry Smith This function is only needed if auxiliary data needs to be set up on subdomain `DM`s. 34505dbd56e3SPeter Brune 34515dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 34525dbd56e3SPeter Brune 34535dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3454bb7acecfSBarry Smith extract the global information from its context (instead of from the `SNES`). 34555dbd56e3SPeter Brune 34561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 34575dbd56e3SPeter Brune @*/ 3458a4e35b19SJacob Faibussowitsch PetscErrorCode DMSubDomainHookAdd(DM global, PetscErrorCode (*ddhook)(DM global, DM block, void *ctx), PetscErrorCode (*restricthook)(DM global, VecScatter out, VecScatter in, DM block, void *ctx), void *ctx) 3459d71ae5a4SJacob Faibussowitsch { 3460be081cd6SPeter Brune DMSubDomainHookLink link, *p; 34615dbd56e3SPeter Brune 34625dbd56e3SPeter Brune PetscFunctionBegin; 34635dbd56e3SPeter Brune PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3464b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 34653ba16761SJacob Faibussowitsch if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 3466b3a6b972SJed Brown } 34679566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 34685dbd56e3SPeter Brune link->restricthook = restricthook; 3469be081cd6SPeter Brune link->ddhook = ddhook; 34705dbd56e3SPeter Brune link->ctx = ctx; 34710298fd71SBarry Smith link->next = NULL; 34725dbd56e3SPeter Brune *p = link; 34733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34745dbd56e3SPeter Brune } 34755dbd56e3SPeter Brune 3476b3a6b972SJed Brown /*@C 3477b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 3478b3a6b972SJed Brown 347920f4b53cSBarry Smith Logically Collective; No Fortran Support 3480b3a6b972SJed Brown 34814165533cSJose E. Roman Input Parameters: 3482bb7acecfSBarry Smith + global - global `DM` 3483bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 3484b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 348520f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3486b3a6b972SJed Brown 3487b3a6b972SJed Brown Level: advanced 3488b3a6b972SJed Brown 34891cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3490b3a6b972SJed Brown @*/ 3491d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookRemove(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3492d71ae5a4SJacob Faibussowitsch { 3493b3a6b972SJed Brown DMSubDomainHookLink link, *p; 3494b3a6b972SJed Brown 3495b3a6b972SJed Brown PetscFunctionBegin; 3496b3a6b972SJed Brown PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3497b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3498b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3499b3a6b972SJed Brown link = *p; 3500b3a6b972SJed Brown *p = link->next; 35019566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3502b3a6b972SJed Brown break; 3503b3a6b972SJed Brown } 3504b3a6b972SJed Brown } 35053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3506b3a6b972SJed Brown } 3507b3a6b972SJed Brown 35085dbd56e3SPeter Brune /*@ 3509bb7acecfSBarry Smith DMSubDomainRestrict - restricts user-defined problem data to a block `DM` by running hooks registered by `DMSubDomainHookAdd()` 35105dbd56e3SPeter Brune 35115dbd56e3SPeter Brune Collective if any hooks are 35125dbd56e3SPeter Brune 35134165533cSJose E. Roman Input Parameters: 3514a4e35b19SJacob Faibussowitsch + global - The global `DM` to use as a base 3515a4e35b19SJacob Faibussowitsch . oscatter - The scatter from domain global vector filling subdomain global vector with overlap 3516a4e35b19SJacob Faibussowitsch . gscatter - The scatter from domain global vector filling subdomain local vector with ghosts 3517a4e35b19SJacob Faibussowitsch - subdm - The subdomain `DM` to update 35185dbd56e3SPeter Brune 35195dbd56e3SPeter Brune Level: developer 35205dbd56e3SPeter Brune 35211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `MatRestrict()` 35225dbd56e3SPeter Brune @*/ 3523d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainRestrict(DM global, VecScatter oscatter, VecScatter gscatter, DM subdm) 3524d71ae5a4SJacob Faibussowitsch { 3525be081cd6SPeter Brune DMSubDomainHookLink link; 35265dbd56e3SPeter Brune 35275dbd56e3SPeter Brune PetscFunctionBegin; 3528be081cd6SPeter Brune for (link = global->subdomainhook; link; link = link->next) { 35291baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(global, oscatter, gscatter, subdm, link->ctx)); 35305dbd56e3SPeter Brune } 35313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35325dbd56e3SPeter Brune } 35335dbd56e3SPeter Brune 35345fe1f584SPeter Brune /*@ 3535bb7acecfSBarry Smith DMGetCoarsenLevel - Gets the number of coarsenings that have generated this `DM`. 35365fe1f584SPeter Brune 35375fe1f584SPeter Brune Not Collective 35385fe1f584SPeter Brune 35395fe1f584SPeter Brune Input Parameter: 3540bb7acecfSBarry Smith . dm - the `DM` object 35415fe1f584SPeter Brune 35425fe1f584SPeter Brune Output Parameter: 35436a7d9d85SPeter Brune . level - number of coarsenings 35445fe1f584SPeter Brune 35455fe1f584SPeter Brune Level: developer 35465fe1f584SPeter Brune 35471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMSetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35485fe1f584SPeter Brune @*/ 3549d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarsenLevel(DM dm, PetscInt *level) 3550d71ae5a4SJacob Faibussowitsch { 35515fe1f584SPeter Brune PetscFunctionBegin; 35525fe1f584SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 35534f572ea9SToby Isaac PetscAssertPointer(level, 2); 35545fe1f584SPeter Brune *level = dm->leveldown; 35553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35565fe1f584SPeter Brune } 35575fe1f584SPeter Brune 35589a64c4a8SMatthew G. Knepley /*@ 3559bb7acecfSBarry Smith DMSetCoarsenLevel - Sets the number of coarsenings that have generated this `DM`. 35609a64c4a8SMatthew G. Knepley 356120f4b53cSBarry Smith Collective 35629a64c4a8SMatthew G. Knepley 35639a64c4a8SMatthew G. Knepley Input Parameters: 3564bb7acecfSBarry Smith + dm - the `DM` object 35659a64c4a8SMatthew G. Knepley - level - number of coarsenings 35669a64c4a8SMatthew G. Knepley 35679a64c4a8SMatthew G. Knepley Level: developer 35689a64c4a8SMatthew G. Knepley 3569bb7acecfSBarry Smith Note: 3570bb7acecfSBarry Smith This is rarely used directly, the information is automatically set when a `DM` is created with `DMCoarsen()` 3571bb7acecfSBarry Smith 357242747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35739a64c4a8SMatthew G. Knepley @*/ 3574d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarsenLevel(DM dm, PetscInt level) 3575d71ae5a4SJacob Faibussowitsch { 35769a64c4a8SMatthew G. Knepley PetscFunctionBegin; 35779a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 35789a64c4a8SMatthew G. Knepley dm->leveldown = level; 35793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35809a64c4a8SMatthew G. Knepley } 35819a64c4a8SMatthew G. Knepley 358247c6ae99SBarry Smith /*@C 3583bb7acecfSBarry Smith DMRefineHierarchy - Refines a `DM` object, all levels at once 358447c6ae99SBarry Smith 358520f4b53cSBarry Smith Collective 358647c6ae99SBarry Smith 3587d8d19677SJose E. Roman Input Parameters: 3588bb7acecfSBarry Smith + dm - the `DM` object 358947c6ae99SBarry Smith - nlevels - the number of levels of refinement 359047c6ae99SBarry Smith 359147c6ae99SBarry Smith Output Parameter: 3592bb7acecfSBarry Smith . dmf - the refined `DM` hierarchy 359347c6ae99SBarry Smith 359447c6ae99SBarry Smith Level: developer 359547c6ae99SBarry Smith 35961cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMCoarsenHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 359747c6ae99SBarry Smith @*/ 3598d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHierarchy(DM dm, PetscInt nlevels, DM dmf[]) 3599d71ae5a4SJacob Faibussowitsch { 360047c6ae99SBarry Smith PetscFunctionBegin; 3601171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36027a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36033ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 36044f572ea9SToby Isaac PetscAssertPointer(dmf, 3); 360547c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 3606dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refinehierarchy, nlevels, dmf); 360747c6ae99SBarry Smith } else if (dm->ops->refine) { 360847c6ae99SBarry Smith PetscInt i; 360947c6ae99SBarry Smith 36109566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0])); 361148a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i])); 3612ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No RefineHierarchy for this DM yet"); 36133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 361447c6ae99SBarry Smith } 361547c6ae99SBarry Smith 361647c6ae99SBarry Smith /*@C 3617bb7acecfSBarry Smith DMCoarsenHierarchy - Coarsens a `DM` object, all levels at once 361847c6ae99SBarry Smith 361920f4b53cSBarry Smith Collective 362047c6ae99SBarry Smith 3621d8d19677SJose E. Roman Input Parameters: 3622bb7acecfSBarry Smith + dm - the `DM` object 362347c6ae99SBarry Smith - nlevels - the number of levels of coarsening 362447c6ae99SBarry Smith 362547c6ae99SBarry Smith Output Parameter: 3626bb7acecfSBarry Smith . dmc - the coarsened `DM` hierarchy 362747c6ae99SBarry Smith 362847c6ae99SBarry Smith Level: developer 362947c6ae99SBarry Smith 36301cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMRefineHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 363147c6ae99SBarry Smith @*/ 3632d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 3633d71ae5a4SJacob Faibussowitsch { 363447c6ae99SBarry Smith PetscFunctionBegin; 3635171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36367a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36373ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 36384f572ea9SToby Isaac PetscAssertPointer(dmc, 3); 363947c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 3640dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsenhierarchy, nlevels, dmc); 364147c6ae99SBarry Smith } else if (dm->ops->coarsen) { 364247c6ae99SBarry Smith PetscInt i; 364347c6ae99SBarry Smith 36449566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0])); 364548a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i])); 3646ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No CoarsenHierarchy for this DM yet"); 36473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 364847c6ae99SBarry Smith } 364947c6ae99SBarry Smith 36501a266240SBarry Smith /*@C 3651bb7acecfSBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the `DM` is destroyed 36521a266240SBarry Smith 3653bb7acecfSBarry Smith Logically Collective if the function is collective 36541a266240SBarry Smith 36551a266240SBarry Smith Input Parameters: 3656bb7acecfSBarry Smith + dm - the `DM` object 36571a266240SBarry Smith - destroy - the destroy function 36581a266240SBarry Smith 36591a266240SBarry Smith Level: intermediate 36601a266240SBarry Smith 36611cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 3662f07f9ceaSJed Brown @*/ 3663d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContextDestroy(DM dm, PetscErrorCode (*destroy)(void **)) 3664d71ae5a4SJacob Faibussowitsch { 36651a266240SBarry Smith PetscFunctionBegin; 3666171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36671a266240SBarry Smith dm->ctxdestroy = destroy; 36683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36691a266240SBarry Smith } 36701a266240SBarry Smith 3671b07ff414SBarry Smith /*@ 3672bb7acecfSBarry Smith DMSetApplicationContext - Set a user context into a `DM` object 367347c6ae99SBarry Smith 367447c6ae99SBarry Smith Not Collective 367547c6ae99SBarry Smith 367647c6ae99SBarry Smith Input Parameters: 3677bb7acecfSBarry Smith + dm - the `DM` object 367847c6ae99SBarry Smith - ctx - the user context 367947c6ae99SBarry Smith 368047c6ae99SBarry Smith Level: intermediate 368147c6ae99SBarry Smith 3682bb7acecfSBarry Smith Note: 368335cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3684bb7acecfSBarry Smith 368560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 368647c6ae99SBarry Smith @*/ 3687d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContext(DM dm, void *ctx) 3688d71ae5a4SJacob Faibussowitsch { 368947c6ae99SBarry Smith PetscFunctionBegin; 3690171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 369147c6ae99SBarry Smith dm->ctx = ctx; 36923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 369347c6ae99SBarry Smith } 369447c6ae99SBarry Smith 369547c6ae99SBarry Smith /*@ 3696bb7acecfSBarry Smith DMGetApplicationContext - Gets a user context from a `DM` object 369747c6ae99SBarry Smith 369847c6ae99SBarry Smith Not Collective 369947c6ae99SBarry Smith 370047c6ae99SBarry Smith Input Parameter: 3701bb7acecfSBarry Smith . dm - the `DM` object 370247c6ae99SBarry Smith 370347c6ae99SBarry Smith Output Parameter: 370447c6ae99SBarry Smith . ctx - the user context 370547c6ae99SBarry Smith 370647c6ae99SBarry Smith Level: intermediate 370747c6ae99SBarry Smith 3708bb7acecfSBarry Smith Note: 370935cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3710bb7acecfSBarry Smith 371142747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 371247c6ae99SBarry Smith @*/ 3713d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetApplicationContext(DM dm, void *ctx) 3714d71ae5a4SJacob Faibussowitsch { 371547c6ae99SBarry Smith PetscFunctionBegin; 3716171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37171b2093e4SBarry Smith *(void **)ctx = dm->ctx; 37183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 371947c6ae99SBarry Smith } 372047c6ae99SBarry Smith 372108da532bSDmitry Karpeev /*@C 3722bb7acecfSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for `SNESVI`. 372308da532bSDmitry Karpeev 372420f4b53cSBarry Smith Logically Collective 372508da532bSDmitry Karpeev 3726d8d19677SJose E. Roman Input Parameters: 372708da532bSDmitry Karpeev + dm - the DM object 372820f4b53cSBarry Smith - f - the function that computes variable bounds used by SNESVI (use `NULL` to cancel a previous function that was set) 372908da532bSDmitry Karpeev 373008da532bSDmitry Karpeev Level: intermediate 373108da532bSDmitry Karpeev 37321cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()`, 3733db781477SPatrick Sanan `DMSetJacobian()` 373408da532bSDmitry Karpeev @*/ 3735d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVariableBounds(DM dm, PetscErrorCode (*f)(DM, Vec, Vec)) 3736d71ae5a4SJacob Faibussowitsch { 373708da532bSDmitry Karpeev PetscFunctionBegin; 37385a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 373908da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 37403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 374108da532bSDmitry Karpeev } 374208da532bSDmitry Karpeev 374308da532bSDmitry Karpeev /*@ 3744bb7acecfSBarry Smith DMHasVariableBounds - does the `DM` object have a variable bounds function? 374508da532bSDmitry Karpeev 374608da532bSDmitry Karpeev Not Collective 374708da532bSDmitry Karpeev 374808da532bSDmitry Karpeev Input Parameter: 3749bb7acecfSBarry Smith . dm - the `DM` object to destroy 375008da532bSDmitry Karpeev 375108da532bSDmitry Karpeev Output Parameter: 3752bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the variable bounds function exists 375308da532bSDmitry Karpeev 375408da532bSDmitry Karpeev Level: developer 375508da532bSDmitry Karpeev 37561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 375708da532bSDmitry Karpeev @*/ 3758d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasVariableBounds(DM dm, PetscBool *flg) 3759d71ae5a4SJacob Faibussowitsch { 376008da532bSDmitry Karpeev PetscFunctionBegin; 37615a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37624f572ea9SToby Isaac PetscAssertPointer(flg, 2); 376308da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 37643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 376508da532bSDmitry Karpeev } 376608da532bSDmitry Karpeev 376708da532bSDmitry Karpeev /*@C 3768bb7acecfSBarry Smith DMComputeVariableBounds - compute variable bounds used by `SNESVI`. 376908da532bSDmitry Karpeev 377020f4b53cSBarry Smith Logically Collective 377108da532bSDmitry Karpeev 3772f899ff85SJose E. Roman Input Parameter: 3773bb7acecfSBarry Smith . dm - the `DM` object 377408da532bSDmitry Karpeev 377560225df5SJacob Faibussowitsch Output Parameters: 377608da532bSDmitry Karpeev + xl - lower bound 377708da532bSDmitry Karpeev - xu - upper bound 377808da532bSDmitry Karpeev 3779907376e6SBarry Smith Level: advanced 3780907376e6SBarry Smith 378120f4b53cSBarry Smith Note: 378295452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 378308da532bSDmitry Karpeev 37841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 378508da532bSDmitry Karpeev @*/ 3786d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 3787d71ae5a4SJacob Faibussowitsch { 378808da532bSDmitry Karpeev PetscFunctionBegin; 37895a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 379008da532bSDmitry Karpeev PetscValidHeaderSpecific(xl, VEC_CLASSID, 2); 37915a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu, VEC_CLASSID, 3); 3792dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, computevariablebounds, xl, xu); 37933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 379408da532bSDmitry Karpeev } 379508da532bSDmitry Karpeev 3796b0ae01b7SPeter Brune /*@ 3797bb7acecfSBarry Smith DMHasColoring - does the `DM` object have a method of providing a coloring? 3798b0ae01b7SPeter Brune 3799b0ae01b7SPeter Brune Not Collective 3800b0ae01b7SPeter Brune 3801b0ae01b7SPeter Brune Input Parameter: 3802b0ae01b7SPeter Brune . dm - the DM object 3803b0ae01b7SPeter Brune 3804b0ae01b7SPeter Brune Output Parameter: 3805bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateColoring()`. 3806b0ae01b7SPeter Brune 3807b0ae01b7SPeter Brune Level: developer 3808b0ae01b7SPeter Brune 38091cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateColoring()` 3810b0ae01b7SPeter Brune @*/ 3811d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasColoring(DM dm, PetscBool *flg) 3812d71ae5a4SJacob Faibussowitsch { 3813b0ae01b7SPeter Brune PetscFunctionBegin; 38145a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38154f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3816b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 38173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3818b0ae01b7SPeter Brune } 3819b0ae01b7SPeter Brune 38203ad4599aSBarry Smith /*@ 3821bb7acecfSBarry Smith DMHasCreateRestriction - does the `DM` object have a method of providing a restriction? 38223ad4599aSBarry Smith 38233ad4599aSBarry Smith Not Collective 38243ad4599aSBarry Smith 38253ad4599aSBarry Smith Input Parameter: 3826bb7acecfSBarry Smith . dm - the `DM` object 38273ad4599aSBarry Smith 38283ad4599aSBarry Smith Output Parameter: 3829bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateRestriction()`. 38303ad4599aSBarry Smith 38313ad4599aSBarry Smith Level: developer 38323ad4599aSBarry Smith 38331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateRestriction()`, `DMHasCreateInterpolation()`, `DMHasCreateInjection()` 38343ad4599aSBarry Smith @*/ 3835d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateRestriction(DM dm, PetscBool *flg) 3836d71ae5a4SJacob Faibussowitsch { 38373ad4599aSBarry Smith PetscFunctionBegin; 38385a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38394f572ea9SToby Isaac PetscAssertPointer(flg, 2); 38403ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 38413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38423ad4599aSBarry Smith } 38433ad4599aSBarry Smith 3844a7058e45SLawrence Mitchell /*@ 3845bb7acecfSBarry Smith DMHasCreateInjection - does the `DM` object have a method of providing an injection? 3846a7058e45SLawrence Mitchell 3847a7058e45SLawrence Mitchell Not Collective 3848a7058e45SLawrence Mitchell 3849a7058e45SLawrence Mitchell Input Parameter: 3850bb7acecfSBarry Smith . dm - the `DM` object 3851a7058e45SLawrence Mitchell 3852a7058e45SLawrence Mitchell Output Parameter: 3853bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateInjection()`. 3854a7058e45SLawrence Mitchell 3855a7058e45SLawrence Mitchell Level: developer 3856a7058e45SLawrence Mitchell 38571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateInjection()`, `DMHasCreateRestriction()`, `DMHasCreateInterpolation()` 3858a7058e45SLawrence Mitchell @*/ 3859d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateInjection(DM dm, PetscBool *flg) 3860d71ae5a4SJacob Faibussowitsch { 3861a7058e45SLawrence Mitchell PetscFunctionBegin; 38625a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38634f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3864dbbe0bcdSBarry Smith if (dm->ops->hascreateinjection) PetscUseTypeMethod(dm, hascreateinjection, flg); 3865ad540459SPierre Jolivet else *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 38663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3867a7058e45SLawrence Mitchell } 3868a7058e45SLawrence Mitchell 38690298fd71SBarry Smith PetscFunctionList DMList = NULL; 3870264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3871264ace61SBarry Smith 3872264ace61SBarry Smith /*@C 3873bb7acecfSBarry Smith DMSetType - Builds a `DM`, for a particular `DM` implementation. 3874264ace61SBarry Smith 387520f4b53cSBarry Smith Collective 3876264ace61SBarry Smith 3877264ace61SBarry Smith Input Parameters: 3878bb7acecfSBarry Smith + dm - The `DM` object 3879bb7acecfSBarry Smith - method - The name of the `DMType`, for example `DMDA`, `DMPLEX` 3880264ace61SBarry Smith 3881264ace61SBarry Smith Options Database Key: 3882bb7acecfSBarry Smith . -dm_type <type> - Sets the `DM` type; use -help for a list of available types 3883264ace61SBarry Smith 3884264ace61SBarry Smith Level: intermediate 3885264ace61SBarry Smith 3886bb7acecfSBarry Smith Note: 38870462cc06SPierre Jolivet Of the `DM` is constructed by directly calling a function to construct a particular `DM`, for example, `DMDACreate2d()` or `DMPlexCreateBoxMesh()` 3888bb7acecfSBarry Smith 38891cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMGetType()`, `DMCreate()`, `DMDACreate2d()` 3890264ace61SBarry Smith @*/ 3891d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetType(DM dm, DMType method) 3892d71ae5a4SJacob Faibussowitsch { 3893264ace61SBarry Smith PetscErrorCode (*r)(DM); 3894264ace61SBarry Smith PetscBool match; 3895264ace61SBarry Smith 3896264ace61SBarry Smith PetscFunctionBegin; 3897264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, method, &match)); 38993ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 3900264ace61SBarry Smith 39019566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 39029566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(DMList, method, &r)); 39037a8be351SBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3904264ace61SBarry Smith 3905dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, destroy); 39069566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops, sizeof(*dm->ops))); 39079566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)dm, method)); 39089566063dSJacob Faibussowitsch PetscCall((*r)(dm)); 39093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3910264ace61SBarry Smith } 3911264ace61SBarry Smith 3912264ace61SBarry Smith /*@C 3913bb7acecfSBarry Smith DMGetType - Gets the `DM` type name (as a string) from the `DM`. 3914264ace61SBarry Smith 3915264ace61SBarry Smith Not Collective 3916264ace61SBarry Smith 3917264ace61SBarry Smith Input Parameter: 3918bb7acecfSBarry Smith . dm - The `DM` 3919264ace61SBarry Smith 3920264ace61SBarry Smith Output Parameter: 3921bb7acecfSBarry Smith . type - The `DMType` name 3922264ace61SBarry Smith 3923264ace61SBarry Smith Level: intermediate 3924264ace61SBarry Smith 39251cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMSetType()`, `DMCreate()` 3926264ace61SBarry Smith @*/ 3927d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetType(DM dm, DMType *type) 3928d71ae5a4SJacob Faibussowitsch { 3929264ace61SBarry Smith PetscFunctionBegin; 3930264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39314f572ea9SToby Isaac PetscAssertPointer(type, 2); 39329566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 3933264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 39343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3935264ace61SBarry Smith } 3936264ace61SBarry Smith 393767a56275SMatthew G Knepley /*@C 3938bb7acecfSBarry Smith DMConvert - Converts a `DM` to another `DM`, either of the same or different type. 393967a56275SMatthew G Knepley 394020f4b53cSBarry Smith Collective 394167a56275SMatthew G Knepley 394267a56275SMatthew G Knepley Input Parameters: 3943bb7acecfSBarry Smith + dm - the `DM` 3944bb7acecfSBarry Smith - newtype - new `DM` type (use "same" for the same type) 394567a56275SMatthew G Knepley 394667a56275SMatthew G Knepley Output Parameter: 3947bb7acecfSBarry Smith . M - pointer to new `DM` 394867a56275SMatthew G Knepley 394920f4b53cSBarry Smith Level: intermediate 395020f4b53cSBarry Smith 395167a56275SMatthew G Knepley Notes: 3952bb7acecfSBarry Smith Cannot be used to convert a sequential `DM` to a parallel or a parallel to sequential, 3953bb7acecfSBarry Smith the MPI communicator of the generated `DM` is always the same as the communicator 3954bb7acecfSBarry Smith of the input `DM`. 395567a56275SMatthew G Knepley 39561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetType()`, `DMCreate()`, `DMClone()` 395767a56275SMatthew G Knepley @*/ 3958d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 3959d71ae5a4SJacob Faibussowitsch { 396067a56275SMatthew G Knepley DM B; 396167a56275SMatthew G Knepley char convname[256]; 3962c067b6caSMatthew G. Knepley PetscBool sametype /*, issame */; 396367a56275SMatthew G Knepley 396467a56275SMatthew G Knepley PetscFunctionBegin; 396567a56275SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 396667a56275SMatthew G Knepley PetscValidType(dm, 1); 39674f572ea9SToby Isaac PetscAssertPointer(M, 3); 39689566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, newtype, &sametype)); 39699566063dSJacob Faibussowitsch /* PetscCall(PetscStrcmp(newtype, "same", &issame)); */ 3970c067b6caSMatthew G. Knepley if (sametype) { 3971c067b6caSMatthew G. Knepley *M = dm; 39729566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 39733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3974c067b6caSMatthew G. Knepley } else { 39750298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM *) = NULL; 397667a56275SMatthew G Knepley 397767a56275SMatthew G Knepley /* 397867a56275SMatthew G Knepley Order of precedence: 397967a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 398067a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 398167a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 398267a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 398367a56275SMatthew G Knepley 5) Use a really basic converter. 398467a56275SMatthew G Knepley */ 398567a56275SMatthew G Knepley 398667a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 39879566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 39889566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 39899566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 39909566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 39919566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 39929566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)dm, convname, &conv)); 399367a56275SMatthew G Knepley if (conv) goto foundconv; 399467a56275SMatthew G Knepley 399567a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 39969566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &B)); 39979566063dSJacob Faibussowitsch PetscCall(DMSetType(B, newtype)); 39989566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 39999566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40009566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40019566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40029566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40039566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 400467a56275SMatthew G Knepley if (conv) { 40059566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 400667a56275SMatthew G Knepley goto foundconv; 400767a56275SMatthew G Knepley } 400867a56275SMatthew G Knepley 400967a56275SMatthew G Knepley #if 0 401067a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 401167a56275SMatthew G Knepley conv = B->ops->convertfrom; 40129566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 401367a56275SMatthew G Knepley if (conv) goto foundconv; 401467a56275SMatthew G Knepley 401567a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 401667a56275SMatthew G Knepley if (dm->ops->convert) { 401767a56275SMatthew G Knepley conv = dm->ops->convert; 401867a56275SMatthew G Knepley } 401967a56275SMatthew G Knepley if (conv) goto foundconv; 402067a56275SMatthew G Knepley #endif 402167a56275SMatthew G Knepley 402267a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 402398921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject)dm)->type_name, newtype); 402467a56275SMatthew G Knepley 402567a56275SMatthew G Knepley foundconv: 40269566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Convert, dm, 0, 0, 0)); 40279566063dSJacob Faibussowitsch PetscCall((*conv)(dm, newtype, M)); 402812fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 402990b157c4SStefano Zampini { 40304fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 40316858538eSMatthew G. Knepley 40324fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 40334fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*M, maxCell, Lstart, L)); 4034c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 40359566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->vectype)); 40369566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*M)->vectype)); 40379566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->mattype)); 40389566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*M)->mattype)); 403912fa691eSMatthew G. Knepley } 40409566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Convert, dm, 0, 0, 0)); 404167a56275SMatthew G Knepley } 40429566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 40433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 404467a56275SMatthew G Knepley } 4045264ace61SBarry Smith 4046264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 4047264ace61SBarry Smith 4048264ace61SBarry Smith /*@C 4049bb7acecfSBarry Smith DMRegister - Adds a new `DM` type implementation 40501c84c290SBarry Smith 40511c84c290SBarry Smith Not Collective 40521c84c290SBarry Smith 40531c84c290SBarry Smith Input Parameters: 405420f4b53cSBarry Smith + sname - The name of a new user-defined creation routine 405520f4b53cSBarry Smith - function - The creation routine itself 405620f4b53cSBarry Smith 405720f4b53cSBarry Smith Level: advanced 40581c84c290SBarry Smith 40591c84c290SBarry Smith Notes: 406020f4b53cSBarry Smith `DMRegister()` may be called multiple times to add several user-defined `DM`s 40611c84c290SBarry Smith 406260225df5SJacob Faibussowitsch Example Usage: 40631c84c290SBarry Smith .vb 4064bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 40651c84c290SBarry Smith .ve 40661c84c290SBarry Smith 406720f4b53cSBarry Smith Then, your `DM` type can be chosen with the procedural interface via 40681c84c290SBarry Smith .vb 40691c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 40701c84c290SBarry Smith DMSetType(DM,"my_da"); 40711c84c290SBarry Smith .ve 40721c84c290SBarry Smith or at runtime via the option 40731c84c290SBarry Smith .vb 40741c84c290SBarry Smith -da_type my_da 40751c84c290SBarry Smith .ve 4076264ace61SBarry Smith 40771cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMSetType()`, `DMRegisterAll()`, `DMRegisterDestroy()` 4078264ace61SBarry Smith @*/ 4079d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRegister(const char sname[], PetscErrorCode (*function)(DM)) 4080d71ae5a4SJacob Faibussowitsch { 4081264ace61SBarry Smith PetscFunctionBegin; 40829566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 40839566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&DMList, sname, function)); 40843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4085264ace61SBarry Smith } 4086264ace61SBarry Smith 4087b859378eSBarry Smith /*@C 4088bb7acecfSBarry Smith DMLoad - Loads a DM that has been stored in binary with `DMView()`. 4089b859378eSBarry Smith 409020f4b53cSBarry Smith Collective 4091b859378eSBarry Smith 4092b859378eSBarry Smith Input Parameters: 4093bb7acecfSBarry Smith + newdm - the newly loaded `DM`, this needs to have been created with `DMCreate()` or 4094bb7acecfSBarry Smith some related function before a call to `DMLoad()`. 4095bb7acecfSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or 4096bb7acecfSBarry Smith `PETSCVIEWERHDF5` file viewer, obtained from `PetscViewerHDF5Open()` 4097b859378eSBarry Smith 4098b859378eSBarry Smith Level: intermediate 4099b859378eSBarry Smith 4100b859378eSBarry Smith Notes: 410155849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4102b859378eSBarry Smith 4103bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` format, one can save multiple `DMPLEX` 4104bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 4105bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 4106cd7e8a5eSksagiyam 41071cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewerBinaryOpen()`, `DMView()`, `MatLoad()`, `VecLoad()` 4108b859378eSBarry Smith @*/ 4109d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4110d71ae5a4SJacob Faibussowitsch { 41119331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4112b859378eSBarry Smith 4113b859378eSBarry Smith PetscFunctionBegin; 4114b859378eSBarry Smith PetscValidHeaderSpecific(newdm, DM_CLASSID, 1); 4115b859378eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 41169566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckReadable(viewer)); 41179566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 41189566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 41199566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Load, viewer, 0, 0, 0)); 41209331c7a4SMatthew G. Knepley if (isbinary) { 41219331c7a4SMatthew G. Knepley PetscInt classid; 41229331c7a4SMatthew G. Knepley char type[256]; 4123b859378eSBarry Smith 41249566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 41257a8be351SBarry Smith PetscCheck(classid == DM_FILE_CLASSID, PetscObjectComm((PetscObject)newdm), PETSC_ERR_ARG_WRONG, "Not DM next in file, classid found %d", (int)classid); 41269566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 41279566063dSJacob Faibussowitsch PetscCall(DMSetType(newdm, type)); 4128dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41299331c7a4SMatthew G. Knepley } else if (ishdf5) { 4130dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41319331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 41329566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Load, viewer, 0, 0, 0)); 41333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4134b859378eSBarry Smith } 4135b859378eSBarry Smith 41367da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 41377da65231SMatthew G Knepley 41382ecf6ec3SMatthew G. Knepley PetscErrorCode DMPrintCellIndices(PetscInt c, const char name[], PetscInt len, const PetscInt x[]) 41392ecf6ec3SMatthew G. Knepley { 41402ecf6ec3SMatthew G. Knepley PetscInt f; 41412ecf6ec3SMatthew G. Knepley 41422ecf6ec3SMatthew G. Knepley PetscFunctionBegin; 41432ecf6ec3SMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41442ecf6ec3SMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %" PetscInt_FMT " |\n", x[f])); 41452ecf6ec3SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 41462ecf6ec3SMatthew G. Knepley } 41472ecf6ec3SMatthew G. Knepley 4148d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4149d71ae5a4SJacob Faibussowitsch { 41501d47ebbbSSatish Balay PetscInt f; 41511b30c384SMatthew G Knepley 41527da65231SMatthew G Knepley PetscFunctionBegin; 415363a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 415448a46eb9SPierre Jolivet for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]))); 41553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41567da65231SMatthew G Knepley } 41577da65231SMatthew G Knepley 41585962854dSMatthew G. Knepley PetscErrorCode DMPrintCellVectorReal(PetscInt c, const char name[], PetscInt len, const PetscReal x[]) 41595962854dSMatthew G. Knepley { 41605962854dSMatthew G. Knepley PetscInt f; 41615962854dSMatthew G. Knepley 41625962854dSMatthew G. Knepley PetscFunctionBegin; 41635962854dSMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41645962854dSMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)x[f])); 41655962854dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 41665962854dSMatthew G. Knepley } 41675962854dSMatthew G. Knepley 4168d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4169d71ae5a4SJacob Faibussowitsch { 41701b30c384SMatthew G Knepley PetscInt f, g; 41717da65231SMatthew G Knepley 41727da65231SMatthew G Knepley PetscFunctionBegin; 417363a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41741d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 41759566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |")); 417648a46eb9SPierre Jolivet for (g = 0; g < cols; ++g) PetscCall(PetscPrintf(PETSC_COMM_SELF, " % 9.5g", (double)PetscRealPart(A[f * cols + g]))); 41779566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |\n")); 41787da65231SMatthew G Knepley } 41793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41807da65231SMatthew G Knepley } 4181e7c4fc90SDmitry Karpeev 4182d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4183d71ae5a4SJacob Faibussowitsch { 41840c5b8624SToby Isaac PetscInt localSize, bs; 41850c5b8624SToby Isaac PetscMPIInt size; 41860c5b8624SToby Isaac Vec x, xglob; 41870c5b8624SToby Isaac const PetscScalar *xarray; 4188e759306cSMatthew G. Knepley 4189e759306cSMatthew G. Knepley PetscFunctionBegin; 41909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 41919566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &x)); 41929566063dSJacob Faibussowitsch PetscCall(VecCopy(X, x)); 419393ec0da9SPierre Jolivet PetscCall(VecFilter(x, tol)); 41949566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "%s:\n", name)); 41950c5b8624SToby Isaac if (size > 1) { 41969566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(x, &localSize)); 41979566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xarray)); 41989566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(x, &bs)); 41999566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm), bs, localSize, PETSC_DETERMINE, xarray, &xglob)); 42000c5b8624SToby Isaac } else { 42010c5b8624SToby Isaac xglob = x; 42020c5b8624SToby Isaac } 42039566063dSJacob Faibussowitsch PetscCall(VecView(xglob, PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)dm)))); 42040c5b8624SToby Isaac if (size > 1) { 42059566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xglob)); 42069566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xarray)); 42070c5b8624SToby Isaac } 42089566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 42093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4210e759306cSMatthew G. Knepley } 4211e759306cSMatthew G. Knepley 421288ed4aceSMatthew G Knepley /*@ 4213bb7acecfSBarry Smith DMGetSection - Get the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMGetLocalSection()`. Deprecated in v3.12 4214061576a5SJed Brown 4215061576a5SJed Brown Input Parameter: 4216bb7acecfSBarry Smith . dm - The `DM` 4217061576a5SJed Brown 4218061576a5SJed Brown Output Parameter: 4219bb7acecfSBarry Smith . section - The `PetscSection` 4220061576a5SJed Brown 422120f4b53cSBarry Smith Options Database Key: 4222bb7acecfSBarry Smith . -dm_petscsection_view - View the `PetscSection` created by the `DM` 4223061576a5SJed Brown 4224061576a5SJed Brown Level: advanced 4225061576a5SJed Brown 4226061576a5SJed Brown Notes: 4227bb7acecfSBarry Smith Use `DMGetLocalSection()` in new code. 4228061576a5SJed Brown 4229bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 4230061576a5SJed Brown 42311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetLocalSection()`, `DMSetLocalSection()`, `DMGetGlobalSection()` 4232061576a5SJed Brown @*/ 4233d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4234d71ae5a4SJacob Faibussowitsch { 4235061576a5SJed Brown PetscFunctionBegin; 42369566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, section)); 42373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4238061576a5SJed Brown } 4239061576a5SJed Brown 4240061576a5SJed Brown /*@ 4241bb7acecfSBarry Smith DMGetLocalSection - Get the `PetscSection` encoding the local data layout for the `DM`. 424288ed4aceSMatthew G Knepley 424388ed4aceSMatthew G Knepley Input Parameter: 4244bb7acecfSBarry Smith . dm - The `DM` 424588ed4aceSMatthew G Knepley 424688ed4aceSMatthew G Knepley Output Parameter: 4247bb7acecfSBarry Smith . section - The `PetscSection` 424888ed4aceSMatthew G Knepley 424920f4b53cSBarry Smith Options Database Key: 4250bb7acecfSBarry Smith . -dm_petscsection_view - View the section created by the `DM` 4251e5893cccSMatthew G. Knepley 425288ed4aceSMatthew G Knepley Level: intermediate 425388ed4aceSMatthew G Knepley 4254bb7acecfSBarry Smith Note: 4255bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 425688ed4aceSMatthew G Knepley 42571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetGlobalSection()` 425888ed4aceSMatthew G Knepley @*/ 4259d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 4260d71ae5a4SJacob Faibussowitsch { 426188ed4aceSMatthew G Knepley PetscFunctionBegin; 426288ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 42634f572ea9SToby Isaac PetscAssertPointer(section, 2); 42641bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4265e5e52638SMatthew G. Knepley PetscInt d; 4266e5e52638SMatthew G. Knepley 426745480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 426845480ffeSMatthew G. Knepley PetscObject obj = (PetscObject)dm; 426945480ffeSMatthew G. Knepley PetscViewer viewer; 427045480ffeSMatthew G. Knepley PetscViewerFormat format; 427145480ffeSMatthew G. Knepley PetscBool flg; 427245480ffeSMatthew G. Knepley 42739566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg)); 42749566063dSJacob Faibussowitsch if (flg) PetscCall(PetscViewerPushFormat(viewer, format)); 427545480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 42769566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(dm->probs[d].ds)); 42779566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDSView(dm->probs[d].ds, viewer)); 427845480ffeSMatthew G. Knepley } 427945480ffeSMatthew G. Knepley if (flg) { 42809566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 42819566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 42829566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 428345480ffeSMatthew G. Knepley } 428445480ffeSMatthew G. Knepley } 4285dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalsection); 42869566063dSJacob Faibussowitsch if (dm->localSection) PetscCall(PetscObjectViewFromOptions((PetscObject)dm->localSection, NULL, "-dm_petscsection_view")); 42872f0f8703SMatthew G. Knepley } 42881bb6d2a8SBarry Smith *section = dm->localSection; 42893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 429088ed4aceSMatthew G Knepley } 429188ed4aceSMatthew G Knepley 429288ed4aceSMatthew G Knepley /*@ 4293bb7acecfSBarry Smith DMSetSection - Set the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMSetLocalSection()`. Deprecated in v3.12 4294061576a5SJed Brown 4295061576a5SJed Brown Input Parameters: 4296bb7acecfSBarry Smith + dm - The `DM` 4297bb7acecfSBarry Smith - section - The `PetscSection` 4298061576a5SJed Brown 4299061576a5SJed Brown Level: advanced 4300061576a5SJed Brown 4301061576a5SJed Brown Notes: 4302bb7acecfSBarry Smith Use `DMSetLocalSection()` in new code. 4303061576a5SJed Brown 4304bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4305061576a5SJed Brown 43061cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetLocalSection()`, `DMSetGlobalSection()` 4307061576a5SJed Brown @*/ 4308d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSection(DM dm, PetscSection section) 4309d71ae5a4SJacob Faibussowitsch { 4310061576a5SJed Brown PetscFunctionBegin; 43119566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm, section)); 43123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4313061576a5SJed Brown } 4314061576a5SJed Brown 4315061576a5SJed Brown /*@ 4316bb7acecfSBarry Smith DMSetLocalSection - Set the `PetscSection` encoding the local data layout for the `DM`. 431788ed4aceSMatthew G Knepley 431888ed4aceSMatthew G Knepley Input Parameters: 4319bb7acecfSBarry Smith + dm - The `DM` 4320bb7acecfSBarry Smith - section - The `PetscSection` 432188ed4aceSMatthew G Knepley 432288ed4aceSMatthew G Knepley Level: intermediate 432388ed4aceSMatthew G Knepley 4324bb7acecfSBarry Smith Note: 4325bb7acecfSBarry Smith Any existing Section will be destroyed 432688ed4aceSMatthew G Knepley 43271cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscSection`, `DMGetLocalSection()`, `DMSetGlobalSection()` 432888ed4aceSMatthew G Knepley @*/ 4329d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 4330d71ae5a4SJacob Faibussowitsch { 4331c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4332af122d2aSMatthew G Knepley PetscInt f; 433388ed4aceSMatthew G Knepley 433488ed4aceSMatthew G Knepley PetscFunctionBegin; 433588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4336b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 43379566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 43389566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->localSection)); 43391bb6d2a8SBarry Smith dm->localSection = section; 43409566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(dm->localSection, &numFields)); 4341af122d2aSMatthew G Knepley if (numFields) { 43429566063dSJacob Faibussowitsch PetscCall(DMSetNumFields(dm, numFields)); 4343af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43440f21e855SMatthew G. Knepley PetscObject disc; 4345af122d2aSMatthew G Knepley const char *name; 4346af122d2aSMatthew G Knepley 43479566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(dm->localSection, f, &name)); 43489566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, &disc)); 43499566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName(disc, name)); 4350af122d2aSMatthew G Knepley } 4351af122d2aSMatthew G Knepley } 4352e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 43539566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 43543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 435588ed4aceSMatthew G Knepley } 435688ed4aceSMatthew G Knepley 43579435951eSToby Isaac /*@ 4358bb7acecfSBarry Smith DMGetDefaultConstraints - Get the `PetscSection` and `Mat` that specify the local constraint interpolation. See `DMSetDefaultConstraints()` for a description of the purpose of constraint interpolation. 43599435951eSToby Isaac 436020f4b53cSBarry Smith not Collective 4361e228b242SToby Isaac 43629435951eSToby Isaac Input Parameter: 4363bb7acecfSBarry Smith . dm - The `DM` 43649435951eSToby Isaac 4365d8d19677SJose E. Roman Output Parameters: 436620f4b53cSBarry 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. 436720f4b53cSBarry 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. 436879769bd5SJed Brown - bias - Vector containing bias to be added to constrained dofs 43699435951eSToby Isaac 43709435951eSToby Isaac Level: advanced 43719435951eSToby Isaac 4372bb7acecfSBarry Smith Note: 4373bb7acecfSBarry Smith This gets borrowed references, so the user should not destroy the `PetscSection`, `Mat`, or `Vec`. 43749435951eSToby Isaac 43751cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDefaultConstraints()` 43769435951eSToby Isaac @*/ 4377d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat, Vec *bias) 4378d71ae5a4SJacob Faibussowitsch { 43799435951eSToby Isaac PetscFunctionBegin; 43809435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4381dbbe0bcdSBarry Smith if (!dm->defaultConstraint.section && !dm->defaultConstraint.mat && dm->ops->createdefaultconstraints) PetscUseTypeMethod(dm, createdefaultconstraints); 43823b8ba7d1SJed Brown if (section) *section = dm->defaultConstraint.section; 43833b8ba7d1SJed Brown if (mat) *mat = dm->defaultConstraint.mat; 438479769bd5SJed Brown if (bias) *bias = dm->defaultConstraint.bias; 43853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 43869435951eSToby Isaac } 43879435951eSToby Isaac 43889435951eSToby Isaac /*@ 4389bb7acecfSBarry Smith DMSetDefaultConstraints - Set the `PetscSection` and `Mat` that specify the local constraint interpolation. 43909435951eSToby Isaac 439120f4b53cSBarry Smith Collective 4392e228b242SToby Isaac 43939435951eSToby Isaac Input Parameters: 4394bb7acecfSBarry Smith + dm - The `DM` 4395bb7acecfSBarry 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). 439620f4b53cSBarry 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). 439720f4b53cSBarry 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). 43989435951eSToby Isaac 43999435951eSToby Isaac Level: advanced 44009435951eSToby Isaac 440120f4b53cSBarry Smith Notes: 440220f4b53cSBarry 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()`. 440320f4b53cSBarry Smith 440420f4b53cSBarry 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. 440520f4b53cSBarry Smith 4406bb7acecfSBarry Smith This increments the references of the `PetscSection`, `Mat`, and `Vec`, so they user can destroy them. 44079435951eSToby Isaac 44081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDefaultConstraints()` 44099435951eSToby Isaac @*/ 4410d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat, Vec bias) 4411d71ae5a4SJacob Faibussowitsch { 4412e228b242SToby Isaac PetscMPIInt result; 44139435951eSToby Isaac 44149435951eSToby Isaac PetscFunctionBegin; 44159435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4416e228b242SToby Isaac if (section) { 4417e228b242SToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 44189566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)section), &result)); 44197a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint section must have local communicator"); 4420e228b242SToby Isaac } 4421e228b242SToby Isaac if (mat) { 4422e228b242SToby Isaac PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 44239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)mat), &result)); 44247a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint matrix must have local communicator"); 4425e228b242SToby Isaac } 442679769bd5SJed Brown if (bias) { 442779769bd5SJed Brown PetscValidHeaderSpecific(bias, VEC_CLASSID, 4); 44289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)bias), &result)); 442979769bd5SJed Brown PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint bias must have local communicator"); 443079769bd5SJed Brown } 44319566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 44329566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->defaultConstraint.section)); 44333b8ba7d1SJed Brown dm->defaultConstraint.section = section; 44349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 44359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dm->defaultConstraint.mat)); 44363b8ba7d1SJed Brown dm->defaultConstraint.mat = mat; 44379566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)bias)); 44389566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dm->defaultConstraint.bias)); 443979769bd5SJed Brown dm->defaultConstraint.bias = bias; 44403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44419435951eSToby Isaac } 44429435951eSToby Isaac 4443497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4444507e4973SMatthew G. Knepley /* 4445bb7acecfSBarry Smith DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. Generates and error if they are not consistent. 4446507e4973SMatthew G. Knepley 4447507e4973SMatthew G. Knepley Input Parameters: 4448bb7acecfSBarry Smith + dm - The `DM` 4449bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4450bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 4451507e4973SMatthew G. Knepley 4452507e4973SMatthew G. Knepley Level: intermediate 4453507e4973SMatthew G. Knepley 44541cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()` 4455507e4973SMatthew G. Knepley */ 4456d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4457d71ae5a4SJacob Faibussowitsch { 4458507e4973SMatthew G. Knepley MPI_Comm comm; 4459507e4973SMatthew G. Knepley PetscLayout layout; 4460507e4973SMatthew G. Knepley const PetscInt *ranges; 4461507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4462507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4463507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4464507e4973SMatthew G. Knepley 4465507e4973SMatthew G. Knepley PetscFunctionBegin; 44669566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4467507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 44699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 44709566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(globalSection, &pStart, &pEnd)); 44719566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(globalSection, &nroots)); 44729566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &layout)); 44739566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(layout, 1)); 44749566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(layout, nroots)); 44759566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(layout)); 44769566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRanges(layout, &ranges)); 4477507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4478f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4479507e4973SMatthew G. Knepley 44809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(localSection, p, &dof)); 44819566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(localSection, p, &off)); 44829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(localSection, p, &cdof)); 44839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(globalSection, p, &gdof)); 44849566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(globalSection, p, &gcdof)); 44859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(globalSection, p, &goff)); 4486507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 44879371c9d4SSatish Balay if ((gdof < 0 ? -(gdof + 1) : gdof) != dof) { 44889371c9d4SSatish 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)); 44899371c9d4SSatish Balay valid = PETSC_FALSE; 44909371c9d4SSatish Balay } 44919371c9d4SSatish Balay if (gcdof && (gcdof != cdof)) { 44929371c9d4SSatish 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)); 44939371c9d4SSatish Balay valid = PETSC_FALSE; 44949371c9d4SSatish Balay } 4495507e4973SMatthew G. Knepley if (gdof < 0) { 4496507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof + 1) - gcdof : gdof - gcdof; 4497507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4498507e4973SMatthew G. Knepley PetscInt offset = -(goff + 1) + d, r; 4499507e4973SMatthew G. Knepley 45009566063dSJacob Faibussowitsch PetscCall(PetscFindInt(offset, size + 1, ranges, &r)); 4501507e4973SMatthew G. Knepley if (r < 0) r = -(r + 2); 45029371c9d4SSatish Balay if ((r < 0) || (r >= size)) { 45039371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Point %" PetscInt_FMT " mapped to invalid process %" PetscInt_FMT " (%" PetscInt_FMT ", %" PetscInt_FMT ")\n", rank, p, r, gdof, goff)); 45049371c9d4SSatish Balay valid = PETSC_FALSE; 45059371c9d4SSatish Balay break; 45069371c9d4SSatish Balay } 4507507e4973SMatthew G. Knepley } 4508507e4973SMatthew G. Knepley } 4509507e4973SMatthew G. Knepley } 45109566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&layout)); 45119566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 45121c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm)); 4513507e4973SMatthew G. Knepley if (!gvalid) { 45149566063dSJacob Faibussowitsch PetscCall(DMView(dm, NULL)); 4515507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4516507e4973SMatthew G. Knepley } 45173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4518507e4973SMatthew G. Knepley } 4519f741bcd2SMatthew G. Knepley #endif 4520507e4973SMatthew G. Knepley 45215f06a3ddSJed Brown static PetscErrorCode DMGetIsoperiodicPointSF_Internal(DM dm, PetscSF *sf) 45226725e60dSJed Brown { 45236725e60dSJed Brown PetscErrorCode (*f)(DM, PetscSF *); 45246725e60dSJed Brown PetscFunctionBegin; 45256725e60dSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45264f572ea9SToby Isaac PetscAssertPointer(sf, 2); 45275f06a3ddSJed Brown PetscCall(PetscObjectQueryFunction((PetscObject)dm, "DMGetIsoperiodicPointSF_C", &f)); 45286725e60dSJed Brown if (f) PetscCall(f(dm, sf)); 45296725e60dSJed Brown else *sf = dm->sf; 45303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45316725e60dSJed Brown } 45326725e60dSJed Brown 453388ed4aceSMatthew G Knepley /*@ 4534bb7acecfSBarry Smith DMGetGlobalSection - Get the `PetscSection` encoding the global data layout for the `DM`. 453588ed4aceSMatthew G Knepley 453620f4b53cSBarry Smith Collective 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 45491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `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); 45554f572ea9SToby Isaac PetscAssertPointer(section, 2); 45561bb6d2a8SBarry Smith if (!dm->globalSection) { 4557fd59a867SMatthew G. Knepley PetscSection s; 45586725e60dSJed Brown PetscSF sf; 4559fd59a867SMatthew G. Knepley 45609566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 45617a8be351SBarry Smith PetscCheck(s, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 45627a8be351SBarry Smith PetscCheck(dm->sf, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 45635f06a3ddSJed Brown PetscCall(DMGetIsoperiodicPointSF_Internal(dm, &sf)); 45646725e60dSJed Brown PetscCall(PetscSectionCreateGlobalSection(s, sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection)); 45659566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&dm->map)); 45669566063dSJacob Faibussowitsch PetscCall(PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map)); 45679566063dSJacob Faibussowitsch PetscCall(PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view")); 456888ed4aceSMatthew G Knepley } 45691bb6d2a8SBarry Smith *section = dm->globalSection; 45703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 457188ed4aceSMatthew G Knepley } 457288ed4aceSMatthew G Knepley 4573b21d0597SMatthew G Knepley /*@ 4574bb7acecfSBarry Smith DMSetGlobalSection - Set the `PetscSection` encoding the global data layout for the `DM`. 4575b21d0597SMatthew G Knepley 4576b21d0597SMatthew G Knepley Input Parameters: 4577bb7acecfSBarry Smith + dm - The `DM` 45782fe279fdSBarry Smith - section - The PetscSection, or `NULL` 4579b21d0597SMatthew G Knepley 4580b21d0597SMatthew G Knepley Level: intermediate 4581b21d0597SMatthew G Knepley 4582bb7acecfSBarry Smith Note: 4583bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4584b21d0597SMatthew G Knepley 45851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetGlobalSection()`, `DMSetLocalSection()` 4586b21d0597SMatthew G Knepley @*/ 4587d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 4588d71ae5a4SJacob Faibussowitsch { 4589b21d0597SMatthew G Knepley PetscFunctionBegin; 4590b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45915080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 45929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 45939566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 45941bb6d2a8SBarry Smith dm->globalSection = section; 4595497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 45969566063dSJacob Faibussowitsch if (section) PetscCall(DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section)); 4597507e4973SMatthew G. Knepley #endif 45983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4599b21d0597SMatthew G Knepley } 4600b21d0597SMatthew G Knepley 460188ed4aceSMatthew G Knepley /*@ 4602bb7acecfSBarry Smith DMGetSectionSF - Get the `PetscSF` encoding the parallel dof overlap for the `DM`. If it has not been set, 4603bb7acecfSBarry Smith it is created from the default `PetscSection` layouts in the `DM`. 460488ed4aceSMatthew G Knepley 460588ed4aceSMatthew G Knepley Input Parameter: 4606bb7acecfSBarry Smith . dm - The `DM` 460788ed4aceSMatthew G Knepley 460888ed4aceSMatthew G Knepley Output Parameter: 4609bb7acecfSBarry Smith . sf - The `PetscSF` 461088ed4aceSMatthew G Knepley 461188ed4aceSMatthew G Knepley Level: intermediate 461288ed4aceSMatthew G Knepley 4613bb7acecfSBarry Smith Note: 4614bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 461588ed4aceSMatthew G Knepley 46161cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetSectionSF()`, `DMCreateSectionSF()` 461788ed4aceSMatthew G Knepley @*/ 4618d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 4619d71ae5a4SJacob Faibussowitsch { 462088ed4aceSMatthew G Knepley PetscInt nroots; 462188ed4aceSMatthew G Knepley 462288ed4aceSMatthew G Knepley PetscFunctionBegin; 462388ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46244f572ea9SToby Isaac PetscAssertPointer(sf, 2); 462548a46eb9SPierre Jolivet if (!dm->sectionSF) PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 46269566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL)); 462788ed4aceSMatthew G Knepley if (nroots < 0) { 462888ed4aceSMatthew G Knepley PetscSection section, gSection; 462988ed4aceSMatthew G Knepley 46309566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 463131ea6d37SMatthew G Knepley if (section) { 46329566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gSection)); 46339566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSF(dm, section, gSection)); 463431ea6d37SMatthew G Knepley } else { 46350298fd71SBarry Smith *sf = NULL; 46363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 463731ea6d37SMatthew G Knepley } 463888ed4aceSMatthew G Knepley } 46391bb6d2a8SBarry Smith *sf = dm->sectionSF; 46403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 464188ed4aceSMatthew G Knepley } 464288ed4aceSMatthew G Knepley 464388ed4aceSMatthew G Knepley /*@ 4644bb7acecfSBarry Smith DMSetSectionSF - Set the `PetscSF` encoding the parallel dof overlap for the `DM` 464588ed4aceSMatthew G Knepley 464688ed4aceSMatthew G Knepley Input Parameters: 4647bb7acecfSBarry Smith + dm - The `DM` 4648bb7acecfSBarry Smith - sf - The `PetscSF` 464988ed4aceSMatthew G Knepley 465088ed4aceSMatthew G Knepley Level: intermediate 465188ed4aceSMatthew G Knepley 4652bb7acecfSBarry Smith Note: 4653bb7acecfSBarry Smith Any previous `PetscSF` is destroyed 465488ed4aceSMatthew G Knepley 46551cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMCreateSectionSF()` 465688ed4aceSMatthew G Knepley @*/ 4657d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 4658d71ae5a4SJacob Faibussowitsch { 465988ed4aceSMatthew G Knepley PetscFunctionBegin; 466088ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4661b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 46629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 46639566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sectionSF)); 46641bb6d2a8SBarry Smith dm->sectionSF = sf; 46653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 466688ed4aceSMatthew G Knepley } 466788ed4aceSMatthew G Knepley 466888ed4aceSMatthew G Knepley /*@C 4669bb7acecfSBarry Smith DMCreateSectionSF - Create the `PetscSF` encoding the parallel dof overlap for the `DM` based upon the `PetscSection`s 467088ed4aceSMatthew G Knepley describing the data layout. 467188ed4aceSMatthew G Knepley 467288ed4aceSMatthew G Knepley Input Parameters: 4673bb7acecfSBarry Smith + dm - The `DM` 4674bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4675bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 467688ed4aceSMatthew G Knepley 46771bb6d2a8SBarry Smith Level: developer 46781bb6d2a8SBarry Smith 4679bb7acecfSBarry Smith Note: 4680bb7acecfSBarry Smith One usually uses `DMGetSectionSF()` to obtain the `PetscSF` 4681bb7acecfSBarry Smith 468260225df5SJacob Faibussowitsch Developer Notes: 4683bb7acecfSBarry Smith Since this routine has for arguments the two sections from the `DM` and puts the resulting `PetscSF` 4684bb7acecfSBarry Smith directly into the `DM`, perhaps this function should not take the local and global sections as 4685bb7acecfSBarry Smith input and should just obtain them from the `DM`? 46861bb6d2a8SBarry Smith 46871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMGetLocalSection()`, `DMGetGlobalSection()` 468888ed4aceSMatthew G Knepley @*/ 4689d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 4690d71ae5a4SJacob Faibussowitsch { 469188ed4aceSMatthew G Knepley PetscFunctionBegin; 469288ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46939566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection)); 46943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 469588ed4aceSMatthew G Knepley } 4696af122d2aSMatthew G Knepley 4697b21d0597SMatthew G Knepley /*@ 4698bb7acecfSBarry Smith DMGetPointSF - Get the `PetscSF` encoding the parallel section point overlap for the `DM`. 4699bb7acecfSBarry Smith 4700bb7acecfSBarry Smith Not collective but the resulting `PetscSF` is collective 4701b21d0597SMatthew G Knepley 4702b21d0597SMatthew G Knepley Input Parameter: 4703bb7acecfSBarry Smith . dm - The `DM` 4704b21d0597SMatthew G Knepley 4705b21d0597SMatthew G Knepley Output Parameter: 4706bb7acecfSBarry Smith . sf - The `PetscSF` 4707b21d0597SMatthew G Knepley 4708b21d0597SMatthew G Knepley Level: intermediate 4709b21d0597SMatthew G Knepley 4710bb7acecfSBarry Smith Note: 4711bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 4712b21d0597SMatthew G Knepley 47131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4714b21d0597SMatthew G Knepley @*/ 4715d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 4716d71ae5a4SJacob Faibussowitsch { 4717b21d0597SMatthew G Knepley PetscFunctionBegin; 4718b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47194f572ea9SToby Isaac PetscAssertPointer(sf, 2); 4720b21d0597SMatthew G Knepley *sf = dm->sf; 47213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4722b21d0597SMatthew G Knepley } 4723b21d0597SMatthew G Knepley 4724057b4bcdSMatthew G Knepley /*@ 4725bb7acecfSBarry Smith DMSetPointSF - Set the `PetscSF` encoding the parallel section point overlap for the `DM`. 4726bb7acecfSBarry Smith 472720f4b53cSBarry Smith Collective 4728057b4bcdSMatthew G Knepley 4729057b4bcdSMatthew G Knepley Input Parameters: 4730bb7acecfSBarry Smith + dm - The `DM` 4731bb7acecfSBarry Smith - sf - The `PetscSF` 4732057b4bcdSMatthew G Knepley 4733057b4bcdSMatthew G Knepley Level: intermediate 4734057b4bcdSMatthew G Knepley 47351cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4736057b4bcdSMatthew G Knepley @*/ 4737d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 4738d71ae5a4SJacob Faibussowitsch { 4739057b4bcdSMatthew G Knepley PetscFunctionBegin; 4740057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4741b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47429566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47439566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sf)); 4744057b4bcdSMatthew G Knepley dm->sf = sf; 47453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4746057b4bcdSMatthew G Knepley } 4747057b4bcdSMatthew G Knepley 47484f37162bSMatthew G. Knepley /*@ 4749bb7acecfSBarry Smith DMGetNaturalSF - Get the `PetscSF` encoding the map back to the original mesh ordering 47504f37162bSMatthew G. Knepley 47514f37162bSMatthew G. Knepley Input Parameter: 4752bb7acecfSBarry Smith . dm - The `DM` 47534f37162bSMatthew G. Knepley 47544f37162bSMatthew G. Knepley Output Parameter: 4755bb7acecfSBarry Smith . sf - The `PetscSF` 47564f37162bSMatthew G. Knepley 47574f37162bSMatthew G. Knepley Level: intermediate 47584f37162bSMatthew G. Knepley 4759bb7acecfSBarry Smith Note: 4760bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 47614f37162bSMatthew G. Knepley 47621cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47634f37162bSMatthew G. Knepley @*/ 4764d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 4765d71ae5a4SJacob Faibussowitsch { 47664f37162bSMatthew G. Knepley PetscFunctionBegin; 47674f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47684f572ea9SToby Isaac PetscAssertPointer(sf, 2); 47694f37162bSMatthew G. Knepley *sf = dm->sfNatural; 47703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47714f37162bSMatthew G. Knepley } 47724f37162bSMatthew G. Knepley 47734f37162bSMatthew G. Knepley /*@ 47744f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 47754f37162bSMatthew G. Knepley 47764f37162bSMatthew G. Knepley Input Parameters: 47774f37162bSMatthew G. Knepley + dm - The DM 47784f37162bSMatthew G. Knepley - sf - The PetscSF 47794f37162bSMatthew G. Knepley 47804f37162bSMatthew G. Knepley Level: intermediate 47814f37162bSMatthew G. Knepley 47821cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47834f37162bSMatthew G. Knepley @*/ 4784d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 4785d71ae5a4SJacob Faibussowitsch { 47864f37162bSMatthew G. Knepley PetscFunctionBegin; 47874f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47884f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47899566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47909566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sfNatural)); 47914f37162bSMatthew G. Knepley dm->sfNatural = sf; 47923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47934f37162bSMatthew G. Knepley } 47944f37162bSMatthew G. Knepley 4795d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 4796d71ae5a4SJacob Faibussowitsch { 479734aa8a36SMatthew G. Knepley PetscClassId id; 479834aa8a36SMatthew G. Knepley 479934aa8a36SMatthew G. Knepley PetscFunctionBegin; 48009566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 480134aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 48029566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 480334aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 48049566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE)); 480517c1d62eSMatthew G. Knepley } else { 48069566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 480734aa8a36SMatthew G. Knepley } 48083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 480934aa8a36SMatthew G. Knepley } 481034aa8a36SMatthew G. Knepley 4811d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 4812d71ae5a4SJacob Faibussowitsch { 481344a7f3ddSMatthew G. Knepley RegionField *tmpr; 481444a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 481544a7f3ddSMatthew G. Knepley 481644a7f3ddSMatthew G. Knepley PetscFunctionBegin; 48173ba16761SJacob Faibussowitsch if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS); 48189566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NfNew, &tmpr)); 481944a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 48209371c9d4SSatish Balay for (f = Nf; f < NfNew; ++f) { 48219371c9d4SSatish Balay tmpr[f].disc = NULL; 48229371c9d4SSatish Balay tmpr[f].label = NULL; 48239371c9d4SSatish Balay tmpr[f].avoidTensor = PETSC_FALSE; 48249371c9d4SSatish Balay } 48259566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 482644a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 482744a7f3ddSMatthew G. Knepley dm->fields = tmpr; 48283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 482944a7f3ddSMatthew G. Knepley } 483044a7f3ddSMatthew G. Knepley 483144a7f3ddSMatthew G. Knepley /*@ 483220f4b53cSBarry Smith DMClearFields - Remove all fields from the `DM` 483344a7f3ddSMatthew G. Knepley 483420f4b53cSBarry Smith Logically Collective 483544a7f3ddSMatthew G. Knepley 483644a7f3ddSMatthew G. Knepley Input Parameter: 483720f4b53cSBarry Smith . dm - The `DM` 483844a7f3ddSMatthew G. Knepley 483944a7f3ddSMatthew G. Knepley Level: intermediate 484044a7f3ddSMatthew G. Knepley 48411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetNumFields()`, `DMSetField()` 484244a7f3ddSMatthew G. Knepley @*/ 4843d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearFields(DM dm) 4844d71ae5a4SJacob Faibussowitsch { 484544a7f3ddSMatthew G. Knepley PetscInt f; 484644a7f3ddSMatthew G. Knepley 484744a7f3ddSMatthew G. Knepley PetscFunctionBegin; 484844a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 484944a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 48509566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 48519566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 485244a7f3ddSMatthew G. Knepley } 48539566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 485444a7f3ddSMatthew G. Knepley dm->fields = NULL; 485544a7f3ddSMatthew G. Knepley dm->Nf = 0; 48563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 485744a7f3ddSMatthew G. Knepley } 485844a7f3ddSMatthew G. Knepley 4859689b5837SMatthew G. Knepley /*@ 486020f4b53cSBarry Smith DMGetNumFields - Get the number of fields in the `DM` 4861689b5837SMatthew G. Knepley 486220f4b53cSBarry Smith Not Collective 4863689b5837SMatthew G. Knepley 4864689b5837SMatthew G. Knepley Input Parameter: 486520f4b53cSBarry Smith . dm - The `DM` 4866689b5837SMatthew G. Knepley 4867689b5837SMatthew G. Knepley Output Parameter: 486860225df5SJacob Faibussowitsch . numFields - The number of fields 4869689b5837SMatthew G. Knepley 4870689b5837SMatthew G. Knepley Level: intermediate 4871689b5837SMatthew G. Knepley 48721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNumFields()`, `DMSetField()` 4873689b5837SMatthew G. Knepley @*/ 4874d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 4875d71ae5a4SJacob Faibussowitsch { 48760f21e855SMatthew G. Knepley PetscFunctionBegin; 48770f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48784f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 487944a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 48803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4881af122d2aSMatthew G Knepley } 4882af122d2aSMatthew G Knepley 4883689b5837SMatthew G. Knepley /*@ 488420f4b53cSBarry Smith DMSetNumFields - Set the number of fields in the `DM` 4885689b5837SMatthew G. Knepley 488620f4b53cSBarry Smith Logically Collective 4887689b5837SMatthew G. Knepley 4888689b5837SMatthew G. Knepley Input Parameters: 488920f4b53cSBarry Smith + dm - The `DM` 489060225df5SJacob Faibussowitsch - numFields - The number of fields 4891689b5837SMatthew G. Knepley 4892689b5837SMatthew G. Knepley Level: intermediate 4893689b5837SMatthew G. Knepley 48941cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetField()` 4895689b5837SMatthew G. Knepley @*/ 4896d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4897d71ae5a4SJacob Faibussowitsch { 48980f21e855SMatthew G. Knepley PetscInt Nf, f; 4899af122d2aSMatthew G Knepley 4900af122d2aSMatthew G Knepley PetscFunctionBegin; 4901af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49029566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 49030f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 49040f21e855SMatthew G. Knepley PetscContainer obj; 49050f21e855SMatthew G. Knepley 49069566063dSJacob Faibussowitsch PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)dm), &obj)); 49079566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject)obj)); 49089566063dSJacob Faibussowitsch PetscCall(PetscContainerDestroy(&obj)); 4909af122d2aSMatthew G Knepley } 49103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4911af122d2aSMatthew G Knepley } 4912af122d2aSMatthew G Knepley 4913c1929be8SMatthew G. Knepley /*@ 4914bb7acecfSBarry Smith DMGetField - Return the `DMLabel` and discretization object for a given `DM` field 4915c1929be8SMatthew G. Knepley 491620f4b53cSBarry Smith Not Collective 4917c1929be8SMatthew G. Knepley 4918c1929be8SMatthew G. Knepley Input Parameters: 4919bb7acecfSBarry Smith + dm - The `DM` 4920c1929be8SMatthew G. Knepley - f - The field number 4921c1929be8SMatthew G. Knepley 492244a7f3ddSMatthew G. Knepley Output Parameters: 492320f4b53cSBarry Smith + label - The label indicating the support of the field, or `NULL` for the entire mesh (pass in `NULL` if not needed) 492420f4b53cSBarry Smith - disc - The discretization object (pass in `NULL` if not needed) 4925c1929be8SMatthew G. Knepley 492644a7f3ddSMatthew G. Knepley Level: intermediate 4927c1929be8SMatthew G. Knepley 49281cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()` 4929c1929be8SMatthew G. Knepley @*/ 4930d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *disc) 4931d71ae5a4SJacob Faibussowitsch { 4932af122d2aSMatthew G Knepley PetscFunctionBegin; 4933af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49344f572ea9SToby Isaac PetscAssertPointer(disc, 4); 49357a8be351SBarry 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); 493644a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 4937bb7acecfSBarry Smith if (disc) *disc = dm->fields[f].disc; 49383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4939decb47aaSMatthew G. Knepley } 4940decb47aaSMatthew G. Knepley 4941083401c6SMatthew G. Knepley /* Does not clear the DS */ 4942d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4943d71ae5a4SJacob Faibussowitsch { 4944083401c6SMatthew G. Knepley PetscFunctionBegin; 49459566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, f + 1)); 49469566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 49479566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 4948083401c6SMatthew G. Knepley dm->fields[f].label = label; 4949bb7acecfSBarry Smith dm->fields[f].disc = disc; 49509566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 4951bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 49523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4953083401c6SMatthew G. Knepley } 4954083401c6SMatthew G. Knepley 495546560f82SMatthew G. Knepley /*@C 4956bb7acecfSBarry Smith DMSetField - Set the discretization object for a given `DM` field. Usually one would call `DMAddField()` which automatically handles 4957bb7acecfSBarry Smith the field numbering. 4958c1929be8SMatthew G. Knepley 495920f4b53cSBarry Smith Logically Collective 4960c1929be8SMatthew G. Knepley 4961c1929be8SMatthew G. Knepley Input Parameters: 4962bb7acecfSBarry Smith + dm - The `DM` 4963c1929be8SMatthew G. Knepley . f - The field number 496420f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 4965bb7acecfSBarry Smith - disc - The discretization object 4966c1929be8SMatthew G. Knepley 496744a7f3ddSMatthew G. Knepley Level: intermediate 4968c1929be8SMatthew G. Knepley 49691cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()` 4970c1929be8SMatthew G. Knepley @*/ 4971d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4972d71ae5a4SJacob Faibussowitsch { 4973decb47aaSMatthew G. Knepley PetscFunctionBegin; 4974decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4975e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 4976bb7acecfSBarry Smith PetscValidHeader(disc, 4); 49777a8be351SBarry Smith PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f); 4978bb7acecfSBarry Smith PetscCall(DMSetField_Internal(dm, f, label, disc)); 4979bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, f, disc)); 49809566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 49813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 498244a7f3ddSMatthew G. Knepley } 498344a7f3ddSMatthew G. Knepley 498446560f82SMatthew G. Knepley /*@C 4985bb7acecfSBarry 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) 4986bb7acecfSBarry Smith and a discretization object that defines the function space associated with those points. 498744a7f3ddSMatthew G. Knepley 498820f4b53cSBarry Smith Logically Collective 498944a7f3ddSMatthew G. Knepley 499044a7f3ddSMatthew G. Knepley Input Parameters: 4991bb7acecfSBarry Smith + dm - The `DM` 499220f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 4993bb7acecfSBarry Smith - disc - The discretization object 499444a7f3ddSMatthew G. Knepley 499544a7f3ddSMatthew G. Knepley Level: intermediate 499644a7f3ddSMatthew G. Knepley 4997bb7acecfSBarry Smith Notes: 4998bb7acecfSBarry Smith The label already exists or will be added to the `DM` with `DMSetLabel()`. 4999bb7acecfSBarry Smith 5000da81f932SPierre Jolivet For example, a piecewise continuous pressure field can be defined by coefficients at the cell centers of a mesh and piecewise constant functions 5001bb7acecfSBarry 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 5002bb7acecfSBarry Smith geometry entities, a `DMLabel` indicating a subset of those geometric entities, and a discretization object, such as a `PetscFE`. 5003bb7acecfSBarry Smith 50041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLabel()`, `DMSetField()`, `DMGetField()`, `PetscFE` 500544a7f3ddSMatthew G. Knepley @*/ 5006d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject disc) 5007d71ae5a4SJacob Faibussowitsch { 500844a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 500944a7f3ddSMatthew G. Knepley 501044a7f3ddSMatthew G. Knepley PetscFunctionBegin; 501144a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5012064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5013bb7acecfSBarry Smith PetscValidHeader(disc, 3); 50149566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, Nf + 1)); 501544a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 5016bb7acecfSBarry Smith dm->fields[Nf].disc = disc; 50179566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5018bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 5019bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, Nf, disc)); 50209566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 50213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5022af122d2aSMatthew G Knepley } 50236636e97aSMatthew G Knepley 5024e5e52638SMatthew G. Knepley /*@ 5025e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 5026e0b68406SMatthew Knepley 502720f4b53cSBarry Smith Logically Collective 5028e0b68406SMatthew Knepley 5029e0b68406SMatthew Knepley Input Parameters: 5030bb7acecfSBarry Smith + dm - The `DM` 5031e0b68406SMatthew Knepley . f - The field index 5032bb7acecfSBarry Smith - avoidTensor - `PETSC_TRUE` to skip defining the field on tensor cells 5033e0b68406SMatthew Knepley 5034e0b68406SMatthew Knepley Level: intermediate 5035e0b68406SMatthew Knepley 50361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5037e0b68406SMatthew Knepley @*/ 5038d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5039d71ae5a4SJacob Faibussowitsch { 5040e0b68406SMatthew Knepley PetscFunctionBegin; 504163a3b9bcSJacob 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); 5042e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 50433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5044e0b68406SMatthew Knepley } 5045e0b68406SMatthew Knepley 5046e0b68406SMatthew Knepley /*@ 5047e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5048e0b68406SMatthew Knepley 504920f4b53cSBarry Smith Not Collective 5050e0b68406SMatthew Knepley 5051e0b68406SMatthew Knepley Input Parameters: 5052bb7acecfSBarry Smith + dm - The `DM` 5053e0b68406SMatthew Knepley - f - The field index 5054e0b68406SMatthew Knepley 5055e0b68406SMatthew Knepley Output Parameter: 5056e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5057e0b68406SMatthew Knepley 5058e0b68406SMatthew Knepley Level: intermediate 5059e0b68406SMatthew Knepley 506060225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()`, `DMGetField()`, `DMSetFieldAvoidTensor()` 5061e0b68406SMatthew Knepley @*/ 5062d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5063d71ae5a4SJacob Faibussowitsch { 5064e0b68406SMatthew Knepley PetscFunctionBegin; 506563a3b9bcSJacob 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); 5066e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 50673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5068e0b68406SMatthew Knepley } 5069e0b68406SMatthew Knepley 5070e0b68406SMatthew Knepley /*@ 5071bb7acecfSBarry Smith DMCopyFields - Copy the discretizations for the `DM` into another `DM` 5072e5e52638SMatthew G. Knepley 507320f4b53cSBarry Smith Collective 5074e5e52638SMatthew G. Knepley 5075e5e52638SMatthew G. Knepley Input Parameter: 5076bb7acecfSBarry Smith . dm - The `DM` 5077e5e52638SMatthew G. Knepley 5078e5e52638SMatthew G. Knepley Output Parameter: 5079bb7acecfSBarry Smith . newdm - The `DM` 5080e5e52638SMatthew G. Knepley 5081e5e52638SMatthew G. Knepley Level: advanced 5082e5e52638SMatthew G. Knepley 50831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetField()`, `DMSetField()`, `DMAddField()`, `DMCopyDS()`, `DMGetDS()`, `DMGetCellDS()` 5084e5e52638SMatthew G. Knepley @*/ 5085d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyFields(DM dm, DM newdm) 5086d71ae5a4SJacob Faibussowitsch { 5087e5e52638SMatthew G. Knepley PetscInt Nf, f; 5088e5e52638SMatthew G. Knepley 5089e5e52638SMatthew G. Knepley PetscFunctionBegin; 50903ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 50919566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 50929566063dSJacob Faibussowitsch PetscCall(DMClearFields(newdm)); 5093e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5094e5e52638SMatthew G. Knepley DMLabel label; 5095e5e52638SMatthew G. Knepley PetscObject field; 509634aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5097e5e52638SMatthew G. Knepley 50989566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, &label, &field)); 50999566063dSJacob Faibussowitsch PetscCall(DMSetField(newdm, f, label, field)); 51009566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, f, &useCone, &useClosure)); 51019566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(newdm, f, useCone, useClosure)); 510234aa8a36SMatthew G. Knepley } 51033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 510434aa8a36SMatthew G. Knepley } 510534aa8a36SMatthew G. Knepley 510634aa8a36SMatthew G. Knepley /*@ 510734aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 510834aa8a36SMatthew G. Knepley 510920f4b53cSBarry Smith Not Collective 511034aa8a36SMatthew G. Knepley 511134aa8a36SMatthew G. Knepley Input Parameters: 511220f4b53cSBarry Smith + dm - The `DM` object 511320f4b53cSBarry Smith - f - The field number, or `PETSC_DEFAULT` for the default adjacency 511434aa8a36SMatthew G. Knepley 5115d8d19677SJose E. Roman Output Parameters: 511634aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 511734aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 511834aa8a36SMatthew G. Knepley 511934aa8a36SMatthew G. Knepley Level: developer 512034aa8a36SMatthew G. Knepley 512120f4b53cSBarry Smith Notes: 512220f4b53cSBarry Smith .vb 512320f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 512420f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 512520f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 512620f4b53cSBarry Smith .ve 512720f4b53cSBarry Smith Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 512820f4b53cSBarry Smith 51291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetAdjacency()`, `DMGetField()`, `DMSetField()` 513034aa8a36SMatthew G. Knepley @*/ 5131d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 5132d71ae5a4SJacob Faibussowitsch { 513334aa8a36SMatthew G. Knepley PetscFunctionBegin; 513434aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 51354f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 3); 51364f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 4); 513734aa8a36SMatthew G. Knepley if (f < 0) { 513834aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 513934aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 514034aa8a36SMatthew G. Knepley } else { 514134aa8a36SMatthew G. Knepley PetscInt Nf; 514234aa8a36SMatthew G. Knepley 51439566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51447a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 514534aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 514634aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 514734aa8a36SMatthew G. Knepley } 51483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 514934aa8a36SMatthew G. Knepley } 515034aa8a36SMatthew G. Knepley 515134aa8a36SMatthew G. Knepley /*@ 515234aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 515334aa8a36SMatthew G. Knepley 515420f4b53cSBarry Smith Not Collective 515534aa8a36SMatthew G. Knepley 515634aa8a36SMatthew G. Knepley Input Parameters: 515720f4b53cSBarry Smith + dm - The `DM` object 515834aa8a36SMatthew G. Knepley . f - The field number 515934aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 516034aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 516134aa8a36SMatthew G. Knepley 516234aa8a36SMatthew G. Knepley Level: developer 516334aa8a36SMatthew G. Knepley 516420f4b53cSBarry Smith Notes: 516520f4b53cSBarry Smith .vb 516620f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 516720f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 516820f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 516920f4b53cSBarry Smith .ve 517020f4b53cSBarry Smith Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 517120f4b53cSBarry Smith 51721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetAdjacency()`, `DMGetField()`, `DMSetField()` 517334aa8a36SMatthew G. Knepley @*/ 5174d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 5175d71ae5a4SJacob Faibussowitsch { 517634aa8a36SMatthew G. Knepley PetscFunctionBegin; 517734aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 517834aa8a36SMatthew G. Knepley if (f < 0) { 517934aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 518034aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 518134aa8a36SMatthew G. Knepley } else { 518234aa8a36SMatthew G. Knepley PetscInt Nf; 518334aa8a36SMatthew G. Knepley 51849566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51857a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 518634aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 518734aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5188e5e52638SMatthew G. Knepley } 51893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5190e5e52638SMatthew G. Knepley } 5191e5e52638SMatthew G. Knepley 5192b0441da4SMatthew G. Knepley /*@ 5193b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5194b0441da4SMatthew G. Knepley 5195b0441da4SMatthew G. Knepley Not collective 5196b0441da4SMatthew G. Knepley 5197f899ff85SJose E. Roman Input Parameter: 519820f4b53cSBarry Smith . dm - The `DM` object 5199b0441da4SMatthew G. Knepley 5200d8d19677SJose E. Roman Output Parameters: 5201b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5202b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5203b0441da4SMatthew G. Knepley 5204b0441da4SMatthew G. Knepley Level: developer 5205b0441da4SMatthew G. Knepley 520620f4b53cSBarry Smith Notes: 520720f4b53cSBarry Smith .vb 520820f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 520920f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 521020f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 521120f4b53cSBarry Smith .ve 521220f4b53cSBarry Smith 52131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5214b0441da4SMatthew G. Knepley @*/ 5215d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5216d71ae5a4SJacob Faibussowitsch { 5217b0441da4SMatthew G. Knepley PetscInt Nf; 5218b0441da4SMatthew G. Knepley 5219b0441da4SMatthew G. Knepley PetscFunctionBegin; 5220b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52214f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 2); 52224f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 3); 52239566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5224b0441da4SMatthew G. Knepley if (!Nf) { 52259566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5226b0441da4SMatthew G. Knepley } else { 52279566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, 0, useCone, useClosure)); 5228b0441da4SMatthew G. Knepley } 52293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5230b0441da4SMatthew G. Knepley } 5231b0441da4SMatthew G. Knepley 5232b0441da4SMatthew G. Knepley /*@ 5233b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5234b0441da4SMatthew G. Knepley 523520f4b53cSBarry Smith Not Collective 5236b0441da4SMatthew G. Knepley 5237b0441da4SMatthew G. Knepley Input Parameters: 523820f4b53cSBarry Smith + dm - The `DM` object 5239b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5240b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5241b0441da4SMatthew G. Knepley 5242b0441da4SMatthew G. Knepley Level: developer 5243b0441da4SMatthew G. Knepley 524420f4b53cSBarry Smith Notes: 524520f4b53cSBarry Smith .vb 524620f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 524720f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 524820f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 524920f4b53cSBarry Smith .ve 525020f4b53cSBarry Smith 52511cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5252b0441da4SMatthew G. Knepley @*/ 5253d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5254d71ae5a4SJacob Faibussowitsch { 5255b0441da4SMatthew G. Knepley PetscInt Nf; 5256b0441da4SMatthew G. Knepley 5257b0441da4SMatthew G. Knepley PetscFunctionBegin; 5258b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52599566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5260b0441da4SMatthew G. Knepley if (!Nf) { 52619566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5262b0441da4SMatthew G. Knepley } else { 52639566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, 0, useCone, useClosure)); 5264e5e52638SMatthew G. Knepley } 52653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5266e5e52638SMatthew G. Knepley } 5267e5e52638SMatthew G. Knepley 5268d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompleteBCLabels_Internal(DM dm) 5269d71ae5a4SJacob Faibussowitsch { 5270799db056SMatthew G. Knepley DM plex; 5271799db056SMatthew G. Knepley DMLabel *labels, *glabels; 5272799db056SMatthew G. Knepley const char **names; 5273799db056SMatthew G. Knepley char *sendNames, *recvNames; 5274799db056SMatthew G. Knepley PetscInt Nds, s, maxLabels = 0, maxLen = 0, gmaxLen, Nl = 0, gNl, l, gl, m; 5275799db056SMatthew G. Knepley size_t len; 5276799db056SMatthew G. Knepley MPI_Comm comm; 5277799db056SMatthew G. Knepley PetscMPIInt rank, size, p, *counts, *displs; 5278783e2ec8SMatthew G. Knepley 5279783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5280799db056SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5281799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 5282799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5283799db056SMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 5284799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5285799db056SMatthew G. Knepley PetscDS dsBC; 5286799db056SMatthew G. Knepley PetscInt numBd; 5287799db056SMatthew G. Knepley 528807218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5289799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5290799db056SMatthew G. Knepley maxLabels += numBd; 5291799db056SMatthew G. Knepley } 5292799db056SMatthew G. Knepley PetscCall(PetscCalloc1(maxLabels, &labels)); 5293799db056SMatthew G. Knepley /* Get list of labels to be completed */ 5294799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5295799db056SMatthew G. Knepley PetscDS dsBC; 5296799db056SMatthew G. Knepley PetscInt numBd, bd; 5297799db056SMatthew G. Knepley 529807218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5299799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5300799db056SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5301799db056SMatthew G. Knepley DMLabel label; 5302799db056SMatthew G. Knepley PetscInt field; 5303799db056SMatthew G. Knepley PetscObject obj; 5304799db056SMatthew G. Knepley PetscClassId id; 5305799db056SMatthew G. Knepley 5306799db056SMatthew G. Knepley PetscCall(PetscDSGetBoundary(dsBC, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 53079566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, field, NULL, &obj)); 53089566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(obj, &id)); 5309799db056SMatthew G. Knepley if (!(id == PETSCFE_CLASSID) || !label) continue; 53109371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 53119371c9d4SSatish Balay if (labels[l] == label) break; 5312799db056SMatthew G. Knepley if (l == Nl) labels[Nl++] = label; 5313783e2ec8SMatthew G. Knepley } 5314799db056SMatthew G. Knepley } 5315799db056SMatthew G. Knepley /* Get label names */ 5316799db056SMatthew G. Knepley PetscCall(PetscMalloc1(Nl, &names)); 5317799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscObjectGetName((PetscObject)labels[l], &names[l])); 53189371c9d4SSatish Balay for (l = 0; l < Nl; ++l) { 53199371c9d4SSatish Balay PetscCall(PetscStrlen(names[l], &len)); 53209371c9d4SSatish Balay maxLen = PetscMax(maxLen, (PetscInt)len + 2); 53219371c9d4SSatish Balay } 5322799db056SMatthew G. Knepley PetscCall(PetscFree(labels)); 5323712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&maxLen, &gmaxLen, 1, MPIU_INT, MPI_MAX, comm)); 5324799db056SMatthew G. Knepley PetscCall(PetscCalloc1(Nl * gmaxLen, &sendNames)); 5325c6a7a370SJeremy L Thompson for (l = 0; l < Nl; ++l) PetscCall(PetscStrncpy(&sendNames[gmaxLen * l], names[l], gmaxLen)); 5326799db056SMatthew G. Knepley PetscCall(PetscFree(names)); 5327799db056SMatthew G. Knepley /* Put all names on all processes */ 5328799db056SMatthew G. Knepley PetscCall(PetscCalloc2(size, &counts, size + 1, &displs)); 5329799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgather(&Nl, 1, MPI_INT, counts, 1, MPI_INT, comm)); 5330799db056SMatthew G. Knepley for (p = 0; p < size; ++p) displs[p + 1] = displs[p] + counts[p]; 5331799db056SMatthew G. Knepley gNl = displs[size]; 53329371c9d4SSatish Balay for (p = 0; p < size; ++p) { 53339371c9d4SSatish Balay counts[p] *= gmaxLen; 53349371c9d4SSatish Balay displs[p] *= gmaxLen; 53359371c9d4SSatish Balay } 5336799db056SMatthew G. Knepley PetscCall(PetscCalloc2(gNl * gmaxLen, &recvNames, gNl, &glabels)); 5337799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgatherv(sendNames, counts[rank], MPI_CHAR, recvNames, counts, displs, MPI_CHAR, comm)); 5338799db056SMatthew G. Knepley PetscCall(PetscFree2(counts, displs)); 5339799db056SMatthew G. Knepley PetscCall(PetscFree(sendNames)); 5340799db056SMatthew G. Knepley for (l = 0, gl = 0; l < gNl; ++l) { 5341799db056SMatthew G. Knepley PetscCall(DMGetLabel(dm, &recvNames[l * gmaxLen], &glabels[gl])); 5342799db056SMatthew G. Knepley PetscCheck(glabels[gl], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Label %s missing on rank %d", &recvNames[l * gmaxLen], rank); 53439371c9d4SSatish Balay for (m = 0; m < gl; ++m) 53449371c9d4SSatish Balay if (glabels[m] == glabels[gl]) continue; 53459566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 5346799db056SMatthew G. Knepley PetscCall(DMPlexLabelComplete(plex, glabels[gl])); 53479566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5348799db056SMatthew G. Knepley ++gl; 5349783e2ec8SMatthew G. Knepley } 5350799db056SMatthew G. Knepley PetscCall(PetscFree2(recvNames, glabels)); 53513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5352783e2ec8SMatthew G. Knepley } 5353783e2ec8SMatthew G. Knepley 5354d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5355d71ae5a4SJacob Faibussowitsch { 5356e5e52638SMatthew G. Knepley DMSpace *tmpd; 5357e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5358e5e52638SMatthew G. Knepley 5359e5e52638SMatthew G. Knepley PetscFunctionBegin; 53603ba16761SJacob Faibussowitsch if (Nds >= NdsNew) PetscFunctionReturn(PETSC_SUCCESS); 53619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NdsNew, &tmpd)); 5362e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 53639371c9d4SSatish Balay for (s = Nds; s < NdsNew; ++s) { 53649371c9d4SSatish Balay tmpd[s].ds = NULL; 53659371c9d4SSatish Balay tmpd[s].label = NULL; 53669371c9d4SSatish Balay tmpd[s].fields = NULL; 53679371c9d4SSatish Balay } 53689566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5369e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5370e5e52638SMatthew G. Knepley dm->probs = tmpd; 53713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5372e5e52638SMatthew G. Knepley } 5373e5e52638SMatthew G. Knepley 5374e5e52638SMatthew G. Knepley /*@ 537520f4b53cSBarry Smith DMGetNumDS - Get the number of discrete systems in the `DM` 5376e5e52638SMatthew G. Knepley 537720f4b53cSBarry Smith Not Collective 5378e5e52638SMatthew G. Knepley 5379e5e52638SMatthew G. Knepley Input Parameter: 538020f4b53cSBarry Smith . dm - The `DM` 5381e5e52638SMatthew G. Knepley 5382e5e52638SMatthew G. Knepley Output Parameter: 538320f4b53cSBarry Smith . Nds - The number of `PetscDS` objects 5384e5e52638SMatthew G. Knepley 5385e5e52638SMatthew G. Knepley Level: intermediate 5386e5e52638SMatthew G. Knepley 53871cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMGetCellDS()` 5388e5e52638SMatthew G. Knepley @*/ 5389d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5390d71ae5a4SJacob Faibussowitsch { 5391e5e52638SMatthew G. Knepley PetscFunctionBegin; 5392e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 53934f572ea9SToby Isaac PetscAssertPointer(Nds, 2); 5394e5e52638SMatthew G. Knepley *Nds = dm->Nds; 53953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5396e5e52638SMatthew G. Knepley } 5397e5e52638SMatthew G. Knepley 5398e5e52638SMatthew G. Knepley /*@ 539920f4b53cSBarry Smith DMClearDS - Remove all discrete systems from the `DM` 5400e5e52638SMatthew G. Knepley 540120f4b53cSBarry Smith Logically Collective 5402e5e52638SMatthew G. Knepley 5403e5e52638SMatthew G. Knepley Input Parameter: 540420f4b53cSBarry Smith . dm - The `DM` 5405e5e52638SMatthew G. Knepley 5406e5e52638SMatthew G. Knepley Level: intermediate 5407e5e52638SMatthew G. Knepley 54081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumDS()`, `DMGetDS()`, `DMSetField()` 5409e5e52638SMatthew G. Knepley @*/ 5410d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearDS(DM dm) 5411d71ae5a4SJacob Faibussowitsch { 5412e5e52638SMatthew G. Knepley PetscInt s; 5413e5e52638SMatthew G. Knepley 5414e5e52638SMatthew G. Knepley PetscFunctionBegin; 5415e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5416e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 54179566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 541807218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 54199566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[s].label)); 54209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[s].fields)); 5421e5e52638SMatthew G. Knepley } 54229566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5423e5e52638SMatthew G. Knepley dm->probs = NULL; 5424e5e52638SMatthew G. Knepley dm->Nds = 0; 54253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5426e5e52638SMatthew G. Knepley } 5427e5e52638SMatthew G. Knepley 5428e5e52638SMatthew G. Knepley /*@ 542920f4b53cSBarry Smith DMGetDS - Get the default `PetscDS` 5430e5e52638SMatthew G. Knepley 543120f4b53cSBarry Smith Not Collective 5432e5e52638SMatthew G. Knepley 5433e5e52638SMatthew G. Knepley Input Parameter: 543420f4b53cSBarry Smith . dm - The `DM` 5435e5e52638SMatthew G. Knepley 5436e5e52638SMatthew G. Knepley Output Parameter: 543707218a29SMatthew G. Knepley . ds - The default `PetscDS` 5438e5e52638SMatthew G. Knepley 5439e5e52638SMatthew G. Knepley Level: intermediate 5440e5e52638SMatthew G. Knepley 54411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCellDS()`, `DMGetRegionDS()` 5442e5e52638SMatthew G. Knepley @*/ 544307218a29SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *ds) 5444d71ae5a4SJacob Faibussowitsch { 5445e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5446e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54474f572ea9SToby Isaac PetscAssertPointer(ds, 2); 544807218a29SMatthew G. Knepley PetscCheck(dm->Nds > 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Need to call DMCreateDS() before calling DMGetDS()"); 544907218a29SMatthew G. Knepley *ds = dm->probs[0].ds; 54503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5451e5e52638SMatthew G. Knepley } 5452e5e52638SMatthew G. Knepley 5453e5e52638SMatthew G. Knepley /*@ 545420f4b53cSBarry Smith DMGetCellDS - Get the `PetscDS` defined on a given cell 5455e5e52638SMatthew G. Knepley 545620f4b53cSBarry Smith Not Collective 5457e5e52638SMatthew G. Knepley 5458e5e52638SMatthew G. Knepley Input Parameters: 545920f4b53cSBarry Smith + dm - The `DM` 546020f4b53cSBarry Smith - point - Cell for the `PetscDS` 5461e5e52638SMatthew G. Knepley 546207218a29SMatthew G. Knepley Output Parameters: 546307218a29SMatthew G. Knepley + ds - The `PetscDS` defined on the given cell 546407218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or NULL if the same ds 5465e5e52638SMatthew G. Knepley 5466e5e52638SMatthew G. Knepley Level: developer 5467e5e52638SMatthew G. Knepley 54681cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMSetRegionDS()` 5469e5e52638SMatthew G. Knepley @*/ 547007218a29SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *ds, PetscDS *dsIn) 5471d71ae5a4SJacob Faibussowitsch { 547207218a29SMatthew G. Knepley PetscDS dsDef = NULL; 5473e5e52638SMatthew G. Knepley PetscInt s; 5474e5e52638SMatthew G. Knepley 5475e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5476e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54774f572ea9SToby Isaac if (ds) PetscAssertPointer(ds, 3); 54784f572ea9SToby Isaac if (dsIn) PetscAssertPointer(dsIn, 4); 547963a3b9bcSJacob Faibussowitsch PetscCheck(point >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %" PetscInt_FMT, point); 548007218a29SMatthew G. Knepley if (ds) *ds = NULL; 548107218a29SMatthew G. Knepley if (dsIn) *dsIn = NULL; 5482e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5483e5e52638SMatthew G. Knepley PetscInt val; 5484e5e52638SMatthew G. Knepley 54859371c9d4SSatish Balay if (!dm->probs[s].label) { 548607218a29SMatthew G. Knepley dsDef = dm->probs[s].ds; 54879371c9d4SSatish Balay } else { 54889566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dm->probs[s].label, point, &val)); 54899371c9d4SSatish Balay if (val >= 0) { 549007218a29SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 549107218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 54929371c9d4SSatish Balay break; 54939371c9d4SSatish Balay } 5494e5e52638SMatthew G. Knepley } 5495e5e52638SMatthew G. Knepley } 549607218a29SMatthew G. Knepley if (ds && !*ds) *ds = dsDef; 54973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5498e5e52638SMatthew G. Knepley } 5499e5e52638SMatthew G. Knepley 5500e5e52638SMatthew G. Knepley /*@ 550120f4b53cSBarry Smith DMGetRegionDS - Get the `PetscDS` for a given mesh region, defined by a `DMLabel` 5502e5e52638SMatthew G. Knepley 550320f4b53cSBarry Smith Not Collective 5504e5e52638SMatthew G. Knepley 5505e5e52638SMatthew G. Knepley Input Parameters: 550620f4b53cSBarry Smith + dm - The `DM` 550720f4b53cSBarry Smith - label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 5508e5e52638SMatthew G. Knepley 5509b3cf3223SMatthew G. Knepley Output Parameters: 551020f4b53cSBarry Smith + fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 551107218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 551207218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5513e5e52638SMatthew G. Knepley 5514e5e52638SMatthew G. Knepley Level: advanced 5515e5e52638SMatthew G. Knepley 551620f4b53cSBarry Smith Note: 551720f4b53cSBarry Smith If a non-`NULL` label is given, but there is no `PetscDS` on that specific label, 551820f4b53cSBarry Smith the `PetscDS` for the full domain (if present) is returned. Returns with 551907218a29SMatthew G. Knepley fields = `NULL` and ds = `NULL` if there is no `PetscDS` for the full domain. 552020f4b53cSBarry Smith 55211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5522e5e52638SMatthew G. Knepley @*/ 552307218a29SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5524d71ae5a4SJacob Faibussowitsch { 5525e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5526e5e52638SMatthew G. Knepley 5527e5e52638SMatthew G. Knepley PetscFunctionBegin; 5528e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5529e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 55309371c9d4SSatish Balay if (fields) { 55314f572ea9SToby Isaac PetscAssertPointer(fields, 3); 55329371c9d4SSatish Balay *fields = NULL; 55339371c9d4SSatish Balay } 55349371c9d4SSatish Balay if (ds) { 55354f572ea9SToby Isaac PetscAssertPointer(ds, 4); 55369371c9d4SSatish Balay *ds = NULL; 55379371c9d4SSatish Balay } 553807218a29SMatthew G. Knepley if (dsIn) { 55394f572ea9SToby Isaac PetscAssertPointer(dsIn, 5); 554007218a29SMatthew G. Knepley *dsIn = NULL; 554107218a29SMatthew G. Knepley } 5542e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5543154ca461SJed Brown if (dm->probs[s].label == label || !dm->probs[s].label) { 5544b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5545b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 554607218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 55473ba16761SJacob Faibussowitsch if (dm->probs[s].label) PetscFunctionReturn(PETSC_SUCCESS); 5548b3cf3223SMatthew G. Knepley } 5549e5e52638SMatthew G. Knepley } 55503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5551e5e52638SMatthew G. Knepley } 5552e5e52638SMatthew G. Knepley 5553e5e52638SMatthew G. Knepley /*@ 5554bb7acecfSBarry Smith DMSetRegionDS - Set the `PetscDS` for a given mesh region, defined by a `DMLabel` 5555083401c6SMatthew G. Knepley 555620f4b53cSBarry Smith Collective 5557083401c6SMatthew G. Knepley 5558083401c6SMatthew G. Knepley Input Parameters: 5559bb7acecfSBarry Smith + dm - The `DM` 556020f4b53cSBarry Smith . label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 556107218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` for all fields 556207218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region 556307218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5564083401c6SMatthew G. Knepley 556520f4b53cSBarry Smith Level: advanced 556620f4b53cSBarry Smith 5567bb7acecfSBarry Smith Note: 5568bb7acecfSBarry 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, 5569083401c6SMatthew G. Knepley the fields argument is ignored. 5570083401c6SMatthew G. Knepley 55711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionNumDS()`, `DMGetDS()`, `DMGetCellDS()` 5572083401c6SMatthew G. Knepley @*/ 557307218a29SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5574d71ae5a4SJacob Faibussowitsch { 5575083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5576083401c6SMatthew G. Knepley 5577083401c6SMatthew G. Knepley PetscFunctionBegin; 5578083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5579083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 558007218a29SMatthew G. Knepley if (fields) PetscValidHeaderSpecific(fields, IS_CLASSID, 3); 5581064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 558207218a29SMatthew G. Knepley if (dsIn) PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 5); 5583083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5584083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 55859566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 558607218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 5587083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 558807218a29SMatthew G. Knepley dm->probs[s].dsIn = dsIn; 55893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5590083401c6SMatthew G. Knepley } 5591083401c6SMatthew G. Knepley } 55929566063dSJacob Faibussowitsch PetscCall(DMDSEnlarge_Static(dm, Nds + 1)); 55939566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 55949566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 55959566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 559607218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 5597083401c6SMatthew G. Knepley if (!label) { 5598083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5599083401c6SMatthew G. Knepley for (s = Nds - 1; s >= 0; --s) dm->probs[s + 1] = dm->probs[s]; 5600083401c6SMatthew G. Knepley Nds = 0; 5601083401c6SMatthew G. Knepley } 5602083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5603083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5604083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 560507218a29SMatthew G. Knepley dm->probs[Nds].dsIn = dsIn; 56063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5607083401c6SMatthew G. Knepley } 5608083401c6SMatthew G. Knepley 5609083401c6SMatthew G. Knepley /*@ 561020f4b53cSBarry Smith DMGetRegionNumDS - Get the `PetscDS` for a given mesh region, defined by the region number 5611e5e52638SMatthew G. Knepley 561220f4b53cSBarry Smith Not Collective 5613e5e52638SMatthew G. Knepley 5614e5e52638SMatthew G. Knepley Input Parameters: 561520f4b53cSBarry Smith + dm - The `DM` 5616e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5617e5e52638SMatthew G. Knepley 5618e5e52638SMatthew G. Knepley Output Parameters: 561920f4b53cSBarry Smith + label - The region label, or `NULL` 562020f4b53cSBarry Smith . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 562107218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 562207218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5623e5e52638SMatthew G. Knepley 5624e5e52638SMatthew G. Knepley Level: advanced 5625e5e52638SMatthew G. Knepley 56261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5627e5e52638SMatthew G. Knepley @*/ 562807218a29SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5629d71ae5a4SJacob Faibussowitsch { 5630e5e52638SMatthew G. Knepley PetscInt Nds; 5631e5e52638SMatthew G. Knepley 5632e5e52638SMatthew G. Knepley PetscFunctionBegin; 5633e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56349566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 563563a3b9bcSJacob 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); 5636e5e52638SMatthew G. Knepley if (label) { 56374f572ea9SToby Isaac PetscAssertPointer(label, 3); 5638e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5639e5e52638SMatthew G. Knepley } 5640b3cf3223SMatthew G. Knepley if (fields) { 56414f572ea9SToby Isaac PetscAssertPointer(fields, 4); 5642b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5643b3cf3223SMatthew G. Knepley } 5644e5e52638SMatthew G. Knepley if (ds) { 56454f572ea9SToby Isaac PetscAssertPointer(ds, 5); 5646e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5647e5e52638SMatthew G. Knepley } 564807218a29SMatthew G. Knepley if (dsIn) { 56494f572ea9SToby Isaac PetscAssertPointer(dsIn, 6); 565007218a29SMatthew G. Knepley *dsIn = dm->probs[num].dsIn; 565107218a29SMatthew G. Knepley } 56523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5653e5e52638SMatthew G. Knepley } 5654e5e52638SMatthew G. Knepley 5655e5e52638SMatthew G. Knepley /*@ 565620f4b53cSBarry Smith DMSetRegionNumDS - Set the `PetscDS` for a given mesh region, defined by the region number 5657e5e52638SMatthew G. Knepley 565820f4b53cSBarry Smith Not Collective 5659e5e52638SMatthew G. Knepley 5660e5e52638SMatthew G. Knepley Input Parameters: 566120f4b53cSBarry Smith + dm - The `DM` 5662083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 566320f4b53cSBarry Smith . label - The region label, or `NULL` 566407218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` to prevent setting 566507218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` to prevent setting 566607218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5667e5e52638SMatthew G. Knepley 5668e5e52638SMatthew G. Knepley Level: advanced 5669e5e52638SMatthew G. Knepley 56701cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5671e5e52638SMatthew G. Knepley @*/ 567207218a29SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5673d71ae5a4SJacob Faibussowitsch { 5674083401c6SMatthew G. Knepley PetscInt Nds; 5675e5e52638SMatthew G. Knepley 5676e5e52638SMatthew G. Knepley PetscFunctionBegin; 5677e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5678ad540459SPierre Jolivet if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 56799566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 568063a3b9bcSJacob 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); 56819566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 56829566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[num].label)); 5683083401c6SMatthew G. Knepley dm->probs[num].label = label; 5684083401c6SMatthew G. Knepley if (fields) { 5685083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 56869566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 56879566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[num].fields)); 5688083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5689e5e52638SMatthew G. Knepley } 5690083401c6SMatthew G. Knepley if (ds) { 5691083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 56929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 56939566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[num].ds)); 5694083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5695083401c6SMatthew G. Knepley } 569607218a29SMatthew G. Knepley if (dsIn) { 569707218a29SMatthew G. Knepley PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 6); 569807218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 569907218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[num].dsIn)); 570007218a29SMatthew G. Knepley dm->probs[num].dsIn = dsIn; 570107218a29SMatthew G. Knepley } 57023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5703e5e52638SMatthew G. Knepley } 5704e5e52638SMatthew G. Knepley 5705e5e52638SMatthew G. Knepley /*@ 570620f4b53cSBarry Smith DMFindRegionNum - Find the region number for a given `PetscDS`, or -1 if it is not found. 57071d3af9e0SMatthew G. Knepley 570820f4b53cSBarry Smith Not Collective 57091d3af9e0SMatthew G. Knepley 57101d3af9e0SMatthew G. Knepley Input Parameters: 571120f4b53cSBarry Smith + dm - The `DM` 571220f4b53cSBarry Smith - ds - The `PetscDS` defined on the given region 57131d3af9e0SMatthew G. Knepley 57141d3af9e0SMatthew G. Knepley Output Parameter: 57151d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 57161d3af9e0SMatthew G. Knepley 57171d3af9e0SMatthew G. Knepley Level: advanced 57181d3af9e0SMatthew G. Knepley 57191cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 57201d3af9e0SMatthew G. Knepley @*/ 5721d71ae5a4SJacob Faibussowitsch PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 5722d71ae5a4SJacob Faibussowitsch { 57231d3af9e0SMatthew G. Knepley PetscInt Nds, n; 57241d3af9e0SMatthew G. Knepley 57251d3af9e0SMatthew G. Knepley PetscFunctionBegin; 57261d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57271d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 57284f572ea9SToby Isaac PetscAssertPointer(num, 3); 57299566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 57309371c9d4SSatish Balay for (n = 0; n < Nds; ++n) 57319371c9d4SSatish Balay if (ds == dm->probs[n].ds) break; 57321d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 57331d3af9e0SMatthew G. Knepley else *num = n; 57343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57351d3af9e0SMatthew G. Knepley } 57361d3af9e0SMatthew G. Knepley 57372df84da0SMatthew G. Knepley /*@C 5738bb7acecfSBarry Smith DMCreateFEDefault - Create a `PetscFE` based on the celltype for the mesh 57392df84da0SMatthew G. Knepley 574020f4b53cSBarry Smith Not Collective 57412df84da0SMatthew G. Knepley 5742f1a722f8SMatthew G. Knepley Input Parameters: 5743bb7acecfSBarry Smith + dm - The `DM` 57442df84da0SMatthew G. Knepley . Nc - The number of components for the field 574520f4b53cSBarry Smith . prefix - The options prefix for the output `PetscFE`, or `NULL` 5746bb7acecfSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 57472df84da0SMatthew G. Knepley 57482df84da0SMatthew G. Knepley Output Parameter: 5749bb7acecfSBarry Smith . fem - The `PetscFE` 57502df84da0SMatthew G. Knepley 575120f4b53cSBarry Smith Level: intermediate 575220f4b53cSBarry Smith 5753bb7acecfSBarry Smith Note: 5754bb7acecfSBarry Smith This is a convenience method that just calls `PetscFECreateByCell()` underneath. 57552df84da0SMatthew G. Knepley 57561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscFECreateByCell()`, `DMAddField()`, `DMCreateDS()`, `DMGetCellDS()`, `DMGetRegionDS()` 57572df84da0SMatthew G. Knepley @*/ 5758d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFEDefault(DM dm, PetscInt Nc, const char prefix[], PetscInt qorder, PetscFE *fem) 5759d71ae5a4SJacob Faibussowitsch { 57602df84da0SMatthew G. Knepley DMPolytopeType ct; 57612df84da0SMatthew G. Knepley PetscInt dim, cStart; 57622df84da0SMatthew G. Knepley 57632df84da0SMatthew G. Knepley PetscFunctionBegin; 57642df84da0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57652df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 2); 57664f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 3); 57672df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, qorder, 4); 57684f572ea9SToby Isaac PetscAssertPointer(fem, 5); 57699566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 57709566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 57719566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 57729566063dSJacob Faibussowitsch PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, Nc, ct, prefix, qorder, fem)); 57733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57742df84da0SMatthew G. Knepley } 57752df84da0SMatthew G. Knepley 57761d3af9e0SMatthew G. Knepley /*@ 5777bb7acecfSBarry Smith DMCreateDS - Create the discrete systems for the `DM` based upon the fields added to the `DM` 5778e5e52638SMatthew G. Knepley 577920f4b53cSBarry Smith Collective 5780e5e52638SMatthew G. Knepley 5781e5e52638SMatthew G. Knepley Input Parameter: 5782bb7acecfSBarry Smith . dm - The `DM` 5783e5e52638SMatthew G. Knepley 578420f4b53cSBarry Smith Options Database Key: 5785bb7acecfSBarry Smith . -dm_petscds_view - View all the `PetscDS` objects in this `DM` 578645480ffeSMatthew G. Knepley 578720f4b53cSBarry Smith Level: intermediate 578820f4b53cSBarry Smith 57891cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetField`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 5790e5e52638SMatthew G. Knepley @*/ 5791d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDS(DM dm) 5792d71ae5a4SJacob Faibussowitsch { 5793e5e52638SMatthew G. Knepley MPI_Comm comm; 5794083401c6SMatthew G. Knepley PetscDS dsDef; 5795083401c6SMatthew G. Knepley DMLabel *labelSet; 5796f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5797f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5798e5e52638SMatthew G. Knepley 5799e5e52638SMatthew G. Knepley PetscFunctionBegin; 5800e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58013ba16761SJacob Faibussowitsch if (!dm->fields) PetscFunctionReturn(PETSC_SUCCESS); 58029566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 58039566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dE)); 5804083401c6SMatthew G. Knepley /* Determine how many regions we have */ 58059566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &labelSet)); 5806083401c6SMatthew G. Knepley Nl = 0; 5807083401c6SMatthew G. Knepley Ndef = 0; 5808083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5809083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5810083401c6SMatthew G. Knepley PetscInt l; 5811083401c6SMatthew G. Knepley 5812f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5813f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5814f918ec44SMatthew G. Knepley { 5815f918ec44SMatthew G. Knepley PetscClassId id; 5816f918ec44SMatthew G. Knepley 58179566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(dm->fields[f].disc, &id)); 5818f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5819f918ec44SMatthew G. Knepley Ceed ceed; 5820f918ec44SMatthew G. Knepley 58219566063dSJacob Faibussowitsch PetscCall(DMGetCeed(dm, &ceed)); 58229566063dSJacob Faibussowitsch PetscCall(PetscFESetCeed((PetscFE)dm->fields[f].disc, ceed)); 5823f918ec44SMatthew G. Knepley } 5824f918ec44SMatthew G. Knepley } 5825f918ec44SMatthew G. Knepley #endif 58269371c9d4SSatish Balay if (!label) { 58279371c9d4SSatish Balay ++Ndef; 58289371c9d4SSatish Balay continue; 58299371c9d4SSatish Balay } 58309371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 58319371c9d4SSatish Balay if (label == labelSet[l]) break; 5832083401c6SMatthew G. Knepley if (l < Nl) continue; 5833083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5834083401c6SMatthew G. Knepley } 5835083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 583607218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 5837083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5838b3cf3223SMatthew G. Knepley IS fields; 5839b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5840b3cf3223SMatthew G. Knepley 58419371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58429371c9d4SSatish Balay if (!dm->fields[f].label) ++nf; 58437a8be351SBarry Smith PetscCheck(nf, comm, PETSC_ERR_PLIB, "All fields have labels, but we are trying to create a default DS"); 58449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 58459371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 58469371c9d4SSatish Balay if (!dm->fields[f].label) fld[nf++] = f; 58479566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 58489566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 58499566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 58509566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 585188f0c812SMatthew G. Knepley 58529566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 585307218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, NULL, fields, dsDef, NULL)); 58549566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 58559566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 58562df9ee95SMatthew G. Knepley } 585707218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 58589566063dSJacob Faibussowitsch if (dsDef) PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 5859083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5860083401c6SMatthew G. Knepley if (Ndef && Nl) { 58610122748bSMatthew G. Knepley DM plex; 5862083401c6SMatthew G. Knepley DMLabel cellLabel; 5863083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5864083401c6SMatthew G. Knepley PetscInt *fields; 5865083401c6SMatthew G. Knepley const PetscInt *cells; 5866083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 58670122748bSMatthew G. Knepley 58689566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 58699566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(plex, &depth)); 58709566063dSJacob Faibussowitsch PetscCall(DMGetStratumIS(plex, "dim", depth, &allcellIS)); 58719566063dSJacob Faibussowitsch if (!allcellIS) PetscCall(DMGetStratumIS(plex, "depth", depth, &allcellIS)); 58725fedec97SMatthew G. Knepley /* TODO This looks like it only works for one label */ 5873083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5874083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5875083401c6SMatthew G. Knepley IS pointIS; 5876083401c6SMatthew G. Knepley 58779566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 58789566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, 1, &pointIS)); 58799566063dSJacob Faibussowitsch PetscCall(ISDifference(allcellIS, pointIS, &defcellIS)); 58809566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointIS)); 5881083401c6SMatthew G. Knepley } 58829566063dSJacob Faibussowitsch PetscCall(ISDestroy(&allcellIS)); 5883083401c6SMatthew G. Knepley 58849566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel)); 58859566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(defcellIS, &n)); 58869566063dSJacob Faibussowitsch PetscCall(ISGetIndices(defcellIS, &cells)); 58879566063dSJacob Faibussowitsch for (c = 0; c < n; ++c) PetscCall(DMLabelSetValue(cellLabel, cells[c], 1)); 58889566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(defcellIS, &cells)); 58899566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 58909566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(plex, cellLabel)); 5891083401c6SMatthew G. Knepley 58929566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Ndef, &fields)); 58939371c9d4SSatish Balay for (f = 0; f < Nf; ++f) 58949371c9d4SSatish Balay if (!dm->fields[f].label) fields[nf++] = f; 58959566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fieldIS)); 58969566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fieldIS, "dm_fields_")); 58979566063dSJacob Faibussowitsch PetscCall(ISSetType(fieldIS, ISGENERAL)); 58989566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER)); 5899083401c6SMatthew G. Knepley 59009566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 590107218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, cellLabel, fieldIS, dsDef, NULL)); 59029566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 59039566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&cellLabel)); 59049566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 59059566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fieldIS)); 59069566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5907083401c6SMatthew G. Knepley } 5908083401c6SMatthew G. Knepley /* Create label DSes 5909083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5910083401c6SMatthew G. Knepley */ 5911083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5912083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5913083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 591407218a29SMatthew G. Knepley PetscDS ds, dsIn = NULL; 5915083401c6SMatthew G. Knepley IS fields; 5916083401c6SMatthew G. Knepley PetscInt *fld, nf; 5917083401c6SMatthew G. Knepley 59189566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 59199371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59209371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 59219566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 59229371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59239371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 59249566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 59259566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 59269566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 59279566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 59289566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(ds, dE)); 5929083401c6SMatthew G. Knepley { 5930083401c6SMatthew G. Knepley DMPolytopeType ct; 5931083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 59325fedec97SMatthew G. Knepley PetscBool isCohesiveLocal = PETSC_FALSE, isCohesive; 59330122748bSMatthew G. Knepley 59349566063dSJacob Faibussowitsch PetscCall(DMLabelGetBounds(label, &lStart, &lEnd)); 5935665f567fSMatthew G. Knepley if (lStart >= 0) { 59369566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, lStart, &ct)); 5937412e9a14SMatthew G. Knepley switch (ct) { 5938412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5939412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5940412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5941d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 5942d71ae5a4SJacob Faibussowitsch isCohesiveLocal = PETSC_TRUE; 5943d71ae5a4SJacob Faibussowitsch break; 5944d71ae5a4SJacob Faibussowitsch default: 5945d71ae5a4SJacob Faibussowitsch break; 5946412e9a14SMatthew G. Knepley } 5947665f567fSMatthew G. Knepley } 5948712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&isCohesiveLocal, &isCohesive, 1, MPIU_BOOL, MPI_LOR, comm)); 594907218a29SMatthew G. Knepley if (isCohesive) { 595007218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsIn)); 595107218a29SMatthew G. Knepley PetscCall(PetscDSSetCoordinateDimension(dsIn, dE)); 595207218a29SMatthew G. Knepley } 59535fedec97SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) { 59545fedec97SMatthew G. Knepley if (label == dm->fields[f].label || !dm->fields[f].label) { 59555fedec97SMatthew G. Knepley if (label == dm->fields[f].label) { 59569566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, nf, NULL)); 59579566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(ds, nf, isCohesive)); 595807218a29SMatthew G. Knepley if (dsIn) { 595907218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, nf, NULL)); 596007218a29SMatthew G. Knepley PetscCall(PetscDSSetCohesive(dsIn, nf, isCohesive)); 596107218a29SMatthew G. Knepley } 59625fedec97SMatthew G. Knepley } 59635fedec97SMatthew G. Knepley ++nf; 59645fedec97SMatthew G. Knepley } 59655fedec97SMatthew G. Knepley } 5966e5e52638SMatthew G. Knepley } 596707218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, ds, dsIn)); 596807218a29SMatthew G. Knepley PetscCall(ISDestroy(&fields)); 59699566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 597007218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsIn)); 5971e5e52638SMatthew G. Knepley } 59729566063dSJacob Faibussowitsch PetscCall(PetscFree(labelSet)); 5973e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5974083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5975083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 597607218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 5977083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5978083401c6SMatthew G. Knepley const PetscInt *fld; 59795fedec97SMatthew G. Knepley PetscInt nf, dsnf; 59805fedec97SMatthew G. Knepley PetscBool isCohesive; 5981e5e52638SMatthew G. Knepley 59829566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsnf)); 59839566063dSJacob Faibussowitsch PetscCall(PetscDSIsCohesive(ds, &isCohesive)); 59849566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(fields, &nf)); 59859566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fields, &fld)); 5986083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5987083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 59885fedec97SMatthew G. Knepley PetscBool isCohesiveField; 5989e5e52638SMatthew G. Knepley PetscClassId id; 5990e5e52638SMatthew G. Knepley 59915fedec97SMatthew G. Knepley /* Handle DS with no fields */ 59929566063dSJacob Faibussowitsch if (dsnf) PetscCall(PetscDSGetCohesive(ds, f, &isCohesiveField)); 59935fedec97SMatthew G. Knepley /* If this is a cohesive cell, then regular fields need the lower dimensional discretization */ 599407218a29SMatthew G. Knepley if (isCohesive) { 599507218a29SMatthew G. Knepley if (!isCohesiveField) { 599607218a29SMatthew G. Knepley PetscObject bdDisc; 599707218a29SMatthew G. Knepley 599807218a29SMatthew G. Knepley PetscCall(PetscFEGetHeightSubspace((PetscFE)disc, 1, (PetscFE *)&bdDisc)); 599907218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, bdDisc)); 600007218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 600107218a29SMatthew G. Knepley } else { 60029566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, f, disc)); 600307218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 600407218a29SMatthew G. Knepley } 600507218a29SMatthew G. Knepley } else { 600607218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, disc)); 600707218a29SMatthew G. Knepley } 6008083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 60099566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 6010e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 6011e5e52638SMatthew G. Knepley } 60129566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fields, &fld)); 6013e5e52638SMatthew G. Knepley } 6014f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 60159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)dm)->prefix, "-dm_ds_jet_degree", &k, &flg)); 6016f9244615SMatthew G. Knepley if (flg) { 60173b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 60183b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 601907218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 60203b4aee56SMatthew G. Knepley PetscInt Nf, f; 60213b4aee56SMatthew G. Knepley 60229566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 602307218a29SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 602407218a29SMatthew G. Knepley PetscCall(PetscDSSetJetDegree(ds, f, k)); 602507218a29SMatthew G. Knepley if (dsIn) PetscCall(PetscDSSetJetDegree(dsIn, f, k)); 602607218a29SMatthew G. Knepley } 60273b4aee56SMatthew G. Knepley } 6028f9244615SMatthew G. Knepley } 6029e5e52638SMatthew G. Knepley /* Setup DSes */ 6030e5e52638SMatthew G. Knepley if (doSetup) { 603107218a29SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 603207218a29SMatthew G. Knepley PetscCall(PetscDSSetUp(dm->probs[s].ds)); 603307218a29SMatthew G. Knepley if (dm->probs[s].dsIn) PetscCall(PetscDSSetUp(dm->probs[s].dsIn)); 603407218a29SMatthew G. Knepley } 6035e5e52638SMatthew G. Knepley } 60363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6037e5e52638SMatthew G. Knepley } 6038e5e52638SMatthew G. Knepley 6039e5e52638SMatthew G. Knepley /*@ 6040d2b2dc1eSMatthew G. Knepley DMUseTensorOrder - Use a tensor product closure ordering for the default section 6041d2b2dc1eSMatthew G. Knepley 6042d2b2dc1eSMatthew G. Knepley Input Parameters: 6043d2b2dc1eSMatthew G. Knepley + dm - The DM 6044d2b2dc1eSMatthew G. Knepley - tensor - Flag for tensor order 6045d2b2dc1eSMatthew G. Knepley 6046d2b2dc1eSMatthew G. Knepley Level: developer 6047d2b2dc1eSMatthew G. Knepley 6048d2b2dc1eSMatthew G. Knepley .seealso: `DMPlexSetClosurePermutationTensor()`, `PetscSectionResetClosurePermutation()` 6049d2b2dc1eSMatthew G. Knepley @*/ 6050d2b2dc1eSMatthew G. Knepley PetscErrorCode DMUseTensorOrder(DM dm, PetscBool tensor) 6051d2b2dc1eSMatthew G. Knepley { 6052d2b2dc1eSMatthew G. Knepley PetscInt Nf; 6053d2b2dc1eSMatthew G. Knepley PetscBool reorder = PETSC_TRUE, isPlex; 6054d2b2dc1eSMatthew G. Knepley 6055d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 6056d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMPLEX, &isPlex)); 6057d2b2dc1eSMatthew G. Knepley PetscCall(DMGetNumFields(dm, &Nf)); 6058d2b2dc1eSMatthew G. Knepley for (PetscInt f = 0; f < Nf; ++f) { 6059d2b2dc1eSMatthew G. Knepley PetscObject obj; 6060d2b2dc1eSMatthew G. Knepley PetscClassId id; 6061d2b2dc1eSMatthew G. Knepley 6062d2b2dc1eSMatthew G. Knepley PetscCall(DMGetField(dm, f, NULL, &obj)); 6063d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 6064d2b2dc1eSMatthew G. Knepley if (id == PETSCFE_CLASSID) { 6065d2b2dc1eSMatthew G. Knepley PetscSpace sp; 6066d2b2dc1eSMatthew G. Knepley PetscBool tensor; 6067d2b2dc1eSMatthew G. Knepley 6068d2b2dc1eSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace((PetscFE)obj, &sp)); 6069d2b2dc1eSMatthew G. Knepley PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 6070d2b2dc1eSMatthew G. Knepley reorder = reorder && tensor ? PETSC_TRUE : PETSC_FALSE; 6071d2b2dc1eSMatthew G. Knepley } else reorder = PETSC_FALSE; 6072d2b2dc1eSMatthew G. Knepley } 6073d2b2dc1eSMatthew G. Knepley if (tensor) { 6074d2b2dc1eSMatthew G. Knepley if (reorder && isPlex) PetscCall(DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, NULL)); 6075d2b2dc1eSMatthew G. Knepley } else { 6076d2b2dc1eSMatthew G. Knepley PetscSection s; 6077d2b2dc1eSMatthew G. Knepley 6078d2b2dc1eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm, &s)); 6079d2b2dc1eSMatthew G. Knepley if (s) PetscCall(PetscSectionResetClosurePermutation(s)); 6080d2b2dc1eSMatthew G. Knepley } 6081d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 6082d2b2dc1eSMatthew G. Knepley } 6083d2b2dc1eSMatthew G. Knepley 6084d2b2dc1eSMatthew G. Knepley /*@ 6085bb7acecfSBarry Smith DMComputeExactSolution - Compute the exact solution for a given `DM`, using the `PetscDS` information. 60867f96f943SMatthew G. Knepley 608720f4b53cSBarry Smith Collective 6088f2cacb80SMatthew G. Knepley 60897f96f943SMatthew G. Knepley Input Parameters: 6090bb7acecfSBarry Smith + dm - The `DM` 60917f96f943SMatthew G. Knepley - time - The time 60927f96f943SMatthew G. Knepley 60937f96f943SMatthew G. Knepley Output Parameters: 609420f4b53cSBarry Smith + u - The vector will be filled with exact solution values, or `NULL` 609520f4b53cSBarry Smith - u_t - The vector will be filled with the time derivative of exact solution values, or `NULL` 609620f4b53cSBarry Smith 609720f4b53cSBarry Smith Level: developer 60987f96f943SMatthew G. Knepley 6099bb7acecfSBarry Smith Note: 6100bb7acecfSBarry Smith The user must call `PetscDSSetExactSolution()` before using this routine 61017f96f943SMatthew G. Knepley 61021cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscDSSetExactSolution()` 61037f96f943SMatthew G. Knepley @*/ 6104d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 6105d71ae5a4SJacob Faibussowitsch { 61067f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 61077f96f943SMatthew G. Knepley void **ectxs; 6108f60fa741SMatthew G. Knepley Vec locu, locu_t; 61097f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 61107f96f943SMatthew G. Knepley 61117f96f943SMatthew G. Knepley PetscFunctionBegin; 6112f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6113f60fa741SMatthew G. Knepley if (u) { 6114f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 6115f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu)); 6116f60fa741SMatthew G. Knepley PetscCall(VecSet(locu, 0.)); 6117f60fa741SMatthew G. Knepley } 6118f60fa741SMatthew G. Knepley if (u_t) { 6119f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 6120f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu_t)); 6121f60fa741SMatthew G. Knepley PetscCall(VecSet(locu_t, 0.)); 6122f60fa741SMatthew G. Knepley } 61239566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 61249566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exacts, Nf, &ectxs)); 61259566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 61267f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 61277f96f943SMatthew G. Knepley PetscDS ds; 61287f96f943SMatthew G. Knepley DMLabel label; 61297f96f943SMatthew G. Knepley IS fieldIS; 61307f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 61317f96f943SMatthew G. Knepley PetscInt dsNf, f; 61327f96f943SMatthew G. Knepley 613307218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 61349566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 61359566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fieldIS, &fields)); 61369566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 61379566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6138f2cacb80SMatthew G. Knepley if (u) { 6139f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolution(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6140f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu)); 6141f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu)); 61427f96f943SMatthew G. Knepley } 6143f2cacb80SMatthew G. Knepley if (u_t) { 61449566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 61459566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6146f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6147f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6148f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6149f2cacb80SMatthew G. Knepley } 61509566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 6151f2cacb80SMatthew G. Knepley } 6152f2cacb80SMatthew G. Knepley if (u) { 61539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution")); 61549566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u, "exact_")); 6155f2cacb80SMatthew G. Knepley } 6156f2cacb80SMatthew G. Knepley if (u_t) { 61579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution Time Derivative")); 61589566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u_t, "exact_t_")); 6159f2cacb80SMatthew G. Knepley } 61609566063dSJacob Faibussowitsch PetscCall(PetscFree2(exacts, ectxs)); 6161f60fa741SMatthew G. Knepley if (u) { 6162f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu, INSERT_ALL_VALUES, u)); 6163f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu, INSERT_ALL_VALUES, u)); 6164f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu)); 6165f60fa741SMatthew G. Knepley } 6166f60fa741SMatthew G. Knepley if (u_t) { 6167f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6168f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6169f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu_t)); 6170f60fa741SMatthew G. Knepley } 61713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 61727f96f943SMatthew G. Knepley } 61737f96f943SMatthew G. Knepley 617407218a29SMatthew G. Knepley static PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 6175d71ae5a4SJacob Faibussowitsch { 617607218a29SMatthew G. Knepley PetscDS dsNew, dsInNew = NULL; 617745480ffeSMatthew G. Knepley 617845480ffeSMatthew G. Knepley PetscFunctionBegin; 61799566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)ds), &dsNew)); 618007218a29SMatthew G. Knepley PetscCall(PetscDSCopy(ds, dm, dsNew)); 618107218a29SMatthew G. Knepley if (dsIn) { 618207218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)dsIn), &dsInNew)); 618307218a29SMatthew G. Knepley PetscCall(PetscDSCopy(dsIn, dm, dsInNew)); 618445480ffeSMatthew G. Knepley } 618507218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, dsNew, dsInNew)); 61869566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsNew)); 618707218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsInNew)); 61883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 618945480ffeSMatthew G. Knepley } 619045480ffeSMatthew G. Knepley 61917f96f943SMatthew G. Knepley /*@ 6192bb7acecfSBarry Smith DMCopyDS - Copy the discrete systems for the `DM` into another `DM` 6193e5e52638SMatthew G. Knepley 619420f4b53cSBarry Smith Collective 6195e5e52638SMatthew G. Knepley 6196e5e52638SMatthew G. Knepley Input Parameter: 6197bb7acecfSBarry Smith . dm - The `DM` 6198e5e52638SMatthew G. Knepley 6199e5e52638SMatthew G. Knepley Output Parameter: 6200bb7acecfSBarry Smith . newdm - The `DM` 6201e5e52638SMatthew G. Knepley 6202e5e52638SMatthew G. Knepley Level: advanced 6203e5e52638SMatthew G. Knepley 62041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 6205e5e52638SMatthew G. Knepley @*/ 6206d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDS(DM dm, DM newdm) 6207d71ae5a4SJacob Faibussowitsch { 6208e5e52638SMatthew G. Knepley PetscInt Nds, s; 6209e5e52638SMatthew G. Knepley 6210e5e52638SMatthew G. Knepley PetscFunctionBegin; 62113ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 62129566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 62139566063dSJacob Faibussowitsch PetscCall(DMClearDS(newdm)); 6214e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6215e5e52638SMatthew G. Knepley DMLabel label; 6216b3cf3223SMatthew G. Knepley IS fields; 621707218a29SMatthew G. Knepley PetscDS ds, dsIn, newds; 6218783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6219e5e52638SMatthew G. Knepley 622007218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fields, &ds, &dsIn)); 6221b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 622207218a29SMatthew G. Knepley PetscCall(DMTransferDS_Internal(newdm, label, fields, ds, dsIn)); 6223d5b43468SJose E. Roman /* Complete new labels in the new DS */ 622407218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(newdm, label, NULL, &newds, NULL)); 62259566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumBoundary(newds, &Nbd)); 6226783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6227b8025e53SMatthew G. Knepley PetscWeakForm wf; 622845480ffeSMatthew G. Knepley DMLabel label; 6229783e2ec8SMatthew G. Knepley PetscInt field; 6230783e2ec8SMatthew G. Knepley 62319566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 62329566063dSJacob Faibussowitsch PetscCall(PetscWeakFormReplaceLabel(wf, label)); 6233783e2ec8SMatthew G. Knepley } 6234e5e52638SMatthew G. Knepley } 6235799db056SMatthew G. Knepley PetscCall(DMCompleteBCLabels_Internal(newdm)); 62363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6237e5e52638SMatthew G. Knepley } 6238e5e52638SMatthew G. Knepley 6239e5e52638SMatthew G. Knepley /*@ 6240bb7acecfSBarry Smith DMCopyDisc - Copy the fields and discrete systems for the `DM` into another `DM` 6241e5e52638SMatthew G. Knepley 624220f4b53cSBarry Smith Collective 6243e5e52638SMatthew G. Knepley 6244e5e52638SMatthew G. Knepley Input Parameter: 6245bb7acecfSBarry Smith . dm - The `DM` 6246e5e52638SMatthew G. Knepley 6247e5e52638SMatthew G. Knepley Output Parameter: 6248bb7acecfSBarry Smith . newdm - The `DM` 6249e5e52638SMatthew G. Knepley 6250e5e52638SMatthew G. Knepley Level: advanced 6251e5e52638SMatthew G. Knepley 625260225df5SJacob Faibussowitsch Developer Notes: 6253bb7acecfSBarry Smith Really ugly name, nothing in PETSc is called a `Disc` plus it is an ugly abbreviation 6254bb7acecfSBarry Smith 62551cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMCopyDS()` 6256e5e52638SMatthew G. Knepley @*/ 6257d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6258d71ae5a4SJacob Faibussowitsch { 6259e5e52638SMatthew G. Knepley PetscFunctionBegin; 62609566063dSJacob Faibussowitsch PetscCall(DMCopyFields(dm, newdm)); 62619566063dSJacob Faibussowitsch PetscCall(DMCopyDS(dm, newdm)); 62623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6263e5e52638SMatthew G. Knepley } 6264e5e52638SMatthew G. Knepley 6265c73cfb54SMatthew G. Knepley /*@ 6266bb7acecfSBarry Smith DMGetDimension - Return the topological dimension of the `DM` 6267c73cfb54SMatthew G. Knepley 626820f4b53cSBarry Smith Not Collective 6269c73cfb54SMatthew G. Knepley 6270c73cfb54SMatthew G. Knepley Input Parameter: 6271bb7acecfSBarry Smith . dm - The `DM` 6272c73cfb54SMatthew G. Knepley 6273c73cfb54SMatthew G. Knepley Output Parameter: 6274c73cfb54SMatthew G. Knepley . dim - The topological dimension 6275c73cfb54SMatthew G. Knepley 6276c73cfb54SMatthew G. Knepley Level: beginner 6277c73cfb54SMatthew G. Knepley 62781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDimension()`, `DMCreate()` 6279c73cfb54SMatthew G. Knepley @*/ 6280d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6281d71ae5a4SJacob Faibussowitsch { 6282c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6283c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 62844f572ea9SToby Isaac PetscAssertPointer(dim, 2); 6285c73cfb54SMatthew G. Knepley *dim = dm->dim; 62863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6287c73cfb54SMatthew G. Knepley } 6288c73cfb54SMatthew G. Knepley 6289c73cfb54SMatthew G. Knepley /*@ 6290bb7acecfSBarry Smith DMSetDimension - Set the topological dimension of the `DM` 6291c73cfb54SMatthew G. Knepley 629220f4b53cSBarry Smith Collective 6293c73cfb54SMatthew G. Knepley 6294c73cfb54SMatthew G. Knepley Input Parameters: 6295bb7acecfSBarry Smith + dm - The `DM` 6296c73cfb54SMatthew G. Knepley - dim - The topological dimension 6297c73cfb54SMatthew G. Knepley 6298c73cfb54SMatthew G. Knepley Level: beginner 6299c73cfb54SMatthew G. Knepley 63001cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDimension()`, `DMCreate()` 6301c73cfb54SMatthew G. Knepley @*/ 6302d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6303d71ae5a4SJacob Faibussowitsch { 6304e5e52638SMatthew G. Knepley PetscDS ds; 630545480ffeSMatthew G. Knepley PetscInt Nds, n; 6306f17e8794SMatthew G. Knepley 6307c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6308c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6309c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6310c73cfb54SMatthew G. Knepley dm->dim = dim; 6311d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 63129566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 631345480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 631407218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds, NULL)); 63159566063dSJacob Faibussowitsch if (ds->dimEmbed < 0) PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 631645480ffeSMatthew G. Knepley } 6317d17bd122SMatthew G. Knepley } 63183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6319c73cfb54SMatthew G. Knepley } 6320c73cfb54SMatthew G. Knepley 6321793f3fe5SMatthew G. Knepley /*@ 6322793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6323793f3fe5SMatthew G. Knepley 632420f4b53cSBarry Smith Collective 6325793f3fe5SMatthew G. Knepley 6326793f3fe5SMatthew G. Knepley Input Parameters: 6327bb7acecfSBarry Smith + dm - the `DM` 6328793f3fe5SMatthew G. Knepley - dim - the dimension 6329793f3fe5SMatthew G. Knepley 6330793f3fe5SMatthew G. Knepley Output Parameters: 6331793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6332aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6333793f3fe5SMatthew G. Knepley 633420f4b53cSBarry Smith Level: intermediate 633520f4b53cSBarry Smith 6336793f3fe5SMatthew G. Knepley Note: 6337793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6338a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6339793f3fe5SMatthew G. Knepley then the interval is empty. 6340793f3fe5SMatthew G. Knepley 63411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPLEX`, `DMPlexGetDepthStratum()`, `DMPlexGetHeightStratum()` 6342793f3fe5SMatthew G. Knepley @*/ 6343d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6344d71ae5a4SJacob Faibussowitsch { 6345793f3fe5SMatthew G. Knepley PetscInt d; 6346793f3fe5SMatthew G. Knepley 6347793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6348793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63499566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &d)); 63507a8be351SBarry Smith PetscCheck((dim >= 0) && (dim <= d), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %" PetscInt_FMT, dim); 6351dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getdimpoints, dim, pStart, pEnd); 63523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6353793f3fe5SMatthew G. Knepley } 6354793f3fe5SMatthew G. Knepley 63556636e97aSMatthew G Knepley /*@ 6356bb7acecfSBarry Smith DMGetOutputDM - Retrieve the `DM` associated with the layout for output 6357f4d763aaSMatthew G. Knepley 635820f4b53cSBarry Smith Collective 63598f700142SStefano Zampini 6360f4d763aaSMatthew G. Knepley Input Parameter: 6361bb7acecfSBarry Smith . dm - The original `DM` 6362f4d763aaSMatthew G. Knepley 6363f4d763aaSMatthew G. Knepley Output Parameter: 6364bb7acecfSBarry Smith . odm - The `DM` which provides the layout for output 6365f4d763aaSMatthew G. Knepley 6366f4d763aaSMatthew G. Knepley Level: intermediate 6367f4d763aaSMatthew G. Knepley 6368bb7acecfSBarry Smith Note: 6369bb7acecfSBarry Smith In some situations the vector obtained with `DMCreateGlobalVector()` excludes points for degrees of freedom that are associated with fixed (Dirichelet) boundary 6370bb7acecfSBarry 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 6371bb7acecfSBarry Smith locations for those dof so that they can be output to a file or other viewer along with the unconstrained dof. 6372bb7acecfSBarry Smith 63731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()`, `DMGetGlobalSection()`, `DMCreateGlobalVector()`, `PetscSectionHasConstraints()`, `DMSetGlobalSection()` 6374f4d763aaSMatthew G. Knepley @*/ 6375d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 6376d71ae5a4SJacob Faibussowitsch { 6377c26acbdeSMatthew G. Knepley PetscSection section; 63782d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 637914f150ffSMatthew G. Knepley 638014f150ffSMatthew G. Knepley PetscFunctionBegin; 638114f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63824f572ea9SToby Isaac PetscAssertPointer(odm, 2); 63839566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 63849566063dSJacob Faibussowitsch PetscCall(PetscSectionHasConstraints(section, &hasConstraints)); 6385712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)dm))); 63862d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 6387c26acbdeSMatthew G. Knepley *odm = dm; 63883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6389c26acbdeSMatthew G. Knepley } 639014f150ffSMatthew G. Knepley if (!dm->dmBC) { 6391c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 639214f150ffSMatthew G. Knepley PetscSF sf; 639314f150ffSMatthew G. Knepley 63949566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->dmBC)); 63959566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, dm->dmBC)); 63969566063dSJacob Faibussowitsch PetscCall(PetscSectionClone(section, &newSection)); 63979566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm->dmBC, newSection)); 63989566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&newSection)); 63999566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm->dmBC, &sf)); 64009566063dSJacob Faibussowitsch PetscCall(PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection)); 64019566063dSJacob Faibussowitsch PetscCall(DMSetGlobalSection(dm->dmBC, gsection)); 64029566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&gsection)); 640314f150ffSMatthew G. Knepley } 640414f150ffSMatthew G. Knepley *odm = dm->dmBC; 64053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 640614f150ffSMatthew G. Knepley } 6407f4d763aaSMatthew G. Knepley 6408f4d763aaSMatthew G. Knepley /*@ 6409cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 6410f4d763aaSMatthew G. Knepley 6411f4d763aaSMatthew G. Knepley Input Parameter: 6412bb7acecfSBarry Smith . dm - The original `DM` 6413f4d763aaSMatthew G. Knepley 6414cdb7a50dSMatthew G. Knepley Output Parameters: 6415cdb7a50dSMatthew G. Knepley + num - The output sequence number 6416cdb7a50dSMatthew G. Knepley - val - The output sequence value 6417f4d763aaSMatthew G. Knepley 6418f4d763aaSMatthew G. Knepley Level: intermediate 6419f4d763aaSMatthew G. Knepley 6420bb7acecfSBarry Smith Note: 6421bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6422bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6423bb7acecfSBarry Smith 642460225df5SJacob Faibussowitsch Developer Notes: 6425bb7acecfSBarry Smith The `DM` serves as a convenient place to store the current iteration value. The iteration is not 6426bb7acecfSBarry Smith not directly related to the `DM`. 6427f4d763aaSMatthew G. Knepley 64281cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6429f4d763aaSMatthew G. Knepley @*/ 6430d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 6431d71ae5a4SJacob Faibussowitsch { 6432f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6433f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64349371c9d4SSatish Balay if (num) { 64354f572ea9SToby Isaac PetscAssertPointer(num, 2); 64369371c9d4SSatish Balay *num = dm->outputSequenceNum; 64379371c9d4SSatish Balay } 64389371c9d4SSatish Balay if (val) { 64394f572ea9SToby Isaac PetscAssertPointer(val, 3); 64409371c9d4SSatish Balay *val = dm->outputSequenceVal; 64419371c9d4SSatish Balay } 64423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6443f4d763aaSMatthew G. Knepley } 6444f4d763aaSMatthew G. Knepley 6445f4d763aaSMatthew G. Knepley /*@ 6446cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 6447f4d763aaSMatthew G. Knepley 6448f4d763aaSMatthew G. Knepley Input Parameters: 6449bb7acecfSBarry Smith + dm - The original `DM` 6450cdb7a50dSMatthew G. Knepley . num - The output sequence number 6451cdb7a50dSMatthew G. Knepley - val - The output sequence value 6452f4d763aaSMatthew G. Knepley 6453f4d763aaSMatthew G. Knepley Level: intermediate 6454f4d763aaSMatthew G. Knepley 6455bb7acecfSBarry Smith Note: 6456bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6457bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6458f4d763aaSMatthew G. Knepley 64591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6460f4d763aaSMatthew G. Knepley @*/ 6461d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 6462d71ae5a4SJacob Faibussowitsch { 6463f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6464f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6465f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 6466cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 64673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6468cdb7a50dSMatthew G. Knepley } 6469cdb7a50dSMatthew G. Knepley 6470cdb7a50dSMatthew G. Knepley /*@C 6471bb7acecfSBarry Smith DMOutputSequenceLoad - Retrieve the sequence value from a `PetscViewer` 6472cdb7a50dSMatthew G. Knepley 6473cdb7a50dSMatthew G. Knepley Input Parameters: 6474bb7acecfSBarry Smith + dm - The original `DM` 6475a4e35b19SJacob Faibussowitsch . viewer - The viewer to get it from 6476cdb7a50dSMatthew G. Knepley . name - The sequence name 6477cdb7a50dSMatthew G. Knepley - num - The output sequence number 6478cdb7a50dSMatthew G. Knepley 6479cdb7a50dSMatthew G. Knepley Output Parameter: 6480cdb7a50dSMatthew G. Knepley . val - The output sequence value 6481cdb7a50dSMatthew G. Knepley 6482cdb7a50dSMatthew G. Knepley Level: intermediate 6483cdb7a50dSMatthew G. Knepley 6484bb7acecfSBarry Smith Note: 6485bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6486bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6487bb7acecfSBarry Smith 648860225df5SJacob Faibussowitsch Developer Notes: 6489bb7acecfSBarry Smith It is unclear at the user API level why a `DM` is needed as input 6490cdb7a50dSMatthew G. Knepley 64911cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6492cdb7a50dSMatthew G. Knepley @*/ 6493d71ae5a4SJacob Faibussowitsch PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 6494d71ae5a4SJacob Faibussowitsch { 6495cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 6496cdb7a50dSMatthew G. Knepley 6497cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 6498cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6499cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 65004f572ea9SToby Isaac PetscAssertPointer(val, 5); 65019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6502cdb7a50dSMatthew G. Knepley if (ishdf5) { 6503cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6504cdb7a50dSMatthew G. Knepley PetscScalar value; 6505cdb7a50dSMatthew G. Knepley 65069566063dSJacob Faibussowitsch PetscCall(DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer)); 65074aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 6508cdb7a50dSMatthew G. Knepley #endif 6509cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 65103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6511f4d763aaSMatthew G. Knepley } 65128e4ac7eaSMatthew G. Knepley 65138e4ac7eaSMatthew G. Knepley /*@ 6514bb7acecfSBarry Smith DMGetUseNatural - Get the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 65158e4ac7eaSMatthew G. Knepley 651620f4b53cSBarry Smith Not Collective 65178e4ac7eaSMatthew G. Knepley 65188e4ac7eaSMatthew G. Knepley Input Parameter: 6519bb7acecfSBarry Smith . dm - The `DM` 65208e4ac7eaSMatthew G. Knepley 65218e4ac7eaSMatthew G. Knepley Output Parameter: 6522bb7acecfSBarry Smith . useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 65238e4ac7eaSMatthew G. Knepley 65248e4ac7eaSMatthew G. Knepley Level: beginner 65258e4ac7eaSMatthew G. Knepley 65261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetUseNatural()`, `DMCreate()` 65278e4ac7eaSMatthew G. Knepley @*/ 6528d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 6529d71ae5a4SJacob Faibussowitsch { 65308e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 65318e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65324f572ea9SToby Isaac PetscAssertPointer(useNatural, 2); 65338e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 65343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 65358e4ac7eaSMatthew G. Knepley } 65368e4ac7eaSMatthew G. Knepley 65378e4ac7eaSMatthew G. Knepley /*@ 6538bb7acecfSBarry Smith DMSetUseNatural - Set the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 65398e4ac7eaSMatthew G. Knepley 654020f4b53cSBarry Smith Collective 65418e4ac7eaSMatthew G. Knepley 65428e4ac7eaSMatthew G. Knepley Input Parameters: 6543bb7acecfSBarry Smith + dm - The `DM` 6544bb7acecfSBarry Smith - useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 65458e4ac7eaSMatthew G. Knepley 6546bb7acecfSBarry Smith Note: 6547bb7acecfSBarry Smith This also causes the map to be build after `DMCreateSubDM()` and `DMCreateSuperDM()` 65485d3b26e6SMatthew G. Knepley 65498e4ac7eaSMatthew G. Knepley Level: beginner 65508e4ac7eaSMatthew G. Knepley 65511cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetUseNatural()`, `DMCreate()`, `DMPlexDistribute()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 65528e4ac7eaSMatthew G. Knepley @*/ 6553d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 6554d71ae5a4SJacob Faibussowitsch { 65558e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 65568e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65578833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 65588e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 65593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 65608e4ac7eaSMatthew G. Knepley } 6561c58f1c22SToby Isaac 6562c58f1c22SToby Isaac /*@C 6563bb7acecfSBarry Smith DMCreateLabel - Create a label of the given name if it does not already exist in the `DM` 6564c58f1c22SToby Isaac 6565c58f1c22SToby Isaac Not Collective 6566c58f1c22SToby Isaac 6567c58f1c22SToby Isaac Input Parameters: 6568bb7acecfSBarry Smith + dm - The `DM` object 6569c58f1c22SToby Isaac - name - The label name 6570c58f1c22SToby Isaac 6571c58f1c22SToby Isaac Level: intermediate 6572c58f1c22SToby Isaac 65731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6574c58f1c22SToby Isaac @*/ 6575d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabel(DM dm, const char name[]) 6576d71ae5a4SJacob Faibussowitsch { 65775d80c0bfSVaclav Hapla PetscBool flg; 65785d80c0bfSVaclav Hapla DMLabel label; 6579c58f1c22SToby Isaac 6580c58f1c22SToby Isaac PetscFunctionBegin; 6581c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65824f572ea9SToby Isaac PetscAssertPointer(name, 2); 65839566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 6584c58f1c22SToby Isaac if (!flg) { 65859566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 65869566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 65879566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 6588c58f1c22SToby Isaac } 65893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6590c58f1c22SToby Isaac } 6591c58f1c22SToby Isaac 6592c58f1c22SToby Isaac /*@C 6593bb7acecfSBarry 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. 65940fdc7489SMatthew Knepley 65950fdc7489SMatthew Knepley Not Collective 65960fdc7489SMatthew Knepley 65970fdc7489SMatthew Knepley Input Parameters: 6598bb7acecfSBarry Smith + dm - The `DM` object 65990fdc7489SMatthew Knepley . l - The index for the label 66000fdc7489SMatthew Knepley - name - The label name 66010fdc7489SMatthew Knepley 66020fdc7489SMatthew Knepley Level: intermediate 66030fdc7489SMatthew Knepley 66041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateLabel()`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 66050fdc7489SMatthew Knepley @*/ 6606d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 6607d71ae5a4SJacob Faibussowitsch { 66080fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 66090fdc7489SMatthew Knepley DMLabel label; 66100fdc7489SMatthew Knepley PetscInt Nl, m; 66110fdc7489SMatthew Knepley PetscBool flg, match; 66120fdc7489SMatthew Knepley const char *lname; 66130fdc7489SMatthew Knepley 66140fdc7489SMatthew Knepley PetscFunctionBegin; 66150fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66164f572ea9SToby Isaac PetscAssertPointer(name, 3); 66179566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 66180fdc7489SMatthew Knepley if (!flg) { 66199566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 66209566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 66219566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 66220fdc7489SMatthew Knepley } 66239566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 662463a3b9bcSJacob Faibussowitsch PetscCheck(l < Nl, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", l, Nl); 66250fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 66269566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)orig->label, &lname)); 66279566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &match)); 66280fdc7489SMatthew Knepley if (match) break; 66290fdc7489SMatthew Knepley } 66303ba16761SJacob Faibussowitsch if (m == l) PetscFunctionReturn(PETSC_SUCCESS); 66310fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 66320fdc7489SMatthew Knepley else prev->next = orig->next; 66330fdc7489SMatthew Knepley if (!l) { 66340fdc7489SMatthew Knepley orig->next = dm->labels; 66350fdc7489SMatthew Knepley dm->labels = orig; 66360fdc7489SMatthew Knepley } else { 66379371c9d4SSatish Balay for (m = 0, prev = dm->labels; m < l - 1; ++m, prev = prev->next) 66389371c9d4SSatish Balay ; 66390fdc7489SMatthew Knepley orig->next = prev->next; 66400fdc7489SMatthew Knepley prev->next = orig; 66410fdc7489SMatthew Knepley } 66423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66430fdc7489SMatthew Knepley } 66440fdc7489SMatthew Knepley 66450fdc7489SMatthew Knepley /*@C 6646bb7acecfSBarry Smith DMGetLabelValue - Get the value in a `DMLabel` for the given point, with -1 as the default 6647c58f1c22SToby Isaac 6648c58f1c22SToby Isaac Not Collective 6649c58f1c22SToby Isaac 6650c58f1c22SToby Isaac Input Parameters: 6651bb7acecfSBarry Smith + dm - The `DM` object 6652c58f1c22SToby Isaac . name - The label name 6653c58f1c22SToby Isaac - point - The mesh point 6654c58f1c22SToby Isaac 6655c58f1c22SToby Isaac Output Parameter: 6656c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 6657c58f1c22SToby Isaac 6658c58f1c22SToby Isaac Level: beginner 6659c58f1c22SToby Isaac 66601cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6661c58f1c22SToby Isaac @*/ 6662d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 6663d71ae5a4SJacob Faibussowitsch { 6664c58f1c22SToby Isaac DMLabel label; 6665c58f1c22SToby Isaac 6666c58f1c22SToby Isaac PetscFunctionBegin; 6667c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66684f572ea9SToby Isaac PetscAssertPointer(name, 2); 66699566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 66707a8be351SBarry Smith PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 66719566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, point, value)); 66723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6673c58f1c22SToby Isaac } 6674c58f1c22SToby Isaac 6675c58f1c22SToby Isaac /*@C 6676bb7acecfSBarry Smith DMSetLabelValue - Add a point to a `DMLabel` with given value 6677c58f1c22SToby Isaac 6678c58f1c22SToby Isaac Not Collective 6679c58f1c22SToby Isaac 6680c58f1c22SToby Isaac Input Parameters: 6681bb7acecfSBarry Smith + dm - The `DM` object 6682c58f1c22SToby Isaac . name - The label name 6683c58f1c22SToby Isaac . point - The mesh point 6684c58f1c22SToby Isaac - value - The label value for this point 6685c58f1c22SToby Isaac 6686c58f1c22SToby Isaac Output Parameter: 6687c58f1c22SToby Isaac 6688c58f1c22SToby Isaac Level: beginner 6689c58f1c22SToby Isaac 66901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelSetValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6691c58f1c22SToby Isaac @*/ 6692d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6693d71ae5a4SJacob Faibussowitsch { 6694c58f1c22SToby Isaac DMLabel label; 6695c58f1c22SToby Isaac 6696c58f1c22SToby Isaac PetscFunctionBegin; 6697c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66984f572ea9SToby Isaac PetscAssertPointer(name, 2); 66999566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6700c58f1c22SToby Isaac if (!label) { 67019566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 67029566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6703c58f1c22SToby Isaac } 67049566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, point, value)); 67053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6706c58f1c22SToby Isaac } 6707c58f1c22SToby Isaac 6708c58f1c22SToby Isaac /*@C 6709bb7acecfSBarry Smith DMClearLabelValue - Remove a point from a `DMLabel` with given value 6710c58f1c22SToby Isaac 6711c58f1c22SToby Isaac Not Collective 6712c58f1c22SToby Isaac 6713c58f1c22SToby Isaac Input Parameters: 6714bb7acecfSBarry Smith + dm - The `DM` object 6715c58f1c22SToby Isaac . name - The label name 6716c58f1c22SToby Isaac . point - The mesh point 6717c58f1c22SToby Isaac - value - The label value for this point 6718c58f1c22SToby Isaac 6719c58f1c22SToby Isaac Level: beginner 6720c58f1c22SToby Isaac 67211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelClearValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6722c58f1c22SToby Isaac @*/ 6723d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6724d71ae5a4SJacob Faibussowitsch { 6725c58f1c22SToby Isaac DMLabel label; 6726c58f1c22SToby Isaac 6727c58f1c22SToby Isaac PetscFunctionBegin; 6728c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67294f572ea9SToby Isaac PetscAssertPointer(name, 2); 67309566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 67313ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 67329566063dSJacob Faibussowitsch PetscCall(DMLabelClearValue(label, point, value)); 67333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6734c58f1c22SToby Isaac } 6735c58f1c22SToby Isaac 6736c58f1c22SToby Isaac /*@C 6737bb7acecfSBarry Smith DMGetLabelSize - Get the value of `DMLabelGetNumValues()` of a `DMLabel` in the `DM` 6738c58f1c22SToby Isaac 6739c58f1c22SToby Isaac Not Collective 6740c58f1c22SToby Isaac 6741c58f1c22SToby Isaac Input Parameters: 6742bb7acecfSBarry Smith + dm - The `DM` object 6743c58f1c22SToby Isaac - name - The label name 6744c58f1c22SToby Isaac 6745c58f1c22SToby Isaac Output Parameter: 6746c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 6747c58f1c22SToby Isaac 6748c58f1c22SToby Isaac Level: beginner 6749c58f1c22SToby Isaac 675060225df5SJacob Faibussowitsch Developer Notes: 6751bb7acecfSBarry Smith This should be renamed to something like `DMGetLabelNumValues()` or removed. 6752bb7acecfSBarry Smith 67531cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetNumValues()`, `DMSetLabelValue()`, `DMGetLabel()` 6754c58f1c22SToby Isaac @*/ 6755d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 6756d71ae5a4SJacob Faibussowitsch { 6757c58f1c22SToby Isaac DMLabel label; 6758c58f1c22SToby Isaac 6759c58f1c22SToby Isaac PetscFunctionBegin; 6760c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67614f572ea9SToby Isaac PetscAssertPointer(name, 2); 67624f572ea9SToby Isaac PetscAssertPointer(size, 3); 67639566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6764c58f1c22SToby Isaac *size = 0; 67653ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 67669566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, size)); 67673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6768c58f1c22SToby Isaac } 6769c58f1c22SToby Isaac 6770c58f1c22SToby Isaac /*@C 6771bb7acecfSBarry Smith DMGetLabelIdIS - Get the `DMLabelGetValueIS()` from a `DMLabel` in the `DM` 6772c58f1c22SToby Isaac 6773c58f1c22SToby Isaac Not Collective 6774c58f1c22SToby Isaac 6775c58f1c22SToby Isaac Input Parameters: 677660225df5SJacob Faibussowitsch + dm - The `DM` object 6777c58f1c22SToby Isaac - name - The label name 6778c58f1c22SToby Isaac 6779c58f1c22SToby Isaac Output Parameter: 678020f4b53cSBarry Smith . ids - The integer ids, or `NULL` if the label does not exist 6781c58f1c22SToby Isaac 6782c58f1c22SToby Isaac Level: beginner 6783c58f1c22SToby Isaac 67841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValueIS()`, `DMGetLabelSize()` 6785c58f1c22SToby Isaac @*/ 6786d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 6787d71ae5a4SJacob Faibussowitsch { 6788c58f1c22SToby Isaac DMLabel label; 6789c58f1c22SToby Isaac 6790c58f1c22SToby Isaac PetscFunctionBegin; 6791c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67924f572ea9SToby Isaac PetscAssertPointer(name, 2); 67934f572ea9SToby Isaac PetscAssertPointer(ids, 3); 67949566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6795c58f1c22SToby Isaac *ids = NULL; 6796dab2e251SBlaise Bourdin if (label) { 67979566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, ids)); 6798dab2e251SBlaise Bourdin } else { 6799dab2e251SBlaise Bourdin /* returning an empty IS */ 68009566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 0, NULL, PETSC_USE_POINTER, ids)); 6801dab2e251SBlaise Bourdin } 68023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6803c58f1c22SToby Isaac } 6804c58f1c22SToby Isaac 6805c58f1c22SToby Isaac /*@C 6806c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 6807c58f1c22SToby Isaac 6808c58f1c22SToby Isaac Not Collective 6809c58f1c22SToby Isaac 6810c58f1c22SToby Isaac Input Parameters: 6811bb7acecfSBarry Smith + dm - The `DM` object 6812c58f1c22SToby Isaac . name - The label name 6813c58f1c22SToby Isaac - value - The stratum value 6814c58f1c22SToby Isaac 6815c58f1c22SToby Isaac Output Parameter: 6816bb7acecfSBarry Smith . size - The number of points, also called the stratum size 6817c58f1c22SToby Isaac 6818c58f1c22SToby Isaac Level: beginner 6819c58f1c22SToby Isaac 68201cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumSize()`, `DMGetLabelSize()`, `DMGetLabelIds()` 6821c58f1c22SToby Isaac @*/ 6822d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 6823d71ae5a4SJacob Faibussowitsch { 6824c58f1c22SToby Isaac DMLabel label; 6825c58f1c22SToby Isaac 6826c58f1c22SToby Isaac PetscFunctionBegin; 6827c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68284f572ea9SToby Isaac PetscAssertPointer(name, 2); 68294f572ea9SToby Isaac PetscAssertPointer(size, 4); 68309566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6831c58f1c22SToby Isaac *size = 0; 68323ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68339566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, value, size)); 68343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6835c58f1c22SToby Isaac } 6836c58f1c22SToby Isaac 6837c58f1c22SToby Isaac /*@C 6838c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 6839c58f1c22SToby Isaac 6840c58f1c22SToby Isaac Not Collective 6841c58f1c22SToby Isaac 6842c58f1c22SToby Isaac Input Parameters: 6843bb7acecfSBarry Smith + dm - The `DM` object 6844c58f1c22SToby Isaac . name - The label name 6845c58f1c22SToby Isaac - value - The stratum value 6846c58f1c22SToby Isaac 6847c58f1c22SToby Isaac Output Parameter: 684820f4b53cSBarry Smith . points - The stratum points, or `NULL` if the label does not exist or does not have that value 6849c58f1c22SToby Isaac 6850c58f1c22SToby Isaac Level: beginner 6851c58f1c22SToby Isaac 68521cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumIS()`, `DMGetStratumSize()` 6853c58f1c22SToby Isaac @*/ 6854d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 6855d71ae5a4SJacob Faibussowitsch { 6856c58f1c22SToby Isaac DMLabel label; 6857c58f1c22SToby Isaac 6858c58f1c22SToby Isaac PetscFunctionBegin; 6859c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68604f572ea9SToby Isaac PetscAssertPointer(name, 2); 68614f572ea9SToby Isaac PetscAssertPointer(points, 4); 68629566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6863c58f1c22SToby Isaac *points = NULL; 68643ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68659566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, value, points)); 68663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6867c58f1c22SToby Isaac } 6868c58f1c22SToby Isaac 68694de306b1SToby Isaac /*@C 68709044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 68714de306b1SToby Isaac 68724de306b1SToby Isaac Not Collective 68734de306b1SToby Isaac 68744de306b1SToby Isaac Input Parameters: 6875bb7acecfSBarry Smith + dm - The `DM` object 68764de306b1SToby Isaac . name - The label name 68774de306b1SToby Isaac . value - The stratum value 68784de306b1SToby Isaac - points - The stratum points 68794de306b1SToby Isaac 68804de306b1SToby Isaac Level: beginner 68814de306b1SToby Isaac 68821cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMClearLabelStratum()`, `DMLabelClearStratum()`, `DMLabelSetStratumIS()`, `DMGetStratumSize()` 68834de306b1SToby Isaac @*/ 6884d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 6885d71ae5a4SJacob Faibussowitsch { 68864de306b1SToby Isaac DMLabel label; 68874de306b1SToby Isaac 68884de306b1SToby Isaac PetscFunctionBegin; 68894de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68904f572ea9SToby Isaac PetscAssertPointer(name, 2); 6891292bffcbSToby Isaac PetscValidHeaderSpecific(points, IS_CLASSID, 4); 68929566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 68933ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68949566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, points)); 68953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 68964de306b1SToby Isaac } 68974de306b1SToby Isaac 6898c58f1c22SToby Isaac /*@C 6899bb7acecfSBarry Smith DMClearLabelStratum - Remove all points from a stratum from a `DMLabel` 6900c58f1c22SToby Isaac 6901c58f1c22SToby Isaac Not Collective 6902c58f1c22SToby Isaac 6903c58f1c22SToby Isaac Input Parameters: 6904bb7acecfSBarry Smith + dm - The `DM` object 6905c58f1c22SToby Isaac . name - The label name 6906c58f1c22SToby Isaac - value - The label value for this point 6907c58f1c22SToby Isaac 6908c58f1c22SToby Isaac Output Parameter: 6909c58f1c22SToby Isaac 6910c58f1c22SToby Isaac Level: beginner 6911c58f1c22SToby Isaac 69121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMLabelClearStratum()`, `DMSetLabelValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6913c58f1c22SToby Isaac @*/ 6914d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 6915d71ae5a4SJacob Faibussowitsch { 6916c58f1c22SToby Isaac DMLabel label; 6917c58f1c22SToby Isaac 6918c58f1c22SToby Isaac PetscFunctionBegin; 6919c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69204f572ea9SToby Isaac PetscAssertPointer(name, 2); 69219566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 69223ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69239566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 69243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6925c58f1c22SToby Isaac } 6926c58f1c22SToby Isaac 6927c58f1c22SToby Isaac /*@ 6928bb7acecfSBarry Smith DMGetNumLabels - Return the number of labels defined by on the `DM` 6929c58f1c22SToby Isaac 6930c58f1c22SToby Isaac Not Collective 6931c58f1c22SToby Isaac 6932c58f1c22SToby Isaac Input Parameter: 6933bb7acecfSBarry Smith . dm - The `DM` object 6934c58f1c22SToby Isaac 6935c58f1c22SToby Isaac Output Parameter: 6936c58f1c22SToby Isaac . numLabels - the number of Labels 6937c58f1c22SToby Isaac 6938c58f1c22SToby Isaac Level: intermediate 6939c58f1c22SToby Isaac 69401cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabelName()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6941c58f1c22SToby Isaac @*/ 6942d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 6943d71ae5a4SJacob Faibussowitsch { 69445d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6945c58f1c22SToby Isaac PetscInt n = 0; 6946c58f1c22SToby Isaac 6947c58f1c22SToby Isaac PetscFunctionBegin; 6948c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69494f572ea9SToby Isaac PetscAssertPointer(numLabels, 2); 69509371c9d4SSatish Balay while (next) { 69519371c9d4SSatish Balay ++n; 69529371c9d4SSatish Balay next = next->next; 69539371c9d4SSatish Balay } 6954c58f1c22SToby Isaac *numLabels = n; 69553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6956c58f1c22SToby Isaac } 6957c58f1c22SToby Isaac 6958c58f1c22SToby Isaac /*@C 6959c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 6960c58f1c22SToby Isaac 6961c58f1c22SToby Isaac Not Collective 6962c58f1c22SToby Isaac 6963c58f1c22SToby Isaac Input Parameters: 6964bb7acecfSBarry Smith + dm - The `DM` object 6965c58f1c22SToby Isaac - n - the label number 6966c58f1c22SToby Isaac 6967c58f1c22SToby Isaac Output Parameter: 6968c58f1c22SToby Isaac . name - the label name 6969c58f1c22SToby Isaac 6970c58f1c22SToby Isaac Level: intermediate 6971c58f1c22SToby Isaac 697260225df5SJacob Faibussowitsch Developer Notes: 6973bb7acecfSBarry Smith Some of the functions that appropriate on labels using their number have the suffix ByNum, others do not. 6974bb7acecfSBarry Smith 69751cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6976c58f1c22SToby Isaac @*/ 6977d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 6978d71ae5a4SJacob Faibussowitsch { 69795d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6980c58f1c22SToby Isaac PetscInt l = 0; 6981c58f1c22SToby Isaac 6982c58f1c22SToby Isaac PetscFunctionBegin; 6983c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69844f572ea9SToby Isaac PetscAssertPointer(name, 3); 6985c58f1c22SToby Isaac while (next) { 6986c58f1c22SToby Isaac if (l == n) { 69879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, name)); 69883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6989c58f1c22SToby Isaac } 6990c58f1c22SToby Isaac ++l; 6991c58f1c22SToby Isaac next = next->next; 6992c58f1c22SToby Isaac } 699363a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 6994c58f1c22SToby Isaac } 6995c58f1c22SToby Isaac 6996c58f1c22SToby Isaac /*@C 6997bb7acecfSBarry Smith DMHasLabel - Determine whether the `DM` has a label of a given name 6998c58f1c22SToby Isaac 6999c58f1c22SToby Isaac Not Collective 7000c58f1c22SToby Isaac 7001c58f1c22SToby Isaac Input Parameters: 7002bb7acecfSBarry Smith + dm - The `DM` object 7003c58f1c22SToby Isaac - name - The label name 7004c58f1c22SToby Isaac 7005c58f1c22SToby Isaac Output Parameter: 7006bb7acecfSBarry Smith . hasLabel - `PETSC_TRUE` if the label is present 7007c58f1c22SToby Isaac 7008c58f1c22SToby Isaac Level: intermediate 7009c58f1c22SToby Isaac 70101cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabel()`, `DMGetLabelByNum()`, `DMCreateLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7011c58f1c22SToby Isaac @*/ 7012d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7013d71ae5a4SJacob Faibussowitsch { 70145d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7015d67d17b1SMatthew G. Knepley const char *lname; 7016c58f1c22SToby Isaac 7017c58f1c22SToby Isaac PetscFunctionBegin; 7018c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70194f572ea9SToby Isaac PetscAssertPointer(name, 2); 70204f572ea9SToby Isaac PetscAssertPointer(hasLabel, 3); 7021c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7022c58f1c22SToby Isaac while (next) { 70239566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 70249566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, hasLabel)); 7025c58f1c22SToby Isaac if (*hasLabel) break; 7026c58f1c22SToby Isaac next = next->next; 7027c58f1c22SToby Isaac } 70283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7029c58f1c22SToby Isaac } 7030c58f1c22SToby Isaac 7031a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7032c58f1c22SToby Isaac /*@C 703320f4b53cSBarry Smith DMGetLabel - Return the label of a given name, or `NULL`, from a `DM` 7034c58f1c22SToby Isaac 7035c58f1c22SToby Isaac Not Collective 7036c58f1c22SToby Isaac 7037c58f1c22SToby Isaac Input Parameters: 7038bb7acecfSBarry Smith + dm - The `DM` object 7039c58f1c22SToby Isaac - name - The label name 7040c58f1c22SToby Isaac 7041c58f1c22SToby Isaac Output Parameter: 704220f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent 7043c58f1c22SToby Isaac 7044bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7045bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7046bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7047bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7048bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7049bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7050bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 70516d7c9049SMatthew G. Knepley 7052c58f1c22SToby Isaac Level: intermediate 7053c58f1c22SToby Isaac 705460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMHasLabel()`, `DMGetLabelByNum()`, `DMAddLabel()`, `DMCreateLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 7055c58f1c22SToby Isaac @*/ 7056d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7057d71ae5a4SJacob Faibussowitsch { 70585d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7059c58f1c22SToby Isaac PetscBool hasLabel; 7060d67d17b1SMatthew G. Knepley const char *lname; 7061c58f1c22SToby Isaac 7062c58f1c22SToby Isaac PetscFunctionBegin; 7063c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70644f572ea9SToby Isaac PetscAssertPointer(name, 2); 70654f572ea9SToby Isaac PetscAssertPointer(label, 3); 7066c58f1c22SToby Isaac *label = NULL; 7067c58f1c22SToby Isaac while (next) { 70689566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 70699566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7070c58f1c22SToby Isaac if (hasLabel) { 7071c58f1c22SToby Isaac *label = next->label; 7072c58f1c22SToby Isaac break; 7073c58f1c22SToby Isaac } 7074c58f1c22SToby Isaac next = next->next; 7075c58f1c22SToby Isaac } 70763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7077c58f1c22SToby Isaac } 7078c58f1c22SToby Isaac 7079c58f1c22SToby Isaac /*@C 7080bb7acecfSBarry Smith DMGetLabelByNum - Return the nth label on a `DM` 7081c58f1c22SToby Isaac 7082c58f1c22SToby Isaac Not Collective 7083c58f1c22SToby Isaac 7084c58f1c22SToby Isaac Input Parameters: 7085bb7acecfSBarry Smith + dm - The `DM` object 7086c58f1c22SToby Isaac - n - the label number 7087c58f1c22SToby Isaac 7088c58f1c22SToby Isaac Output Parameter: 7089c58f1c22SToby Isaac . label - the label 7090c58f1c22SToby Isaac 7091c58f1c22SToby Isaac Level: intermediate 7092c58f1c22SToby Isaac 70931cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7094c58f1c22SToby Isaac @*/ 7095d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7096d71ae5a4SJacob Faibussowitsch { 70975d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7098c58f1c22SToby Isaac PetscInt l = 0; 7099c58f1c22SToby Isaac 7100c58f1c22SToby Isaac PetscFunctionBegin; 7101c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71024f572ea9SToby Isaac PetscAssertPointer(label, 3); 7103c58f1c22SToby Isaac while (next) { 7104c58f1c22SToby Isaac if (l == n) { 7105c58f1c22SToby Isaac *label = next->label; 71063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7107c58f1c22SToby Isaac } 7108c58f1c22SToby Isaac ++l; 7109c58f1c22SToby Isaac next = next->next; 7110c58f1c22SToby Isaac } 711163a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7112c58f1c22SToby Isaac } 7113c58f1c22SToby Isaac 7114c58f1c22SToby Isaac /*@C 7115bb7acecfSBarry Smith DMAddLabel - Add the label to this `DM` 7116c58f1c22SToby Isaac 7117c58f1c22SToby Isaac Not Collective 7118c58f1c22SToby Isaac 7119c58f1c22SToby Isaac Input Parameters: 7120bb7acecfSBarry Smith + dm - The `DM` object 7121bb7acecfSBarry Smith - label - The `DMLabel` 7122c58f1c22SToby Isaac 7123c58f1c22SToby Isaac Level: developer 7124c58f1c22SToby Isaac 712560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7126c58f1c22SToby Isaac @*/ 7127d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7128d71ae5a4SJacob Faibussowitsch { 71295d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7130c58f1c22SToby Isaac PetscBool hasLabel; 7131d67d17b1SMatthew G. Knepley const char *lname; 71325d80c0bfSVaclav Hapla PetscBool flg; 7133c58f1c22SToby Isaac 7134c58f1c22SToby Isaac PetscFunctionBegin; 7135c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71369566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 71379566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, lname, &hasLabel)); 71387a8be351SBarry Smith PetscCheck(!hasLabel, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 71399566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(1, &tmpLabel)); 7140c58f1c22SToby Isaac tmpLabel->label = label; 7141c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 71425d80c0bfSVaclav Hapla for (p = &dm->labels; (l = *p); p = &l->next) { } 71435d80c0bfSVaclav Hapla *p = tmpLabel; 71449566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 71459566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 71465d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 71479566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 7148ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 71493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7150c58f1c22SToby Isaac } 7151c58f1c22SToby Isaac 7152a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7153c58f1c22SToby Isaac /*@C 71544a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 71554a7ee7d0SMatthew G. Knepley 71564a7ee7d0SMatthew G. Knepley Not Collective 71574a7ee7d0SMatthew G. Knepley 71584a7ee7d0SMatthew G. Knepley Input Parameters: 7159bb7acecfSBarry Smith + dm - The `DM` object 7160bb7acecfSBarry Smith - label - The `DMLabel`, having the same name, to substitute 71614a7ee7d0SMatthew G. Knepley 7162bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7163bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7164bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7165bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7166bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7167bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7168bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 71694a7ee7d0SMatthew G. Knepley 71704a7ee7d0SMatthew G. Knepley Level: intermediate 71714a7ee7d0SMatthew G. Knepley 71721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 71734a7ee7d0SMatthew G. Knepley @*/ 7174d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabel(DM dm, DMLabel label) 7175d71ae5a4SJacob Faibussowitsch { 71764a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 71774a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 71784a7ee7d0SMatthew G. Knepley const char *name, *lname; 71794a7ee7d0SMatthew G. Knepley 71804a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 71814a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71824a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 71839566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 71844a7ee7d0SMatthew G. Knepley while (next) { 71859566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 71869566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 71874a7ee7d0SMatthew G. Knepley if (hasLabel) { 71889566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 71899566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 71904a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 71919566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 71924a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 71939566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 71944a7ee7d0SMatthew G. Knepley next->label = label; 71954a7ee7d0SMatthew G. Knepley break; 71964a7ee7d0SMatthew G. Knepley } 71974a7ee7d0SMatthew G. Knepley next = next->next; 71984a7ee7d0SMatthew G. Knepley } 71993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 72004a7ee7d0SMatthew G. Knepley } 72014a7ee7d0SMatthew G. Knepley 72024a7ee7d0SMatthew G. Knepley /*@C 7203bb7acecfSBarry Smith DMRemoveLabel - Remove the label given by name from this `DM` 7204c58f1c22SToby Isaac 7205c58f1c22SToby Isaac Not Collective 7206c58f1c22SToby Isaac 7207c58f1c22SToby Isaac Input Parameters: 7208bb7acecfSBarry Smith + dm - The `DM` object 7209c58f1c22SToby Isaac - name - The label name 7210c58f1c22SToby Isaac 7211c58f1c22SToby Isaac Output Parameter: 721220f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent. Pass in `NULL` to call `DMLabelDestroy()` on the label, otherwise the 7213bb7acecfSBarry Smith caller is responsible for calling `DMLabelDestroy()`. 7214c58f1c22SToby Isaac 7215c58f1c22SToby Isaac Level: developer 7216c58f1c22SToby Isaac 72171cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabelBySelf()` 7218c58f1c22SToby Isaac @*/ 7219d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7220d71ae5a4SJacob Faibussowitsch { 722195d578d6SVaclav Hapla DMLabelLink link, *pnext; 7222c58f1c22SToby Isaac PetscBool hasLabel; 7223d67d17b1SMatthew G. Knepley const char *lname; 7224c58f1c22SToby Isaac 7225c58f1c22SToby Isaac PetscFunctionBegin; 7226c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72274f572ea9SToby Isaac PetscAssertPointer(name, 2); 7228e5472504SVaclav Hapla if (label) { 72294f572ea9SToby Isaac PetscAssertPointer(label, 3); 7230c58f1c22SToby Isaac *label = NULL; 7231e5472504SVaclav Hapla } 72325d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 72339566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)link->label, &lname)); 72349566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7235c58f1c22SToby Isaac if (hasLabel) { 723695d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 72379566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &hasLabel)); 723895d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 72399566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &hasLabel)); 7240ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 724195d578d6SVaclav Hapla if (label) *label = link->label; 72429566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&link->label)); 72439566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7244c58f1c22SToby Isaac break; 7245c58f1c22SToby Isaac } 7246c58f1c22SToby Isaac } 72473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7248c58f1c22SToby Isaac } 7249c58f1c22SToby Isaac 7250306894acSVaclav Hapla /*@ 7251bb7acecfSBarry Smith DMRemoveLabelBySelf - Remove the label from this `DM` 7252306894acSVaclav Hapla 7253306894acSVaclav Hapla Not Collective 7254306894acSVaclav Hapla 7255306894acSVaclav Hapla Input Parameters: 7256bb7acecfSBarry Smith + dm - The `DM` object 7257bb7acecfSBarry Smith . label - The `DMLabel` to be removed from the `DM` 725820f4b53cSBarry Smith - failNotFound - Should it fail if the label is not found in the `DM`? 7259306894acSVaclav Hapla 7260306894acSVaclav Hapla Level: developer 7261306894acSVaclav Hapla 7262bb7acecfSBarry Smith Note: 7263306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7264bb7acecfSBarry Smith If the `DM` has an exclusive reference to the label, the label gets destroyed and 7265306894acSVaclav Hapla *label nullified. 7266306894acSVaclav Hapla 72671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()` `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabel()` 7268306894acSVaclav Hapla @*/ 7269d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7270d71ae5a4SJacob Faibussowitsch { 727143e45a93SVaclav Hapla DMLabelLink link, *pnext; 7272306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7273306894acSVaclav Hapla 7274306894acSVaclav Hapla PetscFunctionBegin; 7275306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72764f572ea9SToby Isaac PetscAssertPointer(label, 2); 72773ba16761SJacob Faibussowitsch if (!*label && !failNotFound) PetscFunctionReturn(PETSC_SUCCESS); 7278306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7279306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm, failNotFound, 3); 72805d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 728143e45a93SVaclav Hapla if (*label == link->label) { 7282306894acSVaclav Hapla hasLabel = PETSC_TRUE; 728343e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7284306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7285ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 728643e45a93SVaclav Hapla if (((PetscObject)link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 72879566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&link->label)); 72889566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7289306894acSVaclav Hapla break; 7290306894acSVaclav Hapla } 7291306894acSVaclav Hapla } 72927a8be351SBarry Smith PetscCheck(hasLabel || !failNotFound, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 72933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7294306894acSVaclav Hapla } 7295306894acSVaclav Hapla 7296c58f1c22SToby Isaac /*@C 7297c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7298c58f1c22SToby Isaac 7299c58f1c22SToby Isaac Not Collective 7300c58f1c22SToby Isaac 7301c58f1c22SToby Isaac Input Parameters: 7302bb7acecfSBarry Smith + dm - The `DM` object 7303c58f1c22SToby Isaac - name - The label name 7304c58f1c22SToby Isaac 7305c58f1c22SToby Isaac Output Parameter: 7306c58f1c22SToby Isaac . output - The flag for output 7307c58f1c22SToby Isaac 7308c58f1c22SToby Isaac Level: developer 7309c58f1c22SToby Isaac 73101cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMSetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7311c58f1c22SToby Isaac @*/ 7312d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7313d71ae5a4SJacob Faibussowitsch { 73145d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7315d67d17b1SMatthew G. Knepley const char *lname; 7316c58f1c22SToby Isaac 7317c58f1c22SToby Isaac PetscFunctionBegin; 7318c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73194f572ea9SToby Isaac PetscAssertPointer(name, 2); 73204f572ea9SToby Isaac PetscAssertPointer(output, 3); 7321c58f1c22SToby Isaac while (next) { 7322c58f1c22SToby Isaac PetscBool flg; 7323c58f1c22SToby Isaac 73249566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 73259566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 73269371c9d4SSatish Balay if (flg) { 73279371c9d4SSatish Balay *output = next->output; 73283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 73299371c9d4SSatish Balay } 7330c58f1c22SToby Isaac next = next->next; 7331c58f1c22SToby Isaac } 733298921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7333c58f1c22SToby Isaac } 7334c58f1c22SToby Isaac 7335c58f1c22SToby Isaac /*@C 7336bb7acecfSBarry Smith DMSetLabelOutput - Set if a given label should be saved to a `PetscViewer` in calls to `DMView()` 7337c58f1c22SToby Isaac 7338c58f1c22SToby Isaac Not Collective 7339c58f1c22SToby Isaac 7340c58f1c22SToby Isaac Input Parameters: 7341bb7acecfSBarry Smith + dm - The `DM` object 7342c58f1c22SToby Isaac . name - The label name 7343bb7acecfSBarry Smith - output - `PETSC_TRUE` to save the label to the viewer 7344c58f1c22SToby Isaac 7345c58f1c22SToby Isaac Level: developer 7346c58f1c22SToby Isaac 73471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetOutputFlag()`, `DMGetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7348c58f1c22SToby Isaac @*/ 7349d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7350d71ae5a4SJacob Faibussowitsch { 73515d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7352d67d17b1SMatthew G. Knepley const char *lname; 7353c58f1c22SToby Isaac 7354c58f1c22SToby Isaac PetscFunctionBegin; 7355c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73564f572ea9SToby Isaac PetscAssertPointer(name, 2); 7357c58f1c22SToby Isaac while (next) { 7358c58f1c22SToby Isaac PetscBool flg; 7359c58f1c22SToby Isaac 73609566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 73619566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 73629371c9d4SSatish Balay if (flg) { 73639371c9d4SSatish Balay next->output = output; 73643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 73659371c9d4SSatish Balay } 7366c58f1c22SToby Isaac next = next->next; 7367c58f1c22SToby Isaac } 736898921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7369c58f1c22SToby Isaac } 7370c58f1c22SToby Isaac 7371c58f1c22SToby Isaac /*@ 7372bb7acecfSBarry Smith DMCopyLabels - Copy labels from one `DM` mesh to another `DM` with a superset of the points 7373c58f1c22SToby Isaac 737420f4b53cSBarry Smith Collective 7375c58f1c22SToby Isaac 7376d8d19677SJose E. Roman Input Parameters: 7377bb7acecfSBarry Smith + dmA - The `DM` object with initial labels 7378bb7acecfSBarry Smith . dmB - The `DM` object to which labels are copied 7379bb7acecfSBarry Smith . mode - Copy labels by pointers (`PETSC_OWN_POINTER`) or duplicate them (`PETSC_COPY_VALUES`) 7380bb7acecfSBarry Smith . all - Copy all labels including "depth", "dim", and "celltype" (`PETSC_TRUE`) which are otherwise ignored (`PETSC_FALSE`) 7381bb7acecfSBarry Smith - emode - How to behave when a `DMLabel` in the source and destination `DM`s with the same name is encountered (see `DMCopyLabelsMode`) 7382c58f1c22SToby Isaac 7383c58f1c22SToby Isaac Level: intermediate 7384c58f1c22SToby Isaac 7385bb7acecfSBarry Smith Note: 73862cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 7387c58f1c22SToby Isaac 73881cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode` 7389c58f1c22SToby Isaac @*/ 7390d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 7391d71ae5a4SJacob Faibussowitsch { 73922cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 7393c58f1c22SToby Isaac const char *name; 7394c58f1c22SToby Isaac PetscBool flg; 73955d80c0bfSVaclav Hapla DMLabelLink link; 7396c58f1c22SToby Isaac 73975d80c0bfSVaclav Hapla PetscFunctionBegin; 73985d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 73995d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 74005d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode, 3); 74015d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 74027a8be351SBarry Smith PetscCheck(mode != PETSC_USE_POINTER, PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 74033ba16761SJacob Faibussowitsch if (dmA == dmB) PetscFunctionReturn(PETSC_SUCCESS); 74045d80c0bfSVaclav Hapla for (link = dmA->labels; link; link = link->next) { 74055d80c0bfSVaclav Hapla label = link->label; 74069566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 74075d80c0bfSVaclav Hapla if (!all) { 74089566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &flg)); 7409c58f1c22SToby Isaac if (flg) continue; 74109566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "dim", &flg)); 74117d5acc75SStefano Zampini if (flg) continue; 74129566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &flg)); 7413ba2698f1SMatthew G. Knepley if (flg) continue; 74145d80c0bfSVaclav Hapla } 74159566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmB, name, &labelOld)); 74162cbb9b06SVaclav Hapla if (labelOld) { 74172cbb9b06SVaclav Hapla switch (emode) { 7418d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_KEEP: 7419d71ae5a4SJacob Faibussowitsch continue; 7420d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_REPLACE: 7421d71ae5a4SJacob Faibussowitsch PetscCall(DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE)); 7422d71ae5a4SJacob Faibussowitsch break; 7423d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_FAIL: 7424d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 7425d71ae5a4SJacob Faibussowitsch default: 7426d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", (int)emode); 74272cbb9b06SVaclav Hapla } 74282cbb9b06SVaclav Hapla } 74295d80c0bfSVaclav Hapla if (mode == PETSC_COPY_VALUES) { 74309566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, &labelNew)); 74315d80c0bfSVaclav Hapla } else { 74325d80c0bfSVaclav Hapla labelNew = label; 74335d80c0bfSVaclav Hapla } 74349566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmB, labelNew)); 74359566063dSJacob Faibussowitsch if (mode == PETSC_COPY_VALUES) PetscCall(DMLabelDestroy(&labelNew)); 7436c58f1c22SToby Isaac } 74373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7438c58f1c22SToby Isaac } 7439461a15a0SLisandro Dalcin 7440609dae6eSVaclav Hapla /*@C 7441b4028c23SStefano Zampini DMCompareLabels - Compare labels between two `DM` objects 7442609dae6eSVaclav Hapla 744320f4b53cSBarry Smith Collective; No Fortran Support 7444609dae6eSVaclav Hapla 7445609dae6eSVaclav Hapla Input Parameters: 7446bb7acecfSBarry Smith + dm0 - First `DM` object 7447bb7acecfSBarry Smith - dm1 - Second `DM` object 7448609dae6eSVaclav Hapla 7449a4e35b19SJacob Faibussowitsch Output Parameters: 74505efe38ccSVaclav Hapla + equal - (Optional) Flag whether labels of dm0 and dm1 are the same 745120f4b53cSBarry Smith - message - (Optional) Message describing the difference, or `NULL` if there is no difference 7452609dae6eSVaclav Hapla 7453609dae6eSVaclav Hapla Level: intermediate 7454609dae6eSVaclav Hapla 7455609dae6eSVaclav Hapla Notes: 7456bb7acecfSBarry Smith The output flag equal will be the same on all processes. 7457bb7acecfSBarry Smith 745820f4b53cSBarry Smith If equal is passed as `NULL` and difference is found, an error is thrown on all processes. 7459bb7acecfSBarry Smith 746020f4b53cSBarry Smith Make sure to pass equal is `NULL` on all processes or none of them. 7461609dae6eSVaclav Hapla 74625efe38ccSVaclav Hapla The output message is set independently on each rank. 7463bb7acecfSBarry Smith 7464bb7acecfSBarry Smith message must be freed with `PetscFree()` 7465bb7acecfSBarry Smith 746620f4b53cSBarry Smith If message is passed as `NULL` and a difference is found, the difference description is printed to stderr in synchronized manner. 7467bb7acecfSBarry Smith 746820f4b53cSBarry Smith Make sure to pass message as `NULL` on all processes or no processes. 7469609dae6eSVaclav Hapla 7470609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 7471bb7acecfSBarry Smith `DMLabelCompare()` is used to compare each pair of labels with the same name. 7472609dae6eSVaclav Hapla 74731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode`, `DMLabelCompare()` 7474609dae6eSVaclav Hapla @*/ 7475d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *equal, char **message) 7476d71ae5a4SJacob Faibussowitsch { 74775efe38ccSVaclav Hapla PetscInt n, i; 7478609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 74795efe38ccSVaclav Hapla PetscBool eq; 7480609dae6eSVaclav Hapla MPI_Comm comm; 74815efe38ccSVaclav Hapla PetscMPIInt rank; 7482609dae6eSVaclav Hapla 7483609dae6eSVaclav Hapla PetscFunctionBegin; 7484609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0, DM_CLASSID, 1); 7485609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1, DM_CLASSID, 2); 7486609dae6eSVaclav Hapla PetscCheckSameComm(dm0, 1, dm1, 2); 74874f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 3); 74884f572ea9SToby Isaac if (message) PetscAssertPointer(message, 4); 74899566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm0, &comm)); 74909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 74915efe38ccSVaclav Hapla { 74925efe38ccSVaclav Hapla PetscInt n1; 74935efe38ccSVaclav Hapla 74949566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm0, &n)); 74959566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm1, &n1)); 74965efe38ccSVaclav Hapla eq = (PetscBool)(n == n1); 749748a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %" PetscInt_FMT " != %" PetscInt_FMT " = Number of labels in dm1", n, n1)); 7498712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 74995efe38ccSVaclav Hapla if (!eq) goto finish; 75005efe38ccSVaclav Hapla } 75015efe38ccSVaclav Hapla for (i = 0; i < n; i++) { 7502609dae6eSVaclav Hapla DMLabel l0, l1; 7503609dae6eSVaclav Hapla const char *name; 7504609dae6eSVaclav Hapla char *msgInner; 7505609dae6eSVaclav Hapla 7506609dae6eSVaclav Hapla /* Ignore label order */ 75079566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm0, i, &l0)); 75089566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name)); 75099566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm1, name, &l1)); 7510609dae6eSVaclav Hapla if (!l1) { 751163a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%" PetscInt_FMT " in dm0) not found in dm1", name, i)); 75125efe38ccSVaclav Hapla eq = PETSC_FALSE; 75135efe38ccSVaclav Hapla break; 7514609dae6eSVaclav Hapla } 75159566063dSJacob Faibussowitsch PetscCall(DMLabelCompare(comm, l0, l1, &eq, &msgInner)); 75169566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(msg, msgInner, sizeof(msg))); 75179566063dSJacob Faibussowitsch PetscCall(PetscFree(msgInner)); 75185efe38ccSVaclav Hapla if (!eq) break; 7519609dae6eSVaclav Hapla } 7520712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 7521609dae6eSVaclav Hapla finish: 75225efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 7523609dae6eSVaclav Hapla if (message) { 7524609dae6eSVaclav Hapla *message = NULL; 752548a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 75265efe38ccSVaclav Hapla } else { 752748a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 75289566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 75295efe38ccSVaclav Hapla } 75305efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 75315efe38ccSVaclav Hapla if (equal) *equal = eq; 75327a8be351SBarry Smith else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels are not the same in dm0 and dm1"); 75333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7534609dae6eSVaclav Hapla } 7535609dae6eSVaclav Hapla 7536d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 7537d71ae5a4SJacob Faibussowitsch { 7538461a15a0SLisandro Dalcin PetscFunctionBegin; 75394f572ea9SToby Isaac PetscAssertPointer(label, 2); 7540461a15a0SLisandro Dalcin if (!*label) { 75419566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 75429566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, label)); 7543461a15a0SLisandro Dalcin } 75449566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(*label, point, value)); 75453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7546461a15a0SLisandro Dalcin } 7547461a15a0SLisandro Dalcin 75480fdc7489SMatthew Knepley /* 75490fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 75500fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 75510fdc7489SMatthew Knepley (label, id) pair in the DM. 75520fdc7489SMatthew Knepley 75530fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 75540fdc7489SMatthew Knepley each label. 75550fdc7489SMatthew Knepley */ 7556d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 7557d71ae5a4SJacob Faibussowitsch { 75580fdc7489SMatthew Knepley DMUniversalLabel ul; 75590fdc7489SMatthew Knepley PetscBool *active; 75600fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 75610fdc7489SMatthew Knepley 75620fdc7489SMatthew Knepley PetscFunctionBegin; 75639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &ul)); 75649566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label)); 75659566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 75669566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nl, &active)); 75670fdc7489SMatthew Knepley ul->Nl = 0; 75680fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 75690fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 75700fdc7489SMatthew Knepley const char *name; 75710fdc7489SMatthew Knepley 75729566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 75739566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "depth", 6, &isdepth)); 75749566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "celltype", 9, &iscelltype)); 75750fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 75760fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 75770fdc7489SMatthew Knepley } 75789566063dSJacob 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)); 75790fdc7489SMatthew Knepley ul->Nv = 0; 75800fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 75810fdc7489SMatthew Knepley DMLabel label; 75820fdc7489SMatthew Knepley PetscInt nv; 75830fdc7489SMatthew Knepley const char *name; 75840fdc7489SMatthew Knepley 75850fdc7489SMatthew Knepley if (!active[l]) continue; 75869566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 75879566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 75889566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 75899566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &ul->names[m])); 75900fdc7489SMatthew Knepley ul->indices[m] = l; 75910fdc7489SMatthew Knepley ul->Nv += nv; 75920fdc7489SMatthew Knepley ul->offsets[m + 1] = nv; 75930fdc7489SMatthew Knepley ul->bits[m + 1] = PetscCeilReal(PetscLog2Real(nv + 1)); 75940fdc7489SMatthew Knepley ++m; 75950fdc7489SMatthew Knepley } 75960fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 75970fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l - 1] + ul->offsets[l]; 75980fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l - 1] + ul->bits[l]; 75990fdc7489SMatthew Knepley } 76000fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 76010fdc7489SMatthew Knepley PetscInt b; 76020fdc7489SMatthew Knepley 76030fdc7489SMatthew Knepley ul->masks[l] = 0; 76040fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l + 1]; ++b) ul->masks[l] |= 1 << b; 76050fdc7489SMatthew Knepley } 76069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ul->Nv, &ul->values)); 76070fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 76080fdc7489SMatthew Knepley DMLabel label; 76090fdc7489SMatthew Knepley IS valueIS; 76100fdc7489SMatthew Knepley const PetscInt *varr; 76110fdc7489SMatthew Knepley PetscInt nv, v; 76120fdc7489SMatthew Knepley 76130fdc7489SMatthew Knepley if (!active[l]) continue; 76149566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 76159566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 76169566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &valueIS)); 76179566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &varr)); 7618ad540459SPierre Jolivet for (v = 0; v < nv; ++v) ul->values[ul->offsets[m] + v] = varr[v]; 76199566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(valueIS, &varr)); 76209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valueIS)); 76219566063dSJacob Faibussowitsch PetscCall(PetscSortInt(nv, &ul->values[ul->offsets[m]])); 76220fdc7489SMatthew Knepley ++m; 76230fdc7489SMatthew Knepley } 76249566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 76250fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 76260fdc7489SMatthew Knepley PetscInt uval = 0; 76270fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 76280fdc7489SMatthew Knepley 76290fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 76300fdc7489SMatthew Knepley DMLabel label; 76310649b39aSStefano Zampini PetscInt val, defval, loc, nv; 76320fdc7489SMatthew Knepley 76330fdc7489SMatthew Knepley if (!active[l]) continue; 76349566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 76359566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &val)); 76369566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &defval)); 76379371c9d4SSatish Balay if (val == defval) { 76389371c9d4SSatish Balay ++m; 76399371c9d4SSatish Balay continue; 76409371c9d4SSatish Balay } 76410649b39aSStefano Zampini nv = ul->offsets[m + 1] - ul->offsets[m]; 76420fdc7489SMatthew Knepley marked = PETSC_TRUE; 76439566063dSJacob Faibussowitsch PetscCall(PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc)); 764463a3b9bcSJacob Faibussowitsch PetscCheck(loc >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %" PetscInt_FMT " not found in compression array", val); 76450fdc7489SMatthew Knepley uval += (loc + 1) << ul->bits[m]; 76460fdc7489SMatthew Knepley ++m; 76470fdc7489SMatthew Knepley } 76489566063dSJacob Faibussowitsch if (marked) PetscCall(DMLabelSetValue(ul->label, p, uval)); 76490fdc7489SMatthew Knepley } 76509566063dSJacob Faibussowitsch PetscCall(PetscFree(active)); 76510fdc7489SMatthew Knepley *universal = ul; 76523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76530fdc7489SMatthew Knepley } 76540fdc7489SMatthew Knepley 7655d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 7656d71ae5a4SJacob Faibussowitsch { 76570fdc7489SMatthew Knepley PetscInt l; 76580fdc7489SMatthew Knepley 76590fdc7489SMatthew Knepley PetscFunctionBegin; 76609566063dSJacob Faibussowitsch for (l = 0; l < (*universal)->Nl; ++l) PetscCall(PetscFree((*universal)->names[l])); 76619566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&(*universal)->label)); 76629566063dSJacob Faibussowitsch PetscCall(PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks)); 76639566063dSJacob Faibussowitsch PetscCall(PetscFree((*universal)->values)); 76649566063dSJacob Faibussowitsch PetscCall(PetscFree(*universal)); 76650fdc7489SMatthew Knepley *universal = NULL; 76663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76670fdc7489SMatthew Knepley } 76680fdc7489SMatthew Knepley 7669d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 7670d71ae5a4SJacob Faibussowitsch { 76710fdc7489SMatthew Knepley PetscFunctionBegin; 76724f572ea9SToby Isaac PetscAssertPointer(ulabel, 2); 76730fdc7489SMatthew Knepley *ulabel = ul->label; 76743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76750fdc7489SMatthew Knepley } 76760fdc7489SMatthew Knepley 7677d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 7678d71ae5a4SJacob Faibussowitsch { 76790fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 76800fdc7489SMatthew Knepley 76810fdc7489SMatthew Knepley PetscFunctionBegin; 7682064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 76830fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 76849566063dSJacob Faibussowitsch if (preserveOrder) PetscCall(DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l])); 76859566063dSJacob Faibussowitsch else PetscCall(DMCreateLabel(dm, ul->names[l])); 76860fdc7489SMatthew Knepley } 76870fdc7489SMatthew Knepley if (preserveOrder) { 76880fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 76890fdc7489SMatthew Knepley const char *name; 76900fdc7489SMatthew Knepley PetscBool match; 76910fdc7489SMatthew Knepley 76929566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, ul->indices[l], &name)); 76939566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, ul->names[l], &match)); 769463a3b9bcSJacob 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]); 76950fdc7489SMatthew Knepley } 76960fdc7489SMatthew Knepley } 76973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76980fdc7489SMatthew Knepley } 76990fdc7489SMatthew Knepley 7700d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 7701d71ae5a4SJacob Faibussowitsch { 77020fdc7489SMatthew Knepley PetscInt l; 77030fdc7489SMatthew Knepley 77040fdc7489SMatthew Knepley PetscFunctionBegin; 77050fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 77060fdc7489SMatthew Knepley DMLabel label; 77070fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 77080fdc7489SMatthew Knepley 77090fdc7489SMatthew Knepley if (lval) { 77109566063dSJacob Faibussowitsch if (useIndex) PetscCall(DMGetLabelByNum(dm, ul->indices[l], &label)); 77119566063dSJacob Faibussowitsch else PetscCall(DMGetLabel(dm, ul->names[l], &label)); 77129566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, p, ul->values[ul->offsets[l] + lval - 1])); 77130fdc7489SMatthew Knepley } 77140fdc7489SMatthew Knepley } 77153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77160fdc7489SMatthew Knepley } 7717a8fb8f29SToby Isaac 7718a8fb8f29SToby Isaac /*@ 7719bb7acecfSBarry Smith DMGetCoarseDM - Get the coarse `DM`from which this `DM` was obtained by refinement 7720bb7acecfSBarry Smith 772120f4b53cSBarry Smith Not Collective 7722a8fb8f29SToby Isaac 7723a8fb8f29SToby Isaac Input Parameter: 7724bb7acecfSBarry Smith . dm - The `DM` object 7725a8fb8f29SToby Isaac 7726a8fb8f29SToby Isaac Output Parameter: 7727bb7acecfSBarry Smith . cdm - The coarse `DM` 7728a8fb8f29SToby Isaac 7729a8fb8f29SToby Isaac Level: intermediate 7730a8fb8f29SToby Isaac 77311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetCoarseDM()`, `DMCoarsen()` 7732a8fb8f29SToby Isaac @*/ 7733d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 7734d71ae5a4SJacob Faibussowitsch { 7735a8fb8f29SToby Isaac PetscFunctionBegin; 7736a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 77374f572ea9SToby Isaac PetscAssertPointer(cdm, 2); 7738a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 77393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7740a8fb8f29SToby Isaac } 7741a8fb8f29SToby Isaac 7742a8fb8f29SToby Isaac /*@ 7743bb7acecfSBarry Smith DMSetCoarseDM - Set the coarse `DM` from which this `DM` was obtained by refinement 7744a8fb8f29SToby Isaac 7745a8fb8f29SToby Isaac Input Parameters: 7746bb7acecfSBarry Smith + dm - The `DM` object 7747bb7acecfSBarry Smith - cdm - The coarse `DM` 7748a8fb8f29SToby Isaac 7749a8fb8f29SToby Isaac Level: intermediate 7750a8fb8f29SToby Isaac 7751bb7acecfSBarry Smith Note: 7752bb7acecfSBarry Smith Normally this is set automatically by `DMRefine()` 7753bb7acecfSBarry Smith 77541cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCoarseDM()`, `DMCoarsen()`, `DMSetRefine()`, `DMSetFineDM()` 7755a8fb8f29SToby Isaac @*/ 7756d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 7757d71ae5a4SJacob Faibussowitsch { 7758a8fb8f29SToby Isaac PetscFunctionBegin; 7759a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7760a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 776189d734beSBarry Smith if (dm == cdm) cdm = NULL; 77629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cdm)); 77639566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->coarseMesh)); 7764a8fb8f29SToby Isaac dm->coarseMesh = cdm; 77653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7766a8fb8f29SToby Isaac } 7767a8fb8f29SToby Isaac 776888bdff64SToby Isaac /*@ 7769bb7acecfSBarry Smith DMGetFineDM - Get the fine mesh from which this `DM` was obtained by coarsening 777088bdff64SToby Isaac 777188bdff64SToby Isaac Input Parameter: 7772bb7acecfSBarry Smith . dm - The `DM` object 777388bdff64SToby Isaac 777488bdff64SToby Isaac Output Parameter: 7775bb7acecfSBarry Smith . fdm - The fine `DM` 777688bdff64SToby Isaac 777788bdff64SToby Isaac Level: intermediate 777888bdff64SToby Isaac 77791cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetFineDM()`, `DMCoarsen()`, `DMRefine()` 778088bdff64SToby Isaac @*/ 7781d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 7782d71ae5a4SJacob Faibussowitsch { 778388bdff64SToby Isaac PetscFunctionBegin; 778488bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 77854f572ea9SToby Isaac PetscAssertPointer(fdm, 2); 778688bdff64SToby Isaac *fdm = dm->fineMesh; 77873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 778888bdff64SToby Isaac } 778988bdff64SToby Isaac 779088bdff64SToby Isaac /*@ 7791bb7acecfSBarry Smith DMSetFineDM - Set the fine mesh from which this was obtained by coarsening 779288bdff64SToby Isaac 779388bdff64SToby Isaac Input Parameters: 7794bb7acecfSBarry Smith + dm - The `DM` object 7795bb7acecfSBarry Smith - fdm - The fine `DM` 779688bdff64SToby Isaac 7797bb7acecfSBarry Smith Level: developer 779888bdff64SToby Isaac 7799bb7acecfSBarry Smith Note: 7800bb7acecfSBarry Smith Normally this is set automatically by `DMCoarsen()` 7801bb7acecfSBarry Smith 78021cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFineDM()`, `DMCoarsen()`, `DMRefine()` 780388bdff64SToby Isaac @*/ 7804d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFineDM(DM dm, DM fdm) 7805d71ae5a4SJacob Faibussowitsch { 780688bdff64SToby Isaac PetscFunctionBegin; 780788bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 780888bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 780989d734beSBarry Smith if (dm == fdm) fdm = NULL; 78109566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fdm)); 78119566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->fineMesh)); 781288bdff64SToby Isaac dm->fineMesh = fdm; 78133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 781488bdff64SToby Isaac } 781588bdff64SToby Isaac 7816a6ba4734SToby Isaac /*@C 7817bb7acecfSBarry Smith DMAddBoundary - Add a boundary condition to a model represented by a `DM` 7818a6ba4734SToby Isaac 781920f4b53cSBarry Smith Collective 7820783e2ec8SMatthew G. Knepley 7821a6ba4734SToby Isaac Input Parameters: 7822bb7acecfSBarry Smith + dm - The `DM`, with a `PetscDS` that matches the problem being constrained 7823bb7acecfSBarry Smith . type - The type of condition, e.g. `DM_BC_ESSENTIAL_ANALYTIC`, `DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann) 7824a6ba4734SToby Isaac . name - The BC name 782545480ffeSMatthew G. Knepley . label - The label defining constrained points 7826bb7acecfSBarry Smith . Nv - The number of `DMLabel` values for constrained points 782745480ffeSMatthew G. Knepley . values - An array of values for constrained points 7828a6ba4734SToby Isaac . field - The field to constrain 782945480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 7830a6ba4734SToby Isaac . comps - An array of constrained component numbers 7831a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 783256cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 7833a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 7834a6ba4734SToby Isaac 783545480ffeSMatthew G. Knepley Output Parameter: 783645480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 783745480ffeSMatthew G. Knepley 7838a6ba4734SToby Isaac Options Database Keys: 7839a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 7840a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 7841a6ba4734SToby Isaac 784220f4b53cSBarry Smith Level: intermediate 784320f4b53cSBarry Smith 7844bb7acecfSBarry Smith Notes: 784537fdd005SBarry 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\: 784656cf3b9cSMatthew G. Knepley 784720f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 784856cf3b9cSMatthew G. Knepley 7849a4e35b19SJacob Faibussowitsch If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\: 785056cf3b9cSMatthew G. Knepley 785120f4b53cSBarry Smith .vb 785220f4b53cSBarry Smith void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 785320f4b53cSBarry Smith const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 785420f4b53cSBarry Smith const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 785520f4b53cSBarry Smith PetscReal time, const PetscReal x[], PetscScalar bcval[]) 785620f4b53cSBarry Smith .ve 785756cf3b9cSMatthew G. Knepley + dim - the spatial dimension 785856cf3b9cSMatthew G. Knepley . Nf - the number of fields 785956cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 786056cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 786156cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 786256cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 786356cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 786456cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 786556cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 786656cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 786756cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 786856cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 786956cf3b9cSMatthew G. Knepley . t - current time 787056cf3b9cSMatthew G. Knepley . x - coordinates of the current point 787156cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 787256cf3b9cSMatthew G. Knepley . constants - constant parameters 787356cf3b9cSMatthew G. Knepley - bcval - output values at the current point 787456cf3b9cSMatthew G. Knepley 78751cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DSGetBoundary()`, `PetscDSAddBoundary()` 7876a6ba4734SToby Isaac @*/ 7877d71ae5a4SJacob 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) 7878d71ae5a4SJacob Faibussowitsch { 7879e5e52638SMatthew G. Knepley PetscDS ds; 7880a6ba4734SToby Isaac 7881a6ba4734SToby Isaac PetscFunctionBegin; 7882a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7883783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 788445480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 788545480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 788645480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 788745480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 788801a5d20dSJed Brown PetscCheck(!dm->localSection, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot add boundary to DM after creating local section"); 78899566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7890799db056SMatthew G. Knepley /* Complete label */ 7891799db056SMatthew G. Knepley if (label) { 7892799db056SMatthew G. Knepley PetscObject obj; 7893799db056SMatthew G. Knepley PetscClassId id; 7894799db056SMatthew G. Knepley 7895799db056SMatthew G. Knepley PetscCall(DMGetField(dm, field, NULL, &obj)); 7896799db056SMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 7897799db056SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 7898799db056SMatthew G. Knepley DM plex; 7899799db056SMatthew G. Knepley 7900799db056SMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 7901799db056SMatthew G. Knepley if (plex) PetscCall(DMPlexLabelComplete(plex, label)); 7902799db056SMatthew G. Knepley PetscCall(DMDestroy(&plex)); 7903799db056SMatthew G. Knepley } 7904799db056SMatthew G. Knepley } 79059566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd)); 79063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7907a6ba4734SToby Isaac } 7908a6ba4734SToby Isaac 790945480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 7910d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPopulateBoundary(DM dm) 7911d71ae5a4SJacob Faibussowitsch { 7912e5e52638SMatthew G. Knepley PetscDS ds; 7913dff059c6SToby Isaac DMBoundary *lastnext; 7914e6f8dbb6SToby Isaac DSBoundary dsbound; 7915e6f8dbb6SToby Isaac 7916e6f8dbb6SToby Isaac PetscFunctionBegin; 79179566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7918e5e52638SMatthew G. Knepley dsbound = ds->boundary; 791947a1f5adSToby Isaac if (dm->boundary) { 792047a1f5adSToby Isaac DMBoundary next = dm->boundary; 792147a1f5adSToby Isaac 792247a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 79233ba16761SJacob Faibussowitsch if (next->dsboundary == dsbound) PetscFunctionReturn(PETSC_SUCCESS); 792447a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 792547a1f5adSToby Isaac while (next) { 792647a1f5adSToby Isaac DMBoundary b = next; 792747a1f5adSToby Isaac 792847a1f5adSToby Isaac next = b->next; 79299566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 7930a6ba4734SToby Isaac } 793147a1f5adSToby Isaac dm->boundary = NULL; 7932a6ba4734SToby Isaac } 793347a1f5adSToby Isaac 7934dff059c6SToby Isaac lastnext = &(dm->boundary); 7935e6f8dbb6SToby Isaac while (dsbound) { 7936e6f8dbb6SToby Isaac DMBoundary dmbound; 7937e6f8dbb6SToby Isaac 79389566063dSJacob Faibussowitsch PetscCall(PetscNew(&dmbound)); 7939e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 794045480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 794147a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 7942dff059c6SToby Isaac *lastnext = dmbound; 7943dff059c6SToby Isaac lastnext = &(dmbound->next); 7944dff059c6SToby Isaac dsbound = dsbound->next; 7945a6ba4734SToby Isaac } 79463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7947a6ba4734SToby Isaac } 7948a6ba4734SToby Isaac 7949bb7acecfSBarry Smith /* TODO: missing manual page */ 7950d71ae5a4SJacob Faibussowitsch PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 7951d71ae5a4SJacob Faibussowitsch { 7952b95f2879SToby Isaac DMBoundary b; 7953a6ba4734SToby Isaac 7954a6ba4734SToby Isaac PetscFunctionBegin; 7955a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 79564f572ea9SToby Isaac PetscAssertPointer(isBd, 3); 7957a6ba4734SToby Isaac *isBd = PETSC_FALSE; 79589566063dSJacob Faibussowitsch PetscCall(DMPopulateBoundary(dm)); 7959b95f2879SToby Isaac b = dm->boundary; 7960a6ba4734SToby Isaac while (b && !(*isBd)) { 7961e6f8dbb6SToby Isaac DMLabel label = b->label; 7962e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 7963a6ba4734SToby Isaac PetscInt i; 7964a6ba4734SToby Isaac 796545480ffeSMatthew G. Knepley if (label) { 79669566063dSJacob Faibussowitsch for (i = 0; i < dsb->Nv && !(*isBd); ++i) PetscCall(DMLabelStratumHasPoint(label, dsb->values[i], point, isBd)); 7967a6ba4734SToby Isaac } 7968a6ba4734SToby Isaac b = b->next; 7969a6ba4734SToby Isaac } 79703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7971a6ba4734SToby Isaac } 79724d6f44ffSToby Isaac 79734d6f44ffSToby Isaac /*@C 7974bb7acecfSBarry Smith DMProjectFunction - This projects the given function into the function space provided by a `DM`, putting the coefficients in a global vector. 7975a6e0b375SMatthew G. Knepley 797620f4b53cSBarry Smith Collective 79774d6f44ffSToby Isaac 79784d6f44ffSToby Isaac Input Parameters: 7979bb7acecfSBarry Smith + dm - The `DM` 79800709b2feSToby Isaac . time - The time 79814d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 79824d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 79834d6f44ffSToby Isaac - mode - The insertion mode for values 79844d6f44ffSToby Isaac 79854d6f44ffSToby Isaac Output Parameter: 79864d6f44ffSToby Isaac . X - vector 79874d6f44ffSToby Isaac 798820f4b53cSBarry Smith Calling sequence of `funcs`: 79894d6f44ffSToby Isaac + dim - The spatial dimension 79908ec8862eSJed Brown . time - The time at which to sample 79914d6f44ffSToby Isaac . x - The coordinates 799277b739a6SMatthew Knepley . Nc - The number of components 79934d6f44ffSToby Isaac . u - The output field values 79944d6f44ffSToby Isaac - ctx - optional user-defined function context 79954d6f44ffSToby Isaac 79964d6f44ffSToby Isaac Level: developer 79974d6f44ffSToby Isaac 7998bb7acecfSBarry Smith Developer Notes: 7999bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8000bb7acecfSBarry Smith 8001bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8002bb7acecfSBarry Smith 80031cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 80044d6f44ffSToby Isaac @*/ 8005a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec X) 8006d71ae5a4SJacob Faibussowitsch { 80074d6f44ffSToby Isaac Vec localX; 80084d6f44ffSToby Isaac 80094d6f44ffSToby Isaac PetscFunctionBegin; 80104d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8011708be2fdSJed Brown PetscCall(PetscLogEventBegin(DM_ProjectFunction, dm, X, 0, 0)); 80129566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8013f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 80149566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, time, 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)); 8018708be2fdSJed Brown PetscCall(PetscLogEventEnd(DM_ProjectFunction, dm, X, 0, 0)); 80193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80204d6f44ffSToby Isaac } 80214d6f44ffSToby Isaac 8022a6e0b375SMatthew G. Knepley /*@C 8023bb7acecfSBarry Smith DMProjectFunctionLocal - This projects the given function into the function space provided by a `DM`, putting the coefficients in a local vector. 8024a6e0b375SMatthew G. Knepley 802520f4b53cSBarry Smith Not Collective 8026a6e0b375SMatthew G. Knepley 8027a6e0b375SMatthew G. Knepley Input Parameters: 8028bb7acecfSBarry Smith + dm - The `DM` 8029a6e0b375SMatthew G. Knepley . time - The time 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 803720f4b53cSBarry Smith Calling sequence of `funcs`: 8038a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8039a4e35b19SJacob Faibussowitsch . time - The current timestep 8040a6e0b375SMatthew G. Knepley . x - The coordinates 804177b739a6SMatthew Knepley . Nc - The number of components 8042a6e0b375SMatthew G. Knepley . u - The output field values 8043a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8044a6e0b375SMatthew G. Knepley 8045a6e0b375SMatthew G. Knepley Level: developer 8046a6e0b375SMatthew G. Knepley 8047bb7acecfSBarry Smith Developer Notes: 8048bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8049bb7acecfSBarry Smith 8050bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8051bb7acecfSBarry Smith 80521cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8053a6e0b375SMatthew G. Knepley @*/ 8054a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec localX) 8055d71ae5a4SJacob Faibussowitsch { 80564d6f44ffSToby Isaac PetscFunctionBegin; 80574d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8058064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 80599566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlocal)(dm, time, funcs, ctxs, mode, localX)); 80603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80614d6f44ffSToby Isaac } 80624d6f44ffSToby Isaac 8063a6e0b375SMatthew G. Knepley /*@C 8064bb7acecfSBarry 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. 8065a6e0b375SMatthew G. Knepley 806620f4b53cSBarry Smith Collective 8067a6e0b375SMatthew G. Knepley 8068a6e0b375SMatthew G. Knepley Input Parameters: 8069bb7acecfSBarry Smith + dm - The `DM` 8070a6e0b375SMatthew G. Knepley . time - The time 8071a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8072a4e35b19SJacob Faibussowitsch . ids - The ids 8073a4e35b19SJacob Faibussowitsch . Nc - The number of components 8074a4e35b19SJacob Faibussowitsch . comps - The components 8075bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8076a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8077bb7acecfSBarry Smith . ctxs - Optional array of contexts to pass to each coordinate function. ctxs may be null. 8078a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8079a6e0b375SMatthew G. Knepley 8080a6e0b375SMatthew G. Knepley Output Parameter: 8081a6e0b375SMatthew G. Knepley . X - vector 8082a6e0b375SMatthew G. Knepley 808320f4b53cSBarry Smith Calling sequence of `funcs`: 8084a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8085a4e35b19SJacob Faibussowitsch . time - The current timestep 8086a6e0b375SMatthew G. Knepley . x - The coordinates 808777b739a6SMatthew Knepley . Nc - The number of components 8088a6e0b375SMatthew G. Knepley . u - The output field values 8089a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8090a6e0b375SMatthew G. Knepley 8091a6e0b375SMatthew G. Knepley Level: developer 8092a6e0b375SMatthew G. Knepley 8093bb7acecfSBarry Smith Developer Notes: 8094bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8095bb7acecfSBarry Smith 8096bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8097bb7acecfSBarry Smith 80981cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabelLocal()`, `DMComputeL2Diff()` 8099a6e0b375SMatthew G. Knepley @*/ 8100a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec X) 8101d71ae5a4SJacob Faibussowitsch { 81022c53366bSMatthew G. Knepley Vec localX; 81032c53366bSMatthew G. Knepley 81042c53366bSMatthew G. Knepley PetscFunctionBegin; 81052c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 81069566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8107f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 81089566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 81099566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 81109566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 81119566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 81123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81132c53366bSMatthew G. Knepley } 81142c53366bSMatthew G. Knepley 8115a6e0b375SMatthew G. Knepley /*@C 8116bb7acecfSBarry 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. 8117a6e0b375SMatthew G. Knepley 811820f4b53cSBarry Smith Not Collective 8119a6e0b375SMatthew G. Knepley 8120a6e0b375SMatthew G. Knepley Input Parameters: 8121bb7acecfSBarry Smith + dm - The `DM` 8122a6e0b375SMatthew G. Knepley . time - The time 8123bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8124a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8125a4e35b19SJacob Faibussowitsch . ids - The ids 8126a4e35b19SJacob Faibussowitsch . Nc - The number of components 8127a4e35b19SJacob Faibussowitsch . comps - The components 8128a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8129a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8130a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8131a6e0b375SMatthew G. Knepley 8132a6e0b375SMatthew G. Knepley Output Parameter: 8133a6e0b375SMatthew G. Knepley . localX - vector 8134a6e0b375SMatthew G. Knepley 813520f4b53cSBarry Smith Calling sequence of `funcs`: 8136a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8137a4e35b19SJacob Faibussowitsch . time - The current time 8138a6e0b375SMatthew G. Knepley . x - The coordinates 813977b739a6SMatthew Knepley . Nc - The number of components 8140a6e0b375SMatthew G. Knepley . u - The output field values 8141a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8142a6e0b375SMatthew G. Knepley 8143a6e0b375SMatthew G. Knepley Level: developer 8144a6e0b375SMatthew G. Knepley 8145bb7acecfSBarry Smith Developer Notes: 8146bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8147bb7acecfSBarry Smith 8148bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8149bb7acecfSBarry Smith 81501cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8151a6e0b375SMatthew G. Knepley @*/ 8152a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFunctionLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx), void **ctxs, InsertMode mode, Vec localX) 8153d71ae5a4SJacob Faibussowitsch { 81544d6f44ffSToby Isaac PetscFunctionBegin; 81554d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8156064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 81579566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlabellocal)(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 81583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81594d6f44ffSToby Isaac } 81602716604bSToby Isaac 8161a6e0b375SMatthew G. Knepley /*@C 8162bb7acecfSBarry 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. 8163a6e0b375SMatthew G. Knepley 816420f4b53cSBarry Smith Not Collective 8165a6e0b375SMatthew G. Knepley 8166a6e0b375SMatthew G. Knepley Input Parameters: 8167bb7acecfSBarry Smith + dm - The `DM` 8168a6e0b375SMatthew G. Knepley . time - The time 816920f4b53cSBarry Smith . localU - The input field vector; may be `NULL` if projection is defined purely by coordinates 8170a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8171a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8172a6e0b375SMatthew G. Knepley 8173a6e0b375SMatthew G. Knepley Output Parameter: 8174a6e0b375SMatthew G. Knepley . localX - The output vector 8175a6e0b375SMatthew G. Knepley 817620f4b53cSBarry Smith Calling sequence of `funcs`: 8177a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8178a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8179a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8180a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8181a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8182a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8183a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8184a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8185a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8186a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8187a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8188a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8189a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8190a6e0b375SMatthew G. Knepley . t - The current time 8191a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8192a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8193a6e0b375SMatthew G. Knepley . constants - The value of each constant 8194a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8195a6e0b375SMatthew G. Knepley 8196bb7acecfSBarry Smith Note: 8197bb7acecfSBarry 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. 8198bb7acecfSBarry 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 8199bb7acecfSBarry 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 8200a6e0b375SMatthew 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. 8201a6e0b375SMatthew G. Knepley 8202a6e0b375SMatthew G. Knepley Level: intermediate 8203a6e0b375SMatthew G. Knepley 8204bb7acecfSBarry Smith Developer Notes: 8205bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8206bb7acecfSBarry Smith 8207bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8208bb7acecfSBarry Smith 8209a4e35b19SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, 8210a4e35b19SJacob Faibussowitsch `DMProjectFunction()`, `DMComputeL2Diff()` 8211a6e0b375SMatthew G. Knepley @*/ 8212a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec localX) 8213d71ae5a4SJacob Faibussowitsch { 82148c6c5593SMatthew G. Knepley PetscFunctionBegin; 82158c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8216eb8f539aSJed Brown if (localU) PetscValidHeaderSpecific(localU, VEC_CLASSID, 3); 82178c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 82189566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlocal)(dm, time, localU, funcs, mode, localX)); 82193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82208c6c5593SMatthew G. Knepley } 82218c6c5593SMatthew G. Knepley 8222a6e0b375SMatthew G. Knepley /*@C 8223a6e0b375SMatthew 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. 8224a6e0b375SMatthew G. Knepley 822520f4b53cSBarry Smith Not Collective 8226a6e0b375SMatthew G. Knepley 8227a6e0b375SMatthew G. Knepley Input Parameters: 8228bb7acecfSBarry Smith + dm - The `DM` 8229a6e0b375SMatthew G. Knepley . time - The time 8230bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8231a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8232a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8233bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 823420f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8235a6e0b375SMatthew G. Knepley . localU - The input field vector 8236a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8237a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8238a6e0b375SMatthew G. Knepley 8239a6e0b375SMatthew G. Knepley Output Parameter: 8240a6e0b375SMatthew G. Knepley . localX - The output vector 8241a6e0b375SMatthew G. Knepley 824220f4b53cSBarry Smith Calling sequence of `funcs`: 8243a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8244a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8245a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8246a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8247a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8248a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8249a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8250a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8251a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8252a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8253a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8254a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8255a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8256a6e0b375SMatthew G. Knepley . t - The current time 8257a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8258a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8259a6e0b375SMatthew G. Knepley . constants - The value of each constant 8260a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8261a6e0b375SMatthew G. Knepley 8262bb7acecfSBarry Smith Note: 8263bb7acecfSBarry 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. 8264bb7acecfSBarry 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 8265bb7acecfSBarry 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 8266a6e0b375SMatthew 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. 8267a6e0b375SMatthew G. Knepley 8268a6e0b375SMatthew G. Knepley Level: intermediate 8269a6e0b375SMatthew G. Knepley 8270bb7acecfSBarry Smith Developer Notes: 8271bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8272bb7acecfSBarry Smith 8273bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8274bb7acecfSBarry Smith 82751cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabel()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8276a6e0b375SMatthew G. Knepley @*/ 8277a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec localX) 8278d71ae5a4SJacob Faibussowitsch { 82798c6c5593SMatthew G. Knepley PetscFunctionBegin; 82808c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8281064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8282064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 82839566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 82843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82858c6c5593SMatthew G. Knepley } 82868c6c5593SMatthew G. Knepley 82872716604bSToby Isaac /*@C 8288d29d7c6eSMatthew 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. 8289d29d7c6eSMatthew G. Knepley 829020f4b53cSBarry Smith Not Collective 8291d29d7c6eSMatthew G. Knepley 8292d29d7c6eSMatthew G. Knepley Input Parameters: 8293bb7acecfSBarry Smith + dm - The `DM` 8294d29d7c6eSMatthew G. Knepley . time - The time 8295bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8296d29d7c6eSMatthew G. Knepley . numIds - The number of label ids to use 8297d29d7c6eSMatthew G. Knepley . ids - The label ids to use for marking 8298bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 829920f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8300d29d7c6eSMatthew G. Knepley . U - The input field vector 8301d29d7c6eSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8302d29d7c6eSMatthew G. Knepley - mode - The insertion mode for values 8303d29d7c6eSMatthew G. Knepley 8304d29d7c6eSMatthew G. Knepley Output Parameter: 8305d29d7c6eSMatthew G. Knepley . X - The output vector 8306d29d7c6eSMatthew G. Knepley 830720f4b53cSBarry Smith Calling sequence of `funcs`: 8308d29d7c6eSMatthew G. Knepley + dim - The spatial dimension 8309d29d7c6eSMatthew G. Knepley . Nf - The number of input fields 8310d29d7c6eSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8311d29d7c6eSMatthew G. Knepley . uOff - The offset of each field in u[] 8312d29d7c6eSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8313d29d7c6eSMatthew G. Knepley . u - The field values at this point in space 8314d29d7c6eSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8315d29d7c6eSMatthew G. Knepley . u_x - The field derivatives at this point in space 8316d29d7c6eSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8317d29d7c6eSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8318d29d7c6eSMatthew G. Knepley . a - The auxiliary field values at this point in space 8319d29d7c6eSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8320d29d7c6eSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8321d29d7c6eSMatthew G. Knepley . t - The current time 8322d29d7c6eSMatthew G. Knepley . x - The coordinates of this point 8323d29d7c6eSMatthew G. Knepley . numConstants - The number of constants 8324d29d7c6eSMatthew G. Knepley . constants - The value of each constant 8325d29d7c6eSMatthew G. Knepley - f - The value of the function at this point in space 8326d29d7c6eSMatthew G. Knepley 8327bb7acecfSBarry Smith Note: 8328bb7acecfSBarry 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. 8329bb7acecfSBarry 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 8330bb7acecfSBarry 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 8331d29d7c6eSMatthew 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. 8332d29d7c6eSMatthew G. Knepley 8333d29d7c6eSMatthew G. Knepley Level: intermediate 8334d29d7c6eSMatthew G. Knepley 8335bb7acecfSBarry Smith Developer Notes: 8336bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8337bb7acecfSBarry Smith 8338bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8339bb7acecfSBarry Smith 83401cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8341d29d7c6eSMatthew G. Knepley @*/ 8342a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectFieldLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec U, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec X) 8343d71ae5a4SJacob Faibussowitsch { 8344d29d7c6eSMatthew G. Knepley DM dmIn; 8345d29d7c6eSMatthew G. Knepley Vec localU, localX; 8346d29d7c6eSMatthew G. Knepley 8347d29d7c6eSMatthew G. Knepley PetscFunctionBegin; 8348d29d7c6eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8349d29d7c6eSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn)); 8350d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dmIn, &localU)); 8351d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &localX)); 8352f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 835372fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dmIn, U, mode, localU)); 835472fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dmIn, U, mode, localU)); 8355d29d7c6eSMatthew G. Knepley PetscCall(DMProjectFieldLabelLocal(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8356d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 8357d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 8358d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &localX)); 8359d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dmIn, &localU)); 83603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8361d29d7c6eSMatthew G. Knepley } 8362d29d7c6eSMatthew G. Knepley 8363d29d7c6eSMatthew G. Knepley /*@C 8364ece3a9fcSMatthew 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. 8365ece3a9fcSMatthew G. Knepley 836620f4b53cSBarry Smith Not Collective 8367ece3a9fcSMatthew G. Knepley 8368ece3a9fcSMatthew G. Knepley Input Parameters: 8369bb7acecfSBarry Smith + dm - The `DM` 8370ece3a9fcSMatthew G. Knepley . time - The time 8371bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain boundary to output 8372ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8373ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8374bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 837520f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8376ece3a9fcSMatthew G. Knepley . localU - The input field vector 8377ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8378ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8379ece3a9fcSMatthew G. Knepley 8380ece3a9fcSMatthew G. Knepley Output Parameter: 8381ece3a9fcSMatthew G. Knepley . localX - The output vector 8382ece3a9fcSMatthew G. Knepley 838320f4b53cSBarry Smith Calling sequence of `funcs`: 8384ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8385ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8386ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8387ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8388ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8389ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8390ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8391ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8392ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8393ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8394ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8395ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8396ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8397ece3a9fcSMatthew G. Knepley . t - The current time 8398ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8399ece3a9fcSMatthew G. Knepley . n - The face normal 8400ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8401ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8402ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8403ece3a9fcSMatthew G. Knepley 8404ece3a9fcSMatthew G. Knepley Note: 8405bb7acecfSBarry 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. 8406bb7acecfSBarry 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 8407bb7acecfSBarry 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 8408ece3a9fcSMatthew 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. 8409ece3a9fcSMatthew G. Knepley 8410ece3a9fcSMatthew G. Knepley Level: intermediate 8411ece3a9fcSMatthew G. Knepley 8412bb7acecfSBarry Smith Developer Notes: 8413bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8414bb7acecfSBarry Smith 8415bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8416bb7acecfSBarry Smith 84171cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8418ece3a9fcSMatthew G. Knepley @*/ 8419a4e35b19SJacob Faibussowitsch PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, void (**funcs)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]), InsertMode mode, Vec localX) 8420d71ae5a4SJacob Faibussowitsch { 8421ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8422ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8423064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8424064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 84259566063dSJacob Faibussowitsch PetscCall((dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 84263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8427ece3a9fcSMatthew G. Knepley } 8428ece3a9fcSMatthew G. Knepley 8429ece3a9fcSMatthew G. Knepley /*@C 84302716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 84312716604bSToby Isaac 843220f4b53cSBarry Smith Collective 8433bb7acecfSBarry Smith 84342716604bSToby Isaac Input Parameters: 8435bb7acecfSBarry Smith + dm - The `DM` 84360709b2feSToby Isaac . time - The time 84372716604bSToby Isaac . funcs - The functions to evaluate for each field component 84382716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8439574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 84402716604bSToby Isaac 84412716604bSToby Isaac Output Parameter: 84422716604bSToby Isaac . diff - The diff ||u - u_h||_2 84432716604bSToby Isaac 84442716604bSToby Isaac Level: developer 84452716604bSToby Isaac 8446bb7acecfSBarry Smith Developer Notes: 8447bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8448bb7acecfSBarry Smith 8449bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8450bb7acecfSBarry Smith 84511cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 84522716604bSToby Isaac @*/ 8453d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 8454d71ae5a4SJacob Faibussowitsch { 84552716604bSToby Isaac PetscFunctionBegin; 84562716604bSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8457b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 84589566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2diff)(dm, time, funcs, ctxs, X, diff)); 84593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 84602716604bSToby Isaac } 8461b698f381SToby Isaac 8462b698f381SToby Isaac /*@C 8463b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8464b698f381SToby Isaac 846520f4b53cSBarry Smith Collective 8466d083f849SBarry Smith 8467b698f381SToby Isaac Input Parameters: 8468bb7acecfSBarry Smith + dm - The `DM` 8469a4e35b19SJacob Faibussowitsch . time - The time 8470b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8471b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8472574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8473b698f381SToby Isaac - n - The vector to project along 8474b698f381SToby Isaac 8475b698f381SToby Isaac Output Parameter: 8476b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8477b698f381SToby Isaac 8478b698f381SToby Isaac Level: developer 8479b698f381SToby Isaac 8480bb7acecfSBarry Smith Developer Notes: 8481bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8482bb7acecfSBarry Smith 8483bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8484bb7acecfSBarry Smith 84851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2Diff()`, `DMComputeL2FieldDiff()` 8486b698f381SToby Isaac @*/ 8487d71ae5a4SJacob 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) 8488d71ae5a4SJacob Faibussowitsch { 8489b698f381SToby Isaac PetscFunctionBegin; 8490b698f381SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8491b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 84929566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2gradientdiff)(dm, time, funcs, ctxs, X, n, diff)); 84933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8494b698f381SToby Isaac } 8495b698f381SToby Isaac 84962a16baeaSToby Isaac /*@C 84972a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 84982a16baeaSToby Isaac 849920f4b53cSBarry Smith Collective 8500d083f849SBarry Smith 85012a16baeaSToby Isaac Input Parameters: 8502bb7acecfSBarry Smith + dm - The `DM` 85032a16baeaSToby Isaac . time - The time 85042a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 85052a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8506574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 85072a16baeaSToby Isaac 85082a16baeaSToby Isaac Output Parameter: 85092a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 85102a16baeaSToby Isaac 85112a16baeaSToby Isaac Level: developer 85122a16baeaSToby Isaac 8513bb7acecfSBarry Smith Developer Notes: 8514bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8515bb7acecfSBarry Smith 8516bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8517bb7acecfSBarry Smith 851842747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2GradientDiff()` 85192a16baeaSToby Isaac @*/ 8520d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 8521d71ae5a4SJacob Faibussowitsch { 85222a16baeaSToby Isaac PetscFunctionBegin; 85232a16baeaSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 85242a16baeaSToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 85259566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2fielddiff)(dm, time, funcs, ctxs, X, diff)); 85263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85272a16baeaSToby Isaac } 85282a16baeaSToby Isaac 8529df0b854cSToby Isaac /*@C 8530bb7acecfSBarry Smith DMGetNeighbors - Gets an array containing the MPI ranks of all the processes neighbors 8531502a2867SDave May 8532502a2867SDave May Not Collective 8533502a2867SDave May 8534502a2867SDave May Input Parameter: 8535bb7acecfSBarry Smith . dm - The `DM` 8536502a2867SDave May 85370a19bb7dSprj- Output Parameters: 85380a19bb7dSprj- + nranks - the number of neighbours 85390a19bb7dSprj- - ranks - the neighbors ranks 8540502a2867SDave May 85419bdbcad8SBarry Smith Level: beginner 85429bdbcad8SBarry Smith 8543bb7acecfSBarry Smith Note: 8544bb7acecfSBarry Smith Do not free the array, it is freed when the `DM` is destroyed. 8545502a2867SDave May 85461cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDAGetNeighbors()`, `PetscSFGetRootRanks()` 8547502a2867SDave May @*/ 8548d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNeighbors(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 8549d71ae5a4SJacob Faibussowitsch { 8550502a2867SDave May PetscFunctionBegin; 8551502a2867SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 85529566063dSJacob Faibussowitsch PetscCall((dm->ops->getneighbors)(dm, nranks, ranks)); 85533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8554502a2867SDave May } 8555502a2867SDave May 8556531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 8557531c7667SBarry Smith 8558531c7667SBarry Smith /* 8559531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 85602b6f951bSStefano Zampini This must be a different function because it requires DM which is not defined in the Mat library 8561531c7667SBarry Smith */ 856266976f2fSJacob Faibussowitsch static PetscErrorCode MatFDColoringApply_AIJDM(Mat J, MatFDColoring coloring, Vec x1, void *sctx) 8563d71ae5a4SJacob Faibussowitsch { 8564531c7667SBarry Smith PetscFunctionBegin; 8565531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8566531c7667SBarry Smith Vec x1local; 8567531c7667SBarry Smith DM dm; 85689566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 85697a8be351SBarry Smith PetscCheck(dm, PetscObjectComm((PetscObject)J), PETSC_ERR_ARG_INCOMP, "IS_COLORING_LOCAL requires a DM"); 85709566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &x1local)); 85719566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, x1, INSERT_VALUES, x1local)); 85729566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, x1, INSERT_VALUES, x1local)); 8573531c7667SBarry Smith x1 = x1local; 8574531c7667SBarry Smith } 85759566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply_AIJ(J, coloring, x1, sctx)); 8576531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8577531c7667SBarry Smith DM dm; 85789566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 85799566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &x1)); 8580531c7667SBarry Smith } 85813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8582531c7667SBarry Smith } 8583531c7667SBarry Smith 8584531c7667SBarry Smith /*@ 8585bb7acecfSBarry Smith MatFDColoringUseDM - allows a `MatFDColoring` object to use the `DM` associated with the matrix to compute a `IS_COLORING_LOCAL` coloring 8586531c7667SBarry Smith 8587a4e35b19SJacob Faibussowitsch Input Parameters: 8588a4e35b19SJacob Faibussowitsch + coloring - The matrix to get the `DM` from 8589a4e35b19SJacob Faibussowitsch - fdcoloring - the `MatFDColoring` object 8590531c7667SBarry Smith 85919bdbcad8SBarry Smith Level: advanced 85929bdbcad8SBarry Smith 859360225df5SJacob Faibussowitsch Developer Notes: 8594bb7acecfSBarry Smith this routine exists because the PETSc `Mat` library does not know about the `DM` objects 8595531c7667SBarry Smith 85961cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatFDColoring`, `MatFDColoringCreate()`, `ISColoringType` 8597531c7667SBarry Smith @*/ 8598d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringUseDM(Mat coloring, MatFDColoring fdcoloring) 8599d71ae5a4SJacob Faibussowitsch { 8600531c7667SBarry Smith PetscFunctionBegin; 8601531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 86023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8603531c7667SBarry Smith } 86048320bc6fSPatrick Sanan 86058320bc6fSPatrick Sanan /*@ 8606bb7acecfSBarry Smith DMGetCompatibility - determine if two `DM`s are compatible 86078320bc6fSPatrick Sanan 86088320bc6fSPatrick Sanan Collective 86098320bc6fSPatrick Sanan 86108320bc6fSPatrick Sanan Input Parameters: 8611bb7acecfSBarry Smith + dm1 - the first `DM` 8612bb7acecfSBarry Smith - dm2 - the second `DM` 86138320bc6fSPatrick Sanan 86148320bc6fSPatrick Sanan Output Parameters: 8615bb7acecfSBarry Smith + compatible - whether or not the two `DM`s are compatible 8616bb7acecfSBarry Smith - set - whether or not the compatible value was actually determined and set 86178320bc6fSPatrick Sanan 861820f4b53cSBarry Smith Level: advanced 861920f4b53cSBarry Smith 86208320bc6fSPatrick Sanan Notes: 8621bb7acecfSBarry Smith Two `DM`s are deemed compatible if they represent the same parallel decomposition 86223d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 86238320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 8624bb7acecfSBarry Smith Loosely speaking, compatible `DM`s represent the same domain and parallel 86253d862458SPatrick Sanan decomposition, but hold different data. 86268320bc6fSPatrick Sanan 86278320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 8628bb7acecfSBarry Smith over a pair of vectors obtained from different `DM`s. 86298320bc6fSPatrick Sanan 8630bb7acecfSBarry Smith For example, two `DMDA` objects are compatible if they have the same local 86318320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 86328320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 8633bb7acecfSBarry Smith either `DM` in bounds for a loop over vectors derived from either `DM`. 86348320bc6fSPatrick Sanan 8635bb7acecfSBarry Smith Consider the operation of summing data living on a 2-dof `DMDA` to data living 8636bb7acecfSBarry Smith on a 1-dof `DMDA`, which should be compatible, as in the following snippet. 86378320bc6fSPatrick Sanan .vb 86388320bc6fSPatrick Sanan ... 86399566063dSJacob Faibussowitsch PetscCall(DMGetCompatibility(da1,da2,&compatible,&set)); 86408320bc6fSPatrick Sanan if (set && compatible) { 86419566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1)); 86429566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2)); 86439566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL)); 86448320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 86458320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 86468320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 86478320bc6fSPatrick Sanan } 86488320bc6fSPatrick Sanan } 86499566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1)); 86509566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2)); 86518320bc6fSPatrick Sanan } else { 86528320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 86538320bc6fSPatrick Sanan } 86548320bc6fSPatrick Sanan ... 86558320bc6fSPatrick Sanan .ve 86568320bc6fSPatrick Sanan 8657bb7acecfSBarry Smith Checking compatibility might be expensive for a given implementation of `DM`, 86588320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 86598320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 86608320bc6fSPatrick Sanan always check the "set" output parameter. 86618320bc6fSPatrick Sanan 8662bb7acecfSBarry Smith A `DM` is always compatible with itself. 86638320bc6fSPatrick Sanan 8664bb7acecfSBarry Smith In the current implementation, `DM`s which live on "unequal" communicators 86658320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 86668320bc6fSPatrick Sanan incompatible. 86678320bc6fSPatrick Sanan 86688320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 8669bb7acecfSBarry Smith is required on each rank. However, in `DM` implementations which store all this 86708320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 86718320bc6fSPatrick Sanan 867260225df5SJacob Faibussowitsch Developer Notes: 8673bb7acecfSBarry Smith Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B 86743d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 8675a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 8676bb7acecfSBarry Smith compatibility. It is left to `DM` implementers to ensure that symmetry is 86778320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 86783d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 8679bb7acecfSBarry Smith of other `DM` types and let *set = PETSC_FALSE if found. 86808320bc6fSPatrick Sanan 86811cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()` 86828320bc6fSPatrick Sanan @*/ 8683d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCompatibility(DM dm1, DM dm2, PetscBool *compatible, PetscBool *set) 8684d71ae5a4SJacob Faibussowitsch { 86858320bc6fSPatrick Sanan PetscMPIInt compareResult; 86868320bc6fSPatrick Sanan DMType type, type2; 86878320bc6fSPatrick Sanan PetscBool sameType; 86888320bc6fSPatrick Sanan 86898320bc6fSPatrick Sanan PetscFunctionBegin; 8690a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 86918320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 86928320bc6fSPatrick Sanan 86938320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 8694a5bc1bf3SBarry Smith if (dm1 == dm2) { 86958320bc6fSPatrick Sanan *set = PETSC_TRUE; 86968320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 86973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86988320bc6fSPatrick Sanan } 86998320bc6fSPatrick Sanan 87008320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 87018320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 87028320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 87038320bc6fSPatrick Sanan determined by the implementation-specific logic */ 87049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)dm1), PetscObjectComm((PetscObject)dm2), &compareResult)); 87058320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 87068320bc6fSPatrick Sanan *set = PETSC_TRUE; 87078320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 87083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 87098320bc6fSPatrick Sanan } 87108320bc6fSPatrick Sanan 87118320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 8712a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 8713dbbe0bcdSBarry Smith PetscUseTypeMethod(dm1, getcompatibility, dm2, compatible, set); 87143ba16761SJacob Faibussowitsch if (*set) PetscFunctionReturn(PETSC_SUCCESS); 87158320bc6fSPatrick Sanan } 87168320bc6fSPatrick Sanan 8717a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 87188320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 87199566063dSJacob Faibussowitsch PetscCall(DMGetType(dm1, &type)); 87209566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2, &type2)); 87219566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, type2, &sameType)); 87228320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 8723dbbe0bcdSBarry Smith PetscUseTypeMethod(dm2, getcompatibility, dm1, compatible, set); /* Note argument order */ 87248320bc6fSPatrick Sanan } else { 87258320bc6fSPatrick Sanan *set = PETSC_FALSE; 87268320bc6fSPatrick Sanan } 87273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 87288320bc6fSPatrick Sanan } 8729c0f0dcc3SMatthew G. Knepley 8730c0f0dcc3SMatthew G. Knepley /*@C 8731bb7acecfSBarry Smith DMMonitorSet - Sets an additional monitor function that is to be used after a solve to monitor discretization performance. 8732c0f0dcc3SMatthew G. Knepley 873320f4b53cSBarry Smith Logically Collective 8734c0f0dcc3SMatthew G. Knepley 8735c0f0dcc3SMatthew G. Knepley Input Parameters: 873660225df5SJacob Faibussowitsch + dm - the `DM` 8737c0f0dcc3SMatthew G. Knepley . f - the monitor function 873820f4b53cSBarry Smith . mctx - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired) 873920f4b53cSBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`) 8740c0f0dcc3SMatthew G. Knepley 874120f4b53cSBarry Smith Options Database Key: 874260225df5SJacob Faibussowitsch . -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `DMMonitorSet()`, but 8743c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 8744c0f0dcc3SMatthew G. Knepley 87459bdbcad8SBarry Smith Level: intermediate 87469bdbcad8SBarry Smith 8747bb7acecfSBarry Smith Note: 8748c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 8749bb7acecfSBarry Smith `DMMonitorSet()` multiple times or with `DMMonitorSetFromOptions()`; all will be called in the 8750c0f0dcc3SMatthew G. Knepley order in which they were set. 8751c0f0dcc3SMatthew G. Knepley 875260225df5SJacob Faibussowitsch Fortran Notes: 8753bb7acecfSBarry Smith Only a single monitor function can be set for each `DM` object 8754bb7acecfSBarry Smith 875560225df5SJacob Faibussowitsch Developer Notes: 8756bb7acecfSBarry Smith This API has a generic name but seems specific to a very particular aspect of the use of `DM` 8757c0f0dcc3SMatthew G. Knepley 87581cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorCancel()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8759c0f0dcc3SMatthew G. Knepley @*/ 8760d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 8761d71ae5a4SJacob Faibussowitsch { 8762c0f0dcc3SMatthew G. Knepley PetscInt m; 8763c0f0dcc3SMatthew G. Knepley 8764c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8765c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8766c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 8767c0f0dcc3SMatthew G. Knepley PetscBool identical; 8768c0f0dcc3SMatthew G. Knepley 87699566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical)); 87703ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 8771c0f0dcc3SMatthew G. Knepley } 87727a8be351SBarry Smith PetscCheck(dm->numbermonitors < MAXDMMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 8773c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 8774c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 8775c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *)mctx; 87763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8777c0f0dcc3SMatthew G. Knepley } 8778c0f0dcc3SMatthew G. Knepley 8779c0f0dcc3SMatthew G. Knepley /*@ 8780bb7acecfSBarry Smith DMMonitorCancel - Clears all the monitor functions for a `DM` object. 8781c0f0dcc3SMatthew G. Knepley 878220f4b53cSBarry Smith Logically Collective 8783c0f0dcc3SMatthew G. Knepley 8784c0f0dcc3SMatthew G. Knepley Input Parameter: 8785c0f0dcc3SMatthew G. Knepley . dm - the DM 8786c0f0dcc3SMatthew G. Knepley 8787c0f0dcc3SMatthew G. Knepley Options Database Key: 8788c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 8789bb7acecfSBarry Smith into a code by calls to `DMonitorSet()`, but does not cancel those 8790c0f0dcc3SMatthew G. Knepley set via the options database 8791c0f0dcc3SMatthew G. Knepley 87929bdbcad8SBarry Smith Level: intermediate 87939bdbcad8SBarry Smith 8794bb7acecfSBarry Smith Note: 8795bb7acecfSBarry Smith There is no way to clear one specific monitor from a `DM` object. 8796c0f0dcc3SMatthew G. Knepley 87971cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8798c0f0dcc3SMatthew G. Knepley @*/ 8799d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorCancel(DM dm) 8800d71ae5a4SJacob Faibussowitsch { 8801c0f0dcc3SMatthew G. Knepley PetscInt m; 8802c0f0dcc3SMatthew G. Knepley 8803c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8804c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8805c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 88069566063dSJacob Faibussowitsch if (dm->monitordestroy[m]) PetscCall((*dm->monitordestroy[m])(&dm->monitorcontext[m])); 8807c0f0dcc3SMatthew G. Knepley } 8808c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 88093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8810c0f0dcc3SMatthew G. Knepley } 8811c0f0dcc3SMatthew G. Knepley 8812c0f0dcc3SMatthew G. Knepley /*@C 8813c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 8814c0f0dcc3SMatthew G. Knepley 881520f4b53cSBarry Smith Collective 8816c0f0dcc3SMatthew G. Knepley 8817c0f0dcc3SMatthew G. Knepley Input Parameters: 8818bb7acecfSBarry Smith + dm - `DM` object you wish to monitor 8819c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 8820c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 8821c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 8822c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 8823bb7acecfSBarry 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 8824c0f0dcc3SMatthew G. Knepley 8825c0f0dcc3SMatthew G. Knepley Output Parameter: 8826c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 8827c0f0dcc3SMatthew G. Knepley 8828c0f0dcc3SMatthew G. Knepley Level: developer 8829c0f0dcc3SMatthew G. Knepley 88301cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 8831db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 883260225df5SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 8833db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 8834c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 8835db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 8836bb7acecfSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `DMMonitor()`, `DMMonitorSet()` 8837c0f0dcc3SMatthew G. Knepley @*/ 8838d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 8839d71ae5a4SJacob Faibussowitsch { 8840c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 8841c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 8842c0f0dcc3SMatthew G. Knepley 8843c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8844c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 88459566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)dm), ((PetscObject)dm)->options, ((PetscObject)dm)->prefix, name, &viewer, &format, flg)); 8846c0f0dcc3SMatthew G. Knepley if (*flg) { 8847c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 8848c0f0dcc3SMatthew G. Knepley 88499566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 88509566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 88519566063dSJacob Faibussowitsch if (monitorsetup) PetscCall((*monitorsetup)(dm, vf)); 88529566063dSJacob Faibussowitsch PetscCall(DMMonitorSet(dm, (PetscErrorCode(*)(DM, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 8853c0f0dcc3SMatthew G. Knepley } 88543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8855c0f0dcc3SMatthew G. Knepley } 8856c0f0dcc3SMatthew G. Knepley 8857c0f0dcc3SMatthew G. Knepley /*@ 8858c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 8859c0f0dcc3SMatthew G. Knepley 886020f4b53cSBarry Smith Collective 8861c0f0dcc3SMatthew G. Knepley 88622fe279fdSBarry Smith Input Parameter: 8863bb7acecfSBarry Smith . dm - The `DM` 8864c0f0dcc3SMatthew G. Knepley 8865c0f0dcc3SMatthew G. Knepley Level: developer 8866c0f0dcc3SMatthew G. Knepley 8867a4e35b19SJacob Faibussowitsch Developer Notes: 8868a4e35b19SJacob Faibussowitsch Note should indicate when during the life of the `DM` the monitor is run. It appears to be 8869a4e35b19SJacob Faibussowitsch related to the discretization process seems rather specialized since some `DM` have no 8870a4e35b19SJacob Faibussowitsch concept of discretization. 8871bb7acecfSBarry Smith 88721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()` 8873c0f0dcc3SMatthew G. Knepley @*/ 8874d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitor(DM dm) 8875d71ae5a4SJacob Faibussowitsch { 8876c0f0dcc3SMatthew G. Knepley PetscInt m; 8877c0f0dcc3SMatthew G. Knepley 8878c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 88793ba16761SJacob Faibussowitsch if (!dm) PetscFunctionReturn(PETSC_SUCCESS); 8880c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 888148a46eb9SPierre Jolivet for (m = 0; m < dm->numbermonitors; ++m) PetscCall((*dm->monitor[m])(dm, dm->monitorcontext[m])); 88823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8883c0f0dcc3SMatthew G. Knepley } 88842e4af2aeSMatthew G. Knepley 88852e4af2aeSMatthew G. Knepley /*@ 8886bb7acecfSBarry Smith DMComputeError - Computes the error assuming the user has provided the exact solution functions 88872e4af2aeSMatthew G. Knepley 888820f4b53cSBarry Smith Collective 88892e4af2aeSMatthew G. Knepley 88902e4af2aeSMatthew G. Knepley Input Parameters: 8891bb7acecfSBarry Smith + dm - The `DM` 88926b867d5aSJose E. Roman - sol - The solution vector 88932e4af2aeSMatthew G. Knepley 88946b867d5aSJose E. Roman Input/Output Parameter: 889520f4b53cSBarry Smith . errors - An array of length Nf, the number of fields, or `NULL` for no output; on output 88966b867d5aSJose E. Roman contains the error in each field 88976b867d5aSJose E. Roman 88986b867d5aSJose E. Roman Output Parameter: 889920f4b53cSBarry Smith . errorVec - A vector to hold the cellwise error (may be `NULL`) 890020f4b53cSBarry Smith 890120f4b53cSBarry Smith Level: developer 89022e4af2aeSMatthew G. Knepley 8903bb7acecfSBarry Smith Note: 8904bb7acecfSBarry Smith The exact solutions come from the `PetscDS` object, and the time comes from `DMGetOutputSequenceNumber()`. 89052e4af2aeSMatthew G. Knepley 89061cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMGetRegionNumDS()`, `PetscDSGetExactSolution()`, `DMGetOutputSequenceNumber()` 89072e4af2aeSMatthew G. Knepley @*/ 8908d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 8909d71ae5a4SJacob Faibussowitsch { 89102e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 89112e4af2aeSMatthew G. Knepley void **ctxs; 89122e4af2aeSMatthew G. Knepley PetscReal time; 89132e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 89142e4af2aeSMatthew G. Knepley 89152e4af2aeSMatthew G. Knepley PetscFunctionBegin; 89169566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 89179566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nf, &exactSol, Nf, &ctxs)); 89189566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 89192e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 89202e4af2aeSMatthew G. Knepley PetscDS ds; 89212e4af2aeSMatthew G. Knepley DMLabel label; 89222e4af2aeSMatthew G. Knepley IS fieldIS; 89232e4af2aeSMatthew G. Knepley const PetscInt *fields; 89242e4af2aeSMatthew G. Knepley PetscInt dsNf; 89252e4af2aeSMatthew G. Knepley 892607218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 89279566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 89289566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISGetIndices(fieldIS, &fields)); 89292e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 89302e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 89319566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field])); 89322e4af2aeSMatthew G. Knepley } 89339566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISRestoreIndices(fieldIS, &fields)); 89342e4af2aeSMatthew G. Knepley } 8935ad540459SPierre 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); 89369566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, NULL, &time)); 89379566063dSJacob Faibussowitsch if (errors) PetscCall(DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors)); 89382e4af2aeSMatthew G. Knepley if (errorVec) { 89392e4af2aeSMatthew G. Knepley DM edm; 89402e4af2aeSMatthew G. Knepley DMPolytopeType ct; 89412e4af2aeSMatthew G. Knepley PetscBool simplex; 89422e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 89432e4af2aeSMatthew G. Knepley 89449566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &edm)); 89459566063dSJacob Faibussowitsch PetscCall(DMGetDimension(edm, &dim)); 89469566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 89479566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 89482e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 89499566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 89502e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 89512e4af2aeSMatthew G. Knepley PetscFE fe, efe; 89522e4af2aeSMatthew G. Knepley PetscQuadrature q; 89532e4af2aeSMatthew G. Knepley const char *name; 89542e4af2aeSMatthew G. Knepley 89559566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, (PetscObject *)&fe)); 89569566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe)); 89579566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 89589566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)efe, name)); 89599566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 89609566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(efe, q)); 89619566063dSJacob Faibussowitsch PetscCall(DMSetField(edm, f, NULL, (PetscObject)efe)); 89629566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&efe)); 89632e4af2aeSMatthew G. Knepley } 89649566063dSJacob Faibussowitsch PetscCall(DMCreateDS(edm)); 89652e4af2aeSMatthew G. Knepley 89669566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(edm, errorVec)); 89679566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*errorVec, "Error")); 89689566063dSJacob Faibussowitsch PetscCall(DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec)); 89699566063dSJacob Faibussowitsch PetscCall(DMDestroy(&edm)); 89702e4af2aeSMatthew G. Knepley } 89719566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, ctxs)); 89723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89732e4af2aeSMatthew G. Knepley } 89749a2a23afSMatthew G. Knepley 89759a2a23afSMatthew G. Knepley /*@ 8976bb7acecfSBarry Smith DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this `DM` 89779a2a23afSMatthew G. Knepley 897820f4b53cSBarry Smith Not Collective 89799a2a23afSMatthew G. Knepley 89809a2a23afSMatthew G. Knepley Input Parameter: 8981bb7acecfSBarry Smith . dm - The `DM` 89829a2a23afSMatthew G. Knepley 89839a2a23afSMatthew G. Knepley Output Parameter: 8984a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 89859a2a23afSMatthew G. Knepley 89869a2a23afSMatthew G. Knepley Level: advanced 89879a2a23afSMatthew G. Knepley 898860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMSetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMGetAuxiliaryVec()` 89899a2a23afSMatthew G. Knepley @*/ 8990d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 8991d71ae5a4SJacob Faibussowitsch { 89929a2a23afSMatthew G. Knepley PetscFunctionBegin; 89939a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89949566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize(dm->auxData, numAux)); 89953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89969a2a23afSMatthew G. Knepley } 89979a2a23afSMatthew G. Knepley 89989a2a23afSMatthew G. Knepley /*@ 8999ac17215fSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value, and equation part 90009a2a23afSMatthew G. Knepley 900120f4b53cSBarry Smith Not Collective 90029a2a23afSMatthew G. Knepley 90039a2a23afSMatthew G. Knepley Input Parameters: 9004bb7acecfSBarry Smith + dm - The `DM` 9005bb7acecfSBarry Smith . label - The `DMLabel` 9006ac17215fSMatthew G. Knepley . value - The label value indicating the region 9007ac17215fSMatthew G. Knepley - part - The equation part, or 0 if unused 90089a2a23afSMatthew G. Knepley 90099a2a23afSMatthew G. Knepley Output Parameter: 9010bb7acecfSBarry Smith . aux - The `Vec` holding auxiliary field data 90119a2a23afSMatthew G. Knepley 90129bdbcad8SBarry Smith Level: advanced 90139bdbcad8SBarry Smith 9014bb7acecfSBarry Smith Note: 9015bb7acecfSBarry Smith If no auxiliary vector is found for this (label, value), (NULL, 0, 0) is checked as well. 901604c51a94SMatthew G. Knepley 90171cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryLabels()` 90189a2a23afSMatthew G. Knepley @*/ 9019d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec *aux) 9020d71ae5a4SJacob Faibussowitsch { 9021ac17215fSMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0, 0}; 902204c51a94SMatthew G. Knepley PetscBool has; 90239a2a23afSMatthew G. Knepley 90249a2a23afSMatthew G. Knepley PetscFunctionBegin; 90259a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90269a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 90279a2a23afSMatthew G. Knepley key.label = label; 90289a2a23afSMatthew G. Knepley key.value = value; 9029ac17215fSMatthew G. Knepley key.part = part; 90309566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxHas(dm->auxData, key, &has)); 90319566063dSJacob Faibussowitsch if (has) PetscCall(PetscHMapAuxGet(dm->auxData, key, aux)); 90329566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxGet(dm->auxData, wild, aux)); 90333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 90349a2a23afSMatthew G. Knepley } 90359a2a23afSMatthew G. Knepley 90369a2a23afSMatthew G. Knepley /*@ 9037bb7acecfSBarry Smith DMSetAuxiliaryVec - Set an auxiliary vector for region specified by the given label and value, and equation part 90389a2a23afSMatthew G. Knepley 903920f4b53cSBarry Smith Not Collective because auxiliary vectors are not parallel 90409a2a23afSMatthew G. Knepley 90419a2a23afSMatthew G. Knepley Input Parameters: 9042bb7acecfSBarry Smith + dm - The `DM` 9043bb7acecfSBarry Smith . label - The `DMLabel` 90449a2a23afSMatthew G. Knepley . value - The label value indicating the region 9045ac17215fSMatthew G. Knepley . part - The equation part, or 0 if unused 9046bb7acecfSBarry Smith - aux - The `Vec` holding auxiliary field data 90479a2a23afSMatthew G. Knepley 90489a2a23afSMatthew G. Knepley Level: advanced 90499a2a23afSMatthew G. Knepley 90501cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMCopyAuxiliaryVec()` 90519a2a23afSMatthew G. Knepley @*/ 9052d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec aux) 9053d71ae5a4SJacob Faibussowitsch { 90549a2a23afSMatthew G. Knepley Vec old; 90559a2a23afSMatthew G. Knepley PetscHashAuxKey key; 90569a2a23afSMatthew G. Knepley 90579a2a23afSMatthew G. Knepley PetscFunctionBegin; 90589a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90599a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 90609a2a23afSMatthew G. Knepley key.label = label; 90619a2a23afSMatthew G. Knepley key.value = value; 9062ac17215fSMatthew G. Knepley key.part = part; 90639566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGet(dm->auxData, key, &old)); 90649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)aux)); 90659566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)old)); 90669566063dSJacob Faibussowitsch if (!aux) PetscCall(PetscHMapAuxDel(dm->auxData, key)); 90679566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxSet(dm->auxData, key, aux)); 90683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 90699a2a23afSMatthew G. Knepley } 90709a2a23afSMatthew G. Knepley 90719a2a23afSMatthew G. Knepley /*@C 9072bb7acecfSBarry Smith DMGetAuxiliaryLabels - Get the labels, values, and parts for all auxiliary vectors in this `DM` 90739a2a23afSMatthew G. Knepley 907420f4b53cSBarry Smith Not Collective 90759a2a23afSMatthew G. Knepley 90769a2a23afSMatthew G. Knepley Input Parameter: 9077bb7acecfSBarry Smith . dm - The `DM` 90789a2a23afSMatthew G. Knepley 90799a2a23afSMatthew G. Knepley Output Parameters: 9080bb7acecfSBarry Smith + labels - The `DMLabel`s for each `Vec` 9081bb7acecfSBarry Smith . values - The label values for each `Vec` 9082bb7acecfSBarry Smith - parts - The equation parts for each `Vec` 90839a2a23afSMatthew G. Knepley 90849bdbcad8SBarry Smith Level: advanced 90859bdbcad8SBarry Smith 9086bb7acecfSBarry Smith Note: 9087bb7acecfSBarry Smith The arrays passed in must be at least as large as `DMGetNumAuxiliaryVec()`. 90889a2a23afSMatthew G. Knepley 908960225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMCopyAuxiliaryVec()` 90909a2a23afSMatthew G. Knepley @*/ 9091d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[], PetscInt parts[]) 9092d71ae5a4SJacob Faibussowitsch { 90939a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 90949a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 90959a2a23afSMatthew G. Knepley 90969a2a23afSMatthew G. Knepley PetscFunctionBegin; 90979a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90984f572ea9SToby Isaac PetscAssertPointer(labels, 2); 90994f572ea9SToby Isaac PetscAssertPointer(values, 3); 91004f572ea9SToby Isaac PetscAssertPointer(parts, 4); 91019566063dSJacob Faibussowitsch PetscCall(DMGetNumAuxiliaryVec(dm, &n)); 91029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &keys)); 91039566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetKeys(dm->auxData, &off, keys)); 91049371c9d4SSatish Balay for (i = 0; i < n; ++i) { 91059371c9d4SSatish Balay labels[i] = keys[i].label; 91069371c9d4SSatish Balay values[i] = keys[i].value; 91079371c9d4SSatish Balay parts[i] = keys[i].part; 91089371c9d4SSatish Balay } 91099566063dSJacob Faibussowitsch PetscCall(PetscFree(keys)); 91103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91119a2a23afSMatthew G. Knepley } 91129a2a23afSMatthew G. Knepley 91139a2a23afSMatthew G. Knepley /*@ 9114bb7acecfSBarry Smith DMCopyAuxiliaryVec - Copy the auxiliary vector data on a `DM` to a new `DM` 91159a2a23afSMatthew G. Knepley 911620f4b53cSBarry Smith Not Collective 91179a2a23afSMatthew G. Knepley 91189a2a23afSMatthew G. Knepley Input Parameter: 9119bb7acecfSBarry Smith . dm - The `DM` 91209a2a23afSMatthew G. Knepley 91219a2a23afSMatthew G. Knepley Output Parameter: 9122bb7acecfSBarry Smith . dmNew - The new `DM`, now with the same auxiliary data 91239a2a23afSMatthew G. Knepley 91249a2a23afSMatthew G. Knepley Level: advanced 91259a2a23afSMatthew G. Knepley 9126bb7acecfSBarry Smith Note: 9127bb7acecfSBarry Smith This is a shallow copy of the auxiliary vectors 9128bb7acecfSBarry Smith 91291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 91309a2a23afSMatthew G. Knepley @*/ 9131d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 9132d71ae5a4SJacob Faibussowitsch { 91339a2a23afSMatthew G. Knepley PetscFunctionBegin; 91349a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 91359566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&dmNew->auxData)); 91369566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData)); 91373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91389a2a23afSMatthew G. Knepley } 9139b5a892a1SMatthew G. Knepley 9140b5a892a1SMatthew G. Knepley /*@C 9141bb7acecfSBarry Smith DMPolytopeMatchOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9142b5a892a1SMatthew G. Knepley 914320f4b53cSBarry Smith Not Collective 9144b5a892a1SMatthew G. Knepley 9145b5a892a1SMatthew G. Knepley Input Parameters: 9146bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9147b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9148b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9149b5a892a1SMatthew G. Knepley 9150b5a892a1SMatthew G. Knepley Output Parameters: 9151bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9152b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9153b5a892a1SMatthew G. Knepley 9154b5a892a1SMatthew G. Knepley Level: advanced 9155b5a892a1SMatthew G. Knepley 9156bb7acecfSBarry Smith Note: 9157bb7acecfSBarry Smith An arrangement is a face order combined with an orientation for each face 9158bb7acecfSBarry Smith 9159bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9160bb7acecfSBarry Smith that labels each arrangement (face ordering plus orientation for each face). 9161bb7acecfSBarry Smith 9162bb7acecfSBarry Smith See `DMPolytopeMatchVertexOrientation()` to find a new vertex orientation that takes the source vertex arrangement to the target vertex arrangement 9163bb7acecfSBarry Smith 91641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetVertexOrientation()` 9165b5a892a1SMatthew G. Knepley @*/ 9166d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9167d71ae5a4SJacob Faibussowitsch { 9168b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 9169b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct) / 2; 9170b5a892a1SMatthew G. Knepley PetscInt o, c; 9171b5a892a1SMatthew G. Knepley 9172b5a892a1SMatthew G. Knepley PetscFunctionBegin; 91739371c9d4SSatish Balay if (!nO) { 91749371c9d4SSatish Balay *ornt = 0; 91759371c9d4SSatish Balay *found = PETSC_TRUE; 91763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91779371c9d4SSatish Balay } 9178b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9179b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 9180b5a892a1SMatthew G. Knepley 91819371c9d4SSatish Balay for (c = 0; c < cS; ++c) 91829371c9d4SSatish Balay if (sourceCone[arr[c * 2]] != targetCone[c]) break; 91839371c9d4SSatish Balay if (c == cS) { 91849371c9d4SSatish Balay *ornt = o; 91859371c9d4SSatish Balay break; 91869371c9d4SSatish Balay } 9187b5a892a1SMatthew G. Knepley } 9188b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 91893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9190b5a892a1SMatthew G. Knepley } 9191b5a892a1SMatthew G. Knepley 9192b5a892a1SMatthew G. Knepley /*@C 9193bb7acecfSBarry Smith DMPolytopeGetOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9194b5a892a1SMatthew G. Knepley 919520f4b53cSBarry Smith Not Collective 9196b5a892a1SMatthew G. Knepley 9197b5a892a1SMatthew G. Knepley Input Parameters: 9198bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9199b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9200b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9201b5a892a1SMatthew G. Knepley 92022fe279fdSBarry Smith Output Parameter: 9203bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9204b5a892a1SMatthew G. Knepley 9205b5a892a1SMatthew G. Knepley Level: advanced 9206b5a892a1SMatthew G. Knepley 9207bb7acecfSBarry Smith Note: 9208bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchOrientation()` except it will generate an error if no suitable orientation can be found. 9209bb7acecfSBarry Smith 921060225df5SJacob Faibussowitsch Developer Notes: 9211bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchOrientation()` and error if none is found 9212bb7acecfSBarry Smith 92131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchOrientation()`, `DMPolytopeGetVertexOrientation()`, `DMPolytopeMatchVertexOrientation()` 9214b5a892a1SMatthew G. Knepley @*/ 9215d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9216d71ae5a4SJacob Faibussowitsch { 9217b5a892a1SMatthew G. Knepley PetscBool found; 9218b5a892a1SMatthew G. Knepley 9219b5a892a1SMatthew G. Knepley PetscFunctionBegin; 92209566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found)); 92217a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 92223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9223b5a892a1SMatthew G. Knepley } 9224b5a892a1SMatthew G. Knepley 9225b5a892a1SMatthew G. Knepley /*@C 9226bb7acecfSBarry Smith DMPolytopeMatchVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9227b5a892a1SMatthew G. Knepley 922820f4b53cSBarry Smith Not Collective 9229b5a892a1SMatthew G. Knepley 9230b5a892a1SMatthew G. Knepley Input Parameters: 9231bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9232b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 9233b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 9234b5a892a1SMatthew G. Knepley 9235b5a892a1SMatthew G. Knepley Output Parameters: 9236bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9237b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9238b5a892a1SMatthew G. Knepley 9239b5a892a1SMatthew G. Knepley Level: advanced 9240b5a892a1SMatthew G. Knepley 9241bb7acecfSBarry Smith Note: 9242bb7acecfSBarry Smith An arrangement is a vertex order 9243bb7acecfSBarry Smith 9244bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9245bb7acecfSBarry Smith that labels each arrangement (vertex ordering). 9246bb7acecfSBarry Smith 9247bb7acecfSBarry Smith See `DMPolytopeMatchOrientation()` to find a new face orientation that takes the source face arrangement to the target face arrangement 9248bb7acecfSBarry Smith 92491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchOrientation()`, `DMPolytopeTypeGetNumVertices()`, `DMPolytopeTypeGetVertexArrangment()` 9250b5a892a1SMatthew G. Knepley @*/ 9251d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 9252d71ae5a4SJacob Faibussowitsch { 9253b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 9254b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct) / 2; 9255b5a892a1SMatthew G. Knepley PetscInt o, c; 9256b5a892a1SMatthew G. Knepley 9257b5a892a1SMatthew G. Knepley PetscFunctionBegin; 92589371c9d4SSatish Balay if (!nO) { 92599371c9d4SSatish Balay *ornt = 0; 92609371c9d4SSatish Balay *found = PETSC_TRUE; 92613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92629371c9d4SSatish Balay } 9263b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9264b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangment(ct, o); 9265b5a892a1SMatthew G. Knepley 92669371c9d4SSatish Balay for (c = 0; c < cS; ++c) 92679371c9d4SSatish Balay if (sourceVert[arr[c]] != targetVert[c]) break; 92689371c9d4SSatish Balay if (c == cS) { 92699371c9d4SSatish Balay *ornt = o; 92709371c9d4SSatish Balay break; 92719371c9d4SSatish Balay } 9272b5a892a1SMatthew G. Knepley } 9273b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 92743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9275b5a892a1SMatthew G. Knepley } 9276b5a892a1SMatthew G. Knepley 9277b5a892a1SMatthew G. Knepley /*@C 9278bb7acecfSBarry Smith DMPolytopeGetVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9279b5a892a1SMatthew G. Knepley 928020f4b53cSBarry Smith Not Collective 9281b5a892a1SMatthew G. Knepley 9282b5a892a1SMatthew G. Knepley Input Parameters: 9283bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9284b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 9285b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 9286b5a892a1SMatthew G. Knepley 92872fe279fdSBarry Smith Output Parameter: 9288bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9289b5a892a1SMatthew G. Knepley 9290b5a892a1SMatthew G. Knepley Level: advanced 9291b5a892a1SMatthew G. Knepley 9292bb7acecfSBarry Smith Note: 9293bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchVertexOrientation()` except it errors if not orientation is possible. 9294bb7acecfSBarry Smith 929560225df5SJacob Faibussowitsch Developer Notes: 9296bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchVertexOrientation()` and error if none is found 9297bb7acecfSBarry Smith 92981cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetOrientation()` 9299b5a892a1SMatthew G. Knepley @*/ 9300d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9301d71ae5a4SJacob Faibussowitsch { 9302b5a892a1SMatthew G. Knepley PetscBool found; 9303b5a892a1SMatthew G. Knepley 9304b5a892a1SMatthew G. Knepley PetscFunctionBegin; 93059566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found)); 93067a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 93073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9308b5a892a1SMatthew G. Knepley } 9309012bc364SMatthew G. Knepley 9310012bc364SMatthew G. Knepley /*@C 9311012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 9312012bc364SMatthew G. Knepley 931320f4b53cSBarry Smith Not Collective 9314012bc364SMatthew G. Knepley 9315012bc364SMatthew G. Knepley Input Parameters: 9316bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9317012bc364SMatthew G. Knepley - point - Coordinates of the point 9318012bc364SMatthew G. Knepley 93192fe279fdSBarry Smith Output Parameter: 9320012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 9321012bc364SMatthew G. Knepley 9322012bc364SMatthew G. Knepley Level: advanced 9323012bc364SMatthew G. Knepley 93241cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMLocatePoints()` 9325012bc364SMatthew G. Knepley @*/ 9326d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 9327d71ae5a4SJacob Faibussowitsch { 9328012bc364SMatthew G. Knepley PetscReal sum = 0.0; 9329012bc364SMatthew G. Knepley PetscInt d; 9330012bc364SMatthew G. Knepley 9331012bc364SMatthew G. Knepley PetscFunctionBegin; 9332012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 9333012bc364SMatthew G. Knepley switch (ct) { 9334012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 9335012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 9336012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 93379371c9d4SSatish Balay if (point[d] < -1.0) { 93389371c9d4SSatish Balay *inside = PETSC_FALSE; 93399371c9d4SSatish Balay break; 93409371c9d4SSatish Balay } 9341012bc364SMatthew G. Knepley sum += point[d]; 9342012bc364SMatthew G. Knepley } 93439371c9d4SSatish Balay if (sum > PETSC_SMALL) { 93449371c9d4SSatish Balay *inside = PETSC_FALSE; 93459371c9d4SSatish Balay break; 93469371c9d4SSatish Balay } 9347012bc364SMatthew G. Knepley break; 9348012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 9349012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 9350012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 93519371c9d4SSatish Balay if (PetscAbsReal(point[d]) > 1. + PETSC_SMALL) { 93529371c9d4SSatish Balay *inside = PETSC_FALSE; 9353012bc364SMatthew G. Knepley break; 93549371c9d4SSatish Balay } 93559371c9d4SSatish Balay break; 9356d71ae5a4SJacob Faibussowitsch default: 9357d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 9358012bc364SMatthew G. Knepley } 93593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9360012bc364SMatthew G. Knepley } 9361