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}; 26476787b7SMatthew G. Knepley const char *const DMPolytopeTypes[] = 27476787b7SMatthew 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", 28476787b7SMatthew 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; 140ec196627SMatthew G. Knepley MatOrderingType otype; 141ec196627SMatthew G. Knepley DMReorderDefaultFlag flg; 1426858538eSMatthew G. Knepley PetscInt dim, cdim, i; 14338221697SMatthew G. Knepley 14438221697SMatthew G. Knepley PetscFunctionBegin; 14538221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1464f572ea9SToby Isaac PetscAssertPointer(newdm, 2); 1479566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), newdm)); 1489566063dSJacob Faibussowitsch PetscCall(DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE, DM_COPY_LABELS_FAIL)); 149ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 150ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 151c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 152fc214432SJed Brown (*newdm)->prealloc_skip = dm->prealloc_skip; 1539566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->vectype)); 1549566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*newdm)->vectype)); 1559566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->mattype)); 1569566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*newdm)->mattype)); 1579566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1589566063dSJacob Faibussowitsch PetscCall(DMSetDimension(*newdm, dim)); 159dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, clone, newdm); 1603f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 1619566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm, &sf)); 1629566063dSJacob Faibussowitsch PetscCall(DMSetPointSF(*newdm, sf)); 1639566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dm, &ctx)); 1649566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(*newdm, ctx)); 165ec196627SMatthew G. Knepley PetscCall(DMReorderSectionGetDefault(dm, &flg)); 166ec196627SMatthew G. Knepley PetscCall(DMReorderSectionSetDefault(*newdm, flg)); 167ec196627SMatthew G. Knepley PetscCall(DMReorderSectionGetType(dm, &otype)); 168ec196627SMatthew G. Knepley PetscCall(DMReorderSectionSetType(*newdm, otype)); 1696858538eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 1706858538eSMatthew G. Knepley if (dm->coordinates[i].dm) { 171be4c1c3eSMatthew G. Knepley DM ncdm; 172be4c1c3eSMatthew G. Knepley PetscSection cs; 1735a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 174be4c1c3eSMatthew G. Knepley 1756858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm->coordinates[i].dm, &cs)); 1769566063dSJacob Faibussowitsch if (cs) PetscCall(PetscSectionGetChart(cs, NULL, &pEnd)); 177712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&pEnd, &pEndMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 1785a0206caSToby Isaac if (pEndMax >= 0) { 1796858538eSMatthew G. Knepley PetscCall(DMClone(dm->coordinates[i].dm, &ncdm)); 1806858538eSMatthew G. Knepley PetscCall(DMCopyDisc(dm->coordinates[i].dm, ncdm)); 1819566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(ncdm, cs)); 1826858538eSMatthew G. Knepley if (i) PetscCall(DMSetCellCoordinateDM(*newdm, ncdm)); 1836858538eSMatthew G. Knepley else PetscCall(DMSetCoordinateDM(*newdm, ncdm)); 1849566063dSJacob Faibussowitsch PetscCall(DMDestroy(&ncdm)); 185be4c1c3eSMatthew G. Knepley } 186be4c1c3eSMatthew G. Knepley } 1876858538eSMatthew G. Knepley } 1889566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 1899566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateDim(*newdm, cdim)); 1909566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coords)); 19138221697SMatthew G. Knepley if (coords) { 1929566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(*newdm, coords)); 19338221697SMatthew G. Knepley } else { 1949566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm, &coords)); 1959566063dSJacob Faibussowitsch if (coords) PetscCall(DMSetCoordinates(*newdm, coords)); 19638221697SMatthew G. Knepley } 1976858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coords)); 1986858538eSMatthew G. Knepley if (coords) { 1996858538eSMatthew G. Knepley PetscCall(DMSetCellCoordinatesLocal(*newdm, coords)); 2006858538eSMatthew G. Knepley } else { 2016858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinates(dm, &coords)); 2026858538eSMatthew G. Knepley if (coords) PetscCall(DMSetCellCoordinates(*newdm, coords)); 2036858538eSMatthew G. Knepley } 20490b157c4SStefano Zampini { 2054fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 2066858538eSMatthew G. Knepley 2074fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 2084fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*newdm, maxCell, Lstart, L)); 209c6b900c6SMatthew G. Knepley } 21034aa8a36SMatthew G. Knepley { 21134aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 21234aa8a36SMatthew G. Knepley 2139566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure)); 2149566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure)); 21534aa8a36SMatthew G. Knepley } 2163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21738221697SMatthew G. Knepley } 21838221697SMatthew G. Knepley 2199a42bb27SBarry Smith /*@C 220bb7acecfSBarry Smith DMSetVecType - Sets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 2219a42bb27SBarry Smith 22220f4b53cSBarry Smith Logically Collective 2239a42bb27SBarry Smith 224147403d9SBarry Smith Input Parameters: 22532546409SMatthew G. Knepley + dm - initial distributed array 226bb7acecfSBarry Smith - ctype - the vector type, for example `VECSTANDARD`, `VECCUDA`, or `VECVIENNACL` 2279a42bb27SBarry Smith 22820f4b53cSBarry Smith Options Database Key: 229147403d9SBarry Smith . -dm_vec_type ctype - the type of vector to create 2309a42bb27SBarry Smith 2319a42bb27SBarry Smith Level: intermediate 2329a42bb27SBarry Smith 23360225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMDestroy()`, `DMDAInterpolationType`, `VecType`, `DMGetVecType()`, `DMSetMatType()`, `DMGetMatType()`, 234bb7acecfSBarry Smith `VECSTANDARD`, `VECCUDA`, `VECVIENNACL`, `DMCreateLocalVector()`, `DMCreateGlobalVector()` 2359a42bb27SBarry Smith @*/ 23632546409SMatthew G. Knepley PetscErrorCode DMSetVecType(DM dm, VecType ctype) 237d71ae5a4SJacob Faibussowitsch { 23832546409SMatthew G. Knepley char *tmp; 23932546409SMatthew G. Knepley 2409a42bb27SBarry Smith PetscFunctionBegin; 24132546409SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 24232546409SMatthew G. Knepley PetscAssertPointer(ctype, 2); 24332546409SMatthew G. Knepley tmp = (char *)dm->vectype; 24432546409SMatthew G. Knepley PetscCall(PetscStrallocpy(ctype, (char **)&dm->vectype)); 24532546409SMatthew G. Knepley PetscCall(PetscFree(tmp)); 2463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2479a42bb27SBarry Smith } 2489a42bb27SBarry Smith 249c0dedaeaSBarry Smith /*@C 250bb7acecfSBarry Smith DMGetVecType - Gets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 251c0dedaeaSBarry Smith 25220f4b53cSBarry Smith Logically Collective 253c0dedaeaSBarry Smith 254c0dedaeaSBarry Smith Input Parameter: 255c0dedaeaSBarry Smith . da - initial distributed array 256c0dedaeaSBarry Smith 257c0dedaeaSBarry Smith Output Parameter: 258c0dedaeaSBarry Smith . ctype - the vector type 259c0dedaeaSBarry Smith 260c0dedaeaSBarry Smith Level: intermediate 261c0dedaeaSBarry Smith 26260225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMDestroy()`, `DMDAInterpolationType`, `VecType`, `DMSetMatType()`, `DMGetMatType()`, `DMSetVecType()` 263c0dedaeaSBarry Smith @*/ 264d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetVecType(DM da, VecType *ctype) 265d71ae5a4SJacob Faibussowitsch { 266c0dedaeaSBarry Smith PetscFunctionBegin; 267c0dedaeaSBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 268c0dedaeaSBarry Smith *ctype = da->vectype; 2693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 270c0dedaeaSBarry Smith } 271c0dedaeaSBarry Smith 2725f1ad066SMatthew G Knepley /*@ 273bb7acecfSBarry Smith VecGetDM - Gets the `DM` defining the data layout of the vector 2745f1ad066SMatthew G Knepley 27520f4b53cSBarry Smith Not Collective 2765f1ad066SMatthew G Knepley 2775f1ad066SMatthew G Knepley Input Parameter: 278bb7acecfSBarry Smith . v - The `Vec` 2795f1ad066SMatthew G Knepley 2805f1ad066SMatthew G Knepley Output Parameter: 281bb7acecfSBarry Smith . dm - The `DM` 2825f1ad066SMatthew G Knepley 2835f1ad066SMatthew G Knepley Level: intermediate 2845f1ad066SMatthew G Knepley 285bb7acecfSBarry Smith Note: 286bb7acecfSBarry Smith A `Vec` may not have a `DM` associated with it. 287bb7acecfSBarry Smith 2881cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecSetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 2895f1ad066SMatthew G Knepley @*/ 290d71ae5a4SJacob Faibussowitsch PetscErrorCode VecGetDM(Vec v, DM *dm) 291d71ae5a4SJacob Faibussowitsch { 2925f1ad066SMatthew G Knepley PetscFunctionBegin; 2935f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 2944f572ea9SToby Isaac PetscAssertPointer(dm, 2); 2959566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)v, "__PETSc_dm", (PetscObject *)dm)); 2963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2975f1ad066SMatthew G Knepley } 2985f1ad066SMatthew G Knepley 2995f1ad066SMatthew G Knepley /*@ 300bb7acecfSBarry Smith VecSetDM - Sets the `DM` defining the data layout of the vector. 3015f1ad066SMatthew G Knepley 30220f4b53cSBarry Smith Not Collective 3035f1ad066SMatthew G Knepley 3045f1ad066SMatthew G Knepley Input Parameters: 305bb7acecfSBarry Smith + v - The `Vec` 306bb7acecfSBarry Smith - dm - The `DM` 3075f1ad066SMatthew G Knepley 30820f4b53cSBarry Smith Level: developer 30920f4b53cSBarry Smith 31073ff1848SBarry Smith Notes: 311bb7acecfSBarry Smith This is rarely used, generally one uses `DMGetLocalVector()` or `DMGetGlobalVector()` to create a vector associated with a given `DM` 312d9805387SMatthew G. Knepley 313bb7acecfSBarry 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. 314bb7acecfSBarry Smith 3151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecGetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 3165f1ad066SMatthew G Knepley @*/ 317d71ae5a4SJacob Faibussowitsch PetscErrorCode VecSetDM(Vec v, DM dm) 318d71ae5a4SJacob Faibussowitsch { 3195f1ad066SMatthew G Knepley PetscFunctionBegin; 3205f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 1); 321d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 3229566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)v, "__PETSc_dm", (PetscObject)dm)); 3233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3245f1ad066SMatthew G Knepley } 3255f1ad066SMatthew G Knepley 326521d9a4cSLisandro Dalcin /*@C 327bb7acecfSBarry Smith DMSetISColoringType - Sets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 3288f1509bcSBarry Smith 32920f4b53cSBarry Smith Logically Collective 3308f1509bcSBarry Smith 3318f1509bcSBarry Smith Input Parameters: 332bb7acecfSBarry Smith + dm - the `DM` context 3338f1509bcSBarry Smith - ctype - the matrix type 3348f1509bcSBarry Smith 33520f4b53cSBarry Smith Options Database Key: 3368f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3378f1509bcSBarry Smith 3388f1509bcSBarry Smith Level: intermediate 3398f1509bcSBarry Smith 3401cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 341bb7acecfSBarry Smith `DMGetISColoringType()`, `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3428f1509bcSBarry Smith @*/ 343d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetISColoringType(DM dm, ISColoringType ctype) 344d71ae5a4SJacob Faibussowitsch { 3458f1509bcSBarry Smith PetscFunctionBegin; 3468f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3478f1509bcSBarry Smith dm->coloringtype = ctype; 3483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3498f1509bcSBarry Smith } 3508f1509bcSBarry Smith 3518f1509bcSBarry Smith /*@C 352bb7acecfSBarry Smith DMGetISColoringType - Gets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 353521d9a4cSLisandro Dalcin 35420f4b53cSBarry Smith Logically Collective 355521d9a4cSLisandro Dalcin 356521d9a4cSLisandro Dalcin Input Parameter: 357bb7acecfSBarry Smith . dm - the `DM` context 3588f1509bcSBarry Smith 3598f1509bcSBarry Smith Output Parameter: 3608f1509bcSBarry Smith . ctype - the matrix type 3618f1509bcSBarry Smith 36220f4b53cSBarry Smith Options Database Key: 3638f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3648f1509bcSBarry Smith 3658f1509bcSBarry Smith Level: intermediate 3668f1509bcSBarry Smith 3671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 36842747ad1SJacob Faibussowitsch `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3698f1509bcSBarry Smith @*/ 370d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetISColoringType(DM dm, ISColoringType *ctype) 371d71ae5a4SJacob Faibussowitsch { 3728f1509bcSBarry Smith PetscFunctionBegin; 3738f1509bcSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3748f1509bcSBarry Smith *ctype = dm->coloringtype; 3753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3768f1509bcSBarry Smith } 3778f1509bcSBarry Smith 3788f1509bcSBarry Smith /*@C 379bb7acecfSBarry Smith DMSetMatType - Sets the type of matrix created with `DMCreateMatrix()` 3808f1509bcSBarry Smith 38120f4b53cSBarry Smith Logically Collective 3828f1509bcSBarry Smith 3838f1509bcSBarry Smith Input Parameters: 384bb7acecfSBarry Smith + dm - the `DM` context 385bb7acecfSBarry Smith - ctype - the matrix type, for example `MATMPIAIJ` 386521d9a4cSLisandro Dalcin 38720f4b53cSBarry Smith Options Database Key: 388bb7acecfSBarry Smith . -dm_mat_type ctype - the type of the matrix to create, for example mpiaij 389521d9a4cSLisandro Dalcin 390521d9a4cSLisandro Dalcin Level: intermediate 391521d9a4cSLisandro Dalcin 39242747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `MatType`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMGetMatType()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()` 393521d9a4cSLisandro Dalcin @*/ 394d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatType(DM dm, MatType ctype) 395d71ae5a4SJacob Faibussowitsch { 39632546409SMatthew G. Knepley char *tmp; 39732546409SMatthew G. Knepley 398521d9a4cSLisandro Dalcin PetscFunctionBegin; 399521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 40032546409SMatthew G. Knepley PetscAssertPointer(ctype, 2); 40132546409SMatthew G. Knepley tmp = (char *)dm->mattype; 4029566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype, (char **)&dm->mattype)); 40332546409SMatthew G. Knepley PetscCall(PetscFree(tmp)); 4043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 405521d9a4cSLisandro Dalcin } 406521d9a4cSLisandro Dalcin 407c0dedaeaSBarry Smith /*@C 40820f4b53cSBarry Smith DMGetMatType - Gets the type of matrix that would be created with `DMCreateMatrix()` 409c0dedaeaSBarry Smith 41020f4b53cSBarry Smith Logically Collective 411c0dedaeaSBarry Smith 412c0dedaeaSBarry Smith Input Parameter: 413bb7acecfSBarry Smith . dm - the `DM` context 414c0dedaeaSBarry Smith 415c0dedaeaSBarry Smith Output Parameter: 416c0dedaeaSBarry Smith . ctype - the matrix type 417c0dedaeaSBarry Smith 418c0dedaeaSBarry Smith Level: intermediate 419c0dedaeaSBarry Smith 42042747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMSetMatType()` 421c0dedaeaSBarry Smith @*/ 422d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetMatType(DM dm, MatType *ctype) 423d71ae5a4SJacob Faibussowitsch { 424c0dedaeaSBarry Smith PetscFunctionBegin; 425c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 426c0dedaeaSBarry Smith *ctype = dm->mattype; 4273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 428c0dedaeaSBarry Smith } 429c0dedaeaSBarry Smith 430c688c046SMatthew G Knepley /*@ 431bb7acecfSBarry Smith MatGetDM - Gets the `DM` defining the data layout of the matrix 432c688c046SMatthew G Knepley 43320f4b53cSBarry Smith Not Collective 434c688c046SMatthew G Knepley 435c688c046SMatthew G Knepley Input Parameter: 436bb7acecfSBarry Smith . A - The `Mat` 437c688c046SMatthew G Knepley 438c688c046SMatthew G Knepley Output Parameter: 439bb7acecfSBarry Smith . dm - The `DM` 440c688c046SMatthew G Knepley 441c688c046SMatthew G Knepley Level: intermediate 442c688c046SMatthew G Knepley 443bb7acecfSBarry Smith Note: 444bb7acecfSBarry Smith A matrix may not have a `DM` associated with it 445bb7acecfSBarry Smith 44673ff1848SBarry Smith Developer Note: 447bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with the `Mat` through a `PetscObjectCompose()` operation 4488f1509bcSBarry Smith 4491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatSetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 450c688c046SMatthew G Knepley @*/ 451d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetDM(Mat A, DM *dm) 452d71ae5a4SJacob Faibussowitsch { 453c688c046SMatthew G Knepley PetscFunctionBegin; 454c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4554f572ea9SToby Isaac PetscAssertPointer(dm, 2); 4569566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_dm", (PetscObject *)dm)); 4573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 458c688c046SMatthew G Knepley } 459c688c046SMatthew G Knepley 460c688c046SMatthew G Knepley /*@ 461bb7acecfSBarry Smith MatSetDM - Sets the `DM` defining the data layout of the matrix 462c688c046SMatthew G Knepley 46320f4b53cSBarry Smith Not Collective 464c688c046SMatthew G Knepley 465c688c046SMatthew G Knepley Input Parameters: 46620f4b53cSBarry Smith + A - The `Mat` 46720f4b53cSBarry Smith - dm - The `DM` 468c688c046SMatthew G Knepley 469bb7acecfSBarry Smith Level: developer 470c688c046SMatthew G Knepley 471bb7acecfSBarry Smith Note: 472bb7acecfSBarry Smith This is rarely used in practice, rather `DMCreateMatrix()` is used to create a matrix associated with a particular `DM` 473bb7acecfSBarry Smith 47473ff1848SBarry Smith Developer Note: 475bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with 476bb7acecfSBarry Smith the `Mat` through a `PetscObjectCompose()` operation 4778f1509bcSBarry Smith 4781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatGetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 479c688c046SMatthew G Knepley @*/ 480d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetDM(Mat A, DM dm) 481d71ae5a4SJacob Faibussowitsch { 482c688c046SMatthew G Knepley PetscFunctionBegin; 483c688c046SMatthew G Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4848865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 4859566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_dm", (PetscObject)dm)); 4863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 487c688c046SMatthew G Knepley } 488c688c046SMatthew G Knepley 4899a42bb27SBarry Smith /*@C 490bb7acecfSBarry Smith DMSetOptionsPrefix - Sets the prefix prepended to all option names when searching through the options database 4919a42bb27SBarry Smith 49220f4b53cSBarry Smith Logically Collective 4939a42bb27SBarry Smith 494d8d19677SJose E. Roman Input Parameters: 49560225df5SJacob Faibussowitsch + dm - the `DM` context 496bb7acecfSBarry Smith - prefix - the prefix to prepend 4979a42bb27SBarry Smith 49820f4b53cSBarry Smith Level: advanced 49920f4b53cSBarry Smith 50020f4b53cSBarry Smith Note: 5019a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 5029a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 5039a42bb27SBarry Smith 5041cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscObjectSetOptionsPrefix()`, `DMSetFromOptions()` 5059a42bb27SBarry Smith @*/ 506d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOptionsPrefix(DM dm, const char prefix[]) 507d71ae5a4SJacob Faibussowitsch { 5089a42bb27SBarry Smith PetscFunctionBegin; 5099a42bb27SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5109566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm, prefix)); 5111baa6e33SBarry Smith if (dm->sf) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sf, prefix)); 5121baa6e33SBarry Smith if (dm->sectionSF) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF, prefix)); 5133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5149a42bb27SBarry Smith } 5159a42bb27SBarry Smith 51631697293SDave May /*@C 517da81f932SPierre Jolivet DMAppendOptionsPrefix - Appends an additional string to an already existing prefix used for searching for 518bb7acecfSBarry Smith `DM` options in the options database. 51931697293SDave May 52020f4b53cSBarry Smith Logically Collective 52131697293SDave May 52231697293SDave May Input Parameters: 523bb7acecfSBarry Smith + dm - the `DM` context 524bb7acecfSBarry Smith - prefix - the string to append to the current prefix 52531697293SDave May 52620f4b53cSBarry Smith Level: advanced 52720f4b53cSBarry Smith 52820f4b53cSBarry Smith Note: 529bb7acecfSBarry 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. 53031697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 53131697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 53231697293SDave May 5331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetOptionsPrefix()`, `DMGetOptionsPrefix()`, `PetscObjectAppendOptionsPrefix()`, `DMSetFromOptions()` 53431697293SDave May @*/ 535d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAppendOptionsPrefix(DM dm, const char prefix[]) 536d71ae5a4SJacob Faibussowitsch { 53731697293SDave May PetscFunctionBegin; 53831697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5399566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)dm, prefix)); 5403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54131697293SDave May } 54231697293SDave May 54331697293SDave May /*@C 54431697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 545bb7acecfSBarry Smith DM options in the options database. 54631697293SDave May 54731697293SDave May Not Collective 54831697293SDave May 5492fe279fdSBarry Smith Input Parameter: 550bb7acecfSBarry Smith . dm - the `DM` context 55131697293SDave May 5522fe279fdSBarry Smith Output Parameter: 55331697293SDave May . prefix - pointer to the prefix string used is returned 55431697293SDave May 55531697293SDave May Level: advanced 55631697293SDave May 55773ff1848SBarry Smith Fortran Note: 55820f4b53cSBarry Smith Pass in a string 'prefix' of 55920f4b53cSBarry Smith sufficient length to hold the prefix. 56020f4b53cSBarry Smith 5611cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetOptionsPrefix()`, `DMAppendOptionsPrefix()`, `DMSetFromOptions()` 56231697293SDave May @*/ 563d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOptionsPrefix(DM dm, const char *prefix[]) 564d71ae5a4SJacob Faibussowitsch { 56531697293SDave May PetscFunctionBegin; 56631697293SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5679566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, prefix)); 5683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56931697293SDave May } 57031697293SDave May 57162e5d2d2SJDBetteridge static PetscErrorCode DMCountNonCyclicReferences_Internal(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 572d71ae5a4SJacob Faibussowitsch { 5736eb26441SStefano Zampini PetscInt refct = ((PetscObject)dm)->refct; 57488bdff64SToby Isaac 57588bdff64SToby Isaac PetscFunctionBegin; 576aab5bcd8SJed Brown *ncrefct = 0; 57788bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 57888bdff64SToby Isaac refct--; 57988bdff64SToby Isaac if (recurseCoarse) { 58088bdff64SToby Isaac PetscInt coarseCount; 58188bdff64SToby Isaac 58262e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE, &coarseCount)); 58388bdff64SToby Isaac refct += coarseCount; 58488bdff64SToby Isaac } 58588bdff64SToby Isaac } 58688bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 58788bdff64SToby Isaac refct--; 58888bdff64SToby Isaac if (recurseFine) { 58988bdff64SToby Isaac PetscInt fineCount; 59088bdff64SToby Isaac 59162e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(dm->fineMesh, PETSC_FALSE, PETSC_TRUE, &fineCount)); 59288bdff64SToby Isaac refct += fineCount; 59388bdff64SToby Isaac } 59488bdff64SToby Isaac } 59588bdff64SToby Isaac *ncrefct = refct; 5963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 59788bdff64SToby Isaac } 59888bdff64SToby Isaac 59962e5d2d2SJDBetteridge /* Generic wrapper for DMCountNonCyclicReferences_Internal() */ 60062e5d2d2SJDBetteridge PetscErrorCode DMCountNonCyclicReferences(PetscObject dm, PetscInt *ncrefct) 60162e5d2d2SJDBetteridge { 60262e5d2d2SJDBetteridge PetscFunctionBegin; 60362e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal((DM)dm, PETSC_TRUE, PETSC_TRUE, ncrefct)); 6043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 60562e5d2d2SJDBetteridge } 60662e5d2d2SJDBetteridge 607d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 608d71ae5a4SJacob Faibussowitsch { 6095d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 610354557abSToby Isaac 611354557abSToby Isaac PetscFunctionBegin; 612354557abSToby Isaac /* destroy the labels */ 613354557abSToby Isaac while (next) { 614354557abSToby Isaac DMLabelLink tmp = next->next; 615354557abSToby Isaac 6165d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 617ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 6189566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 6199566063dSJacob Faibussowitsch PetscCall(PetscFree(next)); 620354557abSToby Isaac next = tmp; 621354557abSToby Isaac } 6225d80c0bfSVaclav Hapla dm->labels = NULL; 6233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 624354557abSToby Isaac } 625354557abSToby Isaac 62666976f2fSJacob Faibussowitsch static PetscErrorCode DMDestroyCoordinates_Private(DMCoordinates *c) 627d71ae5a4SJacob Faibussowitsch { 6286858538eSMatthew G. Knepley PetscFunctionBegin; 6296858538eSMatthew G. Knepley c->dim = PETSC_DEFAULT; 6306858538eSMatthew G. Knepley PetscCall(DMDestroy(&c->dm)); 6316858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->x)); 6326858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->xl)); 6336858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&c->field)); 6343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6356858538eSMatthew G. Knepley } 6366858538eSMatthew G. Knepley 6371fb7b255SJunchao Zhang /*@C 638bb7acecfSBarry Smith DMDestroy - Destroys a `DM`. 63947c6ae99SBarry Smith 64020f4b53cSBarry Smith Collective 64147c6ae99SBarry Smith 64247c6ae99SBarry Smith Input Parameter: 643bb7acecfSBarry Smith . dm - the `DM` object to destroy 64447c6ae99SBarry Smith 64547c6ae99SBarry Smith Level: developer 64647c6ae99SBarry Smith 6471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMType`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 64847c6ae99SBarry Smith @*/ 649d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroy(DM *dm) 650d71ae5a4SJacob Faibussowitsch { 6516eb26441SStefano Zampini PetscInt cnt; 65247c6ae99SBarry Smith 65347c6ae99SBarry Smith PetscFunctionBegin; 6543ba16761SJacob Faibussowitsch if (!*dm) PetscFunctionReturn(PETSC_SUCCESS); 655f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*dm, DM_CLASSID, 1); 65687e657c6SBarry Smith 65788bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 65862e5d2d2SJDBetteridge PetscCall(DMCountNonCyclicReferences_Internal(*dm, PETSC_TRUE, PETSC_TRUE, &cnt)); 659f4f49eeaSPierre Jolivet --((PetscObject)*dm)->refct; 6609371c9d4SSatish Balay if (--cnt > 0) { 6619371c9d4SSatish Balay *dm = NULL; 6623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6639371c9d4SSatish Balay } 664f4f49eeaSPierre Jolivet if (((PetscObject)*dm)->refct < 0) PetscFunctionReturn(PETSC_SUCCESS); 665f4f49eeaSPierre Jolivet ((PetscObject)*dm)->refct = 0; 6666eb26441SStefano Zampini 6679566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(*dm)); 6689566063dSJacob Faibussowitsch PetscCall(DMClearLocalVectors(*dm)); 669974ca4ecSStefano Zampini PetscCall(DMClearNamedGlobalVectors(*dm)); 670974ca4ecSStefano Zampini PetscCall(DMClearNamedLocalVectors(*dm)); 6712348bcf4SPeter Brune 672b17ce1afSJed Brown /* Destroy the list of hooks */ 673c833c3b5SJed Brown { 674c833c3b5SJed Brown DMCoarsenHookLink link, next; 675b17ce1afSJed Brown for (link = (*dm)->coarsenhook; link; link = next) { 676b17ce1afSJed Brown next = link->next; 6779566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 678b17ce1afSJed Brown } 6790298fd71SBarry Smith (*dm)->coarsenhook = NULL; 680c833c3b5SJed Brown } 681c833c3b5SJed Brown { 682c833c3b5SJed Brown DMRefineHookLink link, next; 683c833c3b5SJed Brown for (link = (*dm)->refinehook; link; link = next) { 684c833c3b5SJed Brown next = link->next; 6859566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 686c833c3b5SJed Brown } 6870298fd71SBarry Smith (*dm)->refinehook = NULL; 688c833c3b5SJed Brown } 689be081cd6SPeter Brune { 690be081cd6SPeter Brune DMSubDomainHookLink link, next; 691be081cd6SPeter Brune for (link = (*dm)->subdomainhook; link; link = next) { 692be081cd6SPeter Brune next = link->next; 6939566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 694be081cd6SPeter Brune } 6950298fd71SBarry Smith (*dm)->subdomainhook = NULL; 696be081cd6SPeter Brune } 697baf369e7SPeter Brune { 698baf369e7SPeter Brune DMGlobalToLocalHookLink link, next; 699baf369e7SPeter Brune for (link = (*dm)->gtolhook; link; link = next) { 700baf369e7SPeter Brune next = link->next; 7019566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 702baf369e7SPeter Brune } 7030298fd71SBarry Smith (*dm)->gtolhook = NULL; 704baf369e7SPeter Brune } 705d4d07f1eSToby Isaac { 706d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, next; 707d4d07f1eSToby Isaac for (link = (*dm)->ltoghook; link; link = next) { 708d4d07f1eSToby Isaac next = link->next; 7099566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 710d4d07f1eSToby Isaac } 711d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 712d4d07f1eSToby Isaac } 713aa1993deSMatthew G Knepley /* Destroy the work arrays */ 714aa1993deSMatthew G Knepley { 715aa1993deSMatthew G Knepley DMWorkLink link, next; 716936381afSPierre 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); 717aa1993deSMatthew G Knepley for (link = (*dm)->workin; link; link = next) { 718aa1993deSMatthew G Knepley next = link->next; 7199566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 7209566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 721aa1993deSMatthew G Knepley } 7220298fd71SBarry Smith (*dm)->workin = NULL; 723aa1993deSMatthew G Knepley } 724c58f1c22SToby Isaac /* destroy the labels */ 7259566063dSJacob Faibussowitsch PetscCall(DMDestroyLabelLinkList_Internal(*dm)); 726f4cdcedcSVaclav Hapla /* destroy the fields */ 7279566063dSJacob Faibussowitsch PetscCall(DMClearFields(*dm)); 728f4cdcedcSVaclav Hapla /* destroy the boundaries */ 729e6f8dbb6SToby Isaac { 730e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 731e6f8dbb6SToby Isaac while (next) { 732e6f8dbb6SToby Isaac DMBoundary b = next; 733e6f8dbb6SToby Isaac 734e6f8dbb6SToby Isaac next = b->next; 7359566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 736e6f8dbb6SToby Isaac } 737e6f8dbb6SToby Isaac } 738b17ce1afSJed Brown 7399566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmksp)); 7409566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmsnes)); 7419566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmts)); 74252536dc3SBarry Smith 74348a46eb9SPierre Jolivet if ((*dm)->ctx && (*dm)->ctxdestroy) PetscCall((*(*dm)->ctxdestroy)(&(*dm)->ctx)); 7449566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&(*dm)->fd)); 7459566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap)); 7469566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->vectype)); 7479566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->mattype)); 74888ed4aceSMatthew G Knepley 7499566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->localSection)); 7509566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->globalSection)); 751adc21957SMatthew G. Knepley PetscCall(PetscFree((*dm)->reorderSectionType)); 7529566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&(*dm)->map)); 7539566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->defaultConstraint.section)); 7549566063dSJacob Faibussowitsch PetscCall(MatDestroy(&(*dm)->defaultConstraint.mat)); 7559566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sf)); 7569566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sectionSF)); 75748a46eb9SPierre Jolivet if ((*dm)->sfNatural) PetscCall(PetscSFDestroy(&(*dm)->sfNatural)); 7589566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)(*dm)->sfMigration)); 759e4d5475eSStefano Zampini PetscCall(DMClearAuxiliaryVec(*dm)); 7609566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&(*dm)->auxData)); 76148a46eb9SPierre Jolivet if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) PetscCall(DMSetFineDM((*dm)->coarseMesh, NULL)); 7626eb26441SStefano Zampini 7639566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->coarseMesh)); 76448a46eb9SPierre Jolivet if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) PetscCall(DMSetCoarseDM((*dm)->fineMesh, NULL)); 7659566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->fineMesh)); 7664fb89dddSMatthew G. Knepley PetscCall(PetscFree((*dm)->Lstart)); 7679566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->L)); 7689566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->maxCell)); 7696858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[0])); 7706858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[1])); 7719566063dSJacob Faibussowitsch if ((*dm)->transformDestroy) PetscCall((*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx)); 7729566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->transformDM)); 7739566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*dm)->transform)); 774ddedc8f6SJames Wright for (PetscInt i = 0; i < (*dm)->periodic.num_affines; i++) { 775ddedc8f6SJames Wright PetscCall(VecScatterDestroy(&(*dm)->periodic.affine_to_local[i])); 776ddedc8f6SJames Wright PetscCall(VecDestroy(&(*dm)->periodic.affine[i])); 777ddedc8f6SJames Wright } 778ddedc8f6SJames Wright if ((*dm)->periodic.num_affines > 0) PetscCall(PetscFree2((*dm)->periodic.affine_to_local, (*dm)->periodic.affine)); 7796636e97aSMatthew G Knepley 7809566063dSJacob Faibussowitsch PetscCall(DMClearDS(*dm)); 7819566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->dmBC)); 782e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 7839566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*dm)); 784732e2eb9SMatthew G Knepley 785213acdd3SPierre Jolivet PetscTryTypeMethod(*dm, destroy); 7869566063dSJacob Faibussowitsch PetscCall(DMMonitorCancel(*dm)); 787d2b2dc1eSMatthew G. Knepley PetscCall(DMCeedDestroy(&(*dm)->dmceed)); 788f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 7899566063dSJacob Faibussowitsch PetscCallCEED(CeedElemRestrictionDestroy(&(*dm)->ceedERestrict)); 7909566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*dm)->ceed)); 791f918ec44SMatthew G. Knepley #endif 792435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 7939566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(dm)); 7943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 79547c6ae99SBarry Smith } 79647c6ae99SBarry Smith 797d7bf68aeSBarry Smith /*@ 798bb7acecfSBarry Smith DMSetUp - sets up the data structures inside a `DM` object 799d7bf68aeSBarry Smith 80020f4b53cSBarry Smith Collective 801d7bf68aeSBarry Smith 802d7bf68aeSBarry Smith Input Parameter: 803bb7acecfSBarry Smith . dm - the `DM` object to setup 804d7bf68aeSBarry Smith 805bb7acecfSBarry Smith Level: intermediate 806d7bf68aeSBarry Smith 807bb7acecfSBarry Smith Note: 808bb7acecfSBarry Smith This is usually called after various parameter setting operations and `DMSetFromOptions()` are called on the `DM` 809bb7acecfSBarry Smith 8101cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreate()`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 811d7bf68aeSBarry Smith @*/ 812d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUp(DM dm) 813d71ae5a4SJacob Faibussowitsch { 814d7bf68aeSBarry Smith PetscFunctionBegin; 815171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8163ba16761SJacob Faibussowitsch if (dm->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 817dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setup); 8188387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 8193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 820d7bf68aeSBarry Smith } 821d7bf68aeSBarry Smith 822d7bf68aeSBarry Smith /*@ 823bb7acecfSBarry Smith DMSetFromOptions - sets parameters in a `DM` from the options database 824d7bf68aeSBarry Smith 82520f4b53cSBarry Smith Collective 826d7bf68aeSBarry Smith 827d7bf68aeSBarry Smith Input Parameter: 828bb7acecfSBarry Smith . dm - the `DM` object to set options for 829d7bf68aeSBarry Smith 83020f4b53cSBarry Smith Options Database Keys: 831bb7acecfSBarry Smith + -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 832bb7acecfSBarry Smith . -dm_vec_type <type> - type of vector to create inside `DM` 833bb7acecfSBarry Smith . -dm_mat_type <type> - type of matrix to create inside `DM` 834a4ea9b21SRichard Tran Mills . -dm_is_coloring_type - <global or local> 83520f4b53cSBarry 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` 83620f4b53cSBarry Smith . -dm_plex_filename <str> - File containing a mesh 8379318fe57SMatthew G. Knepley . -dm_plex_boundary_filename <str> - File containing a mesh boundary 838cd7e8a5eSksagiyam . -dm_plex_name <str> - Name of the mesh in the file 8395dca41c3SJed Brown . -dm_plex_shape <shape> - The domain shape, such as `BOX`, `SPHERE`, etc. 8409318fe57SMatthew G. Knepley . -dm_plex_cell <ct> - Cell shape 8419318fe57SMatthew G. Knepley . -dm_plex_reference_cell_domain <bool> - Use a reference cell domain 8429318fe57SMatthew G. Knepley . -dm_plex_dim <dim> - Set the topological dimension 843bb7acecfSBarry Smith . -dm_plex_simplex <bool> - `PETSC_TRUE` for simplex elements, `PETSC_FALSE` for tensor elements 844bb7acecfSBarry Smith . -dm_plex_interpolate <bool> - `PETSC_TRUE` turns on topological interpolation (creating edges and faces) 8459318fe57SMatthew G. Knepley . -dm_plex_scale <sc> - Scale factor for mesh coordinates 846be664eb1SMatthew G. Knepley . -dm_coord_remap <bool> - Map coordinates using a function 847be664eb1SMatthew G. Knepley . -dm_coord_map <mapname> - Select a builtin coordinate map 848be664eb1SMatthew G. Knepley . -dm_coord_map_params <p0,p1,p2,...> - Set coordinate mapping parameters 8499318fe57SMatthew G. Knepley . -dm_plex_box_faces <m,n,p> - Number of faces along each dimension 8509318fe57SMatthew G. Knepley . -dm_plex_box_lower <x,y,z> - Specify lower-left-bottom coordinates for the box 8519318fe57SMatthew G. Knepley . -dm_plex_box_upper <x,y,z> - Specify upper-right-top coordinates for the box 852bb7acecfSBarry Smith . -dm_plex_box_bd <bx,by,bz> - Specify the `DMBoundaryType` for each direction 8539318fe57SMatthew G. Knepley . -dm_plex_sphere_radius <r> - The sphere radius 8549318fe57SMatthew G. Knepley . -dm_plex_ball_radius <r> - Radius of the ball 8559318fe57SMatthew G. Knepley . -dm_plex_cylinder_bd <bz> - Boundary type in the z direction 8569318fe57SMatthew G. Knepley . -dm_plex_cylinder_num_wedges <n> - Number of wedges around the cylinder 857bdf63967SMatthew G. Knepley . -dm_plex_reorder <order> - Reorder the mesh using the specified algorithm 8589318fe57SMatthew G. Knepley . -dm_refine_pre <n> - The number of refinements before distribution 8599318fe57SMatthew G. Knepley . -dm_refine_uniform_pre <bool> - Flag for uniform refinement before distribution 8609318fe57SMatthew G. Knepley . -dm_refine_volume_limit_pre <v> - The maximum cell volume after refinement before distribution 8619318fe57SMatthew G. Knepley . -dm_refine <n> - The number of refinements after distribution 862bdf63967SMatthew G. Knepley . -dm_extrude <l> - Activate extrusion and specify the number of layers to extrude 863d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers 864d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding 865d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface 866d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction 867d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer 868909dfd52SMatthew G. Knepley . -dm_plex_create_fv_ghost_cells - Flag to create finite volume ghost cells on the boundary 869909dfd52SMatthew G. Knepley . -dm_plex_fv_ghost_cells_label <name> - Label name for ghost cells boundary 8709318fe57SMatthew G. Knepley . -dm_distribute <bool> - Flag to redistribute a mesh among processes 8719318fe57SMatthew G. Knepley . -dm_distribute_overlap <n> - The size of the overlap halo 8729318fe57SMatthew G. Knepley . -dm_plex_adj_cone <bool> - Set adjacency direction 87320f4b53cSBarry Smith . -dm_plex_adj_closure <bool> - Set adjacency size 874d2b2dc1eSMatthew G. Knepley . -dm_plex_use_ceed <bool> - Use LibCEED as the FEM backend 87520f4b53cSBarry Smith . -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - `DMPlexCheckSymmetry()` 876bb7acecfSBarry Smith . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - `DMPlexCheckSkeleton()` 877bb7acecfSBarry 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()` 878bb7acecfSBarry Smith . -dm_plex_check_geometry - Check that cells have positive volume - `DMPlexCheckGeometry()` 879bb7acecfSBarry Smith . -dm_plex_check_pointsf - Check some necessary conditions for `PointSF` - `DMPlexCheckPointSF()` 880bb7acecfSBarry Smith . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - `DMPlexCheckInterfaceCones()` 881384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 882d7bf68aeSBarry Smith 88395eb5ee5SVaclav Hapla Level: intermediate 88495eb5ee5SVaclav Hapla 8851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 886bb7acecfSBarry Smith `DMPlexCheckSymmetry()`, `DMPlexCheckSkeleton()`, `DMPlexCheckFaces()`, `DMPlexCheckGeometry()`, `DMPlexCheckPointSF()`, `DMPlexCheckInterfaceCones()`, 88760225df5SJacob Faibussowitsch `DMSetOptionsPrefix()`, `DMType`, `DMPLEX`, `DMDA` 888d7bf68aeSBarry Smith @*/ 889d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFromOptions(DM dm) 890d71ae5a4SJacob Faibussowitsch { 8917781c08eSBarry Smith char typeName[256]; 892ca266f36SBarry Smith PetscBool flg; 893d7bf68aeSBarry Smith 894d7bf68aeSBarry Smith PetscFunctionBegin; 895171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89649be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 8979566063dSJacob Faibussowitsch if (dm->sf) PetscCall(PetscSFSetFromOptions(dm->sf)); 8989566063dSJacob Faibussowitsch if (dm->sectionSF) PetscCall(PetscSFSetFromOptions(dm->sectionSF)); 899dd4c3f67SMatthew G. Knepley if (dm->coordinates[0].dm) PetscCall(DMSetFromOptions(dm->coordinates[0].dm)); 900d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)dm); 9019566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-dm_preallocate_only", "only preallocate matrix, but do not set column indices", "DMSetMatrixPreallocateOnly", dm->prealloc_only, &dm->prealloc_only, NULL)); 9029566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_vec_type", "Vector type used for created vectors", "DMSetVecType", VecList, dm->vectype, typeName, 256, &flg)); 9031baa6e33SBarry Smith if (flg) PetscCall(DMSetVecType(dm, typeName)); 9049566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_mat_type", "Matrix type used for created matrices", "DMSetMatType", MatList, dm->mattype ? dm->mattype : typeName, typeName, sizeof(typeName), &flg)); 9051baa6e33SBarry Smith if (flg) PetscCall(DMSetMatType(dm, typeName)); 906863027abSJed Brown PetscCall(PetscOptionsEnum("-dm_blocking_type", "Topological point or field node blocking", "DMSetBlockingType", DMBlockingTypes, (PetscEnum)dm->blocking_type, (PetscEnum *)&dm->blocking_type, NULL)); 9079566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-dm_is_coloring_type", "Global or local coloring of Jacobian", "DMSetISColoringType", ISColoringTypes, (PetscEnum)dm->coloringtype, (PetscEnum *)&dm->coloringtype, NULL)); 9089566063dSJacob 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)); 909eb9d3e4dSMatthew G. Knepley PetscCall(PetscOptionsBool("-dm_ignore_perm_output", "Ignore the local section permutation on output", "DMGetOutputDM", dm->ignorePermOutput, &dm->ignorePermOutput, NULL)); 910dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, setfromoptions, PetscOptionsObject); 911f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 912dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)dm, PetscOptionsObject)); 913d0609cedSBarry Smith PetscOptionsEnd(); 9143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 915d7bf68aeSBarry Smith } 916d7bf68aeSBarry Smith 917fc9bc008SSatish Balay /*@C 918bb7acecfSBarry Smith DMViewFromOptions - View a `DM` in a particular way based on a request in the options database 919fe2efc57SMark 92020f4b53cSBarry Smith Collective 921fe2efc57SMark 922fe2efc57SMark Input Parameters: 923bb7acecfSBarry Smith + dm - the `DM` object 92420f4b53cSBarry Smith . obj - optional object that provides the prefix for the options database (if `NULL` then the prefix in obj is used) 92560225df5SJacob Faibussowitsch - name - option string that is used to activate viewing 926fe2efc57SMark 927fe2efc57SMark Level: intermediate 928bb7acecfSBarry Smith 929bb7acecfSBarry Smith Note: 930bb7acecfSBarry Smith See `PetscObjectViewFromOptions()` for a list of values that can be provided in the options database to determine how the `DM` is viewed 931bb7acecfSBarry Smith 93260225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `PetscObjectViewFromOptions()`, `DMCreate()` 933fe2efc57SMark @*/ 934d71ae5a4SJacob Faibussowitsch PetscErrorCode DMViewFromOptions(DM dm, PetscObject obj, const char name[]) 935d71ae5a4SJacob Faibussowitsch { 936fe2efc57SMark PetscFunctionBegin; 937fe2efc57SMark PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9389566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)dm, obj, name)); 9393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 940fe2efc57SMark } 941fe2efc57SMark 942fe2efc57SMark /*@C 943bb7acecfSBarry 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 944bb7acecfSBarry Smith save the `DM` in a binary file to be loaded later or create a visualization of the `DM` 94547c6ae99SBarry Smith 94620f4b53cSBarry Smith Collective 94747c6ae99SBarry Smith 948d8d19677SJose E. Roman Input Parameters: 949bb7acecfSBarry Smith + dm - the `DM` object to view 95047c6ae99SBarry Smith - v - the viewer 95147c6ae99SBarry Smith 95220f4b53cSBarry Smith Level: beginner 95320f4b53cSBarry Smith 95473ff1848SBarry Smith Note: 955bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` as the `PetscViewerFormat` one can save multiple `DMPLEX` 956bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 957bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 958cd7e8a5eSksagiyam 9591cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewer`, `PetscViewerFormat`, `PetscViewerSetFormat()`, `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMLoad()`, `PetscObjectSetName()` 96047c6ae99SBarry Smith @*/ 961d71ae5a4SJacob Faibussowitsch PetscErrorCode DMView(DM dm, PetscViewer v) 962d71ae5a4SJacob Faibussowitsch { 96332c0f0efSBarry Smith PetscBool isbinary; 96476a8abe0SBarry Smith PetscMPIInt size; 96576a8abe0SBarry Smith PetscViewerFormat format; 96647c6ae99SBarry Smith 96747c6ae99SBarry Smith PetscFunctionBegin; 968171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 96948a46eb9SPierre Jolivet if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm), &v)); 970b1b135c8SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2); 97174903a4fSStefano Zampini /* Ideally, we would like to have this test on. 97274903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 97374903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 97474903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 97574903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 97674903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 97774903a4fSStefano Zampini in an error here */ 97874903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9799566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckWritable(v)); 980b1b135c8SBarry Smith 9819566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(v, &format)); 9829566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 9833ba16761SJacob Faibussowitsch if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS); 9849566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)dm, v)); 9859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERBINARY, &isbinary)); 98632c0f0efSBarry Smith if (isbinary) { 98755849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 98832c0f0efSBarry Smith char type[256]; 98932c0f0efSBarry Smith 9909566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, &classid, 1, PETSC_INT)); 991c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(type, ((PetscObject)dm)->type_name, sizeof(type))); 9929566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v, type, 256, PETSC_CHAR)); 99332c0f0efSBarry Smith } 994dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, view, v); 9953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99647c6ae99SBarry Smith } 99747c6ae99SBarry Smith 99847c6ae99SBarry Smith /*@ 999bb7acecfSBarry 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, 1000bb7acecfSBarry Smith that is it has no ghost locations. 100147c6ae99SBarry Smith 100220f4b53cSBarry Smith Collective 100347c6ae99SBarry Smith 100447c6ae99SBarry Smith Input Parameter: 1005bb7acecfSBarry Smith . dm - the `DM` object 100647c6ae99SBarry Smith 100747c6ae99SBarry Smith Output Parameter: 100847c6ae99SBarry Smith . vec - the global vector 100947c6ae99SBarry Smith 1010073dac72SJed Brown Level: beginner 101147c6ae99SBarry Smith 10121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1013bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 101447c6ae99SBarry Smith @*/ 1015d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector(DM dm, Vec *vec) 1016d71ae5a4SJacob Faibussowitsch { 101747c6ae99SBarry Smith PetscFunctionBegin; 1018171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10194f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1020dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createglobalvector, vec); 102176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1022c6b011d8SStefano Zampini DM vdm; 1023c6b011d8SStefano Zampini 10249566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10257a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1026c6b011d8SStefano Zampini } 10273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 102847c6ae99SBarry Smith } 102947c6ae99SBarry Smith 103047c6ae99SBarry Smith /*@ 1031bb7acecfSBarry Smith DMCreateLocalVector - Creates a local vector from a `DM` object. 103247c6ae99SBarry Smith 103347c6ae99SBarry Smith Not Collective 103447c6ae99SBarry Smith 103547c6ae99SBarry Smith Input Parameter: 1036bb7acecfSBarry Smith . dm - the `DM` object 103747c6ae99SBarry Smith 103847c6ae99SBarry Smith Output Parameter: 103947c6ae99SBarry Smith . vec - the local vector 104047c6ae99SBarry Smith 1041073dac72SJed Brown Level: beginner 104247c6ae99SBarry Smith 104320f4b53cSBarry Smith Note: 1044bb7acecfSBarry 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. 1045bb7acecfSBarry Smith 10461cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `Vec`, `DMCreateGlobalVector()`, `DMGetLocalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 1047bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 104847c6ae99SBarry Smith @*/ 1049d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector(DM dm, Vec *vec) 1050d71ae5a4SJacob Faibussowitsch { 105147c6ae99SBarry Smith PetscFunctionBegin; 1052171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10534f572ea9SToby Isaac PetscAssertPointer(vec, 2); 1054dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalvector, vec); 105576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1056c6b011d8SStefano Zampini DM vdm; 1057c6b011d8SStefano Zampini 10589566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec, &vdm)); 10597a8be351SBarry Smith PetscCheck(vdm, PETSC_COMM_SELF, PETSC_ERR_LIB, "DM type '%s' did not attach the DM to the vector", ((PetscObject)dm)->type_name); 1060c6b011d8SStefano Zampini } 10613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 106247c6ae99SBarry Smith } 106347c6ae99SBarry Smith 10641411c6eeSJed Brown /*@ 1065bb7acecfSBarry Smith DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a `DM`. 10661411c6eeSJed Brown 106720f4b53cSBarry Smith Collective 10681411c6eeSJed Brown 10691411c6eeSJed Brown Input Parameter: 1070bb7acecfSBarry Smith . dm - the `DM` that provides the mapping 10711411c6eeSJed Brown 10721411c6eeSJed Brown Output Parameter: 10731411c6eeSJed Brown . ltog - the mapping 10741411c6eeSJed Brown 1075bb7acecfSBarry Smith Level: advanced 10761411c6eeSJed Brown 10771411c6eeSJed Brown Notes: 1078bb7acecfSBarry Smith The global to local mapping allows one to set values into the global vector or matrix using `VecSetValuesLocal()` and `MatSetValuesLocal()` 10791411c6eeSJed Brown 1080bb7acecfSBarry Smith Vectors obtained with `DMCreateGlobalVector()` and matrices obtained with `DMCreateMatrix()` already contain the global mapping so you do 1081bb7acecfSBarry Smith need to use this function with those objects. 1082bb7acecfSBarry Smith 1083bb7acecfSBarry Smith This mapping can then be used by `VecSetLocalToGlobalMapping()` or `MatSetLocalToGlobalMapping()`. 1084bb7acecfSBarry Smith 108560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `VecSetLocalToGlobalMapping()`, `MatSetLocalToGlobalMapping()`, 1086bb7acecfSBarry Smith `DMCreateMatrix()` 10871411c6eeSJed Brown @*/ 1088d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalToGlobalMapping(DM dm, ISLocalToGlobalMapping *ltog) 1089d71ae5a4SJacob Faibussowitsch { 10900be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 10911411c6eeSJed Brown 10921411c6eeSJed Brown PetscFunctionBegin; 10931411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10944f572ea9SToby Isaac PetscAssertPointer(ltog, 2); 10951411c6eeSJed Brown if (!dm->ltogmap) { 109637d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 109737d0c07bSMatthew G Knepley 10989566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 109937d0c07bSMatthew G Knepley if (section) { 1100a974ec88SMatthew G. Knepley const PetscInt *cdofs; 110137d0c07bSMatthew G Knepley PetscInt *ltog; 1102ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 110337d0c07bSMatthew G Knepley 11049566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 11059566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 11069566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(section, &n)); 11079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, <og)); /* We want the local+overlap size */ 110837d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1109e6befd46SJed Brown PetscInt bdof, cdof, dof, off, c, cind; 111037d0c07bSMatthew G Knepley 111137d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 11129566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(section, p, &dof)); 11139566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(section, p, &cdof)); 11149566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(section, p, &cdofs)); 11159566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &off)); 11161a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 11171a7dc684SMatthew G. Knepley bdof = cdof && (dof - cdof) ? 1 : dof; 1118ad540459SPierre Jolivet if (dof) bs = bs < 0 ? bdof : PetscGCD(bs, bdof); 11195227eafbSStefano Zampini 1120e6befd46SJed Brown for (c = 0, cind = 0; c < dof; ++c, ++l) { 11215227eafbSStefano Zampini if (cind < cdof && c == cdofs[cind]) { 1122e6befd46SJed Brown ltog[l] = off < 0 ? off - c : -(off + c + 1); 1123e6befd46SJed Brown cind++; 1124e6befd46SJed Brown } else { 11255227eafbSStefano Zampini ltog[l] = (off < 0 ? -(off + 1) : off) + c - cind; 1126e6befd46SJed Brown } 112737d0c07bSMatthew G Knepley } 112837d0c07bSMatthew G Knepley } 1129bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 11309371c9d4SSatish Balay bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; 11319371c9d4SSatish Balay bsLocal[1] = bs; 11329566063dSJacob Faibussowitsch PetscCall(PetscGlobalMinMaxInt(PetscObjectComm((PetscObject)dm), bsLocal, bsMinMax)); 11339371c9d4SSatish Balay if (bsMinMax[0] != bsMinMax[1]) { 11349371c9d4SSatish Balay bs = 1; 11359371c9d4SSatish Balay } else { 11369371c9d4SSatish Balay bs = bsMinMax[0]; 11379371c9d4SSatish Balay } 11387591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 11397591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1140ccf3bd66SMatthew G. Knepley if (bs > 1) { 1141ca469d19SJed Brown for (l = 0, k = 0; l < n; l += bs, ++k) { 1142ca469d19SJed Brown // Integer division of negative values truncates toward zero(!), not toward negative infinity 1143ca469d19SJed Brown ltog[k] = ltog[l] >= 0 ? ltog[l] / bs : -(-(ltog[l] + 1) / bs + 1); 1144ca469d19SJed Brown } 1145ccf3bd66SMatthew G. Knepley n /= bs; 1146ccf3bd66SMatthew G. Knepley } 11479566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap)); 1148dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, getlocaltoglobalmapping); 114937d0c07bSMatthew G Knepley } 11501411c6eeSJed Brown *ltog = dm->ltogmap; 11513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11521411c6eeSJed Brown } 11531411c6eeSJed Brown 11541411c6eeSJed Brown /*@ 1155bb7acecfSBarry Smith DMGetBlockSize - Gets the inherent block size associated with a `DM` 11561411c6eeSJed Brown 11571411c6eeSJed Brown Not Collective 11581411c6eeSJed Brown 11591411c6eeSJed Brown Input Parameter: 1160bb7acecfSBarry Smith . dm - the `DM` with block structure 11611411c6eeSJed Brown 11621411c6eeSJed Brown Output Parameter: 11631411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11641411c6eeSJed Brown 11651411c6eeSJed Brown Level: intermediate 11661411c6eeSJed Brown 116773ff1848SBarry Smith Notes: 1168bb7acecfSBarry Smith This might be the number of degrees of freedom at each grid point for a structured grid. 1169bb7acecfSBarry Smith 1170bb7acecfSBarry Smith Complex `DM` that represent multiphysics or staggered grids or mixed-methods do not generally have a single inherent block size, but 1171bb7acecfSBarry Smith rather different locations in the vectors may have a different block size. 1172bb7acecfSBarry Smith 11731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISCreateBlock()`, `VecSetBlockSize()`, `MatSetBlockSize()`, `DMGetLocalToGlobalMapping()` 11741411c6eeSJed Brown @*/ 1175d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBlockSize(DM dm, PetscInt *bs) 1176d71ae5a4SJacob Faibussowitsch { 11771411c6eeSJed Brown PetscFunctionBegin; 11781411c6eeSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11794f572ea9SToby Isaac PetscAssertPointer(bs, 2); 11807a8be351SBarry Smith PetscCheck(dm->bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM does not have enough information to provide a block size yet"); 11811411c6eeSJed Brown *bs = dm->bs; 11823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11831411c6eeSJed Brown } 11841411c6eeSJed Brown 118548eeb7c8SBarry Smith /*@C 1186bb7acecfSBarry Smith DMCreateInterpolation - Gets the interpolation matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1187bb7acecfSBarry Smith `DMCreateGlobalVector()` on the coarse `DM` to similar vectors on the fine grid `DM`. 118847c6ae99SBarry Smith 118920f4b53cSBarry Smith Collective 119047c6ae99SBarry Smith 1191d8d19677SJose E. Roman Input Parameters: 1192bb7acecfSBarry Smith + dmc - the `DM` object 1193bb7acecfSBarry Smith - dmf - the second, finer `DM` object 119447c6ae99SBarry Smith 1195d8d19677SJose E. Roman Output Parameters: 119647c6ae99SBarry Smith + mat - the interpolation 1197bb7acecfSBarry Smith - vec - the scaling (optional), see `DMCreateInterpolationScale()` 119847c6ae99SBarry Smith 119947c6ae99SBarry Smith Level: developer 120047c6ae99SBarry Smith 120195452b02SPatrick Sanan Notes: 1202bb7acecfSBarry 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 1203bb7acecfSBarry Smith DMCoarsen(). The coordinates set into the `DMDA` are completely ignored in computing the interpolation. 1204d52bd9f3SBarry Smith 1205bb7acecfSBarry Smith For `DMDA` objects you can use this interpolation (more precisely the interpolation from the `DMGetCoordinateDM()`) to interpolate the mesh coordinate 1206bb7acecfSBarry Smith vectors EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 120785afcc9aSBarry Smith 12081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolationScale()` 120947c6ae99SBarry Smith @*/ 1210d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolation(DM dmc, DM dmf, Mat *mat, Vec *vec) 1211d71ae5a4SJacob Faibussowitsch { 121247c6ae99SBarry Smith PetscFunctionBegin; 1213a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1214a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 12154f572ea9SToby Isaac PetscAssertPointer(mat, 3); 12169566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInterpolation, dmc, dmf, 0, 0)); 1217dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createinterpolation, dmf, mat, vec); 12189566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInterpolation, dmc, dmf, 0, 0)); 12193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 122047c6ae99SBarry Smith } 122147c6ae99SBarry Smith 12223ad4599aSBarry Smith /*@ 1223a4e35b19SJacob Faibussowitsch DMCreateInterpolationScale - Forms L = 1/(R*1) where 1 is the vector of all ones, and R is 1224a4e35b19SJacob Faibussowitsch the transpose of the interpolation between the `DM`. 12252ed6491fSPatrick Sanan 12262ed6491fSPatrick Sanan Input Parameters: 1227bb7acecfSBarry Smith + dac - `DM` that defines a coarse mesh 1228bb7acecfSBarry Smith . daf - `DM` that defines a fine mesh 12292ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 12302ed6491fSPatrick Sanan 12312ed6491fSPatrick Sanan Output Parameter: 12322ed6491fSPatrick Sanan . scale - the scaled vector 12332ed6491fSPatrick Sanan 1234bb7acecfSBarry Smith Level: advanced 12352ed6491fSPatrick Sanan 123673ff1848SBarry Smith Note: 1237a4e35b19SJacob Faibussowitsch xcoarse = diag(L)*R*xfine preserves scale and is thus suitable for state (versus residual) 1238a4e35b19SJacob Faibussowitsch restriction. In other words xcoarse is the coarse representation of xfine. 1239a4e35b19SJacob Faibussowitsch 124073ff1848SBarry Smith Developer Note: 1241bb7acecfSBarry Smith If the fine-scale `DMDA` has the -dm_bind_below option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 1242e9c74fd6SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 1243e9c74fd6SRichard Tran Mills 124460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `MatRestrict()`, `MatInterpolate()`, `DMCreateInterpolation()`, `DMCreateRestriction()`, `DMCreateGlobalVector()` 12452ed6491fSPatrick Sanan @*/ 1246d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolationScale(DM dac, DM daf, Mat mat, Vec *scale) 1247d71ae5a4SJacob Faibussowitsch { 12482ed6491fSPatrick Sanan Vec fine; 12492ed6491fSPatrick Sanan PetscScalar one = 1.0; 12509704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 1251e9c74fd6SRichard Tran Mills PetscBool bindingpropagates, isbound; 12529704db99SRichard Tran Mills #endif 12532ed6491fSPatrick Sanan 12542ed6491fSPatrick Sanan PetscFunctionBegin; 12559566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(daf, &fine)); 12569566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dac, scale)); 12579566063dSJacob Faibussowitsch PetscCall(VecSet(fine, one)); 12589704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 12599704db99SRichard Tran Mills /* If the 'fine' Vec is bound to the CPU, it makes sense to bind 'mat' as well. 12609704db99SRichard Tran Mills * Note that we only do this for the CUDA case, right now, but if we add support for MatMultTranspose() via ViennaCL, 12619704db99SRichard Tran Mills * we'll need to do it for that case, too.*/ 12629566063dSJacob Faibussowitsch PetscCall(VecGetBindingPropagates(fine, &bindingpropagates)); 1263e9c74fd6SRichard Tran Mills if (bindingpropagates) { 12649566063dSJacob Faibussowitsch PetscCall(MatSetBindingPropagates(mat, PETSC_TRUE)); 12659566063dSJacob Faibussowitsch PetscCall(VecBoundToCPU(fine, &isbound)); 12669566063dSJacob Faibussowitsch PetscCall(MatBindToCPU(mat, isbound)); 126783aa49f4SRichard Tran Mills } 12689704db99SRichard Tran Mills #endif 12699566063dSJacob Faibussowitsch PetscCall(MatRestrict(mat, fine, *scale)); 12709566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fine)); 12719566063dSJacob Faibussowitsch PetscCall(VecReciprocal(*scale)); 12723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12732ed6491fSPatrick Sanan } 12742ed6491fSPatrick Sanan 12752ed6491fSPatrick Sanan /*@ 1276bb7acecfSBarry Smith DMCreateRestriction - Gets restriction matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1277bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine `DM` to similar vectors on the coarse grid `DM`. 12783ad4599aSBarry Smith 127920f4b53cSBarry Smith Collective 12803ad4599aSBarry Smith 1281d8d19677SJose E. Roman Input Parameters: 1282bb7acecfSBarry Smith + dmc - the `DM` object 1283bb7acecfSBarry Smith - dmf - the second, finer `DM` object 12843ad4599aSBarry Smith 12853ad4599aSBarry Smith Output Parameter: 12863ad4599aSBarry Smith . mat - the restriction 12873ad4599aSBarry Smith 12883ad4599aSBarry Smith Level: developer 12893ad4599aSBarry Smith 1290bb7acecfSBarry Smith Note: 1291bb7acecfSBarry Smith This only works for `DMSTAG`. For many situations either the transpose of the operator obtained with `DMCreateInterpolation()` or that 1292bb7acecfSBarry Smith matrix multiplied by the vector obtained with `DMCreateInterpolationScale()` provides the desired object. 12933ad4599aSBarry Smith 12941cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRestrict()`, `DMInterpolate()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateInterpolation()` 12953ad4599aSBarry Smith @*/ 1296d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateRestriction(DM dmc, DM dmf, Mat *mat) 1297d71ae5a4SJacob Faibussowitsch { 12983ad4599aSBarry Smith PetscFunctionBegin; 1299a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1300a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13014f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13029566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateRestriction, dmc, dmf, 0, 0)); 1303dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createrestriction, dmf, mat); 13049566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateRestriction, dmc, dmf, 0, 0)); 13053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13063ad4599aSBarry Smith } 13073ad4599aSBarry Smith 130847c6ae99SBarry Smith /*@ 1309a4e35b19SJacob Faibussowitsch DMCreateInjection - Gets injection matrix between two `DM` objects. 131047c6ae99SBarry Smith 131120f4b53cSBarry Smith Collective 131247c6ae99SBarry Smith 1313d8d19677SJose E. Roman Input Parameters: 1314bb7acecfSBarry Smith + dac - the `DM` object 1315bb7acecfSBarry Smith - daf - the second, finer `DM` object 131647c6ae99SBarry Smith 131747c6ae99SBarry Smith Output Parameter: 13186dbf9973SLawrence Mitchell . mat - the injection 131947c6ae99SBarry Smith 132047c6ae99SBarry Smith Level: developer 132147c6ae99SBarry Smith 1322a4e35b19SJacob Faibussowitsch Notes: 1323a4e35b19SJacob Faibussowitsch This is an operator that applied to a vector obtained with `DMCreateGlobalVector()` on the 1324a4e35b19SJacob Faibussowitsch fine grid maps the values to a vector on the vector on the coarse `DM` by simply selecting 1325a4e35b19SJacob Faibussowitsch the values on the coarse grid points. This compares to the operator obtained by 1326a4e35b19SJacob Faibussowitsch `DMCreateRestriction()` or the transpose of the operator obtained by 1327a4e35b19SJacob Faibussowitsch `DMCreateInterpolation()` that uses a "local weighted average" of the values around the 1328a4e35b19SJacob Faibussowitsch coarse grid point as the coarse grid value. 1329a4e35b19SJacob Faibussowitsch 1330bb7acecfSBarry 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 1331bb7acecfSBarry Smith `DMCoarsen()`. The coordinates set into the `DMDA` are completely ignored in computing the injection. 133285afcc9aSBarry Smith 13331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateInterpolation()`, 1334bb7acecfSBarry Smith `DMCreateRestriction()`, `MatRestrict()`, `MatInterpolate()` 133547c6ae99SBarry Smith @*/ 1336d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInjection(DM dac, DM daf, Mat *mat) 1337d71ae5a4SJacob Faibussowitsch { 133847c6ae99SBarry Smith PetscFunctionBegin; 1339a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac, DM_CLASSID, 1); 1340a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf, DM_CLASSID, 2); 13414f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13429566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInjection, dac, daf, 0, 0)); 1343dbbe0bcdSBarry Smith PetscUseTypeMethod(dac, createinjection, daf, mat); 13449566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInjection, dac, daf, 0, 0)); 13453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 134647c6ae99SBarry Smith } 134747c6ae99SBarry Smith 1348b412c318SBarry Smith /*@ 1349bb7acecfSBarry 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 1350bb7acecfSBarry Smith a Galerkin finite element model on the `DM` 1351bd041c0cSMatthew G. Knepley 135220f4b53cSBarry Smith Collective 1353bd041c0cSMatthew G. Knepley 1354d8d19677SJose E. Roman Input Parameters: 1355bb7acecfSBarry Smith + dmc - the target `DM` object 1356bb7acecfSBarry Smith - dmf - the source `DM` object 1357bd041c0cSMatthew G. Knepley 1358bd041c0cSMatthew G. Knepley Output Parameter: 1359b4937a87SMatthew G. Knepley . mat - the mass matrix 1360bd041c0cSMatthew G. Knepley 1361bd041c0cSMatthew G. Knepley Level: developer 1362bd041c0cSMatthew G. Knepley 1363bb7acecfSBarry Smith Notes: 1364bb7acecfSBarry Smith For `DMPLEX` the finite element model for the `DM` must have been already provided. 1365bb7acecfSBarry Smith 136620f4b53cSBarry 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()` 1367bb7acecfSBarry Smith 136842747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrixLumped()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1369bd041c0cSMatthew G. Knepley @*/ 1370d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrix(DM dmc, DM dmf, Mat *mat) 1371d71ae5a4SJacob Faibussowitsch { 1372bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1373b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1374b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13754f572ea9SToby Isaac PetscAssertPointer(mat, 3); 13765b8ffe73SMark Adams PetscCall(PetscLogEventBegin(DM_CreateMassMatrix, 0, 0, 0, 0)); 1377dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc, createmassmatrix, dmf, mat); 13785b8ffe73SMark Adams PetscCall(PetscLogEventEnd(DM_CreateMassMatrix, 0, 0, 0, 0)); 13793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1380b4937a87SMatthew G. Knepley } 1381b4937a87SMatthew G. Knepley 1382b4937a87SMatthew G. Knepley /*@ 1383bb7acecfSBarry Smith DMCreateMassMatrixLumped - Gets the lumped mass matrix for a given `DM` 1384b4937a87SMatthew G. Knepley 138520f4b53cSBarry Smith Collective 1386b4937a87SMatthew G. Knepley 1387b4937a87SMatthew G. Knepley Input Parameter: 1388bb7acecfSBarry Smith . dm - the `DM` object 1389b4937a87SMatthew G. Knepley 1390b4937a87SMatthew G. Knepley Output Parameter: 1391bb7acecfSBarry Smith . lm - the lumped mass matrix, which is a diagonal matrix, represented as a vector 1392b4937a87SMatthew G. Knepley 1393b4937a87SMatthew G. Knepley Level: developer 1394b4937a87SMatthew G. Knepley 1395bb7acecfSBarry Smith Note: 1396bb7acecfSBarry Smith See `DMCreateMassMatrix()` for how to create the non-lumped version of the mass matrix. 1397bb7acecfSBarry Smith 139860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateMassMatrix()`, `DMCreateMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1399b4937a87SMatthew G. Knepley @*/ 1400d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMassMatrixLumped(DM dm, Vec *lm) 1401d71ae5a4SJacob Faibussowitsch { 1402b4937a87SMatthew G. Knepley PetscFunctionBegin; 1403b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14044f572ea9SToby Isaac PetscAssertPointer(lm, 2); 1405dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createmassmatrixlumped, lm); 14063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1407bd041c0cSMatthew G. Knepley } 1408bd041c0cSMatthew G. Knepley 1409bd041c0cSMatthew G. Knepley /*@ 1410bb7acecfSBarry Smith DMCreateColoring - Gets coloring of a graph associated with the `DM`. Often the graph represents the operator matrix associated with the discretization 1411bb7acecfSBarry Smith of a PDE on the `DM`. 141247c6ae99SBarry Smith 141320f4b53cSBarry Smith Collective 141447c6ae99SBarry Smith 1415d8d19677SJose E. Roman Input Parameters: 1416bb7acecfSBarry Smith + dm - the `DM` object 1417bb7acecfSBarry Smith - ctype - `IS_COLORING_LOCAL` or `IS_COLORING_GLOBAL` 141847c6ae99SBarry Smith 141947c6ae99SBarry Smith Output Parameter: 142047c6ae99SBarry Smith . coloring - the coloring 142147c6ae99SBarry Smith 14221bf8429eSBarry Smith Level: developer 14231bf8429eSBarry Smith 1424ec5066bdSBarry Smith Notes: 1425bb7acecfSBarry 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 1426bb7acecfSBarry Smith matrix comes from (what this function provides). In general using the mesh produces a more optimal coloring (fewer colors). 1427ec5066bdSBarry Smith 1428bb7acecfSBarry Smith This produces a coloring with the distance of 2, see `MatSetColoringDistance()` which can be used for efficiently computing Jacobians with `MatFDColoringCreate()` 14291bf8429eSBarry 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, 14301bf8429eSBarry Smith otherwise an error will be generated. 1431ec5066bdSBarry Smith 14321cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `ISColoring`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatType()`, `MatColoring`, `MatFDColoringCreate()` 1433aab9d709SJed Brown @*/ 1434d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateColoring(DM dm, ISColoringType ctype, ISColoring *coloring) 1435d71ae5a4SJacob Faibussowitsch { 143647c6ae99SBarry Smith PetscFunctionBegin; 1437171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14384f572ea9SToby Isaac PetscAssertPointer(coloring, 3); 1439dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getcoloring, ctype, coloring); 14403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 144147c6ae99SBarry Smith } 144247c6ae99SBarry Smith 1443b412c318SBarry Smith /*@ 1444bb7acecfSBarry Smith DMCreateMatrix - Gets an empty matrix for a `DM` that is most commonly used to store the Jacobian of a discrete PDE operator. 144547c6ae99SBarry Smith 144620f4b53cSBarry Smith Collective 144747c6ae99SBarry Smith 144847c6ae99SBarry Smith Input Parameter: 1449bb7acecfSBarry Smith . dm - the `DM` object 145047c6ae99SBarry Smith 145147c6ae99SBarry Smith Output Parameter: 145247c6ae99SBarry Smith . mat - the empty Jacobian 145347c6ae99SBarry Smith 145420f4b53cSBarry Smith Options Database Key: 1455bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 1456f27dd7c6SMatthew G. Knepley 145720f4b53cSBarry Smith Level: beginner 145820f4b53cSBarry Smith 145995452b02SPatrick Sanan Notes: 146095452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 146194013140SBarry Smith do not need to do it yourself. 146294013140SBarry Smith 146394013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 1464bb7acecfSBarry Smith the nonzero pattern call `DMSetMatrixPreallocateOnly()` 146594013140SBarry Smith 1466bb7acecfSBarry Smith For `DMDA`, when you call `MatView()` on this matrix it is displayed using the global natural ordering, NOT in the ordering used 146794013140SBarry Smith internally by PETSc. 146894013140SBarry Smith 1469bb7acecfSBarry Smith For `DMDA`, in general it is easiest to use `MatSetValuesStencil()` or `MatSetValuesLocal()` to put values into the matrix because 1470bb7acecfSBarry Smith `MatSetValues()` requires the indices for the global numbering for the `DMDA` which is complic`ated to compute 147194013140SBarry Smith 14721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMSetMatType()`, `DMCreateMassMatrix()` 1473aab9d709SJed Brown @*/ 1474d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateMatrix(DM dm, Mat *mat) 1475d71ae5a4SJacob Faibussowitsch { 147647c6ae99SBarry Smith PetscFunctionBegin; 1477171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14784f572ea9SToby Isaac PetscAssertPointer(mat, 2); 14799566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 14809566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateMatrix, 0, 0, 0, 0)); 1481dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, creatematrix, mat); 148276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1483c6b011d8SStefano Zampini DM mdm; 1484c6b011d8SStefano Zampini 14859566063dSJacob Faibussowitsch PetscCall(MatGetDM(*mat, &mdm)); 14867a8be351SBarry Smith PetscCheck(mdm, PETSC_COMM_SELF, PETSC_ERR_PLIB, "DM type '%s' did not attach the DM to the matrix", ((PetscObject)dm)->type_name); 1487c6b011d8SStefano Zampini } 1488e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1489e5e52638SMatthew G. Knepley if (dm->Nf) { 1490e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1491649ef022SMatthew Knepley PetscInt Nf, f; 1492e571a35bSMatthew G. Knepley 14939566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1494649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1495649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 14969566063dSJacob Faibussowitsch PetscCall((*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace)); 14979566063dSJacob Faibussowitsch PetscCall(MatSetNullSpace(*mat, nullSpace)); 14989566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1499649ef022SMatthew Knepley break; 1500e571a35bSMatthew G. Knepley } 1501649ef022SMatthew Knepley } 1502649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1503649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 15049566063dSJacob Faibussowitsch PetscCall((*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace)); 15059566063dSJacob Faibussowitsch PetscCall(MatSetNearNullSpace(*mat, nullSpace)); 15069566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1507e571a35bSMatthew G. Knepley } 1508e571a35bSMatthew G. Knepley } 1509e571a35bSMatthew G. Knepley } 15109566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateMatrix, 0, 0, 0, 0)); 15113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 151247c6ae99SBarry Smith } 151347c6ae99SBarry Smith 1514732e2eb9SMatthew G Knepley /*@ 1515a4e35b19SJacob Faibussowitsch DMSetMatrixPreallocateSkip - When `DMCreateMatrix()` is called the matrix sizes and 1516a4e35b19SJacob Faibussowitsch `ISLocalToGlobalMapping` will be properly set, but the data structures to store values in the 1517a4e35b19SJacob Faibussowitsch matrices will not be preallocated. 1518aa0f6e3cSJed Brown 151920f4b53cSBarry Smith Logically Collective 1520aa0f6e3cSJed Brown 1521aa0f6e3cSJed Brown Input Parameters: 1522bb7acecfSBarry Smith + dm - the `DM` 1523bb7acecfSBarry Smith - skip - `PETSC_TRUE` to skip preallocation 1524aa0f6e3cSJed Brown 1525aa0f6e3cSJed Brown Level: developer 1526aa0f6e3cSJed Brown 152773ff1848SBarry Smith Note: 1528a4e35b19SJacob Faibussowitsch This is most useful to reduce initialization costs when `MatSetPreallocationCOO()` and 1529a4e35b19SJacob Faibussowitsch `MatSetValuesCOO()` will be used. 1530a4e35b19SJacob Faibussowitsch 15311cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateOnly()` 1532aa0f6e3cSJed Brown @*/ 1533d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateSkip(DM dm, PetscBool skip) 1534d71ae5a4SJacob Faibussowitsch { 1535aa0f6e3cSJed Brown PetscFunctionBegin; 1536aa0f6e3cSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1537aa0f6e3cSJed Brown dm->prealloc_skip = skip; 15383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1539aa0f6e3cSJed Brown } 1540aa0f6e3cSJed Brown 1541aa0f6e3cSJed Brown /*@ 1542bb7acecfSBarry Smith DMSetMatrixPreallocateOnly - When `DMCreateMatrix()` is called the matrix will be properly 1543732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1544732e2eb9SMatthew G Knepley 154520f4b53cSBarry Smith Logically Collective 1546732e2eb9SMatthew G Knepley 1547d8d19677SJose E. Roman Input Parameters: 1548bb7acecfSBarry Smith + dm - the `DM` 1549bb7acecfSBarry Smith - only - `PETSC_TRUE` if only want preallocation 1550732e2eb9SMatthew G Knepley 155120f4b53cSBarry Smith Options Database Key: 1552bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()`, `DMCreateMassMatrix()`, but do not fill it with zeros 1553f27dd7c6SMatthew G. Knepley 155420f4b53cSBarry Smith Level: developer 155520f4b53cSBarry Smith 15561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateSkip()` 1557732e2eb9SMatthew G Knepley @*/ 1558d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1559d71ae5a4SJacob Faibussowitsch { 1560732e2eb9SMatthew G Knepley PetscFunctionBegin; 1561732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1562732e2eb9SMatthew G Knepley dm->prealloc_only = only; 15633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1564732e2eb9SMatthew G Knepley } 1565732e2eb9SMatthew G Knepley 1566b06ff27eSHong Zhang /*@ 1567bb7acecfSBarry Smith DMSetMatrixStructureOnly - When `DMCreateMatrix()` is called, the matrix structure will be created 1568bb7acecfSBarry Smith but the array for numerical values will not be allocated. 1569b06ff27eSHong Zhang 157020f4b53cSBarry Smith Logically Collective 1571b06ff27eSHong Zhang 1572d8d19677SJose E. Roman Input Parameters: 1573bb7acecfSBarry Smith + dm - the `DM` 1574da81f932SPierre Jolivet - only - `PETSC_TRUE` if you only want matrix structure 1575b06ff27eSHong Zhang 1576b06ff27eSHong Zhang Level: developer 1577bb7acecfSBarry Smith 15781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMSetMatrixPreallocateSkip()` 1579b06ff27eSHong Zhang @*/ 1580d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1581d71ae5a4SJacob Faibussowitsch { 1582b06ff27eSHong Zhang PetscFunctionBegin; 1583b06ff27eSHong Zhang PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1584b06ff27eSHong Zhang dm->structure_only = only; 15853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1586b06ff27eSHong Zhang } 1587b06ff27eSHong Zhang 1588863027abSJed Brown /*@ 1589863027abSJed Brown DMSetBlockingType - set the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1590863027abSJed Brown 159120f4b53cSBarry Smith Logically Collective 1592863027abSJed Brown 1593863027abSJed Brown Input Parameters: 1594863027abSJed Brown + dm - the `DM` 1595863027abSJed Brown - btype - block by topological point or field node 1596863027abSJed Brown 159720f4b53cSBarry Smith Options Database Key: 15980e762ea3SJed Brown . -dm_blocking_type [topological_point, field_node] - use topological point blocking or field node blocking 1599863027abSJed Brown 160020f4b53cSBarry Smith Level: advanced 160120f4b53cSBarry Smith 16021cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1603863027abSJed Brown @*/ 1604863027abSJed Brown PetscErrorCode DMSetBlockingType(DM dm, DMBlockingType btype) 1605863027abSJed Brown { 1606863027abSJed Brown PetscFunctionBegin; 1607863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1608863027abSJed Brown dm->blocking_type = btype; 16093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1610863027abSJed Brown } 1611863027abSJed Brown 1612863027abSJed Brown /*@ 1613863027abSJed Brown DMGetBlockingType - get the blocking granularity to be used for variable block size `DMCreateMatrix()` is called 1614863027abSJed Brown 1615863027abSJed Brown Not Collective 1616863027abSJed Brown 16172fe279fdSBarry Smith Input Parameter: 1618863027abSJed Brown . dm - the `DM` 1619863027abSJed Brown 16202fe279fdSBarry Smith Output Parameter: 1621863027abSJed Brown . btype - block by topological point or field node 1622863027abSJed Brown 1623863027abSJed Brown Level: advanced 1624863027abSJed Brown 16251cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateMatrix()`, `MatSetVariableBlockSizes()` 1626863027abSJed Brown @*/ 1627863027abSJed Brown PetscErrorCode DMGetBlockingType(DM dm, DMBlockingType *btype) 1628863027abSJed Brown { 1629863027abSJed Brown PetscFunctionBegin; 1630863027abSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16314f572ea9SToby Isaac PetscAssertPointer(btype, 2); 1632863027abSJed Brown *btype = dm->blocking_type; 16333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1634863027abSJed Brown } 1635863027abSJed Brown 1636a89ea682SMatthew G Knepley /*@C 1637bb7acecfSBarry Smith DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with `DMRestoreWorkArray()` 1638a89ea682SMatthew G Knepley 1639a89ea682SMatthew G Knepley Not Collective 1640a89ea682SMatthew G Knepley 1641a89ea682SMatthew G Knepley Input Parameters: 1642bb7acecfSBarry Smith + dm - the `DM` object 1643a5b23f4aSJose E. Roman . count - The minimum size 164420f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, or `MPIU_INT`) 1645a89ea682SMatthew G Knepley 1646a89ea682SMatthew G Knepley Output Parameter: 164760225df5SJacob Faibussowitsch . mem - the work array 1648a89ea682SMatthew G Knepley 1649a89ea682SMatthew G Knepley Level: developer 1650a89ea682SMatthew G Knepley 165173ff1848SBarry Smith Notes: 1652da81f932SPierre Jolivet A `DM` may stash the array between instantiations so using this routine may be more efficient than calling `PetscMalloc()` 1653bb7acecfSBarry Smith 1654bb7acecfSBarry Smith The array may contain nonzero values 1655bb7acecfSBarry Smith 16561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMRestoreWorkArray()`, `PetscMalloc()` 1657a89ea682SMatthew G Knepley @*/ 1658d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1659d71ae5a4SJacob Faibussowitsch { 1660aa1993deSMatthew G Knepley DMWorkLink link; 166169291d52SBarry Smith PetscMPIInt dsize; 1662a89ea682SMatthew G Knepley 1663a89ea682SMatthew G Knepley PetscFunctionBegin; 1664a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16654f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1666442f3b32SStefano Zampini if (!count) { 1667442f3b32SStefano Zampini *(void **)mem = NULL; 1668442f3b32SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 1669442f3b32SStefano Zampini } 1670aa1993deSMatthew G Knepley if (dm->workin) { 1671aa1993deSMatthew G Knepley link = dm->workin; 1672aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1673aa1993deSMatthew G Knepley } else { 16744dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&link)); 1675a89ea682SMatthew G Knepley } 1676b77fa653SStefano Zampini /* Avoid MPI_Type_size for most used datatypes 1677b77fa653SStefano Zampini Get size directly */ 1678b77fa653SStefano Zampini if (dtype == MPIU_INT) dsize = sizeof(PetscInt); 1679b77fa653SStefano Zampini else if (dtype == MPIU_REAL) dsize = sizeof(PetscReal); 1680b77fa653SStefano Zampini #if defined(PETSC_USE_64BIT_INDICES) 1681b77fa653SStefano Zampini else if (dtype == MPI_INT) dsize = sizeof(int); 1682b77fa653SStefano Zampini #endif 1683b77fa653SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1684b77fa653SStefano Zampini else if (dtype == MPIU_SCALAR) dsize = sizeof(PetscScalar); 1685b77fa653SStefano Zampini #endif 1686b77fa653SStefano Zampini else PetscCallMPI(MPI_Type_size(dtype, &dsize)); 1687b77fa653SStefano Zampini 16885056fcd2SBarry Smith if (((size_t)dsize * count) > link->bytes) { 16899566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 16909566063dSJacob Faibussowitsch PetscCall(PetscMalloc(dsize * count, &link->mem)); 1691854ce69bSBarry Smith link->bytes = dsize * count; 1692aa1993deSMatthew G Knepley } 1693aa1993deSMatthew G Knepley link->next = dm->workout; 1694aa1993deSMatthew G Knepley dm->workout = link; 1695cea3dcb8SSatish Balay #if defined(__MEMCHECK_H) && (defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) || defined(PLAT_amd64_darwin)) 169600d952a4SJed Brown VALGRIND_MAKE_MEM_NOACCESS((char *)link->mem + (size_t)dsize * count, link->bytes - (size_t)dsize * count); 169700d952a4SJed Brown VALGRIND_MAKE_MEM_UNDEFINED(link->mem, (size_t)dsize * count); 169800d952a4SJed Brown #endif 1699aa1993deSMatthew G Knepley *(void **)mem = link->mem; 17003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1701a89ea682SMatthew G Knepley } 1702a89ea682SMatthew G Knepley 1703aa1993deSMatthew G Knepley /*@C 1704bb7acecfSBarry Smith DMRestoreWorkArray - Restores a work array obtained with `DMCreateWorkArray()` 1705aa1993deSMatthew G Knepley 1706aa1993deSMatthew G Knepley Not Collective 1707aa1993deSMatthew G Knepley 1708aa1993deSMatthew G Knepley Input Parameters: 1709bb7acecfSBarry Smith + dm - the `DM` object 1710a5b23f4aSJose E. Roman . count - The minimum size 171120f4b53cSBarry Smith - dtype - MPI data type, often `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_INT` 1712aa1993deSMatthew G Knepley 1713aa1993deSMatthew G Knepley Output Parameter: 171460225df5SJacob Faibussowitsch . mem - the work array 1715aa1993deSMatthew G Knepley 1716aa1993deSMatthew G Knepley Level: developer 1717aa1993deSMatthew G Knepley 171873ff1848SBarry Smith Developer Note: 1719bb7acecfSBarry Smith count and dtype are ignored, they are only needed for `DMGetWorkArray()` 1720147403d9SBarry Smith 17211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDestroy()`, `DMCreate()`, `DMGetWorkArray()` 1722aa1993deSMatthew G Knepley @*/ 1723d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestoreWorkArray(DM dm, PetscInt count, MPI_Datatype dtype, void *mem) 1724d71ae5a4SJacob Faibussowitsch { 1725aa1993deSMatthew G Knepley DMWorkLink *p, link; 1726aa1993deSMatthew G Knepley 1727aa1993deSMatthew G Knepley PetscFunctionBegin; 1728aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17294f572ea9SToby Isaac PetscAssertPointer(mem, 4); 1730a4e35b19SJacob Faibussowitsch (void)count; 1731a4e35b19SJacob Faibussowitsch (void)dtype; 1732442f3b32SStefano Zampini if (!*(void **)mem) PetscFunctionReturn(PETSC_SUCCESS); 1733aa1993deSMatthew G Knepley for (p = &dm->workout; (link = *p); p = &link->next) { 1734aa1993deSMatthew G Knepley if (link->mem == *(void **)mem) { 1735aa1993deSMatthew G Knepley *p = link->next; 1736aa1993deSMatthew G Knepley link->next = dm->workin; 1737aa1993deSMatthew G Knepley dm->workin = link; 17380298fd71SBarry Smith *(void **)mem = NULL; 17393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1740aa1993deSMatthew G Knepley } 1741aa1993deSMatthew G Knepley } 1742aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Array was not checked out"); 1743aa1993deSMatthew G Knepley } 1744e7c4fc90SDmitry Karpeev 17458cda7954SMatthew G. Knepley /*@C 1746bb7acecfSBarry Smith DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field, defined with `DMAddField()`, when function spaces 1747bb7acecfSBarry Smith are joined or split, such as in `DMCreateSubDM()` 17488cda7954SMatthew G. Knepley 174920f4b53cSBarry Smith Logically Collective; No Fortran Support 17508cda7954SMatthew G. Knepley 17518cda7954SMatthew G. Knepley Input Parameters: 1752bb7acecfSBarry Smith + dm - The `DM` 17538cda7954SMatthew G. Knepley . field - The field number for the nullspace 17548cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 17558cda7954SMatthew G. Knepley 175620f4b53cSBarry Smith Calling sequence of `nullsp`: 1757bb7acecfSBarry Smith + dm - The present `DM` 1758bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1759147403d9SBarry Smith . field - The field number in dm 1760147403d9SBarry Smith - nullSpace - The nullspace for the given field 17618cda7954SMatthew G. Knepley 176249762cbcSSatish Balay Level: intermediate 176349762cbcSSatish Balay 17641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1765147403d9SBarry Smith @*/ 1766a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1767d71ae5a4SJacob Faibussowitsch { 1768435a35e8SMatthew G Knepley PetscFunctionBegin; 1769435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17707a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1771435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 17723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1773435a35e8SMatthew G Knepley } 1774435a35e8SMatthew G Knepley 17758cda7954SMatthew G. Knepley /*@C 1776bb7acecfSBarry Smith DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, defined with `DMAddField()` 17778cda7954SMatthew G. Knepley 177820f4b53cSBarry Smith Not Collective; No Fortran Support 17798cda7954SMatthew G. Knepley 17808cda7954SMatthew G. Knepley Input Parameters: 1781bb7acecfSBarry Smith + dm - The `DM` 17828cda7954SMatthew G. Knepley - field - The field number for the nullspace 17838cda7954SMatthew G. Knepley 17848cda7954SMatthew G. Knepley Output Parameter: 17858cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 17868cda7954SMatthew G. Knepley 178720f4b53cSBarry Smith Calling sequence of `nullsp`: 1788147403d9SBarry Smith + dm - The present DM 1789147403d9SBarry Smith . origField - The field number given above, in the original DM 1790147403d9SBarry Smith . field - The field number in dm 1791147403d9SBarry Smith - nullSpace - The nullspace for the given field 17928cda7954SMatthew G. Knepley 179349762cbcSSatish Balay Level: intermediate 179449762cbcSSatish Balay 17951cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1796147403d9SBarry Smith @*/ 1797a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1798d71ae5a4SJacob Faibussowitsch { 17990a50eb56SMatthew G. Knepley PetscFunctionBegin; 18000a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18014f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 18027a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 18030a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 18043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18050a50eb56SMatthew G. Knepley } 18060a50eb56SMatthew G. Knepley 18078cda7954SMatthew G. Knepley /*@C 1808bb7acecfSBarry Smith DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 18098cda7954SMatthew G. Knepley 181020f4b53cSBarry Smith Logically Collective; No Fortran Support 18118cda7954SMatthew G. Knepley 18128cda7954SMatthew G. Knepley Input Parameters: 1813bb7acecfSBarry Smith + dm - The `DM` 18148cda7954SMatthew G. Knepley . field - The field number for the nullspace 18158cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 18168cda7954SMatthew G. Knepley 181720f4b53cSBarry Smith Calling sequence of `nullsp`: 1818bb7acecfSBarry Smith + dm - The present `DM` 1819bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1820147403d9SBarry Smith . field - The field number in dm 1821147403d9SBarry Smith - nullSpace - The nullspace for the given field 18228cda7954SMatthew G. Knepley 182349762cbcSSatish Balay Level: intermediate 182449762cbcSSatish Balay 18251cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()`, 1826bb7acecfSBarry Smith `MatNullSpace` 1827147403d9SBarry Smith @*/ 1828a4e35b19SJacob Faibussowitsch PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1829d71ae5a4SJacob Faibussowitsch { 1830f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1831f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18327a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1833f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 18343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1835f9d4088aSMatthew G. Knepley } 1836f9d4088aSMatthew G. Knepley 18378cda7954SMatthew G. Knepley /*@C 1838bb7acecfSBarry Smith DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 18398cda7954SMatthew G. Knepley 184020f4b53cSBarry Smith Not Collective; No Fortran Support 18418cda7954SMatthew G. Knepley 18428cda7954SMatthew G. Knepley Input Parameters: 1843bb7acecfSBarry Smith + dm - The `DM` 18448cda7954SMatthew G. Knepley - field - The field number for the nullspace 18458cda7954SMatthew G. Knepley 18468cda7954SMatthew G. Knepley Output Parameter: 18478cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 18488cda7954SMatthew G. Knepley 184920f4b53cSBarry Smith Calling sequence of `nullsp`: 1850bb7acecfSBarry Smith + dm - The present `DM` 1851bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1852147403d9SBarry Smith . field - The field number in dm 1853147403d9SBarry Smith - nullSpace - The nullspace for the given field 18548cda7954SMatthew G. Knepley 185549762cbcSSatish Balay Level: intermediate 185649762cbcSSatish Balay 18571cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMSetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, 1858bb7acecfSBarry Smith `MatNullSpace`, `DMCreateSuperDM()` 1859147403d9SBarry Smith @*/ 1860a4e35b19SJacob Faibussowitsch PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace)) 1861d71ae5a4SJacob Faibussowitsch { 1862f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1863f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18644f572ea9SToby Isaac PetscAssertPointer(nullsp, 3); 18657a8be351SBarry Smith PetscCheck(field < 10, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1866f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 18673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1868f9d4088aSMatthew G. Knepley } 1869f9d4088aSMatthew G. Knepley 18704f3b5142SJed Brown /*@C 1871bb7acecfSBarry Smith DMCreateFieldIS - Creates a set of `IS` objects with the global indices of dofs for each field defined with `DMAddField()` 18724d343eeaSMatthew G Knepley 187320f4b53cSBarry Smith Not Collective; No Fortran Support 18744d343eeaSMatthew G Knepley 18754d343eeaSMatthew G Knepley Input Parameter: 1876bb7acecfSBarry Smith . dm - the `DM` object 18774d343eeaSMatthew G Knepley 18784d343eeaSMatthew G Knepley Output Parameters: 187920f4b53cSBarry Smith + numFields - The number of fields (or `NULL` if not requested) 188020f4b53cSBarry Smith . fieldNames - The number of each field (or `NULL` if not requested) 188120f4b53cSBarry Smith - fields - The global indices for each field (or `NULL` if not requested) 18824d343eeaSMatthew G Knepley 18834d343eeaSMatthew G Knepley Level: intermediate 18844d343eeaSMatthew G Knepley 1885bb7acecfSBarry Smith Note: 188673ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `fieldNames` should be freed with 188773ff1848SBarry Smith `PetscFree()`, every entry of `fields` should be destroyed with `ISDestroy()`, and both arrays should be freed with 1888bb7acecfSBarry Smith `PetscFree()`. 188921c9b008SJed Brown 189073ff1848SBarry Smith Developer Note: 1891bb7acecfSBarry Smith It is not clear why both this function and `DMCreateFieldDecomposition()` exist. Having two seems redundant and confusing. This function should 1892bb7acecfSBarry Smith likely be removed. 1893bb7acecfSBarry Smith 18941cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1895bb7acecfSBarry Smith `DMCreateFieldDecomposition()` 18964d343eeaSMatthew G Knepley @*/ 1897d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 1898d71ae5a4SJacob Faibussowitsch { 189937d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 19004d343eeaSMatthew G Knepley 19014d343eeaSMatthew G Knepley PetscFunctionBegin; 19024d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 190369ca1f37SDmitry Karpeev if (numFields) { 19044f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 190569ca1f37SDmitry Karpeev *numFields = 0; 190669ca1f37SDmitry Karpeev } 190737d0c07bSMatthew G Knepley if (fieldNames) { 19084f572ea9SToby Isaac PetscAssertPointer(fieldNames, 3); 19090298fd71SBarry Smith *fieldNames = NULL; 191069ca1f37SDmitry Karpeev } 191169ca1f37SDmitry Karpeev if (fields) { 19124f572ea9SToby Isaac PetscAssertPointer(fields, 4); 19130298fd71SBarry Smith *fields = NULL; 191469ca1f37SDmitry Karpeev } 19159566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 191637d0c07bSMatthew G Knepley if (section) { 19173a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 191837d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 191937d0c07bSMatthew G Knepley 19209566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 19219566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nF)); 19229566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nF, &fieldSizes, nF, &fieldNc, nF, &fieldIndices)); 19239566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(sectionGlobal, &pStart, &pEnd)); 192437d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 192537d0c07bSMatthew G Knepley fieldSizes[f] = 0; 19269566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(section, f, &fieldNc[f])); 192737d0c07bSMatthew G Knepley } 192837d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 192937d0c07bSMatthew G Knepley PetscInt gdof; 193037d0c07bSMatthew G Knepley 19319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 193237d0c07bSMatthew G Knepley if (gdof > 0) { 193337d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19343a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 193537d0c07bSMatthew G Knepley 19369566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19379566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 19383a544194SStefano Zampini fpdof = fdof - fcdof; 19393a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 19403a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 19413a544194SStefano Zampini fieldNc[f] = 1; 19423a544194SStefano Zampini } 19433a544194SStefano Zampini fieldSizes[f] += fpdof; 194437d0c07bSMatthew G Knepley } 194537d0c07bSMatthew G Knepley } 194637d0c07bSMatthew G Knepley } 194737d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fieldSizes[f], &fieldIndices[f])); 194937d0c07bSMatthew G Knepley fieldSizes[f] = 0; 195037d0c07bSMatthew G Knepley } 195137d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 195237d0c07bSMatthew G Knepley PetscInt gdof, goff; 195337d0c07bSMatthew G Knepley 19549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 195537d0c07bSMatthew G Knepley if (gdof > 0) { 19569566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &goff)); 195737d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 195837d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 195937d0c07bSMatthew G Knepley 19609566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19619566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 1962ad540459SPierre Jolivet for (fc = 0; fc < fdof - fcdof; ++fc, ++fieldSizes[f]) fieldIndices[f][fieldSizes[f]] = goff++; 196337d0c07bSMatthew G Knepley } 196437d0c07bSMatthew G Knepley } 196537d0c07bSMatthew G Knepley } 19668865f1eaSKarl Rupp if (numFields) *numFields = nF; 196737d0c07bSMatthew G Knepley if (fieldNames) { 19689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fieldNames)); 196937d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 197037d0c07bSMatthew G Knepley const char *fieldName; 197137d0c07bSMatthew G Knepley 19729566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 19739566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char **)&(*fieldNames)[f])); 197437d0c07bSMatthew G Knepley } 197537d0c07bSMatthew G Knepley } 197637d0c07bSMatthew G Knepley if (fields) { 19779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fields)); 197837d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19793a544194SStefano Zampini PetscInt bs, in[2], out[2]; 19803a544194SStefano Zampini 19819566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f])); 19823a544194SStefano Zampini in[0] = -fieldNc[f]; 19833a544194SStefano Zampini in[1] = fieldNc[f]; 19841c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 19853a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 19869566063dSJacob Faibussowitsch PetscCall(ISSetBlockSize((*fields)[f], bs)); 198737d0c07bSMatthew G Knepley } 198837d0c07bSMatthew G Knepley } 19899566063dSJacob Faibussowitsch PetscCall(PetscFree3(fieldSizes, fieldNc, fieldIndices)); 1990dbbe0bcdSBarry Smith } else PetscTryTypeMethod(dm, createfieldis, numFields, fieldNames, fields); 19913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19924d343eeaSMatthew G Knepley } 19934d343eeaSMatthew G Knepley 199416621825SDmitry Karpeev /*@C 1995bb7acecfSBarry Smith DMCreateFieldDecomposition - Returns a list of `IS` objects defining a decomposition of a problem into subproblems 1996a4e35b19SJacob Faibussowitsch corresponding to different fields. 1997e7c4fc90SDmitry Karpeev 199820f4b53cSBarry Smith Not Collective; No Fortran Support 1999e7c4fc90SDmitry Karpeev 2000e7c4fc90SDmitry Karpeev Input Parameter: 2001bb7acecfSBarry Smith . dm - the `DM` object 2002e7c4fc90SDmitry Karpeev 2003e7c4fc90SDmitry Karpeev Output Parameters: 200420f4b53cSBarry Smith + len - The number of fields (or `NULL` if not requested) 200520f4b53cSBarry Smith . namelist - The name for each field (or `NULL` if not requested) 200620f4b53cSBarry Smith . islist - The global indices for each field (or `NULL` if not requested) 200720f4b53cSBarry Smith - dmlist - The `DM`s for each field subproblem (or `NULL`, if not requested; if `NULL` is returned, no `DM`s are defined) 2008e7c4fc90SDmitry Karpeev 2009e7c4fc90SDmitry Karpeev Level: intermediate 2010e7c4fc90SDmitry Karpeev 2011a4e35b19SJacob Faibussowitsch Notes: 2012a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding field, defined by 2013a4e35b19SJacob Faibussowitsch `DMAddField()`. The optional list of `DM`s define the `DM` for each subproblem. 2014a4e35b19SJacob Faibussowitsch 2015a4e35b19SJacob Faibussowitsch The same as `DMCreateFieldIS()` but also returns a `DM` for each field. 2016a4e35b19SJacob Faibussowitsch 201773ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `namelist` should be freed with 201873ff1848SBarry Smith `PetscFree()`, every entry of `islist` should be destroyed with `ISDestroy()`, every entry of `dmlist` should be destroyed with `DMDestroy()`, 2019bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 2020e7c4fc90SDmitry Karpeev 202160225df5SJacob Faibussowitsch Developer Notes: 2022bb7acecfSBarry Smith It is not clear why this function and `DMCreateFieldIS()` exist. Having two seems redundant and confusing. 2023bb7acecfSBarry Smith 202473ff1848SBarry Smith Unlike `DMRefine()`, `DMCoarsen()`, and `DMCreateDomainDecomposition()` this provides no mechanism to provide hooks that are called after the 202573ff1848SBarry Smith decomposition is computed. 202673ff1848SBarry Smith 202773ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMCreateFieldIS()`, `DMCreateSubDM()`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()` 2028e7c4fc90SDmitry Karpeev @*/ 2029d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 2030d71ae5a4SJacob Faibussowitsch { 2031e7c4fc90SDmitry Karpeev PetscFunctionBegin; 2032e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20338865f1eaSKarl Rupp if (len) { 20344f572ea9SToby Isaac PetscAssertPointer(len, 2); 20358865f1eaSKarl Rupp *len = 0; 20368865f1eaSKarl Rupp } 20378865f1eaSKarl Rupp if (namelist) { 20384f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 2039ea78f98cSLisandro Dalcin *namelist = NULL; 20408865f1eaSKarl Rupp } 20418865f1eaSKarl Rupp if (islist) { 20424f572ea9SToby Isaac PetscAssertPointer(islist, 4); 2043ea78f98cSLisandro Dalcin *islist = NULL; 20448865f1eaSKarl Rupp } 20458865f1eaSKarl Rupp if (dmlist) { 20464f572ea9SToby Isaac PetscAssertPointer(dmlist, 5); 2047ea78f98cSLisandro Dalcin *dmlist = NULL; 20488865f1eaSKarl Rupp } 2049f3f0edfdSDmitry Karpeev /* 2050f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2051f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2052f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2053f3f0edfdSDmitry Karpeev */ 20547a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 205516621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 2056435a35e8SMatthew G Knepley PetscSection section; 2057435a35e8SMatthew G Knepley PetscInt numFields, f; 2058435a35e8SMatthew G Knepley 20599566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 20609566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(section, &numFields)); 2061435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 2062f25d98f1SMatthew G. Knepley if (len) *len = numFields; 20639566063dSJacob Faibussowitsch if (namelist) PetscCall(PetscMalloc1(numFields, namelist)); 20649566063dSJacob Faibussowitsch if (islist) PetscCall(PetscMalloc1(numFields, islist)); 20659566063dSJacob Faibussowitsch if (dmlist) PetscCall(PetscMalloc1(numFields, dmlist)); 2066435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 2067435a35e8SMatthew G Knepley const char *fieldName; 2068435a35e8SMatthew G Knepley 20699566063dSJacob Faibussowitsch PetscCall(DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL)); 207003dc3394SMatthew G. Knepley if (namelist) { 20719566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 20729566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char **)&(*namelist)[f])); 2073435a35e8SMatthew G Knepley } 207403dc3394SMatthew G. Knepley } 2075435a35e8SMatthew G Knepley } else { 20769566063dSJacob Faibussowitsch PetscCall(DMCreateFieldIS(dm, len, namelist, islist)); 2077e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 20780298fd71SBarry Smith if (dmlist) *dmlist = NULL; 2079e7c4fc90SDmitry Karpeev } 2080dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm, createfielddecomposition, len, namelist, islist, dmlist); 20813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208216621825SDmitry Karpeev } 208316621825SDmitry Karpeev 2084412a4547SAlexis Marboeuf /*@C 208520f4b53cSBarry Smith DMCreateSubDM - Returns an `IS` and `DM` encapsulating a subproblem defined by the fields passed in. 208620f4b53cSBarry Smith The fields are defined by `DMCreateFieldIS()`. 2087435a35e8SMatthew G Knepley 2088435a35e8SMatthew G Knepley Not collective 2089435a35e8SMatthew G Knepley 2090435a35e8SMatthew G Knepley Input Parameters: 2091bb7acecfSBarry Smith + dm - The `DM` object 2092bb7acecfSBarry Smith . numFields - The number of fields to select 20932adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 2094435a35e8SMatthew G Knepley 2095435a35e8SMatthew G Knepley Output Parameters: 2096bb7acecfSBarry Smith + is - The global indices for all the degrees of freedom in the new sub `DM` 2097bb7acecfSBarry Smith - subdm - The `DM` for the subproblem 2098435a35e8SMatthew G Knepley 209920f4b53cSBarry Smith Level: intermediate 210020f4b53cSBarry Smith 2101bb7acecfSBarry Smith Note: 2102bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 21035d3b26e6SMatthew G. Knepley 210460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCreateFieldIS()`, `DMCreateFieldDecomposition()`, `DMAddField()`, `DMCreateSuperDM()`, `IS`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 2105435a35e8SMatthew G Knepley @*/ 2106d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2107d71ae5a4SJacob Faibussowitsch { 2108435a35e8SMatthew G Knepley PetscFunctionBegin; 2109435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21104f572ea9SToby Isaac PetscAssertPointer(fields, 3); 21114f572ea9SToby Isaac if (is) PetscAssertPointer(is, 4); 21124f572ea9SToby Isaac if (subdm) PetscAssertPointer(subdm, 5); 2113dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createsubdm, numFields, fields, is, subdm); 21143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2115435a35e8SMatthew G Knepley } 2116435a35e8SMatthew G Knepley 21172adcc780SMatthew G. Knepley /*@C 2118bb7acecfSBarry Smith DMCreateSuperDM - Returns an arrays of `IS` and `DM` encapsulating a superproblem defined by multiple `DM`s passed in. 21192adcc780SMatthew G. Knepley 21202adcc780SMatthew G. Knepley Not collective 21212adcc780SMatthew G. Knepley 2122d8d19677SJose E. Roman Input Parameters: 2123bb7acecfSBarry Smith + dms - The `DM` objects 2124bb7acecfSBarry Smith - n - The number of `DM`s 21252adcc780SMatthew G. Knepley 21262adcc780SMatthew G. Knepley Output Parameters: 2127bb7acecfSBarry Smith + is - The global indices for each of subproblem within the super `DM`, or NULL 2128bb7acecfSBarry Smith - superdm - The `DM` for the superproblem 21292adcc780SMatthew G. Knepley 213020f4b53cSBarry Smith Level: intermediate 213120f4b53cSBarry Smith 2132bb7acecfSBarry Smith Note: 2133bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 21345d3b26e6SMatthew G. Knepley 213573ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateSubDM()`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()`, `DMCreateDomainDecomposition()` 21362adcc780SMatthew G. Knepley @*/ 2137d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt n, IS **is, DM *superdm) 2138d71ae5a4SJacob Faibussowitsch { 21392adcc780SMatthew G. Knepley PetscInt i; 21402adcc780SMatthew G. Knepley 21412adcc780SMatthew G. Knepley PetscFunctionBegin; 21424f572ea9SToby Isaac PetscAssertPointer(dms, 1); 2143ad540459SPierre Jolivet for (i = 0; i < n; ++i) PetscValidHeaderSpecific(dms[i], DM_CLASSID, 1); 21444f572ea9SToby Isaac if (is) PetscAssertPointer(is, 3); 21454f572ea9SToby Isaac PetscAssertPointer(superdm, 4); 2146bb7acecfSBarry Smith PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %" PetscInt_FMT, n); 2147bb7acecfSBarry Smith if (n) { 2148b9d85ea2SLisandro Dalcin DM dm = dms[0]; 214900045ab3SPierre Jolivet PetscCheck(dm->ops->createsuperdm, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No method createsuperdm for DM of type %s", ((PetscObject)dm)->type_name); 2150dbbe0bcdSBarry Smith PetscCall((*dm->ops->createsuperdm)(dms, n, is, superdm)); 21512adcc780SMatthew G. Knepley } 21523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21532adcc780SMatthew G. Knepley } 21542adcc780SMatthew G. Knepley 215516621825SDmitry Karpeev /*@C 2156a4e35b19SJacob Faibussowitsch DMCreateDomainDecomposition - Returns lists of `IS` objects defining a decomposition of a 2157a4e35b19SJacob Faibussowitsch problem into subproblems corresponding to restrictions to pairs of nested subdomains. 215816621825SDmitry Karpeev 215920f4b53cSBarry Smith Not Collective 216016621825SDmitry Karpeev 216116621825SDmitry Karpeev Input Parameter: 2162bb7acecfSBarry Smith . dm - the `DM` object 216316621825SDmitry Karpeev 216416621825SDmitry Karpeev Output Parameters: 216520f4b53cSBarry Smith + n - The number of subproblems in the domain decomposition (or `NULL` if not requested) 216620f4b53cSBarry Smith . namelist - The name for each subdomain (or `NULL` if not requested) 216773ff1848SBarry Smith . innerislist - The global indices for each inner subdomain (or `NULL`, if not requested) 216873ff1848SBarry Smith . outerislist - The global indices for each outer subdomain (or `NULL`, if not requested) 216973ff1848SBarry Smith - dmlist - The `DM`s for each subdomain subproblem (or `NULL`, if not requested; if `NULL` is returned, no `DM`s are defined) 217016621825SDmitry Karpeev 217116621825SDmitry Karpeev Level: intermediate 217216621825SDmitry Karpeev 217373ff1848SBarry Smith Notes: 2174a4e35b19SJacob Faibussowitsch Each `IS` contains the global indices of the dofs of the corresponding subdomains with in the 2175a4e35b19SJacob Faibussowitsch dofs of the original `DM`. The inner subdomains conceptually define a nonoverlapping 2176a4e35b19SJacob Faibussowitsch covering, while outer subdomains can overlap. 2177a4e35b19SJacob Faibussowitsch 2178a4e35b19SJacob Faibussowitsch The optional list of `DM`s define a `DM` for each subproblem. 2179a4e35b19SJacob Faibussowitsch 218073ff1848SBarry Smith The user is responsible for freeing all requested arrays. In particular, every entry of `namelist` should be freed with 218173ff1848SBarry Smith `PetscFree()`, every entry of `innerislist` and `outerislist` should be destroyed with `ISDestroy()`, every entry of `dmlist` should be destroyed with `DMDestroy()`, 2182bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 218316621825SDmitry Karpeev 2184a4e35b19SJacob Faibussowitsch Developer Notes: 218520f4b53cSBarry Smith The `dmlist` is for the inner subdomains or the outer subdomains or all subdomains? 2186bb7acecfSBarry Smith 218773ff1848SBarry Smith The names are inconsistent, the hooks use `DMSubDomainHook` which is nothing like `DMCreateDomainDecomposition()` while `DMRefineHook` is used for `DMRefine()`. 218873ff1848SBarry Smith 218973ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateFieldDecomposition()`, `DMDestroy()`, `DMCreateDomainDecompositionScatters()`, `DMView()`, `DMCreateInterpolation()`, 219073ff1848SBarry Smith `DMSubDomainHookAdd()`, `DMSubDomainHookRemove()`,`DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()` 219116621825SDmitry Karpeev @*/ 2192d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *n, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 2193d71ae5a4SJacob Faibussowitsch { 2194be081cd6SPeter Brune DMSubDomainHookLink link; 2195be081cd6SPeter Brune PetscInt i, l; 219616621825SDmitry Karpeev 219716621825SDmitry Karpeev PetscFunctionBegin; 219816621825SDmitry Karpeev PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21999371c9d4SSatish Balay if (n) { 22004f572ea9SToby Isaac PetscAssertPointer(n, 2); 22019371c9d4SSatish Balay *n = 0; 22029371c9d4SSatish Balay } 22039371c9d4SSatish Balay if (namelist) { 22044f572ea9SToby Isaac PetscAssertPointer(namelist, 3); 22059371c9d4SSatish Balay *namelist = NULL; 22069371c9d4SSatish Balay } 22079371c9d4SSatish Balay if (innerislist) { 22084f572ea9SToby Isaac PetscAssertPointer(innerislist, 4); 22099371c9d4SSatish Balay *innerislist = NULL; 22109371c9d4SSatish Balay } 22119371c9d4SSatish Balay if (outerislist) { 22124f572ea9SToby Isaac PetscAssertPointer(outerislist, 5); 22139371c9d4SSatish Balay *outerislist = NULL; 22149371c9d4SSatish Balay } 22159371c9d4SSatish Balay if (dmlist) { 22164f572ea9SToby Isaac PetscAssertPointer(dmlist, 6); 22179371c9d4SSatish Balay *dmlist = NULL; 22189371c9d4SSatish Balay } 2219f3f0edfdSDmitry Karpeev /* 2220f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2221f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2222f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2223f3f0edfdSDmitry Karpeev */ 22247a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 222516621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 2226dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createdomaindecomposition, &l, namelist, innerislist, outerislist, dmlist); 222714a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 2228f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2229be081cd6SPeter Brune for (i = 0; i < l; i++) { 2230be081cd6SPeter Brune for (link = dm->subdomainhook; link; link = link->next) { 22319566063dSJacob Faibussowitsch if (link->ddhook) PetscCall((*link->ddhook)(dm, (*dmlist)[i], link->ctx)); 2232be081cd6SPeter Brune } 2233648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2234e7c4fc90SDmitry Karpeev } 223514a18fd3SPeter Brune } 2236bb7acecfSBarry Smith if (n) *n = l; 223714a18fd3SPeter Brune } 22383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2239e30e807fSPeter Brune } 2240e30e807fSPeter Brune 2241e30e807fSPeter Brune /*@C 224273ff1848SBarry Smith DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector for subdomains created with 224373ff1848SBarry Smith `DMCreateDomainDecomposition()` 2244e30e807fSPeter Brune 224520f4b53cSBarry Smith Not Collective 2246e30e807fSPeter Brune 2247e30e807fSPeter Brune Input Parameters: 2248bb7acecfSBarry Smith + dm - the `DM` object 224973ff1848SBarry Smith . n - the number of subdomains 2250e30e807fSPeter Brune - subdms - the local subdomains 2251e30e807fSPeter Brune 2252e30e807fSPeter Brune Output Parameters: 22536b867d5aSJose E. Roman + iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2254e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2255e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2256e30e807fSPeter Brune 225720f4b53cSBarry Smith Level: developer 225820f4b53cSBarry Smith 2259bb7acecfSBarry Smith Note: 2260bb7acecfSBarry Smith This is an alternative to the iis and ois arguments in `DMCreateDomainDecomposition()` that allow for the solution 2261e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2262e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2263e30e807fSPeter Brune solution and residual data. 2264e30e807fSPeter Brune 226573ff1848SBarry Smith Developer Note: 2266a4e35b19SJacob Faibussowitsch Can the subdms input be anything or are they exactly the `DM` obtained from 2267a4e35b19SJacob Faibussowitsch `DMCreateDomainDecomposition()`? 2268bb7acecfSBarry Smith 22691cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2270e30e807fSPeter Brune @*/ 2271d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDomainDecompositionScatters(DM dm, PetscInt n, DM *subdms, VecScatter **iscat, VecScatter **oscat, VecScatter **gscat) 2272d71ae5a4SJacob Faibussowitsch { 2273e30e807fSPeter Brune PetscFunctionBegin; 2274e30e807fSPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22754f572ea9SToby Isaac PetscAssertPointer(subdms, 3); 2276dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createddscatters, n, subdms, iscat, oscat, gscat); 22773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2278e7c4fc90SDmitry Karpeev } 2279e7c4fc90SDmitry Karpeev 228047c6ae99SBarry Smith /*@ 2281bb7acecfSBarry Smith DMRefine - Refines a `DM` object using a standard nonadaptive refinement of the underlying mesh 228247c6ae99SBarry Smith 228320f4b53cSBarry Smith Collective 228447c6ae99SBarry Smith 2285d8d19677SJose E. Roman Input Parameters: 2286bb7acecfSBarry Smith + dm - the `DM` object 2287bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 228847c6ae99SBarry Smith 228947c6ae99SBarry Smith Output Parameter: 229020f4b53cSBarry Smith . dmf - the refined `DM`, or `NULL` 2291ae0a1c52SMatthew G Knepley 229220f4b53cSBarry Smith Options Database Key: 2293412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2294412e9a14SMatthew G. Knepley 229547c6ae99SBarry Smith Level: developer 229647c6ae99SBarry Smith 229720f4b53cSBarry Smith Note: 229820f4b53cSBarry Smith If no refinement was done, the return value is `NULL` 229920f4b53cSBarry Smith 230073ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateDomainDecomposition()`, 230173ff1848SBarry Smith `DMRefineHookAdd()`, `DMRefineHookRemove()` 230247c6ae99SBarry Smith @*/ 2303d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine(DM dm, MPI_Comm comm, DM *dmf) 2304d71ae5a4SJacob Faibussowitsch { 2305c833c3b5SJed Brown DMRefineHookLink link; 230647c6ae99SBarry Smith 230747c6ae99SBarry Smith PetscFunctionBegin; 2308732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 23099566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Refine, dm, 0, 0, 0)); 2310dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, refine, comm, dmf); 23114057135bSMatthew G Knepley if (*dmf) { 231243842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 23138865f1eaSKarl Rupp 23149566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmf)); 23158865f1eaSKarl Rupp 2316644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 23170598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2318656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 23198865f1eaSKarl Rupp 23209566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmf, dm->mattype)); 2321c833c3b5SJed Brown for (link = dm->refinehook; link; link = link->next) { 23221baa6e33SBarry Smith if (link->refinehook) PetscCall((*link->refinehook)(dm, *dmf, link->ctx)); 2323c833c3b5SJed Brown } 2324c833c3b5SJed Brown } 23259566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Refine, dm, 0, 0, 0)); 23263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2327c833c3b5SJed Brown } 2328c833c3b5SJed Brown 2329bb9467b5SJed Brown /*@C 2330c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2331c833c3b5SJed Brown 233220f4b53cSBarry Smith Logically Collective; No Fortran Support 2333c833c3b5SJed Brown 23344165533cSJose E. Roman Input Parameters: 2335bb7acecfSBarry Smith + coarse - `DM` on which to run a hook when interpolating to a finer level 2336bb7acecfSBarry Smith . refinehook - function to run when setting up the finer level 2337f826b5fcSPierre Jolivet . interphook - function to run to update data on finer levels (once per `SNESSolve()`) 233820f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2339c833c3b5SJed Brown 234020f4b53cSBarry Smith Calling sequence of `refinehook`: 2341bb7acecfSBarry Smith + coarse - coarse level `DM` 2342bb7acecfSBarry Smith . fine - fine level `DM` to interpolate problem to 2343c833c3b5SJed Brown - ctx - optional user-defined function context 2344c833c3b5SJed Brown 234520f4b53cSBarry Smith Calling sequence of `interphook`: 2346bb7acecfSBarry Smith + coarse - coarse level `DM` 2347c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2348bb7acecfSBarry Smith . fine - fine level `DM` to update 2349c833c3b5SJed Brown - ctx - optional user-defined function context 2350c833c3b5SJed Brown 2351c833c3b5SJed Brown Level: advanced 2352c833c3b5SJed Brown 2353c833c3b5SJed Brown Notes: 2354bb7acecfSBarry Smith This function is only needed if auxiliary data that is attached to the `DM`s via, for example, `PetscObjectCompose()`, needs to be 2355bb7acecfSBarry Smith passed to fine grids while grid sequencing. 2356bb7acecfSBarry Smith 2357bb7acecfSBarry Smith The actual interpolation is done when `DMInterpolate()` is called. 2358c833c3b5SJed Brown 2359c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2360c833c3b5SJed Brown 23611cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2362c833c3b5SJed Brown @*/ 2363a4e35b19SJacob 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) 2364d71ae5a4SJacob Faibussowitsch { 2365c833c3b5SJed Brown DMRefineHookLink link, *p; 2366c833c3b5SJed Brown 2367c833c3b5SJed Brown PetscFunctionBegin; 2368c833c3b5SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 23693d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 23703ba16761SJacob Faibussowitsch if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 23713d8e3701SJed Brown } 23729566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2373c833c3b5SJed Brown link->refinehook = refinehook; 2374c833c3b5SJed Brown link->interphook = interphook; 2375c833c3b5SJed Brown link->ctx = ctx; 23760298fd71SBarry Smith link->next = NULL; 2377c833c3b5SJed Brown *p = link; 23783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2379c833c3b5SJed Brown } 2380c833c3b5SJed Brown 23813d8e3701SJed Brown /*@C 2382bb7acecfSBarry Smith DMRefineHookRemove - remove a callback from the list of hooks, that have been set with `DMRefineHookAdd()`, to be run when interpolating 2383bb7acecfSBarry Smith a nonlinear problem to a finer grid 23843d8e3701SJed Brown 238520f4b53cSBarry Smith Logically Collective; No Fortran Support 23863d8e3701SJed Brown 23874165533cSJose E. Roman Input Parameters: 2388bb7acecfSBarry Smith + coarse - the `DM` on which to run a hook when restricting to a coarser level 2389bb7acecfSBarry Smith . refinehook - function to run when setting up a finer level 2390bb7acecfSBarry Smith . interphook - function to run to update data on finer levels 239120f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 23923d8e3701SJed Brown 23933d8e3701SJed Brown Level: advanced 23943d8e3701SJed Brown 2395bb7acecfSBarry Smith Note: 23963d8e3701SJed Brown This function does nothing if the hook is not in the list. 23973d8e3701SJed Brown 23981cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `DMCoarsenHookRemove()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 23993d8e3701SJed Brown @*/ 2400d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHookRemove(DM coarse, PetscErrorCode (*refinehook)(DM, DM, void *), PetscErrorCode (*interphook)(DM, Mat, DM, void *), void *ctx) 2401d71ae5a4SJacob Faibussowitsch { 24023d8e3701SJed Brown DMRefineHookLink link, *p; 24033d8e3701SJed Brown 24043d8e3701SJed Brown PetscFunctionBegin; 24053d8e3701SJed Brown PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 24063d8e3701SJed Brown for (p = &coarse->refinehook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 24073d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 24083d8e3701SJed Brown link = *p; 24093d8e3701SJed Brown *p = link->next; 24109566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 24113d8e3701SJed Brown break; 24123d8e3701SJed Brown } 24133d8e3701SJed Brown } 24143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24153d8e3701SJed Brown } 24163d8e3701SJed Brown 2417c833c3b5SJed Brown /*@ 2418bb7acecfSBarry Smith DMInterpolate - interpolates user-defined problem data attached to a `DM` to a finer `DM` by running hooks registered by `DMRefineHookAdd()` 2419c833c3b5SJed Brown 2420c833c3b5SJed Brown Collective if any hooks are 2421c833c3b5SJed Brown 24224165533cSJose E. Roman Input Parameters: 2423bb7acecfSBarry Smith + coarse - coarser `DM` to use as a base 2424bb7acecfSBarry Smith . interp - interpolation matrix, apply using `MatInterpolate()` 2425bb7acecfSBarry Smith - fine - finer `DM` to update 2426c833c3b5SJed Brown 2427c833c3b5SJed Brown Level: developer 2428c833c3b5SJed Brown 242973ff1848SBarry Smith Developer Note: 2430bb7acecfSBarry Smith This routine is called `DMInterpolate()` while the hook is called `DMRefineHookAdd()`. It would be better to have an 2431bb7acecfSBarry Smith an API with consistent terminology. 2432bb7acecfSBarry Smith 24331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefineHookAdd()`, `MatInterpolate()` 2434c833c3b5SJed Brown @*/ 2435d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolate(DM coarse, Mat interp, DM fine) 2436d71ae5a4SJacob Faibussowitsch { 2437c833c3b5SJed Brown DMRefineHookLink link; 2438c833c3b5SJed Brown 2439c833c3b5SJed Brown PetscFunctionBegin; 2440c833c3b5SJed Brown for (link = fine->refinehook; link; link = link->next) { 24411baa6e33SBarry Smith if (link->interphook) PetscCall((*link->interphook)(coarse, interp, fine, link->ctx)); 24424057135bSMatthew G Knepley } 24433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 244447c6ae99SBarry Smith } 244547c6ae99SBarry Smith 2446eb3f98d2SBarry Smith /*@ 24471f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 24481f3379b2SToby Isaac 244920f4b53cSBarry Smith Collective 24501f3379b2SToby Isaac 24514165533cSJose E. Roman Input Parameters: 2452bb7acecfSBarry Smith + coarse - coarse `DM` 2453bb7acecfSBarry Smith . fine - fine `DM` 2454bb7acecfSBarry Smith . interp - (optional) the matrix computed by `DMCreateInterpolation()`. Implementations may not need this, but if it 2455bb7acecfSBarry Smith is available it can avoid some recomputation. If it is provided, `MatInterpolate()` will be used if 2456bb7acecfSBarry Smith the coarse `DM` does not have a specialized implementation. 24571f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 24581f3379b2SToby Isaac 24594165533cSJose E. Roman Output Parameter: 24601f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 24611f3379b2SToby Isaac 24621f3379b2SToby Isaac Level: developer 24631f3379b2SToby Isaac 2464bb7acecfSBarry Smith Note: 2465bb7acecfSBarry Smith This function exists because the interpolation of a solution vector between meshes is not always a linear 24661f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 24671f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 24681f3379b2SToby Isaac slope-limiting reconstruction. 24691f3379b2SToby Isaac 247073ff1848SBarry Smith Developer Note: 2471bb7acecfSBarry Smith This doesn't just interpolate "solutions" so its API name is questionable. 2472bb7acecfSBarry Smith 24731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMInterpolate()`, `DMCreateInterpolation()` 24741f3379b2SToby Isaac @*/ 2475d71ae5a4SJacob Faibussowitsch PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 2476d71ae5a4SJacob Faibussowitsch { 24771f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM, DM, Mat, Vec, Vec) = NULL; 24781f3379b2SToby Isaac 24791f3379b2SToby Isaac PetscFunctionBegin; 24801f3379b2SToby Isaac PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 24811f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp, MAT_CLASSID, 3); 24821f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol, VEC_CLASSID, 4); 24831f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol, VEC_CLASSID, 5); 24841f3379b2SToby Isaac 24859566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)coarse, "DMInterpolateSolution_C", &interpsol)); 24861f3379b2SToby Isaac if (interpsol) { 24879566063dSJacob Faibussowitsch PetscCall((*interpsol)(coarse, fine, interp, coarseSol, fineSol)); 24881f3379b2SToby Isaac } else if (interp) { 24899566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, coarseSol, fineSol)); 249098921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 24913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24921f3379b2SToby Isaac } 24931f3379b2SToby Isaac 24941f3379b2SToby Isaac /*@ 2495bb7acecfSBarry Smith DMGetRefineLevel - Gets the number of refinements that have generated this `DM` from some initial `DM`. 2496eb3f98d2SBarry Smith 2497eb3f98d2SBarry Smith Not Collective 2498eb3f98d2SBarry Smith 2499eb3f98d2SBarry Smith Input Parameter: 2500bb7acecfSBarry Smith . dm - the `DM` object 2501eb3f98d2SBarry Smith 2502eb3f98d2SBarry Smith Output Parameter: 2503eb3f98d2SBarry Smith . level - number of refinements 2504eb3f98d2SBarry Smith 2505eb3f98d2SBarry Smith Level: developer 2506eb3f98d2SBarry Smith 2507bb7acecfSBarry Smith Note: 2508bb7acecfSBarry Smith This can be used, by example, to set the number of coarser levels associated with this `DM` for a multigrid solver. 2509bb7acecfSBarry Smith 25101cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2511eb3f98d2SBarry Smith @*/ 2512d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetRefineLevel(DM dm, PetscInt *level) 2513d71ae5a4SJacob Faibussowitsch { 2514eb3f98d2SBarry Smith PetscFunctionBegin; 2515eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2516eb3f98d2SBarry Smith *level = dm->levelup; 25173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2518eb3f98d2SBarry Smith } 2519eb3f98d2SBarry Smith 2520fef3a512SBarry Smith /*@ 2521bb7acecfSBarry Smith DMSetRefineLevel - Sets the number of refinements that have generated this `DM`. 2522fef3a512SBarry Smith 2523fef3a512SBarry Smith Not Collective 2524fef3a512SBarry Smith 2525d8d19677SJose E. Roman Input Parameters: 2526bb7acecfSBarry Smith + dm - the `DM` object 2527fef3a512SBarry Smith - level - number of refinements 2528fef3a512SBarry Smith 2529fef3a512SBarry Smith Level: advanced 2530fef3a512SBarry Smith 253195452b02SPatrick Sanan Notes: 2532bb7acecfSBarry Smith This value is used by `PCMG` to determine how many multigrid levels to use 2533fef3a512SBarry Smith 2534bb7acecfSBarry Smith The values are usually set automatically by the process that is causing the refinements of an initial `DM` by calling this routine. 2535bb7acecfSBarry Smith 25361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRefineLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2537fef3a512SBarry Smith @*/ 2538d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetRefineLevel(DM dm, PetscInt level) 2539d71ae5a4SJacob Faibussowitsch { 2540fef3a512SBarry Smith PetscFunctionBegin; 2541fef3a512SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2542fef3a512SBarry Smith dm->levelup = level; 25433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2544fef3a512SBarry Smith } 2545fef3a512SBarry Smith 2546d410b0cfSMatthew G. Knepley /*@ 2547bb7acecfSBarry Smith DMExtrude - Extrude a `DM` object from a surface 2548d410b0cfSMatthew G. Knepley 254920f4b53cSBarry Smith Collective 2550d410b0cfSMatthew G. Knepley 2551f1a722f8SMatthew G. Knepley Input Parameters: 2552bb7acecfSBarry Smith + dm - the `DM` object 2553d410b0cfSMatthew G. Knepley - layers - the number of extruded cell layers 2554d410b0cfSMatthew G. Knepley 2555d410b0cfSMatthew G. Knepley Output Parameter: 255620f4b53cSBarry Smith . dme - the extruded `DM`, or `NULL` 2557d410b0cfSMatthew G. Knepley 2558d410b0cfSMatthew G. Knepley Level: developer 2559d410b0cfSMatthew G. Knepley 256020f4b53cSBarry Smith Note: 256120f4b53cSBarry Smith If no extrusion was done, the return value is `NULL` 256220f4b53cSBarry Smith 25631cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()` 2564d410b0cfSMatthew G. Knepley @*/ 2565d71ae5a4SJacob Faibussowitsch PetscErrorCode DMExtrude(DM dm, PetscInt layers, DM *dme) 2566d71ae5a4SJacob Faibussowitsch { 2567d410b0cfSMatthew G. Knepley PetscFunctionBegin; 2568d410b0cfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2569dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, extrude, layers, dme); 2570d410b0cfSMatthew G. Knepley if (*dme) { 2571d410b0cfSMatthew G. Knepley (*dme)->ops->creatematrix = dm->ops->creatematrix; 25729566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dme)); 2573d410b0cfSMatthew G. Knepley (*dme)->ctx = dm->ctx; 25749566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dme, dm->mattype)); 2575d410b0cfSMatthew G. Knepley } 25763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2577d410b0cfSMatthew G. Knepley } 2578d410b0cfSMatthew G. Knepley 2579d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2580d71ae5a4SJacob Faibussowitsch { 2581ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2582ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 25834f572ea9SToby Isaac PetscAssertPointer(tdm, 2); 2584ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 25853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2586ca3d3a14SMatthew G. Knepley } 2587ca3d3a14SMatthew G. Knepley 2588d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2589d71ae5a4SJacob Faibussowitsch { 2590ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2591ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 25924f572ea9SToby Isaac PetscAssertPointer(tv, 2); 2593ca3d3a14SMatthew G. Knepley *tv = dm->transform; 25943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2595ca3d3a14SMatthew G. Knepley } 2596ca3d3a14SMatthew G. Knepley 2597ca3d3a14SMatthew G. Knepley /*@ 2598bb7acecfSBarry Smith DMHasBasisTransform - Whether the `DM` employs a basis transformation from functions in global vectors to functions in local vectors 2599ca3d3a14SMatthew G. Knepley 2600ca3d3a14SMatthew G. Knepley Input Parameter: 260120f4b53cSBarry Smith . dm - The `DM` 2602ca3d3a14SMatthew G. Knepley 2603ca3d3a14SMatthew G. Knepley Output Parameter: 260420f4b53cSBarry Smith . flg - `PETSC_TRUE` if a basis transformation should be done 2605ca3d3a14SMatthew G. Knepley 2606ca3d3a14SMatthew G. Knepley Level: developer 2607ca3d3a14SMatthew G. Knepley 26081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPlexGlobalToLocalBasis()`, `DMPlexLocalToGlobalBasis()`, `DMPlexCreateBasisRotation()` 2609ca3d3a14SMatthew G. Knepley @*/ 2610d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2611d71ae5a4SJacob Faibussowitsch { 2612ca3d3a14SMatthew G. Knepley Vec tv; 2613ca3d3a14SMatthew G. Knepley 2614ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2615ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26164f572ea9SToby Isaac PetscAssertPointer(flg, 2); 26179566063dSJacob Faibussowitsch PetscCall(DMGetBasisTransformVec_Internal(dm, &tv)); 2618ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 26193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2620ca3d3a14SMatthew G. Knepley } 2621ca3d3a14SMatthew G. Knepley 2622d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2623d71ae5a4SJacob Faibussowitsch { 2624ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2625ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2626ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2627ca3d3a14SMatthew G. Knepley 2628ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 26299566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 26309566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 26319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 26329566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 26339566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->transformDM)); 26349566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm->transformDM, &ts)); 26359566063dSJacob Faibussowitsch PetscCall(PetscSectionSetNumFields(ts, Nf)); 26369566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(ts, pStart, pEnd)); 2637ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(s, f, &Nc)); 2639ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2640ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2641ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 26429566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &dof)); 2643ca3d3a14SMatthew G. Knepley if (!dof) continue; 26449566063dSJacob Faibussowitsch PetscCall(PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim))); 26459566063dSJacob Faibussowitsch PetscCall(PetscSectionAddDof(ts, p, PetscSqr(cdim))); 2646ca3d3a14SMatthew G. Knepley } 2647ca3d3a14SMatthew G. Knepley } 26489566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(ts)); 26499566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dm->transformDM, &dm->transform)); 26509566063dSJacob Faibussowitsch PetscCall(VecGetArray(dm->transform, &ta)); 2651ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2652ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 26539566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(ts, p, f, &dof)); 2654ca3d3a14SMatthew G. Knepley if (dof) { 2655ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2656ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2657ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2658ca3d3a14SMatthew G. Knepley 2659ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 26609566063dSJacob Faibussowitsch PetscCall((*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx)); 26619566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *)&tva)); 26629566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tva, A, PetscSqr(cdim))); 2663ca3d3a14SMatthew G. Knepley } 2664ca3d3a14SMatthew G. Knepley } 2665ca3d3a14SMatthew G. Knepley } 26669566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(dm->transform, &ta)); 26673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2668ca3d3a14SMatthew G. Knepley } 2669ca3d3a14SMatthew G. Knepley 2670d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2671d71ae5a4SJacob Faibussowitsch { 2672ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2673ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2674ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2675ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2676ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2677ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2678ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 26799566063dSJacob Faibussowitsch if (newdm->transformSetUp) PetscCall(DMConstructBasisTransform_Internal(newdm)); 26803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2681ca3d3a14SMatthew G. Knepley } 2682ca3d3a14SMatthew G. Knepley 2683bb9467b5SJed Brown /*@C 2684bb7acecfSBarry Smith DMGlobalToLocalHookAdd - adds a callback to be run when `DMGlobalToLocal()` is called 2685baf369e7SPeter Brune 268620f4b53cSBarry Smith Logically Collective 2687baf369e7SPeter Brune 26884165533cSJose E. Roman Input Parameters: 2689bb7acecfSBarry Smith + dm - the `DM` 2690bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMGlobalToLocalBegin()` 2691bb7acecfSBarry Smith . endhook - function to run after `DMGlobalToLocalEnd()` has completed 269220f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2693baf369e7SPeter Brune 269420f4b53cSBarry Smith Calling sequence of `beginhook`: 2695a4e35b19SJacob Faibussowitsch + dm - global `DM` 2696baf369e7SPeter Brune . g - global vector 2697baf369e7SPeter Brune . mode - mode 2698baf369e7SPeter Brune . l - local vector 2699baf369e7SPeter Brune - ctx - optional user-defined function context 2700baf369e7SPeter Brune 270120f4b53cSBarry Smith Calling sequence of `endhook`: 2702a4e35b19SJacob Faibussowitsch + dm - global `DM` 2703a4e35b19SJacob Faibussowitsch . g - global vector 2704a4e35b19SJacob Faibussowitsch . mode - mode 2705a4e35b19SJacob Faibussowitsch . l - local vector 2706baf369e7SPeter Brune - ctx - optional user-defined function context 2707baf369e7SPeter Brune 2708baf369e7SPeter Brune Level: advanced 2709baf369e7SPeter Brune 2710bb7acecfSBarry Smith Note: 2711bb7acecfSBarry 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. 2712bb7acecfSBarry Smith 27131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocal()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2714baf369e7SPeter Brune @*/ 2715a4e35b19SJacob 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) 2716d71ae5a4SJacob Faibussowitsch { 2717baf369e7SPeter Brune DMGlobalToLocalHookLink link, *p; 2718baf369e7SPeter Brune 2719baf369e7SPeter Brune PetscFunctionBegin; 2720baf369e7SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2721baf369e7SPeter Brune for (p = &dm->gtolhook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 27229566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2723baf369e7SPeter Brune link->beginhook = beginhook; 2724baf369e7SPeter Brune link->endhook = endhook; 2725baf369e7SPeter Brune link->ctx = ctx; 27260298fd71SBarry Smith link->next = NULL; 2727baf369e7SPeter Brune *p = link; 27283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2729baf369e7SPeter Brune } 2730baf369e7SPeter Brune 2731d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 2732d71ae5a4SJacob Faibussowitsch { 27334c274da1SToby Isaac Mat cMat; 273479769bd5SJed Brown Vec cVec, cBias; 27354c274da1SToby Isaac PetscSection section, cSec; 27364c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 27374c274da1SToby Isaac 27384c274da1SToby Isaac PetscFunctionBegin; 2739a4e35b19SJacob Faibussowitsch (void)g; 2740a4e35b19SJacob Faibussowitsch (void)ctx; 27414c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 27429566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, &cBias)); 27434c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 27445db9a05bSToby Isaac PetscInt nRows; 27455db9a05bSToby Isaac 27469566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 27473ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 27489566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 27499566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 27509566063dSJacob Faibussowitsch PetscCall(MatMult(cMat, l, cVec)); 27519566063dSJacob Faibussowitsch if (cBias) PetscCall(VecAXPY(cVec, 1., cBias)); 27529566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 27534c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 27549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 27554c274da1SToby Isaac if (dof) { 27564c274da1SToby Isaac PetscScalar *vals; 27579566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(cVec, cSec, p, &vals)); 27589566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(l, section, p, vals, INSERT_ALL_VALUES)); 27594c274da1SToby Isaac } 27604c274da1SToby Isaac } 27619566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 27624c274da1SToby Isaac } 27633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27644c274da1SToby Isaac } 27654c274da1SToby Isaac 276647c6ae99SBarry Smith /*@ 276701729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 276801729b5cSPatrick Sanan 276920f4b53cSBarry Smith Neighbor-wise Collective 277001729b5cSPatrick Sanan 277101729b5cSPatrick Sanan Input Parameters: 2772bb7acecfSBarry Smith + dm - the `DM` object 277301729b5cSPatrick Sanan . g - the global vector 2774bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 277501729b5cSPatrick Sanan - l - the local vector 277601729b5cSPatrick Sanan 277720f4b53cSBarry Smith Level: beginner 277820f4b53cSBarry Smith 277901729b5cSPatrick Sanan Notes: 2780bb7acecfSBarry Smith The communication involved in this update can be overlapped with computation by instead using 2781bb7acecfSBarry Smith `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. 2782bb7acecfSBarry Smith 2783bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 278401729b5cSPatrick Sanan 27851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGlobalToLocalHookAdd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, 278660225df5SJacob Faibussowitsch `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, 2787bb7acecfSBarry Smith `DMGlobalToLocalBegin()` `DMGlobalToLocalEnd()` 278801729b5cSPatrick Sanan @*/ 2789d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocal(DM dm, Vec g, InsertMode mode, Vec l) 2790d71ae5a4SJacob Faibussowitsch { 279101729b5cSPatrick Sanan PetscFunctionBegin; 27929566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, g, mode, l)); 27939566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, g, mode, l)); 27943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 279501729b5cSPatrick Sanan } 279601729b5cSPatrick Sanan 279701729b5cSPatrick Sanan /*@ 279847c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 279947c6ae99SBarry Smith 280020f4b53cSBarry Smith Neighbor-wise Collective 280147c6ae99SBarry Smith 280247c6ae99SBarry Smith Input Parameters: 2803bb7acecfSBarry Smith + dm - the `DM` object 280447c6ae99SBarry Smith . g - the global vector 2805bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 280647c6ae99SBarry Smith - l - the local vector 280747c6ae99SBarry Smith 280801729b5cSPatrick Sanan Level: intermediate 280947c6ae99SBarry Smith 2810bb7acecfSBarry Smith Notes: 2811bb7acecfSBarry Smith The operation is completed with `DMGlobalToLocalEnd()` 2812bb7acecfSBarry Smith 2813bb7acecfSBarry Smith One can perform local computations between the `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to overlap communication and computation 2814bb7acecfSBarry Smith 2815bb7acecfSBarry Smith `DMGlobalToLocal()` is a short form of `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` 2816bb7acecfSBarry Smith 2817bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 2818bb7acecfSBarry Smith 281960225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 282047c6ae99SBarry Smith @*/ 2821d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 2822d71ae5a4SJacob Faibussowitsch { 28237128ae9fSMatthew G Knepley PetscSF sf; 2824baf369e7SPeter Brune DMGlobalToLocalHookLink link; 282547c6ae99SBarry Smith 282647c6ae99SBarry Smith PetscFunctionBegin; 2827171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2828baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 28291baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, g, mode, l, link->ctx)); 2830baf369e7SPeter Brune } 28319566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28327128ae9fSMatthew G Knepley if (sf) { 2833ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2834ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2835d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 28367128ae9fSMatthew G Knepley 28377a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28389566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28399566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28409566063dSJacob Faibussowitsch PetscCall(PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE)); 28419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28429566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28437128ae9fSMatthew G Knepley } else { 2844fa1e479aSStefano Zampini PetscUseTypeMethod(dm, globaltolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 28457128ae9fSMatthew G Knepley } 28463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 284747c6ae99SBarry Smith } 284847c6ae99SBarry Smith 284947c6ae99SBarry Smith /*@ 285047c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 285147c6ae99SBarry Smith 285220f4b53cSBarry Smith Neighbor-wise Collective 285347c6ae99SBarry Smith 285447c6ae99SBarry Smith Input Parameters: 2855bb7acecfSBarry Smith + dm - the `DM` object 285647c6ae99SBarry Smith . g - the global vector 2857bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 285847c6ae99SBarry Smith - l - the local vector 285947c6ae99SBarry Smith 286001729b5cSPatrick Sanan Level: intermediate 286147c6ae99SBarry Smith 2862bb7acecfSBarry Smith Note: 2863bb7acecfSBarry Smith See `DMGlobalToLocalBegin()` for details. 2864bb7acecfSBarry Smith 286560225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()` 286647c6ae99SBarry Smith @*/ 2867d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 2868d71ae5a4SJacob Faibussowitsch { 28697128ae9fSMatthew G Knepley PetscSF sf; 2870ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2871ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2872ca3d3a14SMatthew G. Knepley PetscBool transform; 2873baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2874d0295fc0SJunchao Zhang PetscMemType lmtype, gmtype; 287547c6ae99SBarry Smith 287647c6ae99SBarry Smith PetscFunctionBegin; 2877171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 28789566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28799566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 28807128ae9fSMatthew G Knepley if (sf) { 28817a8be351SBarry Smith PetscCheck(mode != ADD_VALUES, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28827128ae9fSMatthew G Knepley 28839566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28849566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28859566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray, MPI_REPLACE)); 28869566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28879566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28889566063dSJacob Faibussowitsch if (transform) PetscCall(DMPlexGlobalToLocalBasis(dm, l)); 28897128ae9fSMatthew G Knepley } else { 2890fa1e479aSStefano Zampini PetscUseTypeMethod(dm, globaltolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 28917128ae9fSMatthew G Knepley } 28929566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalHook_Constraints(dm, g, mode, l, NULL)); 2893baf369e7SPeter Brune for (link = dm->gtolhook; link; link = link->next) { 28949566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 2895baf369e7SPeter Brune } 28963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 289747c6ae99SBarry Smith } 289847c6ae99SBarry Smith 2899d4d07f1eSToby Isaac /*@C 2900d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2901d4d07f1eSToby Isaac 290220f4b53cSBarry Smith Logically Collective 2903d4d07f1eSToby Isaac 29044165533cSJose E. Roman Input Parameters: 2905bb7acecfSBarry Smith + dm - the `DM` 2906bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMLocalToGlobalBegin()` 2907bb7acecfSBarry Smith . endhook - function to run after `DMLocalToGlobalEnd()` has completed 290820f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 2909d4d07f1eSToby Isaac 291020f4b53cSBarry Smith Calling sequence of `beginhook`: 2911a4e35b19SJacob Faibussowitsch + global - global `DM` 2912d4d07f1eSToby Isaac . l - local vector 2913d4d07f1eSToby Isaac . mode - mode 2914d4d07f1eSToby Isaac . g - global vector 2915d4d07f1eSToby Isaac - ctx - optional user-defined function context 2916d4d07f1eSToby Isaac 291720f4b53cSBarry Smith Calling sequence of `endhook`: 2918bb7acecfSBarry Smith + global - global `DM` 2919d4d07f1eSToby Isaac . l - local vector 2920d4d07f1eSToby Isaac . mode - mode 2921d4d07f1eSToby Isaac . g - global vector 2922d4d07f1eSToby Isaac - ctx - optional user-defined function context 2923d4d07f1eSToby Isaac 2924d4d07f1eSToby Isaac Level: advanced 2925d4d07f1eSToby Isaac 29261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMRefineHookAdd()`, `DMGlobalToLocalHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2927d4d07f1eSToby Isaac @*/ 2928a4e35b19SJacob 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) 2929d71ae5a4SJacob Faibussowitsch { 2930d4d07f1eSToby Isaac DMLocalToGlobalHookLink link, *p; 2931d4d07f1eSToby Isaac 2932d4d07f1eSToby Isaac PetscFunctionBegin; 2933d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2934d4d07f1eSToby Isaac for (p = &dm->ltoghook; *p; p = &(*p)->next) { } /* Scan to the end of the current list of hooks */ 29359566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2936d4d07f1eSToby Isaac link->beginhook = beginhook; 2937d4d07f1eSToby Isaac link->endhook = endhook; 2938d4d07f1eSToby Isaac link->ctx = ctx; 2939d4d07f1eSToby Isaac link->next = NULL; 2940d4d07f1eSToby Isaac *p = link; 29413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2942d4d07f1eSToby Isaac } 2943d4d07f1eSToby Isaac 2944d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 2945d71ae5a4SJacob Faibussowitsch { 29464c274da1SToby Isaac PetscFunctionBegin; 2947a4e35b19SJacob Faibussowitsch (void)g; 2948a4e35b19SJacob Faibussowitsch (void)ctx; 29494c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29502b6b7d09SToby Isaac if (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES) { 29512b6b7d09SToby Isaac Mat cMat; 29522b6b7d09SToby Isaac Vec cVec; 29535db9a05bSToby Isaac PetscInt nRows; 29542b6b7d09SToby Isaac PetscSection section, cSec; 29552b6b7d09SToby Isaac PetscInt pStart, pEnd, p, dof; 29562b6b7d09SToby Isaac 29572b6b7d09SToby Isaac PetscCall(DMGetDefaultConstraints(dm, &cSec, &cMat, NULL)); 29582b6b7d09SToby Isaac if (!cMat) PetscFunctionReturn(PETSC_SUCCESS); 29595db9a05bSToby Isaac 29609566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat, &nRows, NULL)); 29613ba16761SJacob Faibussowitsch if (nRows <= 0) PetscFunctionReturn(PETSC_SUCCESS); 29629566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 29639566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat, NULL, &cVec)); 29649566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec, &pStart, &pEnd)); 29654c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 29669566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec, p, &dof)); 29674c274da1SToby Isaac if (dof) { 29684c274da1SToby Isaac PetscInt d; 29694c274da1SToby Isaac PetscScalar *vals; 29709566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(l, section, p, &vals)); 29719566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(cVec, cSec, p, vals, mode)); 29724c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 29734c274da1SToby Isaac * we just extracted */ 2974ad540459SPierre Jolivet for (d = 0; d < dof; d++) vals[d] = 0.; 29754c274da1SToby Isaac } 29764c274da1SToby Isaac } 29779566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd(cMat, cVec, l, l)); 29789566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 29794c274da1SToby Isaac } 29803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29814c274da1SToby Isaac } 298201729b5cSPatrick Sanan /*@ 298301729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 298401729b5cSPatrick Sanan 298520f4b53cSBarry Smith Neighbor-wise Collective 298601729b5cSPatrick Sanan 298701729b5cSPatrick Sanan Input Parameters: 2988bb7acecfSBarry Smith + dm - the `DM` object 298901729b5cSPatrick Sanan . l - the local vector 2990bb7acecfSBarry 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. 299101729b5cSPatrick Sanan - g - the global vector 299201729b5cSPatrick Sanan 299320f4b53cSBarry Smith Level: beginner 299420f4b53cSBarry Smith 299501729b5cSPatrick Sanan Notes: 299601729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 2997bb7acecfSBarry Smith `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. 299801729b5cSPatrick Sanan 2999bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 3000bb7acecfSBarry Smith 3001bb7acecfSBarry 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. 3002bb7acecfSBarry Smith 3003bb7acecfSBarry Smith Use `DMLocalToGlobalHookAdd()` to add additional operations that are performed on the data during the update process 300401729b5cSPatrick Sanan 30051cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalHookAdd()`, `DMGlobaToLocallHookAdd()` 300601729b5cSPatrick Sanan @*/ 3007d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobal(DM dm, Vec l, InsertMode mode, Vec g) 3008d71ae5a4SJacob Faibussowitsch { 300901729b5cSPatrick Sanan PetscFunctionBegin; 30109566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, l, mode, g)); 30119566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, l, mode, g)); 30123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 301301729b5cSPatrick Sanan } 30144c274da1SToby Isaac 301547c6ae99SBarry Smith /*@ 301601729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 30179a42bb27SBarry Smith 301820f4b53cSBarry Smith Neighbor-wise Collective 30199a42bb27SBarry Smith 30209a42bb27SBarry Smith Input Parameters: 3021bb7acecfSBarry Smith + dm - the `DM` object 3022f6813fd5SJed Brown . l - the local vector 3023aa624791SPierre 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. 30241eb28f2eSBarry Smith - g - the global vector 30259a42bb27SBarry Smith 302620f4b53cSBarry Smith Level: intermediate 302720f4b53cSBarry Smith 302895452b02SPatrick Sanan Notes: 3029bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 3030bb7acecfSBarry Smith 3031bb7acecfSBarry 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. 3032bb7acecfSBarry Smith 3033bb7acecfSBarry Smith Use `DMLocalToGlobalEnd()` to complete the communication process. 3034bb7acecfSBarry Smith 3035bb7acecfSBarry Smith `DMLocalToGlobal()` is a short form of `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()` 3036bb7acecfSBarry Smith 3037bb7acecfSBarry Smith `DMLocalToGlobalHookAdd()` may be used to provide additional operations that are performed during the update process. 30389a42bb27SBarry Smith 30391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()` 30409a42bb27SBarry Smith @*/ 3041d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBegin(DM dm, Vec l, InsertMode mode, Vec g) 3042d71ae5a4SJacob Faibussowitsch { 30437128ae9fSMatthew G Knepley PetscSF sf; 304484330215SMatthew G. Knepley PetscSection s, gs; 3045d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3046ca3d3a14SMatthew G. Knepley Vec tmpl; 3047ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3048ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3049fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 3050d0295fc0SJunchao Zhang PetscMemType lmtype = PETSC_MEMTYPE_HOST, gmtype = PETSC_MEMTYPE_HOST; 30519a42bb27SBarry Smith 30529a42bb27SBarry Smith PetscFunctionBegin; 3053171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3054d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 30551baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm, l, mode, g, link->ctx)); 3056d4d07f1eSToby Isaac } 30579566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalHook_Constraints(dm, l, mode, g, NULL)); 30589566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 30599566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 30607128ae9fSMatthew G Knepley switch (mode) { 30617128ae9fSMatthew G Knepley case INSERT_VALUES: 30627128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 3063d71ae5a4SJacob Faibussowitsch case INSERT_BC_VALUES: 3064d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3065d71ae5a4SJacob Faibussowitsch break; 30667128ae9fSMatthew G Knepley case ADD_VALUES: 30677128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 3068d71ae5a4SJacob Faibussowitsch case ADD_BC_VALUES: 3069d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3070d71ae5a4SJacob Faibussowitsch break; 3071d71ae5a4SJacob Faibussowitsch default: 3072d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 30737128ae9fSMatthew G Knepley } 3074ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 30759566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3076ca3d3a14SMatthew G. Knepley if (transform) { 30779566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 30789566063dSJacob Faibussowitsch PetscCall(VecCopy(l, tmpl)); 30799566063dSJacob Faibussowitsch PetscCall(DMPlexLocalToGlobalBasis(dm, tmpl)); 30809566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3081fa88e482SJed Brown } else if (isInsert) { 30829566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(l, &lArray)); 3083fa88e482SJed Brown } else { 30849566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, &lmtype)); 3085fa88e482SJed Brown l_inplace = PETSC_TRUE; 3086ca3d3a14SMatthew G. Knepley } 3087fa88e482SJed Brown if (s && isInsert) { 30889566063dSJacob Faibussowitsch PetscCall(VecGetArray(g, &gArray)); 3089fa88e482SJed Brown } else { 30909566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, &gmtype)); 3091fa88e482SJed Brown g_inplace = PETSC_TRUE; 3092fa88e482SJed Brown } 3093ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 30949566063dSJacob Faibussowitsch PetscCall(PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM)); 309584330215SMatthew G. Knepley } else if (s && isInsert) { 309684330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 309784330215SMatthew G. Knepley 30989566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 30999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 31009566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g, &gStart, NULL)); 310184330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3102b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 310384330215SMatthew G. Knepley 31049566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 31059566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(gs, p, &gdof)); 31069566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 31079566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(gs, p, &gcdof)); 31089566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(s, p, &off)); 31099566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(gs, p, &goff)); 3110b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 311103442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 31127a8be351SBarry 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); 3113b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 3114b3b16f48SMatthew G. Knepley if (!gcdof) { 311584330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff - gStart + d] = lArray[off + d]; 3116b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 3117b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 311884330215SMatthew G. Knepley const PetscInt *cdofs; 311984330215SMatthew G. Knepley PetscInt cind = 0; 312084330215SMatthew G. Knepley 31219566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(s, p, &cdofs)); 3122b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 31239371c9d4SSatish Balay if ((cind < cdof) && (d == cdofs[cind])) { 31249371c9d4SSatish Balay ++cind; 31259371c9d4SSatish Balay continue; 31269371c9d4SSatish Balay } 3127b3b16f48SMatthew G. Knepley gArray[goff - gStart + e++] = lArray[off + d]; 312884330215SMatthew G. Knepley } 31297a8be351SBarry 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); 313084330215SMatthew G. Knepley } 3131ca3d3a14SMatthew G. Knepley } 3132fa88e482SJed Brown if (g_inplace) { 31339566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 3134fa88e482SJed Brown } else { 31359566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(g, &gArray)); 3136fa88e482SJed Brown } 3137ca3d3a14SMatthew G. Knepley if (transform) { 31389566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31399566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3140fa88e482SJed Brown } else if (l_inplace) { 31419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3142ca3d3a14SMatthew G. Knepley } else { 31439566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(l, &lArray)); 3144ca3d3a14SMatthew G. Knepley } 31457128ae9fSMatthew G Knepley } else { 3146fa1e479aSStefano Zampini PetscUseTypeMethod(dm, localtoglobalbegin, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g); 31477128ae9fSMatthew G Knepley } 31483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31499a42bb27SBarry Smith } 31509a42bb27SBarry Smith 31519a42bb27SBarry Smith /*@ 31529a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 315347c6ae99SBarry Smith 315420f4b53cSBarry Smith Neighbor-wise Collective 315547c6ae99SBarry Smith 315647c6ae99SBarry Smith Input Parameters: 3157bb7acecfSBarry Smith + dm - the `DM` object 3158f6813fd5SJed Brown . l - the local vector 3159bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 3160f6813fd5SJed Brown - g - the global vector 316147c6ae99SBarry Smith 316201729b5cSPatrick Sanan Level: intermediate 316347c6ae99SBarry Smith 3164bb7acecfSBarry Smith Note: 3165bb7acecfSBarry Smith See `DMLocalToGlobalBegin()` for full details 3166bb7acecfSBarry Smith 316760225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToGlobalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()` 316847c6ae99SBarry Smith @*/ 3169d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEnd(DM dm, Vec l, InsertMode mode, Vec g) 3170d71ae5a4SJacob Faibussowitsch { 31717128ae9fSMatthew G Knepley PetscSF sf; 317284330215SMatthew G. Knepley PetscSection s; 3173d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3174ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 317547c6ae99SBarry Smith 317647c6ae99SBarry Smith PetscFunctionBegin; 3177171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 31789566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 31799566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 31807128ae9fSMatthew G Knepley switch (mode) { 31817128ae9fSMatthew G Knepley case INSERT_VALUES: 3182d71ae5a4SJacob Faibussowitsch case INSERT_ALL_VALUES: 3183d71ae5a4SJacob Faibussowitsch isInsert = PETSC_TRUE; 3184d71ae5a4SJacob Faibussowitsch break; 31857128ae9fSMatthew G Knepley case ADD_VALUES: 3186d71ae5a4SJacob Faibussowitsch case ADD_ALL_VALUES: 3187d71ae5a4SJacob Faibussowitsch isInsert = PETSC_FALSE; 3188d71ae5a4SJacob Faibussowitsch break; 3189d71ae5a4SJacob Faibussowitsch default: 3190d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 31917128ae9fSMatthew G Knepley } 319284330215SMatthew G. Knepley if (sf && !isInsert) { 3193ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3194ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3195ca3d3a14SMatthew G. Knepley Vec tmpl; 319684330215SMatthew G. Knepley 31979566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3198ca3d3a14SMatthew G. Knepley if (transform) { 31999566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 32009566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3201ca3d3a14SMatthew G. Knepley } else { 32029566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, NULL)); 3203ca3d3a14SMatthew G. Knepley } 32049566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, NULL)); 32059566063dSJacob Faibussowitsch PetscCall(PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM)); 3206ca3d3a14SMatthew G. Knepley if (transform) { 32079566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 32089566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3209ca3d3a14SMatthew G. Knepley } else { 32109566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3211ca3d3a14SMatthew G. Knepley } 32129566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 321384330215SMatthew G. Knepley } else if (s && isInsert) { 32147128ae9fSMatthew G Knepley } else { 3215fa1e479aSStefano Zampini PetscUseTypeMethod(dm, localtoglobalend, l, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), g); 32167128ae9fSMatthew G Knepley } 3217d4d07f1eSToby Isaac for (link = dm->ltoghook; link; link = link->next) { 32189566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm, g, mode, l, link->ctx)); 3219d4d07f1eSToby Isaac } 32203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 322147c6ae99SBarry Smith } 322247c6ae99SBarry Smith 3223f089877aSRichard Tran Mills /*@ 3224a4e35b19SJacob Faibussowitsch DMLocalToLocalBegin - Begins the process of mapping values from a local vector (that include 3225a4e35b19SJacob Faibussowitsch ghost points that contain irrelevant values) to another local vector where the ghost points 3226a4e35b19SJacob Faibussowitsch in the second are set correctly from values on other MPI ranks. 3227f089877aSRichard Tran Mills 322820f4b53cSBarry Smith Neighbor-wise Collective 3229f089877aSRichard Tran Mills 3230f089877aSRichard Tran Mills Input Parameters: 3231bb7acecfSBarry Smith + dm - the `DM` object 3232bc0a1609SRichard Tran Mills . g - the original local vector 3233bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3234f089877aSRichard Tran Mills 3235bc0a1609SRichard Tran Mills Output Parameter: 3236bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3237f089877aSRichard Tran Mills 3238f089877aSRichard Tran Mills Level: intermediate 3239f089877aSRichard Tran Mills 324073ff1848SBarry Smith Note: 3241a4e35b19SJacob Faibussowitsch Must be followed by `DMLocalToLocalEnd()`. 3242a4e35b19SJacob Faibussowitsch 324360225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3244f089877aSRichard Tran Mills @*/ 3245d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBegin(DM dm, Vec g, InsertMode mode, Vec l) 3246d71ae5a4SJacob Faibussowitsch { 3247f089877aSRichard Tran Mills PetscFunctionBegin; 3248f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32499f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 32509f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 32519f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalbegin, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 32523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3253f089877aSRichard Tran Mills } 3254f089877aSRichard Tran Mills 3255f089877aSRichard Tran Mills /*@ 3256bb7acecfSBarry Smith DMLocalToLocalEnd - Maps from a local vector to another local vector where the ghost 3257bb7acecfSBarry Smith points in the second are set correctly. Must be preceded by `DMLocalToLocalBegin()`. 3258f089877aSRichard Tran Mills 325920f4b53cSBarry Smith Neighbor-wise Collective 3260f089877aSRichard Tran Mills 3261f089877aSRichard Tran Mills Input Parameters: 326260225df5SJacob Faibussowitsch + dm - the `DM` object 3263bc0a1609SRichard Tran Mills . g - the original local vector 3264bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3265f089877aSRichard Tran Mills 3266bc0a1609SRichard Tran Mills Output Parameter: 3267bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3268f089877aSRichard Tran Mills 3269f089877aSRichard Tran Mills Level: intermediate 3270f089877aSRichard Tran Mills 327160225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLocalToLocalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3272f089877aSRichard Tran Mills @*/ 3273d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd(DM dm, Vec g, InsertMode mode, Vec l) 3274d71ae5a4SJacob Faibussowitsch { 3275f089877aSRichard Tran Mills PetscFunctionBegin; 3276f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32779f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 32789f4ada15SMatthew G. Knepley PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 32799f4ada15SMatthew G. Knepley PetscUseTypeMethod(dm, localtolocalend, g, mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode), l); 32803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3281f089877aSRichard Tran Mills } 3282f089877aSRichard Tran Mills 328347c6ae99SBarry Smith /*@ 3284bb7acecfSBarry Smith DMCoarsen - Coarsens a `DM` object using a standard, non-adaptive coarsening of the underlying mesh 328547c6ae99SBarry Smith 328620f4b53cSBarry Smith Collective 328747c6ae99SBarry Smith 3288d8d19677SJose E. Roman Input Parameters: 3289bb7acecfSBarry Smith + dm - the `DM` object 329020f4b53cSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 329147c6ae99SBarry Smith 329247c6ae99SBarry Smith Output Parameter: 3293bb7acecfSBarry Smith . dmc - the coarsened `DM` 329447c6ae99SBarry Smith 329547c6ae99SBarry Smith Level: developer 329647c6ae99SBarry Smith 329773ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMRefine()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateDomainDecomposition()`, 329873ff1848SBarry Smith `DMCoarsenHookAdd()`, `DMCoarsenHookRemove()` 329947c6ae99SBarry Smith @*/ 3300d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 3301d71ae5a4SJacob Faibussowitsch { 3302b17ce1afSJed Brown DMCoarsenHookLink link; 330347c6ae99SBarry Smith 330447c6ae99SBarry Smith PetscFunctionBegin; 3305171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 33069566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Coarsen, dm, 0, 0, 0)); 3307dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, coarsen, comm, dmc); 3308b9d85ea2SLisandro Dalcin if (*dmc) { 3309a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 33109566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm, *dmc)); 331143842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 33129566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm, (PetscObject)*dmc)); 3313644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 33140598a293SJed Brown (*dmc)->levelup = dm->levelup; 3315656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 33169566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmc, dm->mattype)); 3317b17ce1afSJed Brown for (link = dm->coarsenhook; link; link = link->next) { 33189566063dSJacob Faibussowitsch if (link->coarsenhook) PetscCall((*link->coarsenhook)(dm, *dmc, link->ctx)); 3319b17ce1afSJed Brown } 3320b9d85ea2SLisandro Dalcin } 33219566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Coarsen, dm, 0, 0, 0)); 33227a8be351SBarry Smith PetscCheck(*dmc, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 33233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3324b17ce1afSJed Brown } 3325b17ce1afSJed Brown 3326bb9467b5SJed Brown /*@C 3327b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3328b17ce1afSJed Brown 332920f4b53cSBarry Smith Logically Collective; No Fortran Support 3330b17ce1afSJed Brown 33314165533cSJose E. Roman Input Parameters: 3332bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3333b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3334bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels (called once per `SNESSolve()`) 333520f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3336b17ce1afSJed Brown 333720f4b53cSBarry Smith Calling sequence of `coarsenhook`: 3338bb7acecfSBarry Smith + fine - fine level `DM` 3339bb7acecfSBarry Smith . coarse - coarse level `DM` to restrict problem to 3340b17ce1afSJed Brown - ctx - optional user-defined function context 3341b17ce1afSJed Brown 334220f4b53cSBarry Smith Calling sequence of `restricthook`: 3343bb7acecfSBarry Smith + fine - fine level `DM` 3344bb7acecfSBarry Smith . mrestrict - matrix restricting a fine-level solution to the coarse grid, usually the transpose of the interpolation 3345c833c3b5SJed Brown . rscale - scaling vector for restriction 3346c833c3b5SJed Brown . inject - matrix restricting by injection 3347b17ce1afSJed Brown . coarse - coarse level DM to update 3348b17ce1afSJed Brown - ctx - optional user-defined function context 3349b17ce1afSJed Brown 3350b17ce1afSJed Brown Level: advanced 3351b17ce1afSJed Brown 3352b17ce1afSJed Brown Notes: 3353bb7acecfSBarry 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`. 3354b17ce1afSJed Brown 3355b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3356b17ce1afSJed Brown 3357b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3358bb7acecfSBarry Smith extract the finest level information from its context (instead of from the `SNES`). 3359b17ce1afSJed Brown 3360bb7acecfSBarry Smith The hooks are automatically called by `DMRestrict()` 3361bb7acecfSBarry Smith 33621cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3363b17ce1afSJed Brown @*/ 3364a4e35b19SJacob 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) 3365d71ae5a4SJacob Faibussowitsch { 3366b17ce1afSJed Brown DMCoarsenHookLink link, *p; 3367b17ce1afSJed Brown 3368b17ce1afSJed Brown PetscFunctionBegin; 3369b17ce1afSJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 33701e3d8eccSJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 33713ba16761SJacob Faibussowitsch if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 33721e3d8eccSJed Brown } 33739566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3374b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3375b17ce1afSJed Brown link->restricthook = restricthook; 3376b17ce1afSJed Brown link->ctx = ctx; 33770298fd71SBarry Smith link->next = NULL; 3378b17ce1afSJed Brown *p = link; 33793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3380b17ce1afSJed Brown } 3381b17ce1afSJed Brown 3382dc822a44SJed Brown /*@C 3383bb7acecfSBarry Smith DMCoarsenHookRemove - remove a callback set with `DMCoarsenHookAdd()` 3384dc822a44SJed Brown 338520f4b53cSBarry Smith Logically Collective; No Fortran Support 3386dc822a44SJed Brown 33874165533cSJose E. Roman Input Parameters: 3388bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3389dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3390bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels 339120f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3392dc822a44SJed Brown 3393dc822a44SJed Brown Level: advanced 3394dc822a44SJed Brown 339573ff1848SBarry Smith Notes: 339673ff1848SBarry Smith This function does nothing if the `coarsenhook` is not in the list. 339773ff1848SBarry Smith 339873ff1848SBarry Smith See `DMCoarsenHookAdd()` for the calling sequence of `coarsenhook` and `restricthook` 3399dc822a44SJed Brown 34001cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3401dc822a44SJed Brown @*/ 3402d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHookRemove(DM fine, PetscErrorCode (*coarsenhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, Mat, Vec, Mat, DM, void *), void *ctx) 3403d71ae5a4SJacob Faibussowitsch { 3404dc822a44SJed Brown DMCoarsenHookLink link, *p; 3405dc822a44SJed Brown 3406dc822a44SJed Brown PetscFunctionBegin; 3407dc822a44SJed Brown PetscValidHeaderSpecific(fine, DM_CLASSID, 1); 3408dc822a44SJed Brown for (p = &fine->coarsenhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3409dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3410dc822a44SJed Brown link = *p; 3411dc822a44SJed Brown *p = link->next; 34129566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3413dc822a44SJed Brown break; 3414dc822a44SJed Brown } 3415dc822a44SJed Brown } 34163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3417dc822a44SJed Brown } 3418dc822a44SJed Brown 3419b17ce1afSJed Brown /*@ 3420bb7acecfSBarry Smith DMRestrict - restricts user-defined problem data to a coarser `DM` by running hooks registered by `DMCoarsenHookAdd()` 3421b17ce1afSJed Brown 3422b17ce1afSJed Brown Collective if any hooks are 3423b17ce1afSJed Brown 34244165533cSJose E. Roman Input Parameters: 3425bb7acecfSBarry Smith + fine - finer `DM` from which the data is obtained 3426bb7acecfSBarry Smith . restrct - restriction matrix, apply using `MatRestrict()`, usually the transpose of the interpolation 3427e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3428bb7acecfSBarry Smith . inject - injection matrix, also use `MatRestrict()` 342920f4b53cSBarry Smith - coarse - coarser `DM` to update 3430b17ce1afSJed Brown 3431b17ce1afSJed Brown Level: developer 3432b17ce1afSJed Brown 343373ff1848SBarry Smith Developer Note: 3434bb7acecfSBarry Smith Though this routine is called `DMRestrict()` the hooks are added with `DMCoarsenHookAdd()`, a consistent terminology would be better 3435bb7acecfSBarry Smith 34361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `MatRestrict()`, `DMInterpolate()`, `DMRefineHookAdd()` 3437b17ce1afSJed Brown @*/ 3438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRestrict(DM fine, Mat restrct, Vec rscale, Mat inject, DM coarse) 3439d71ae5a4SJacob Faibussowitsch { 3440b17ce1afSJed Brown DMCoarsenHookLink link; 3441b17ce1afSJed Brown 3442b17ce1afSJed Brown PetscFunctionBegin; 3443b17ce1afSJed Brown for (link = fine->coarsenhook; link; link = link->next) { 34441baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(fine, restrct, rscale, inject, coarse, link->ctx)); 3445b17ce1afSJed Brown } 34463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 344747c6ae99SBarry Smith } 344847c6ae99SBarry Smith 3449bb9467b5SJed Brown /*@C 345073ff1848SBarry Smith DMSubDomainHookAdd - adds a callback to be run when restricting a problem to subdomain `DM`s with `DMCreateDomainDecomposition()` 34515dbd56e3SPeter Brune 345220f4b53cSBarry Smith Logically Collective; No Fortran Support 34535dbd56e3SPeter Brune 34544165533cSJose E. Roman Input Parameters: 3455bb7acecfSBarry Smith + global - global `DM` 3456bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 34575dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 345820f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 34595dbd56e3SPeter Brune 346020f4b53cSBarry Smith Calling sequence of `ddhook`: 3461bb7acecfSBarry Smith + global - global `DM` 346273ff1848SBarry Smith . block - subdomain `DM` 3463ec4806b8SPeter Brune - ctx - optional user-defined function context 3464ec4806b8SPeter Brune 346520f4b53cSBarry Smith Calling sequence of `restricthook`: 3466bb7acecfSBarry Smith + global - global `DM` 346773ff1848SBarry Smith . out - scatter to the outer (with ghost and overlap points) sub vector 346873ff1848SBarry Smith . in - scatter to sub vector values only owned locally 346973ff1848SBarry Smith . block - subdomain `DM` 34705dbd56e3SPeter Brune - ctx - optional user-defined function context 34715dbd56e3SPeter Brune 34725dbd56e3SPeter Brune Level: advanced 34735dbd56e3SPeter Brune 34745dbd56e3SPeter Brune Notes: 347573ff1848SBarry Smith This function can be used if auxiliary data needs to be set up on subdomain `DM`s. 34765dbd56e3SPeter Brune 34775dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 34785dbd56e3SPeter Brune 34795dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3480bb7acecfSBarry Smith extract the global information from its context (instead of from the `SNES`). 34815dbd56e3SPeter Brune 348273ff1848SBarry Smith Developer Note: 348373ff1848SBarry Smith It is unclear what "block solve" means within the definition of `restricthook` 348473ff1848SBarry Smith 348573ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()`, `DMCreateDomainDecomposition()` 34865dbd56e3SPeter Brune @*/ 3487a4e35b19SJacob 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) 3488d71ae5a4SJacob Faibussowitsch { 3489be081cd6SPeter Brune DMSubDomainHookLink link, *p; 34905dbd56e3SPeter Brune 34915dbd56e3SPeter Brune PetscFunctionBegin; 34925dbd56e3SPeter Brune PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3493b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Scan to the end of the current list of hooks */ 34943ba16761SJacob Faibussowitsch if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(PETSC_SUCCESS); 3495b3a6b972SJed Brown } 34969566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 34975dbd56e3SPeter Brune link->restricthook = restricthook; 3498be081cd6SPeter Brune link->ddhook = ddhook; 34995dbd56e3SPeter Brune link->ctx = ctx; 35000298fd71SBarry Smith link->next = NULL; 35015dbd56e3SPeter Brune *p = link; 35023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35035dbd56e3SPeter Brune } 35045dbd56e3SPeter Brune 3505b3a6b972SJed Brown /*@C 350673ff1848SBarry Smith DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to subdomain `DM`s with `DMCreateDomainDecomposition()` 3507b3a6b972SJed Brown 350820f4b53cSBarry Smith Logically Collective; No Fortran Support 3509b3a6b972SJed Brown 35104165533cSJose E. Roman Input Parameters: 3511bb7acecfSBarry Smith + global - global `DM` 3512bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 3513b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 351420f4b53cSBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be `NULL`) 3515b3a6b972SJed Brown 3516b3a6b972SJed Brown Level: advanced 3517b3a6b972SJed Brown 351873ff1848SBarry Smith Note: 351973ff1848SBarry Smith See `DMSubDomainHookAdd()` for the calling sequences of `ddhook` and `restricthook` 352073ff1848SBarry Smith 352173ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSubDomainHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()`, 352273ff1848SBarry Smith `DMCreateDomainDecomposition()` 3523b3a6b972SJed Brown @*/ 3524d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainHookRemove(DM global, PetscErrorCode (*ddhook)(DM, DM, void *), PetscErrorCode (*restricthook)(DM, VecScatter, VecScatter, DM, void *), void *ctx) 3525d71ae5a4SJacob Faibussowitsch { 3526b3a6b972SJed Brown DMSubDomainHookLink link, *p; 3527b3a6b972SJed Brown 3528b3a6b972SJed Brown PetscFunctionBegin; 3529b3a6b972SJed Brown PetscValidHeaderSpecific(global, DM_CLASSID, 1); 3530b3a6b972SJed Brown for (p = &global->subdomainhook; *p; p = &(*p)->next) { /* Search the list of current hooks */ 3531b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3532b3a6b972SJed Brown link = *p; 3533b3a6b972SJed Brown *p = link->next; 35349566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3535b3a6b972SJed Brown break; 3536b3a6b972SJed Brown } 3537b3a6b972SJed Brown } 35383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3539b3a6b972SJed Brown } 3540b3a6b972SJed Brown 35415dbd56e3SPeter Brune /*@ 354273ff1848SBarry Smith DMSubDomainRestrict - restricts user-defined problem data to a subdomain `DM` by running hooks registered by `DMSubDomainHookAdd()` 35435dbd56e3SPeter Brune 35445dbd56e3SPeter Brune Collective if any hooks are 35455dbd56e3SPeter Brune 35464165533cSJose E. Roman Input Parameters: 3547a4e35b19SJacob Faibussowitsch + global - The global `DM` to use as a base 3548a4e35b19SJacob Faibussowitsch . oscatter - The scatter from domain global vector filling subdomain global vector with overlap 3549a4e35b19SJacob Faibussowitsch . gscatter - The scatter from domain global vector filling subdomain local vector with ghosts 3550a4e35b19SJacob Faibussowitsch - subdm - The subdomain `DM` to update 35515dbd56e3SPeter Brune 35525dbd56e3SPeter Brune Level: developer 35535dbd56e3SPeter Brune 355473ff1848SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsenHookAdd()`, `MatRestrict()`, `DMCreateDomainDecomposition()` 35555dbd56e3SPeter Brune @*/ 3556d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSubDomainRestrict(DM global, VecScatter oscatter, VecScatter gscatter, DM subdm) 3557d71ae5a4SJacob Faibussowitsch { 3558be081cd6SPeter Brune DMSubDomainHookLink link; 35595dbd56e3SPeter Brune 35605dbd56e3SPeter Brune PetscFunctionBegin; 3561be081cd6SPeter Brune for (link = global->subdomainhook; link; link = link->next) { 35621baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(global, oscatter, gscatter, subdm, link->ctx)); 35635dbd56e3SPeter Brune } 35643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35655dbd56e3SPeter Brune } 35665dbd56e3SPeter Brune 35675fe1f584SPeter Brune /*@ 3568bb7acecfSBarry Smith DMGetCoarsenLevel - Gets the number of coarsenings that have generated this `DM`. 35695fe1f584SPeter Brune 35705fe1f584SPeter Brune Not Collective 35715fe1f584SPeter Brune 35725fe1f584SPeter Brune Input Parameter: 3573bb7acecfSBarry Smith . dm - the `DM` object 35745fe1f584SPeter Brune 35755fe1f584SPeter Brune Output Parameter: 35766a7d9d85SPeter Brune . level - number of coarsenings 35775fe1f584SPeter Brune 35785fe1f584SPeter Brune Level: developer 35795fe1f584SPeter Brune 35801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMSetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35815fe1f584SPeter Brune @*/ 3582d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarsenLevel(DM dm, PetscInt *level) 3583d71ae5a4SJacob Faibussowitsch { 35845fe1f584SPeter Brune PetscFunctionBegin; 35855fe1f584SPeter Brune PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 35864f572ea9SToby Isaac PetscAssertPointer(level, 2); 35875fe1f584SPeter Brune *level = dm->leveldown; 35883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35895fe1f584SPeter Brune } 35905fe1f584SPeter Brune 35919a64c4a8SMatthew G. Knepley /*@ 3592bb7acecfSBarry Smith DMSetCoarsenLevel - Sets the number of coarsenings that have generated this `DM`. 35939a64c4a8SMatthew G. Knepley 359420f4b53cSBarry Smith Collective 35959a64c4a8SMatthew G. Knepley 35969a64c4a8SMatthew G. Knepley Input Parameters: 3597bb7acecfSBarry Smith + dm - the `DM` object 35989a64c4a8SMatthew G. Knepley - level - number of coarsenings 35999a64c4a8SMatthew G. Knepley 36009a64c4a8SMatthew G. Knepley Level: developer 36019a64c4a8SMatthew G. Knepley 3602bb7acecfSBarry Smith Note: 3603bb7acecfSBarry Smith This is rarely used directly, the information is automatically set when a `DM` is created with `DMCoarsen()` 3604bb7acecfSBarry Smith 360542747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 36069a64c4a8SMatthew G. Knepley @*/ 3607d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarsenLevel(DM dm, PetscInt level) 3608d71ae5a4SJacob Faibussowitsch { 36099a64c4a8SMatthew G. Knepley PetscFunctionBegin; 36109a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36119a64c4a8SMatthew G. Knepley dm->leveldown = level; 36123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36139a64c4a8SMatthew G. Knepley } 36149a64c4a8SMatthew G. Knepley 361547c6ae99SBarry Smith /*@C 3616bb7acecfSBarry Smith DMRefineHierarchy - Refines a `DM` object, all levels at once 361747c6ae99SBarry Smith 361820f4b53cSBarry Smith Collective 361947c6ae99SBarry Smith 3620d8d19677SJose E. Roman Input Parameters: 3621bb7acecfSBarry Smith + dm - the `DM` object 362247c6ae99SBarry Smith - nlevels - the number of levels of refinement 362347c6ae99SBarry Smith 362447c6ae99SBarry Smith Output Parameter: 3625bb7acecfSBarry Smith . dmf - the refined `DM` hierarchy 362647c6ae99SBarry Smith 362747c6ae99SBarry Smith Level: developer 362847c6ae99SBarry Smith 36291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMCoarsenHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 363047c6ae99SBarry Smith @*/ 3631d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefineHierarchy(DM dm, PetscInt nlevels, DM dmf[]) 3632d71ae5a4SJacob Faibussowitsch { 363347c6ae99SBarry Smith PetscFunctionBegin; 3634171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36357a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36363ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 36374f572ea9SToby Isaac PetscAssertPointer(dmf, 3); 3638213acdd3SPierre Jolivet if (dm->ops->refine && !dm->ops->refinehierarchy) { 363947c6ae99SBarry Smith PetscInt i; 364047c6ae99SBarry Smith 36419566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0])); 364248a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i])); 3643213acdd3SPierre Jolivet } else PetscUseTypeMethod(dm, refinehierarchy, nlevels, dmf); 36443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 364547c6ae99SBarry Smith } 364647c6ae99SBarry Smith 364747c6ae99SBarry Smith /*@C 3648bb7acecfSBarry Smith DMCoarsenHierarchy - Coarsens a `DM` object, all levels at once 364947c6ae99SBarry Smith 365020f4b53cSBarry Smith Collective 365147c6ae99SBarry Smith 3652d8d19677SJose E. Roman Input Parameters: 3653bb7acecfSBarry Smith + dm - the `DM` object 365447c6ae99SBarry Smith - nlevels - the number of levels of coarsening 365547c6ae99SBarry Smith 365647c6ae99SBarry Smith Output Parameter: 3657bb7acecfSBarry Smith . dmc - the coarsened `DM` hierarchy 365847c6ae99SBarry Smith 365947c6ae99SBarry Smith Level: developer 366047c6ae99SBarry Smith 36611cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCoarsen()`, `DMRefineHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 366247c6ae99SBarry Smith @*/ 3663d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 3664d71ae5a4SJacob Faibussowitsch { 366547c6ae99SBarry Smith PetscFunctionBegin; 3666171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36677a8be351SBarry Smith PetscCheck(nlevels >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "nlevels cannot be negative"); 36683ba16761SJacob Faibussowitsch if (nlevels == 0) PetscFunctionReturn(PETSC_SUCCESS); 36694f572ea9SToby Isaac PetscAssertPointer(dmc, 3); 3670213acdd3SPierre Jolivet if (dm->ops->coarsen && !dm->ops->coarsenhierarchy) { 367147c6ae99SBarry Smith PetscInt i; 367247c6ae99SBarry Smith 36739566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0])); 367448a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i])); 3675213acdd3SPierre Jolivet } else PetscUseTypeMethod(dm, coarsenhierarchy, nlevels, dmc); 36763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 367747c6ae99SBarry Smith } 367847c6ae99SBarry Smith 36791a266240SBarry Smith /*@C 3680bb7acecfSBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the `DM` is destroyed 36811a266240SBarry Smith 3682bb7acecfSBarry Smith Logically Collective if the function is collective 36831a266240SBarry Smith 36841a266240SBarry Smith Input Parameters: 3685bb7acecfSBarry Smith + dm - the `DM` object 36861a266240SBarry Smith - destroy - the destroy function 36871a266240SBarry Smith 36881a266240SBarry Smith Level: intermediate 36891a266240SBarry Smith 36901cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 3691f07f9ceaSJed Brown @*/ 3692d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContextDestroy(DM dm, PetscErrorCode (*destroy)(void **)) 3693d71ae5a4SJacob Faibussowitsch { 36941a266240SBarry Smith PetscFunctionBegin; 3695171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36961a266240SBarry Smith dm->ctxdestroy = destroy; 36973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36981a266240SBarry Smith } 36991a266240SBarry Smith 3700b07ff414SBarry Smith /*@ 3701bb7acecfSBarry Smith DMSetApplicationContext - Set a user context into a `DM` object 370247c6ae99SBarry Smith 370347c6ae99SBarry Smith Not Collective 370447c6ae99SBarry Smith 370547c6ae99SBarry Smith Input Parameters: 3706bb7acecfSBarry Smith + dm - the `DM` object 370747c6ae99SBarry Smith - ctx - the user context 370847c6ae99SBarry Smith 370947c6ae99SBarry Smith Level: intermediate 371047c6ae99SBarry Smith 3711bb7acecfSBarry Smith Note: 371235cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3713bb7acecfSBarry Smith 371460225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 371547c6ae99SBarry Smith @*/ 3716d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetApplicationContext(DM dm, void *ctx) 3717d71ae5a4SJacob Faibussowitsch { 371847c6ae99SBarry Smith PetscFunctionBegin; 3719171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 372047c6ae99SBarry Smith dm->ctx = ctx; 37213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 372247c6ae99SBarry Smith } 372347c6ae99SBarry Smith 372447c6ae99SBarry Smith /*@ 3725bb7acecfSBarry Smith DMGetApplicationContext - Gets a user context from a `DM` object 372647c6ae99SBarry Smith 372747c6ae99SBarry Smith Not Collective 372847c6ae99SBarry Smith 372947c6ae99SBarry Smith Input Parameter: 3730bb7acecfSBarry Smith . dm - the `DM` object 373147c6ae99SBarry Smith 373247c6ae99SBarry Smith Output Parameter: 373347c6ae99SBarry Smith . ctx - the user context 373447c6ae99SBarry Smith 373547c6ae99SBarry Smith Level: intermediate 373647c6ae99SBarry Smith 3737bb7acecfSBarry Smith Note: 373835cb6cd3SPierre Jolivet A user context is a way to pass problem specific information that is accessible whenever the `DM` is available 3739bb7acecfSBarry Smith 374042747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()` 374147c6ae99SBarry Smith @*/ 3742d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetApplicationContext(DM dm, void *ctx) 3743d71ae5a4SJacob Faibussowitsch { 374447c6ae99SBarry Smith PetscFunctionBegin; 3745171400e9SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37461b2093e4SBarry Smith *(void **)ctx = dm->ctx; 37473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 374847c6ae99SBarry Smith } 374947c6ae99SBarry Smith 375008da532bSDmitry Karpeev /*@C 3751bb7acecfSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for `SNESVI`. 375208da532bSDmitry Karpeev 375320f4b53cSBarry Smith Logically Collective 375408da532bSDmitry Karpeev 3755d8d19677SJose E. Roman Input Parameters: 375608da532bSDmitry Karpeev + dm - the DM object 375720f4b53cSBarry Smith - f - the function that computes variable bounds used by SNESVI (use `NULL` to cancel a previous function that was set) 375808da532bSDmitry Karpeev 375908da532bSDmitry Karpeev Level: intermediate 376008da532bSDmitry Karpeev 37611cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()`, 3762db781477SPatrick Sanan `DMSetJacobian()` 376308da532bSDmitry Karpeev @*/ 3764d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetVariableBounds(DM dm, PetscErrorCode (*f)(DM, Vec, Vec)) 3765d71ae5a4SJacob Faibussowitsch { 376608da532bSDmitry Karpeev PetscFunctionBegin; 37675a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 376808da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 37693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 377008da532bSDmitry Karpeev } 377108da532bSDmitry Karpeev 377208da532bSDmitry Karpeev /*@ 3773bb7acecfSBarry Smith DMHasVariableBounds - does the `DM` object have a variable bounds function? 377408da532bSDmitry Karpeev 377508da532bSDmitry Karpeev Not Collective 377608da532bSDmitry Karpeev 377708da532bSDmitry Karpeev Input Parameter: 3778bb7acecfSBarry Smith . dm - the `DM` object to destroy 377908da532bSDmitry Karpeev 378008da532bSDmitry Karpeev Output Parameter: 3781bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the variable bounds function exists 378208da532bSDmitry Karpeev 378308da532bSDmitry Karpeev Level: developer 378408da532bSDmitry Karpeev 37851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMComputeVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 378608da532bSDmitry Karpeev @*/ 3787d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasVariableBounds(DM dm, PetscBool *flg) 3788d71ae5a4SJacob Faibussowitsch { 378908da532bSDmitry Karpeev PetscFunctionBegin; 37905a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37914f572ea9SToby Isaac PetscAssertPointer(flg, 2); 379208da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 37933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 379408da532bSDmitry Karpeev } 379508da532bSDmitry Karpeev 379608da532bSDmitry Karpeev /*@C 3797bb7acecfSBarry Smith DMComputeVariableBounds - compute variable bounds used by `SNESVI`. 379808da532bSDmitry Karpeev 379920f4b53cSBarry Smith Logically Collective 380008da532bSDmitry Karpeev 3801f899ff85SJose E. Roman Input Parameter: 3802bb7acecfSBarry Smith . dm - the `DM` object 380308da532bSDmitry Karpeev 380460225df5SJacob Faibussowitsch Output Parameters: 380508da532bSDmitry Karpeev + xl - lower bound 380608da532bSDmitry Karpeev - xu - upper bound 380708da532bSDmitry Karpeev 3808907376e6SBarry Smith Level: advanced 3809907376e6SBarry Smith 381020f4b53cSBarry Smith Note: 381195452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 381208da532bSDmitry Karpeev 38131cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 381408da532bSDmitry Karpeev @*/ 3815d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 3816d71ae5a4SJacob Faibussowitsch { 381708da532bSDmitry Karpeev PetscFunctionBegin; 38185a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 381908da532bSDmitry Karpeev PetscValidHeaderSpecific(xl, VEC_CLASSID, 2); 38205a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu, VEC_CLASSID, 3); 3821dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, computevariablebounds, xl, xu); 38223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 382308da532bSDmitry Karpeev } 382408da532bSDmitry Karpeev 3825b0ae01b7SPeter Brune /*@ 3826bb7acecfSBarry Smith DMHasColoring - does the `DM` object have a method of providing a coloring? 3827b0ae01b7SPeter Brune 3828b0ae01b7SPeter Brune Not Collective 3829b0ae01b7SPeter Brune 3830b0ae01b7SPeter Brune Input Parameter: 3831b0ae01b7SPeter Brune . dm - the DM object 3832b0ae01b7SPeter Brune 3833b0ae01b7SPeter Brune Output Parameter: 3834bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateColoring()`. 3835b0ae01b7SPeter Brune 3836b0ae01b7SPeter Brune Level: developer 3837b0ae01b7SPeter Brune 38381cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateColoring()` 3839b0ae01b7SPeter Brune @*/ 3840d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasColoring(DM dm, PetscBool *flg) 3841d71ae5a4SJacob Faibussowitsch { 3842b0ae01b7SPeter Brune PetscFunctionBegin; 38435a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38444f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3845b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 38463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3847b0ae01b7SPeter Brune } 3848b0ae01b7SPeter Brune 38493ad4599aSBarry Smith /*@ 3850bb7acecfSBarry Smith DMHasCreateRestriction - does the `DM` object have a method of providing a restriction? 38513ad4599aSBarry Smith 38523ad4599aSBarry Smith Not Collective 38533ad4599aSBarry Smith 38543ad4599aSBarry Smith Input Parameter: 3855bb7acecfSBarry Smith . dm - the `DM` object 38563ad4599aSBarry Smith 38573ad4599aSBarry Smith Output Parameter: 3858bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateRestriction()`. 38593ad4599aSBarry Smith 38603ad4599aSBarry Smith Level: developer 38613ad4599aSBarry Smith 38621cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateRestriction()`, `DMHasCreateInterpolation()`, `DMHasCreateInjection()` 38633ad4599aSBarry Smith @*/ 3864d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateRestriction(DM dm, PetscBool *flg) 3865d71ae5a4SJacob Faibussowitsch { 38663ad4599aSBarry Smith PetscFunctionBegin; 38675a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38684f572ea9SToby Isaac PetscAssertPointer(flg, 2); 38693ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 38703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38713ad4599aSBarry Smith } 38723ad4599aSBarry Smith 3873a7058e45SLawrence Mitchell /*@ 3874bb7acecfSBarry Smith DMHasCreateInjection - does the `DM` object have a method of providing an injection? 3875a7058e45SLawrence Mitchell 3876a7058e45SLawrence Mitchell Not Collective 3877a7058e45SLawrence Mitchell 3878a7058e45SLawrence Mitchell Input Parameter: 3879bb7acecfSBarry Smith . dm - the `DM` object 3880a7058e45SLawrence Mitchell 3881a7058e45SLawrence Mitchell Output Parameter: 3882bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateInjection()`. 3883a7058e45SLawrence Mitchell 3884a7058e45SLawrence Mitchell Level: developer 3885a7058e45SLawrence Mitchell 38861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateInjection()`, `DMHasCreateRestriction()`, `DMHasCreateInterpolation()` 3887a7058e45SLawrence Mitchell @*/ 3888d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasCreateInjection(DM dm, PetscBool *flg) 3889d71ae5a4SJacob Faibussowitsch { 3890a7058e45SLawrence Mitchell PetscFunctionBegin; 38915a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 38924f572ea9SToby Isaac PetscAssertPointer(flg, 2); 3893dbbe0bcdSBarry Smith if (dm->ops->hascreateinjection) PetscUseTypeMethod(dm, hascreateinjection, flg); 3894ad540459SPierre Jolivet else *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 38953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3896a7058e45SLawrence Mitchell } 3897a7058e45SLawrence Mitchell 38980298fd71SBarry Smith PetscFunctionList DMList = NULL; 3899264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3900264ace61SBarry Smith 3901264ace61SBarry Smith /*@C 3902bb7acecfSBarry Smith DMSetType - Builds a `DM`, for a particular `DM` implementation. 3903264ace61SBarry Smith 390420f4b53cSBarry Smith Collective 3905264ace61SBarry Smith 3906264ace61SBarry Smith Input Parameters: 3907bb7acecfSBarry Smith + dm - The `DM` object 3908bb7acecfSBarry Smith - method - The name of the `DMType`, for example `DMDA`, `DMPLEX` 3909264ace61SBarry Smith 3910264ace61SBarry Smith Options Database Key: 3911bb7acecfSBarry Smith . -dm_type <type> - Sets the `DM` type; use -help for a list of available types 3912264ace61SBarry Smith 3913264ace61SBarry Smith Level: intermediate 3914264ace61SBarry Smith 3915bb7acecfSBarry Smith Note: 39160462cc06SPierre Jolivet Of the `DM` is constructed by directly calling a function to construct a particular `DM`, for example, `DMDACreate2d()` or `DMPlexCreateBoxMesh()` 3917bb7acecfSBarry Smith 39181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMGetType()`, `DMCreate()`, `DMDACreate2d()` 3919264ace61SBarry Smith @*/ 3920d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetType(DM dm, DMType method) 3921d71ae5a4SJacob Faibussowitsch { 3922264ace61SBarry Smith PetscErrorCode (*r)(DM); 3923264ace61SBarry Smith PetscBool match; 3924264ace61SBarry Smith 3925264ace61SBarry Smith PetscFunctionBegin; 3926264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39279566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, method, &match)); 39283ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 3929264ace61SBarry Smith 39309566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 39319566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(DMList, method, &r)); 39327a8be351SBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3933264ace61SBarry Smith 3934dbbe0bcdSBarry Smith PetscTryTypeMethod(dm, destroy); 39359566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops, sizeof(*dm->ops))); 39369566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)dm, method)); 39379566063dSJacob Faibussowitsch PetscCall((*r)(dm)); 39383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3939264ace61SBarry Smith } 3940264ace61SBarry Smith 3941264ace61SBarry Smith /*@C 3942bb7acecfSBarry Smith DMGetType - Gets the `DM` type name (as a string) from the `DM`. 3943264ace61SBarry Smith 3944264ace61SBarry Smith Not Collective 3945264ace61SBarry Smith 3946264ace61SBarry Smith Input Parameter: 3947bb7acecfSBarry Smith . dm - The `DM` 3948264ace61SBarry Smith 3949264ace61SBarry Smith Output Parameter: 3950bb7acecfSBarry Smith . type - The `DMType` name 3951264ace61SBarry Smith 3952264ace61SBarry Smith Level: intermediate 3953264ace61SBarry Smith 39541cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMDA`, `DMPLEX`, `DMSetType()`, `DMCreate()` 3955264ace61SBarry Smith @*/ 3956d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetType(DM dm, DMType *type) 3957d71ae5a4SJacob Faibussowitsch { 3958264ace61SBarry Smith PetscFunctionBegin; 3959264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 39604f572ea9SToby Isaac PetscAssertPointer(type, 2); 39619566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 3962264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 39633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3964264ace61SBarry Smith } 3965264ace61SBarry Smith 396667a56275SMatthew G Knepley /*@C 3967bb7acecfSBarry Smith DMConvert - Converts a `DM` to another `DM`, either of the same or different type. 396867a56275SMatthew G Knepley 396920f4b53cSBarry Smith Collective 397067a56275SMatthew G Knepley 397167a56275SMatthew G Knepley Input Parameters: 3972bb7acecfSBarry Smith + dm - the `DM` 3973bb7acecfSBarry Smith - newtype - new `DM` type (use "same" for the same type) 397467a56275SMatthew G Knepley 397567a56275SMatthew G Knepley Output Parameter: 3976bb7acecfSBarry Smith . M - pointer to new `DM` 397767a56275SMatthew G Knepley 397820f4b53cSBarry Smith Level: intermediate 397920f4b53cSBarry Smith 398073ff1848SBarry Smith Note: 3981bb7acecfSBarry Smith Cannot be used to convert a sequential `DM` to a parallel or a parallel to sequential, 3982bb7acecfSBarry Smith the MPI communicator of the generated `DM` is always the same as the communicator 3983bb7acecfSBarry Smith of the input `DM`. 398467a56275SMatthew G Knepley 39851cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetType()`, `DMCreate()`, `DMClone()` 398667a56275SMatthew G Knepley @*/ 3987d71ae5a4SJacob Faibussowitsch PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 3988d71ae5a4SJacob Faibussowitsch { 398967a56275SMatthew G Knepley DM B; 399067a56275SMatthew G Knepley char convname[256]; 3991c067b6caSMatthew G. Knepley PetscBool sametype /*, issame */; 399267a56275SMatthew G Knepley 399367a56275SMatthew G Knepley PetscFunctionBegin; 399467a56275SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 399567a56275SMatthew G Knepley PetscValidType(dm, 1); 39964f572ea9SToby Isaac PetscAssertPointer(M, 3); 39979566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, newtype, &sametype)); 39989566063dSJacob Faibussowitsch /* PetscCall(PetscStrcmp(newtype, "same", &issame)); */ 3999c067b6caSMatthew G. Knepley if (sametype) { 4000c067b6caSMatthew G. Knepley *M = dm; 40019566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 40023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4003c067b6caSMatthew G. Knepley } else { 40040298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM *) = NULL; 400567a56275SMatthew G Knepley 400667a56275SMatthew G Knepley /* 400767a56275SMatthew G Knepley Order of precedence: 400867a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 400967a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 401067a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 401167a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 401267a56275SMatthew G Knepley 5) Use a really basic converter. 401367a56275SMatthew G Knepley */ 401467a56275SMatthew G Knepley 401567a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 40169566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40179566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40189566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40199566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40209566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40219566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)dm, convname, &conv)); 402267a56275SMatthew G Knepley if (conv) goto foundconv; 402367a56275SMatthew G Knepley 402467a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 40259566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &B)); 40269566063dSJacob Faibussowitsch PetscCall(DMSetType(B, newtype)); 40279566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname, "DMConvert_", sizeof(convname))); 40289566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, ((PetscObject)dm)->type_name, sizeof(convname))); 40299566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_", sizeof(convname))); 40309566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, newtype, sizeof(convname))); 40319566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname, "_C", sizeof(convname))); 40329566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)B, convname, &conv)); 403367a56275SMatthew G Knepley if (conv) { 40349566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 403567a56275SMatthew G Knepley goto foundconv; 403667a56275SMatthew G Knepley } 403767a56275SMatthew G Knepley 403867a56275SMatthew G Knepley #if 0 403967a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 404067a56275SMatthew G Knepley conv = B->ops->convertfrom; 40419566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 404267a56275SMatthew G Knepley if (conv) goto foundconv; 404367a56275SMatthew G Knepley 404467a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 404567a56275SMatthew G Knepley if (dm->ops->convert) { 404667a56275SMatthew G Knepley conv = dm->ops->convert; 404767a56275SMatthew G Knepley } 404867a56275SMatthew G Knepley if (conv) goto foundconv; 404967a56275SMatthew G Knepley #endif 405067a56275SMatthew G Knepley 405167a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 405298921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject)dm)->type_name, newtype); 405367a56275SMatthew G Knepley 405467a56275SMatthew G Knepley foundconv: 40559566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Convert, dm, 0, 0, 0)); 40569566063dSJacob Faibussowitsch PetscCall((*conv)(dm, newtype, M)); 405712fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 405890b157c4SStefano Zampini { 40594fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 40606858538eSMatthew G. Knepley 40614fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 40624fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*M, maxCell, Lstart, L)); 4063c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 40649566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->vectype)); 40659566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*M)->vectype)); 40669566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->mattype)); 40679566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*M)->mattype)); 406812fa691eSMatthew G. Knepley } 40699566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Convert, dm, 0, 0, 0)); 407067a56275SMatthew G Knepley } 40719566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 40723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 407367a56275SMatthew G Knepley } 4074264ace61SBarry Smith 4075264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 4076264ace61SBarry Smith 4077264ace61SBarry Smith /*@C 4078bb7acecfSBarry Smith DMRegister - Adds a new `DM` type implementation 40791c84c290SBarry Smith 40801c84c290SBarry Smith Not Collective 40811c84c290SBarry Smith 40821c84c290SBarry Smith Input Parameters: 408320f4b53cSBarry Smith + sname - The name of a new user-defined creation routine 408420f4b53cSBarry Smith - function - The creation routine itself 408520f4b53cSBarry Smith 408620f4b53cSBarry Smith Level: advanced 40871c84c290SBarry Smith 408873ff1848SBarry Smith Note: 408920f4b53cSBarry Smith `DMRegister()` may be called multiple times to add several user-defined `DM`s 40901c84c290SBarry Smith 409160225df5SJacob Faibussowitsch Example Usage: 40921c84c290SBarry Smith .vb 4093bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 40941c84c290SBarry Smith .ve 40951c84c290SBarry Smith 409620f4b53cSBarry Smith Then, your `DM` type can be chosen with the procedural interface via 40971c84c290SBarry Smith .vb 40981c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 40991c84c290SBarry Smith DMSetType(DM,"my_da"); 41001c84c290SBarry Smith .ve 41011c84c290SBarry Smith or at runtime via the option 41021c84c290SBarry Smith .vb 41031c84c290SBarry Smith -da_type my_da 41041c84c290SBarry Smith .ve 4105264ace61SBarry Smith 41061cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMType`, `DMSetType()`, `DMRegisterAll()`, `DMRegisterDestroy()` 4107264ace61SBarry Smith @*/ 4108d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRegister(const char sname[], PetscErrorCode (*function)(DM)) 4109d71ae5a4SJacob Faibussowitsch { 4110264ace61SBarry Smith PetscFunctionBegin; 41119566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 41129566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&DMList, sname, function)); 41133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4114264ace61SBarry Smith } 4115264ace61SBarry Smith 4116b859378eSBarry Smith /*@C 4117bb7acecfSBarry Smith DMLoad - Loads a DM that has been stored in binary with `DMView()`. 4118b859378eSBarry Smith 411920f4b53cSBarry Smith Collective 4120b859378eSBarry Smith 4121b859378eSBarry Smith Input Parameters: 4122bb7acecfSBarry Smith + newdm - the newly loaded `DM`, this needs to have been created with `DMCreate()` or 4123bb7acecfSBarry Smith some related function before a call to `DMLoad()`. 4124bb7acecfSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or 4125bb7acecfSBarry Smith `PETSCVIEWERHDF5` file viewer, obtained from `PetscViewerHDF5Open()` 4126b859378eSBarry Smith 4127b859378eSBarry Smith Level: intermediate 4128b859378eSBarry Smith 4129b859378eSBarry Smith Notes: 413055849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4131b859378eSBarry Smith 4132bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` format, one can save multiple `DMPLEX` 4133bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 4134bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 4135cd7e8a5eSksagiyam 41361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscViewerBinaryOpen()`, `DMView()`, `MatLoad()`, `VecLoad()` 4137b859378eSBarry Smith @*/ 4138d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4139d71ae5a4SJacob Faibussowitsch { 41409331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4141b859378eSBarry Smith 4142b859378eSBarry Smith PetscFunctionBegin; 4143b859378eSBarry Smith PetscValidHeaderSpecific(newdm, DM_CLASSID, 1); 4144b859378eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 41459566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckReadable(viewer)); 41469566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 41479566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 41489566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Load, viewer, 0, 0, 0)); 41499331c7a4SMatthew G. Knepley if (isbinary) { 41509331c7a4SMatthew G. Knepley PetscInt classid; 41519331c7a4SMatthew G. Knepley char type[256]; 4152b859378eSBarry Smith 41539566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 41547a8be351SBarry Smith PetscCheck(classid == DM_FILE_CLASSID, PetscObjectComm((PetscObject)newdm), PETSC_ERR_ARG_WRONG, "Not DM next in file, classid found %d", (int)classid); 41559566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 41569566063dSJacob Faibussowitsch PetscCall(DMSetType(newdm, type)); 4157dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41589331c7a4SMatthew G. Knepley } else if (ishdf5) { 4159dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm, load, viewer); 41609331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 41619566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Load, viewer, 0, 0, 0)); 41623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4163b859378eSBarry Smith } 4164b859378eSBarry Smith 41657da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 41667da65231SMatthew G Knepley 41672ecf6ec3SMatthew G. Knepley PetscErrorCode DMPrintCellIndices(PetscInt c, const char name[], PetscInt len, const PetscInt x[]) 41682ecf6ec3SMatthew G. Knepley { 41692ecf6ec3SMatthew G. Knepley PetscInt f; 41702ecf6ec3SMatthew G. Knepley 41712ecf6ec3SMatthew G. Knepley PetscFunctionBegin; 41722ecf6ec3SMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41732ecf6ec3SMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %" PetscInt_FMT " |\n", x[f])); 41742ecf6ec3SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 41752ecf6ec3SMatthew G. Knepley } 41762ecf6ec3SMatthew G. Knepley 4177d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4178d71ae5a4SJacob Faibussowitsch { 41791d47ebbbSSatish Balay PetscInt f; 41801b30c384SMatthew G Knepley 41817da65231SMatthew G Knepley PetscFunctionBegin; 418263a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 418348a46eb9SPierre Jolivet for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]))); 41843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41857da65231SMatthew G Knepley } 41867da65231SMatthew G Knepley 41875962854dSMatthew G. Knepley PetscErrorCode DMPrintCellVectorReal(PetscInt c, const char name[], PetscInt len, const PetscReal x[]) 41885962854dSMatthew G. Knepley { 41895962854dSMatthew G. Knepley PetscInt f; 41905962854dSMatthew G. Knepley 41915962854dSMatthew G. Knepley PetscFunctionBegin; 41925962854dSMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41935962854dSMatthew G. Knepley for (f = 0; f < len; ++f) PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)x[f])); 41945962854dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 41955962854dSMatthew G. Knepley } 41965962854dSMatthew G. Knepley 4197d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4198d71ae5a4SJacob Faibussowitsch { 41991b30c384SMatthew G Knepley PetscInt f, g; 42007da65231SMatthew G Knepley 42017da65231SMatthew G Knepley PetscFunctionBegin; 420263a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 42031d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 42049566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |")); 420548a46eb9SPierre Jolivet for (g = 0; g < cols; ++g) PetscCall(PetscPrintf(PETSC_COMM_SELF, " % 9.5g", (double)PetscRealPart(A[f * cols + g]))); 42069566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |\n")); 42077da65231SMatthew G Knepley } 42083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42097da65231SMatthew G Knepley } 4210e7c4fc90SDmitry Karpeev 4211d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4212d71ae5a4SJacob Faibussowitsch { 42130c5b8624SToby Isaac PetscInt localSize, bs; 42140c5b8624SToby Isaac PetscMPIInt size; 42150c5b8624SToby Isaac Vec x, xglob; 42160c5b8624SToby Isaac const PetscScalar *xarray; 4217e759306cSMatthew G. Knepley 4218e759306cSMatthew G. Knepley PetscFunctionBegin; 42199566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 42209566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &x)); 42219566063dSJacob Faibussowitsch PetscCall(VecCopy(X, x)); 422293ec0da9SPierre Jolivet PetscCall(VecFilter(x, tol)); 42239566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "%s:\n", name)); 42240c5b8624SToby Isaac if (size > 1) { 42259566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(x, &localSize)); 42269566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xarray)); 42279566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(x, &bs)); 42289566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)dm), bs, localSize, PETSC_DETERMINE, xarray, &xglob)); 42290c5b8624SToby Isaac } else { 42300c5b8624SToby Isaac xglob = x; 42310c5b8624SToby Isaac } 42329566063dSJacob Faibussowitsch PetscCall(VecView(xglob, PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)dm)))); 42330c5b8624SToby Isaac if (size > 1) { 42349566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xglob)); 42359566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xarray)); 42360c5b8624SToby Isaac } 42379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 42383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4239e759306cSMatthew G. Knepley } 4240e759306cSMatthew G. Knepley 424188ed4aceSMatthew G Knepley /*@ 4242bb7acecfSBarry Smith DMGetSection - Get the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMGetLocalSection()`. Deprecated in v3.12 4243061576a5SJed Brown 4244061576a5SJed Brown Input Parameter: 4245bb7acecfSBarry Smith . dm - The `DM` 4246061576a5SJed Brown 4247061576a5SJed Brown Output Parameter: 4248bb7acecfSBarry Smith . section - The `PetscSection` 4249061576a5SJed Brown 425020f4b53cSBarry Smith Options Database Key: 4251bb7acecfSBarry Smith . -dm_petscsection_view - View the `PetscSection` created by the `DM` 4252061576a5SJed Brown 4253061576a5SJed Brown Level: advanced 4254061576a5SJed Brown 4255061576a5SJed Brown Notes: 4256bb7acecfSBarry Smith Use `DMGetLocalSection()` in new code. 4257061576a5SJed Brown 4258bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 4259061576a5SJed Brown 42601cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetLocalSection()`, `DMSetLocalSection()`, `DMGetGlobalSection()` 4261061576a5SJed Brown @*/ 4262d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4263d71ae5a4SJacob Faibussowitsch { 4264061576a5SJed Brown PetscFunctionBegin; 42659566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, section)); 42663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4267061576a5SJed Brown } 4268061576a5SJed Brown 4269061576a5SJed Brown /*@ 4270bb7acecfSBarry Smith DMGetLocalSection - Get the `PetscSection` encoding the local data layout for the `DM`. 427188ed4aceSMatthew G Knepley 427288ed4aceSMatthew G Knepley Input Parameter: 4273bb7acecfSBarry Smith . dm - The `DM` 427488ed4aceSMatthew G Knepley 427588ed4aceSMatthew G Knepley Output Parameter: 4276bb7acecfSBarry Smith . section - The `PetscSection` 427788ed4aceSMatthew G Knepley 427820f4b53cSBarry Smith Options Database Key: 4279bb7acecfSBarry Smith . -dm_petscsection_view - View the section created by the `DM` 4280e5893cccSMatthew G. Knepley 428188ed4aceSMatthew G Knepley Level: intermediate 428288ed4aceSMatthew G Knepley 4283bb7acecfSBarry Smith Note: 4284bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 428588ed4aceSMatthew G Knepley 42861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetGlobalSection()` 428788ed4aceSMatthew G Knepley @*/ 4288d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 4289d71ae5a4SJacob Faibussowitsch { 429088ed4aceSMatthew G Knepley PetscFunctionBegin; 429188ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 42924f572ea9SToby Isaac PetscAssertPointer(section, 2); 42931bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4294e5e52638SMatthew G. Knepley PetscInt d; 4295e5e52638SMatthew G. Knepley 429645480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 429745480ffeSMatthew G. Knepley PetscObject obj = (PetscObject)dm; 429845480ffeSMatthew G. Knepley PetscViewer viewer; 429945480ffeSMatthew G. Knepley PetscViewerFormat format; 430045480ffeSMatthew G. Knepley PetscBool flg; 430145480ffeSMatthew G. Knepley 43029566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg)); 43039566063dSJacob Faibussowitsch if (flg) PetscCall(PetscViewerPushFormat(viewer, format)); 430445480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 43059566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(dm->probs[d].ds)); 43069566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDSView(dm->probs[d].ds, viewer)); 430745480ffeSMatthew G. Knepley } 430845480ffeSMatthew G. Knepley if (flg) { 43099566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 43109566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 4311cd791dc2SBarry Smith PetscCall(PetscOptionsRestoreViewer(&viewer)); 431245480ffeSMatthew G. Knepley } 431345480ffeSMatthew G. Knepley } 4314dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, createlocalsection); 43159566063dSJacob Faibussowitsch if (dm->localSection) PetscCall(PetscObjectViewFromOptions((PetscObject)dm->localSection, NULL, "-dm_petscsection_view")); 43162f0f8703SMatthew G. Knepley } 43171bb6d2a8SBarry Smith *section = dm->localSection; 43183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 431988ed4aceSMatthew G Knepley } 432088ed4aceSMatthew G Knepley 432188ed4aceSMatthew G Knepley /*@ 4322bb7acecfSBarry Smith DMSetSection - Set the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMSetLocalSection()`. Deprecated in v3.12 4323061576a5SJed Brown 4324061576a5SJed Brown Input Parameters: 4325bb7acecfSBarry Smith + dm - The `DM` 4326bb7acecfSBarry Smith - section - The `PetscSection` 4327061576a5SJed Brown 4328061576a5SJed Brown Level: advanced 4329061576a5SJed Brown 4330061576a5SJed Brown Notes: 4331bb7acecfSBarry Smith Use `DMSetLocalSection()` in new code. 4332061576a5SJed Brown 4333bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4334061576a5SJed Brown 43351cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetLocalSection()`, `DMSetGlobalSection()` 4336061576a5SJed Brown @*/ 4337d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSection(DM dm, PetscSection section) 4338d71ae5a4SJacob Faibussowitsch { 4339061576a5SJed Brown PetscFunctionBegin; 43409566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm, section)); 43413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4342061576a5SJed Brown } 4343061576a5SJed Brown 4344061576a5SJed Brown /*@ 4345bb7acecfSBarry Smith DMSetLocalSection - Set the `PetscSection` encoding the local data layout for the `DM`. 434688ed4aceSMatthew G Knepley 434788ed4aceSMatthew G Knepley Input Parameters: 4348bb7acecfSBarry Smith + dm - The `DM` 4349bb7acecfSBarry Smith - section - The `PetscSection` 435088ed4aceSMatthew G Knepley 435188ed4aceSMatthew G Knepley Level: intermediate 435288ed4aceSMatthew G Knepley 4353bb7acecfSBarry Smith Note: 4354bb7acecfSBarry Smith Any existing Section will be destroyed 435588ed4aceSMatthew G Knepley 43561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscSection`, `DMGetLocalSection()`, `DMSetGlobalSection()` 435788ed4aceSMatthew G Knepley @*/ 4358d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 4359d71ae5a4SJacob Faibussowitsch { 4360c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4361af122d2aSMatthew G Knepley PetscInt f; 436288ed4aceSMatthew G Knepley 436388ed4aceSMatthew G Knepley PetscFunctionBegin; 436488ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4365b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 43669566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 43679566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->localSection)); 43681bb6d2a8SBarry Smith dm->localSection = section; 43699566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(dm->localSection, &numFields)); 4370af122d2aSMatthew G Knepley if (numFields) { 43719566063dSJacob Faibussowitsch PetscCall(DMSetNumFields(dm, numFields)); 4372af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43730f21e855SMatthew G. Knepley PetscObject disc; 4374af122d2aSMatthew G Knepley const char *name; 4375af122d2aSMatthew G Knepley 43769566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(dm->localSection, f, &name)); 43779566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, &disc)); 43789566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName(disc, name)); 4379af122d2aSMatthew G Knepley } 4380af122d2aSMatthew G Knepley } 438150350c8eSStefano Zampini /* The global section and the SectionSF will be rebuilt 438250350c8eSStefano Zampini in the next call to DMGetGlobalSection() and DMGetSectionSF(). */ 43839566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 438450350c8eSStefano Zampini PetscCall(PetscSFDestroy(&dm->sectionSF)); 438552947b74SStefano Zampini PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 438650350c8eSStefano Zampini 438750350c8eSStefano Zampini /* Clear scratch vectors */ 438850350c8eSStefano Zampini PetscCall(DMClearGlobalVectors(dm)); 438950350c8eSStefano Zampini PetscCall(DMClearLocalVectors(dm)); 439050350c8eSStefano Zampini PetscCall(DMClearNamedGlobalVectors(dm)); 439150350c8eSStefano Zampini PetscCall(DMClearNamedLocalVectors(dm)); 43923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 439388ed4aceSMatthew G Knepley } 439488ed4aceSMatthew G Knepley 4395adc21957SMatthew G. Knepley /*@C 4396*d8b4a066SPierre Jolivet DMCreateSectionPermutation - Create a permutation of the `PetscSection` chart and optionally a block structure. 4397adc21957SMatthew G. Knepley 4398adc21957SMatthew G. Knepley Input Parameter: 4399adc21957SMatthew G. Knepley . dm - The `DM` 4400adc21957SMatthew G. Knepley 44019cde84edSJose E. Roman Output Parameters: 4402adc21957SMatthew G. Knepley + perm - A permutation of the mesh points in the chart 4403adc21957SMatthew G. Knepley - blockStarts - A high bit is set for the point that begins every block, or NULL for default blocking 4404adc21957SMatthew G. Knepley 4405adc21957SMatthew G. Knepley Level: developer 4406adc21957SMatthew G. Knepley 4407adc21957SMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `PetscSection`, `DMGetLocalSection()`, `DMGetGlobalSection()` 4408adc21957SMatthew G. Knepley @*/ 4409adc21957SMatthew G. Knepley PetscErrorCode DMCreateSectionPermutation(DM dm, IS *perm, PetscBT *blockStarts) 4410adc21957SMatthew G. Knepley { 4411adc21957SMatthew G. Knepley PetscFunctionBegin; 4412adc21957SMatthew G. Knepley *perm = NULL; 4413adc21957SMatthew G. Knepley *blockStarts = NULL; 4414adc21957SMatthew G. Knepley PetscTryTypeMethod(dm, createsectionpermutation, perm, blockStarts); 4415adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 4416adc21957SMatthew G. Knepley } 4417adc21957SMatthew G. Knepley 44189435951eSToby Isaac /*@ 4419bb7acecfSBarry Smith DMGetDefaultConstraints - Get the `PetscSection` and `Mat` that specify the local constraint interpolation. See `DMSetDefaultConstraints()` for a description of the purpose of constraint interpolation. 44209435951eSToby Isaac 442120f4b53cSBarry Smith not Collective 4422e228b242SToby Isaac 44239435951eSToby Isaac Input Parameter: 4424bb7acecfSBarry Smith . dm - The `DM` 44259435951eSToby Isaac 4426d8d19677SJose E. Roman Output Parameters: 442720f4b53cSBarry 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. 442820f4b53cSBarry 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. 442979769bd5SJed Brown - bias - Vector containing bias to be added to constrained dofs 44309435951eSToby Isaac 44319435951eSToby Isaac Level: advanced 44329435951eSToby Isaac 4433bb7acecfSBarry Smith Note: 4434bb7acecfSBarry Smith This gets borrowed references, so the user should not destroy the `PetscSection`, `Mat`, or `Vec`. 44359435951eSToby Isaac 44361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDefaultConstraints()` 44379435951eSToby Isaac @*/ 4438d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat, Vec *bias) 4439d71ae5a4SJacob Faibussowitsch { 44409435951eSToby Isaac PetscFunctionBegin; 44419435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4442dbbe0bcdSBarry Smith if (!dm->defaultConstraint.section && !dm->defaultConstraint.mat && dm->ops->createdefaultconstraints) PetscUseTypeMethod(dm, createdefaultconstraints); 44433b8ba7d1SJed Brown if (section) *section = dm->defaultConstraint.section; 44443b8ba7d1SJed Brown if (mat) *mat = dm->defaultConstraint.mat; 444579769bd5SJed Brown if (bias) *bias = dm->defaultConstraint.bias; 44463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44479435951eSToby Isaac } 44489435951eSToby Isaac 44499435951eSToby Isaac /*@ 4450bb7acecfSBarry Smith DMSetDefaultConstraints - Set the `PetscSection` and `Mat` that specify the local constraint interpolation. 44519435951eSToby Isaac 445220f4b53cSBarry Smith Collective 4453e228b242SToby Isaac 44549435951eSToby Isaac Input Parameters: 4455bb7acecfSBarry Smith + dm - The `DM` 4456bb7acecfSBarry 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). 445720f4b53cSBarry 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). 445820f4b53cSBarry 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). 44599435951eSToby Isaac 44609435951eSToby Isaac Level: advanced 44619435951eSToby Isaac 446220f4b53cSBarry Smith Notes: 446320f4b53cSBarry 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()`. 446420f4b53cSBarry Smith 446520f4b53cSBarry 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. 446620f4b53cSBarry Smith 4467bb7acecfSBarry Smith This increments the references of the `PetscSection`, `Mat`, and `Vec`, so they user can destroy them. 44689435951eSToby Isaac 44691cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDefaultConstraints()` 44709435951eSToby Isaac @*/ 4471d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat, Vec bias) 4472d71ae5a4SJacob Faibussowitsch { 4473e228b242SToby Isaac PetscMPIInt result; 44749435951eSToby Isaac 44759435951eSToby Isaac PetscFunctionBegin; 44769435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4477e228b242SToby Isaac if (section) { 4478e228b242SToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 44799566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)section), &result)); 44807a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint section must have local communicator"); 4481e228b242SToby Isaac } 4482e228b242SToby Isaac if (mat) { 4483e228b242SToby Isaac PetscValidHeaderSpecific(mat, MAT_CLASSID, 3); 44849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)mat), &result)); 44857a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint matrix must have local communicator"); 4486e228b242SToby Isaac } 448779769bd5SJed Brown if (bias) { 448879769bd5SJed Brown PetscValidHeaderSpecific(bias, VEC_CLASSID, 4); 44899566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF, PetscObjectComm((PetscObject)bias), &result)); 449079769bd5SJed Brown PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "constraint bias must have local communicator"); 449179769bd5SJed Brown } 44929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 44939566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->defaultConstraint.section)); 44943b8ba7d1SJed Brown dm->defaultConstraint.section = section; 44959566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 44969566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dm->defaultConstraint.mat)); 44973b8ba7d1SJed Brown dm->defaultConstraint.mat = mat; 44989566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)bias)); 44999566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dm->defaultConstraint.bias)); 450079769bd5SJed Brown dm->defaultConstraint.bias = bias; 45013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45029435951eSToby Isaac } 45039435951eSToby Isaac 4504497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4505507e4973SMatthew G. Knepley /* 4506bb7acecfSBarry Smith DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. Generates and error if they are not consistent. 4507507e4973SMatthew G. Knepley 4508507e4973SMatthew G. Knepley Input Parameters: 4509bb7acecfSBarry Smith + dm - The `DM` 4510bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4511bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 4512507e4973SMatthew G. Knepley 4513507e4973SMatthew G. Knepley Level: intermediate 4514507e4973SMatthew G. Knepley 45151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()` 4516507e4973SMatthew G. Knepley */ 4517d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4518d71ae5a4SJacob Faibussowitsch { 4519507e4973SMatthew G. Knepley MPI_Comm comm; 4520507e4973SMatthew G. Knepley PetscLayout layout; 4521507e4973SMatthew G. Knepley const PetscInt *ranges; 4522507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4523507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4524507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4525507e4973SMatthew G. Knepley 4526507e4973SMatthew G. Knepley PetscFunctionBegin; 45279566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4528507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45299566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 45309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 45319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(globalSection, &pStart, &pEnd)); 45329566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(globalSection, &nroots)); 45339566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &layout)); 45349566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(layout, 1)); 45359566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(layout, nroots)); 45369566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(layout)); 45379566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRanges(layout, &ranges)); 4538507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4539f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4540507e4973SMatthew G. Knepley 45419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(localSection, p, &dof)); 45429566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(localSection, p, &off)); 45439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(localSection, p, &cdof)); 45449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(globalSection, p, &gdof)); 45459566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(globalSection, p, &gcdof)); 45469566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(globalSection, p, &goff)); 4547507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 45489371c9d4SSatish Balay if ((gdof < 0 ? -(gdof + 1) : gdof) != dof) { 45499371c9d4SSatish 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)); 45509371c9d4SSatish Balay valid = PETSC_FALSE; 45519371c9d4SSatish Balay } 45529371c9d4SSatish Balay if (gcdof && (gcdof != cdof)) { 45539371c9d4SSatish 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)); 45549371c9d4SSatish Balay valid = PETSC_FALSE; 45559371c9d4SSatish Balay } 4556507e4973SMatthew G. Knepley if (gdof < 0) { 4557507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof + 1) - gcdof : gdof - gcdof; 4558507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4559507e4973SMatthew G. Knepley PetscInt offset = -(goff + 1) + d, r; 4560507e4973SMatthew G. Knepley 45619566063dSJacob Faibussowitsch PetscCall(PetscFindInt(offset, size + 1, ranges, &r)); 4562507e4973SMatthew G. Knepley if (r < 0) r = -(r + 2); 45639371c9d4SSatish Balay if ((r < 0) || (r >= size)) { 45649371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(comm, "[%d]Point %" PetscInt_FMT " mapped to invalid process %" PetscInt_FMT " (%" PetscInt_FMT ", %" PetscInt_FMT ")\n", rank, p, r, gdof, goff)); 45659371c9d4SSatish Balay valid = PETSC_FALSE; 45669371c9d4SSatish Balay break; 45679371c9d4SSatish Balay } 4568507e4973SMatthew G. Knepley } 4569507e4973SMatthew G. Knepley } 4570507e4973SMatthew G. Knepley } 45719566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&layout)); 45729566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 45731c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm)); 4574507e4973SMatthew G. Knepley if (!gvalid) { 45759566063dSJacob Faibussowitsch PetscCall(DMView(dm, NULL)); 4576507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4577507e4973SMatthew G. Knepley } 45783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4579507e4973SMatthew G. Knepley } 4580f741bcd2SMatthew G. Knepley #endif 4581507e4973SMatthew G. Knepley 45825f06a3ddSJed Brown static PetscErrorCode DMGetIsoperiodicPointSF_Internal(DM dm, PetscSF *sf) 45836725e60dSJed Brown { 45846725e60dSJed Brown PetscErrorCode (*f)(DM, PetscSF *); 45854d86920dSPierre Jolivet 45866725e60dSJed Brown PetscFunctionBegin; 45876725e60dSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45884f572ea9SToby Isaac PetscAssertPointer(sf, 2); 45895f06a3ddSJed Brown PetscCall(PetscObjectQueryFunction((PetscObject)dm, "DMGetIsoperiodicPointSF_C", &f)); 45906725e60dSJed Brown if (f) PetscCall(f(dm, sf)); 45916725e60dSJed Brown else *sf = dm->sf; 45923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45936725e60dSJed Brown } 45946725e60dSJed Brown 459588ed4aceSMatthew G Knepley /*@ 4596bb7acecfSBarry Smith DMGetGlobalSection - Get the `PetscSection` encoding the global data layout for the `DM`. 459788ed4aceSMatthew G Knepley 459820f4b53cSBarry Smith Collective 45998b1ab98fSJed Brown 460088ed4aceSMatthew G Knepley Input Parameter: 4601bb7acecfSBarry Smith . dm - The `DM` 460288ed4aceSMatthew G Knepley 460388ed4aceSMatthew G Knepley Output Parameter: 4604bb7acecfSBarry Smith . section - The `PetscSection` 460588ed4aceSMatthew G Knepley 460688ed4aceSMatthew G Knepley Level: intermediate 460788ed4aceSMatthew G Knepley 4608bb7acecfSBarry Smith Note: 4609bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 461088ed4aceSMatthew G Knepley 46111cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLocalSection()`, `DMGetLocalSection()` 461288ed4aceSMatthew G Knepley @*/ 4613d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 4614d71ae5a4SJacob Faibussowitsch { 461588ed4aceSMatthew G Knepley PetscFunctionBegin; 461688ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46174f572ea9SToby Isaac PetscAssertPointer(section, 2); 46181bb6d2a8SBarry Smith if (!dm->globalSection) { 4619fd59a867SMatthew G. Knepley PetscSection s; 46206725e60dSJed Brown PetscSF sf; 4621fd59a867SMatthew G. Knepley 46229566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 46237a8be351SBarry Smith PetscCheck(s, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 46247a8be351SBarry Smith PetscCheck(dm->sf, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 46255f06a3ddSJed Brown PetscCall(DMGetIsoperiodicPointSF_Internal(dm, &sf)); 4626eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionCreateGlobalSection(s, sf, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &dm->globalSection)); 46279566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&dm->map)); 46289566063dSJacob Faibussowitsch PetscCall(PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map)); 46299566063dSJacob Faibussowitsch PetscCall(PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view")); 463088ed4aceSMatthew G Knepley } 46311bb6d2a8SBarry Smith *section = dm->globalSection; 46323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 463388ed4aceSMatthew G Knepley } 463488ed4aceSMatthew G Knepley 4635b21d0597SMatthew G Knepley /*@ 4636bb7acecfSBarry Smith DMSetGlobalSection - Set the `PetscSection` encoding the global data layout for the `DM`. 4637b21d0597SMatthew G Knepley 4638b21d0597SMatthew G Knepley Input Parameters: 4639bb7acecfSBarry Smith + dm - The `DM` 46402fe279fdSBarry Smith - section - The PetscSection, or `NULL` 4641b21d0597SMatthew G Knepley 4642b21d0597SMatthew G Knepley Level: intermediate 4643b21d0597SMatthew G Knepley 4644bb7acecfSBarry Smith Note: 4645bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4646b21d0597SMatthew G Knepley 46471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetGlobalSection()`, `DMSetLocalSection()` 4648b21d0597SMatthew G Knepley @*/ 4649d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 4650d71ae5a4SJacob Faibussowitsch { 4651b21d0597SMatthew G Knepley PetscFunctionBegin; 4652b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46535080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 46549566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 46559566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 46561bb6d2a8SBarry Smith dm->globalSection = section; 4657497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 46589566063dSJacob Faibussowitsch if (section) PetscCall(DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section)); 4659507e4973SMatthew G. Knepley #endif 466050350c8eSStefano Zampini /* Clear global scratch vectors and sectionSF */ 466150350c8eSStefano Zampini PetscCall(PetscSFDestroy(&dm->sectionSF)); 466252947b74SStefano Zampini PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 466350350c8eSStefano Zampini PetscCall(DMClearGlobalVectors(dm)); 466450350c8eSStefano Zampini PetscCall(DMClearNamedGlobalVectors(dm)); 46653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4666b21d0597SMatthew G Knepley } 4667b21d0597SMatthew G Knepley 466888ed4aceSMatthew G Knepley /*@ 4669bb7acecfSBarry Smith DMGetSectionSF - Get the `PetscSF` encoding the parallel dof overlap for the `DM`. If it has not been set, 4670bb7acecfSBarry Smith it is created from the default `PetscSection` layouts in the `DM`. 467188ed4aceSMatthew G Knepley 467288ed4aceSMatthew G Knepley Input Parameter: 4673bb7acecfSBarry Smith . dm - The `DM` 467488ed4aceSMatthew G Knepley 467588ed4aceSMatthew G Knepley Output Parameter: 4676bb7acecfSBarry Smith . sf - The `PetscSF` 467788ed4aceSMatthew G Knepley 467888ed4aceSMatthew G Knepley Level: intermediate 467988ed4aceSMatthew G Knepley 4680bb7acecfSBarry Smith Note: 4681bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 468288ed4aceSMatthew G Knepley 46831cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetSectionSF()`, `DMCreateSectionSF()` 468488ed4aceSMatthew G Knepley @*/ 4685d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 4686d71ae5a4SJacob Faibussowitsch { 468788ed4aceSMatthew G Knepley PetscInt nroots; 468888ed4aceSMatthew G Knepley 468988ed4aceSMatthew G Knepley PetscFunctionBegin; 469088ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46914f572ea9SToby Isaac PetscAssertPointer(sf, 2); 469248a46eb9SPierre Jolivet if (!dm->sectionSF) PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), &dm->sectionSF)); 46939566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL)); 469488ed4aceSMatthew G Knepley if (nroots < 0) { 469588ed4aceSMatthew G Knepley PetscSection section, gSection; 469688ed4aceSMatthew G Knepley 46979566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 469831ea6d37SMatthew G Knepley if (section) { 46999566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gSection)); 47009566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSF(dm, section, gSection)); 470131ea6d37SMatthew G Knepley } else { 47020298fd71SBarry Smith *sf = NULL; 47033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 470431ea6d37SMatthew G Knepley } 470588ed4aceSMatthew G Knepley } 47061bb6d2a8SBarry Smith *sf = dm->sectionSF; 47073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 470888ed4aceSMatthew G Knepley } 470988ed4aceSMatthew G Knepley 471088ed4aceSMatthew G Knepley /*@ 4711bb7acecfSBarry Smith DMSetSectionSF - Set the `PetscSF` encoding the parallel dof overlap for the `DM` 471288ed4aceSMatthew G Knepley 471388ed4aceSMatthew G Knepley Input Parameters: 4714bb7acecfSBarry Smith + dm - The `DM` 4715bb7acecfSBarry Smith - sf - The `PetscSF` 471688ed4aceSMatthew G Knepley 471788ed4aceSMatthew G Knepley Level: intermediate 471888ed4aceSMatthew G Knepley 4719bb7acecfSBarry Smith Note: 4720bb7acecfSBarry Smith Any previous `PetscSF` is destroyed 472188ed4aceSMatthew G Knepley 47221cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMCreateSectionSF()` 472388ed4aceSMatthew G Knepley @*/ 4724d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 4725d71ae5a4SJacob Faibussowitsch { 472688ed4aceSMatthew G Knepley PetscFunctionBegin; 472788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4728b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47299566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 47309566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sectionSF)); 47311bb6d2a8SBarry Smith dm->sectionSF = sf; 47323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 473388ed4aceSMatthew G Knepley } 473488ed4aceSMatthew G Knepley 473588ed4aceSMatthew G Knepley /*@C 4736bb7acecfSBarry Smith DMCreateSectionSF - Create the `PetscSF` encoding the parallel dof overlap for the `DM` based upon the `PetscSection`s 473788ed4aceSMatthew G Knepley describing the data layout. 473888ed4aceSMatthew G Knepley 473988ed4aceSMatthew G Knepley Input Parameters: 4740bb7acecfSBarry Smith + dm - The `DM` 4741bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4742bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 474388ed4aceSMatthew G Knepley 47441bb6d2a8SBarry Smith Level: developer 47451bb6d2a8SBarry Smith 4746bb7acecfSBarry Smith Note: 4747bb7acecfSBarry Smith One usually uses `DMGetSectionSF()` to obtain the `PetscSF` 4748bb7acecfSBarry Smith 474973ff1848SBarry Smith Developer Note: 4750bb7acecfSBarry Smith Since this routine has for arguments the two sections from the `DM` and puts the resulting `PetscSF` 4751bb7acecfSBarry Smith directly into the `DM`, perhaps this function should not take the local and global sections as 4752bb7acecfSBarry Smith input and should just obtain them from the `DM`? 47531bb6d2a8SBarry Smith 47541cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMGetLocalSection()`, `DMGetGlobalSection()` 475588ed4aceSMatthew G Knepley @*/ 4756d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 4757d71ae5a4SJacob Faibussowitsch { 475888ed4aceSMatthew G Knepley PetscFunctionBegin; 475988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47609566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection)); 47613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 476288ed4aceSMatthew G Knepley } 4763af122d2aSMatthew G Knepley 4764b21d0597SMatthew G Knepley /*@ 4765bb7acecfSBarry Smith DMGetPointSF - Get the `PetscSF` encoding the parallel section point overlap for the `DM`. 4766bb7acecfSBarry Smith 4767bb7acecfSBarry Smith Not collective but the resulting `PetscSF` is collective 4768b21d0597SMatthew G Knepley 4769b21d0597SMatthew G Knepley Input Parameter: 4770bb7acecfSBarry Smith . dm - The `DM` 4771b21d0597SMatthew G Knepley 4772b21d0597SMatthew G Knepley Output Parameter: 4773bb7acecfSBarry Smith . sf - The `PetscSF` 4774b21d0597SMatthew G Knepley 4775b21d0597SMatthew G Knepley Level: intermediate 4776b21d0597SMatthew G Knepley 4777bb7acecfSBarry Smith Note: 4778bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 4779b21d0597SMatthew G Knepley 47801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4781b21d0597SMatthew G Knepley @*/ 4782d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 4783d71ae5a4SJacob Faibussowitsch { 4784b21d0597SMatthew G Knepley PetscFunctionBegin; 4785b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47864f572ea9SToby Isaac PetscAssertPointer(sf, 2); 4787b21d0597SMatthew G Knepley *sf = dm->sf; 47883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4789b21d0597SMatthew G Knepley } 4790b21d0597SMatthew G Knepley 4791057b4bcdSMatthew G Knepley /*@ 4792bb7acecfSBarry Smith DMSetPointSF - Set the `PetscSF` encoding the parallel section point overlap for the `DM`. 4793bb7acecfSBarry Smith 479420f4b53cSBarry Smith Collective 4795057b4bcdSMatthew G Knepley 4796057b4bcdSMatthew G Knepley Input Parameters: 4797bb7acecfSBarry Smith + dm - The `DM` 4798bb7acecfSBarry Smith - sf - The `PetscSF` 4799057b4bcdSMatthew G Knepley 4800057b4bcdSMatthew G Knepley Level: intermediate 4801057b4bcdSMatthew G Knepley 48021cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4803057b4bcdSMatthew G Knepley @*/ 4804d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 4805d71ae5a4SJacob Faibussowitsch { 4806057b4bcdSMatthew G Knepley PetscFunctionBegin; 4807057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4808b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 48099566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 48109566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sf)); 4811057b4bcdSMatthew G Knepley dm->sf = sf; 48123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4813057b4bcdSMatthew G Knepley } 4814057b4bcdSMatthew G Knepley 48154f37162bSMatthew G. Knepley /*@ 4816bb7acecfSBarry Smith DMGetNaturalSF - Get the `PetscSF` encoding the map back to the original mesh ordering 48174f37162bSMatthew G. Knepley 48184f37162bSMatthew G. Knepley Input Parameter: 4819bb7acecfSBarry Smith . dm - The `DM` 48204f37162bSMatthew G. Knepley 48214f37162bSMatthew G. Knepley Output Parameter: 4822bb7acecfSBarry Smith . sf - The `PetscSF` 48234f37162bSMatthew G. Knepley 48244f37162bSMatthew G. Knepley Level: intermediate 48254f37162bSMatthew G. Knepley 4826bb7acecfSBarry Smith Note: 4827bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 48284f37162bSMatthew G. Knepley 48291cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 48304f37162bSMatthew G. Knepley @*/ 4831d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 4832d71ae5a4SJacob Faibussowitsch { 48334f37162bSMatthew G. Knepley PetscFunctionBegin; 48344f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48354f572ea9SToby Isaac PetscAssertPointer(sf, 2); 48364f37162bSMatthew G. Knepley *sf = dm->sfNatural; 48373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48384f37162bSMatthew G. Knepley } 48394f37162bSMatthew G. Knepley 48404f37162bSMatthew G. Knepley /*@ 48414f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 48424f37162bSMatthew G. Knepley 48434f37162bSMatthew G. Knepley Input Parameters: 48444f37162bSMatthew G. Knepley + dm - The DM 48454f37162bSMatthew G. Knepley - sf - The PetscSF 48464f37162bSMatthew G. Knepley 48474f37162bSMatthew G. Knepley Level: intermediate 48484f37162bSMatthew G. Knepley 48491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 48504f37162bSMatthew G. Knepley @*/ 4851d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 4852d71ae5a4SJacob Faibussowitsch { 48534f37162bSMatthew G. Knepley PetscFunctionBegin; 48544f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48554f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 48569566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)sf)); 48579566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sfNatural)); 48584f37162bSMatthew G. Knepley dm->sfNatural = sf; 48593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48604f37162bSMatthew G. Knepley } 48614f37162bSMatthew G. Knepley 4862d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 4863d71ae5a4SJacob Faibussowitsch { 486434aa8a36SMatthew G. Knepley PetscClassId id; 486534aa8a36SMatthew G. Knepley 486634aa8a36SMatthew G. Knepley PetscFunctionBegin; 48679566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 486834aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 48699566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 487034aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 48719566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE)); 487217c1d62eSMatthew G. Knepley } else { 48739566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 487434aa8a36SMatthew G. Knepley } 48753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 487634aa8a36SMatthew G. Knepley } 487734aa8a36SMatthew G. Knepley 4878d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 4879d71ae5a4SJacob Faibussowitsch { 488044a7f3ddSMatthew G. Knepley RegionField *tmpr; 488144a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 488244a7f3ddSMatthew G. Knepley 488344a7f3ddSMatthew G. Knepley PetscFunctionBegin; 48843ba16761SJacob Faibussowitsch if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS); 48859566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NfNew, &tmpr)); 488644a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 48879371c9d4SSatish Balay for (f = Nf; f < NfNew; ++f) { 48889371c9d4SSatish Balay tmpr[f].disc = NULL; 48899371c9d4SSatish Balay tmpr[f].label = NULL; 48909371c9d4SSatish Balay tmpr[f].avoidTensor = PETSC_FALSE; 48919371c9d4SSatish Balay } 48929566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 489344a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 489444a7f3ddSMatthew G. Knepley dm->fields = tmpr; 48953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 489644a7f3ddSMatthew G. Knepley } 489744a7f3ddSMatthew G. Knepley 489844a7f3ddSMatthew G. Knepley /*@ 489920f4b53cSBarry Smith DMClearFields - Remove all fields from the `DM` 490044a7f3ddSMatthew G. Knepley 490120f4b53cSBarry Smith Logically Collective 490244a7f3ddSMatthew G. Knepley 490344a7f3ddSMatthew G. Knepley Input Parameter: 490420f4b53cSBarry Smith . dm - The `DM` 490544a7f3ddSMatthew G. Knepley 490644a7f3ddSMatthew G. Knepley Level: intermediate 490744a7f3ddSMatthew G. Knepley 49081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetNumFields()`, `DMSetField()` 490944a7f3ddSMatthew G. Knepley @*/ 4910d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearFields(DM dm) 4911d71ae5a4SJacob Faibussowitsch { 491244a7f3ddSMatthew G. Knepley PetscInt f; 491344a7f3ddSMatthew G. Knepley 491444a7f3ddSMatthew G. Knepley PetscFunctionBegin; 491544a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 491644a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 49179566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 49189566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 491944a7f3ddSMatthew G. Knepley } 49209566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 492144a7f3ddSMatthew G. Knepley dm->fields = NULL; 492244a7f3ddSMatthew G. Knepley dm->Nf = 0; 49233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 492444a7f3ddSMatthew G. Knepley } 492544a7f3ddSMatthew G. Knepley 4926689b5837SMatthew G. Knepley /*@ 492720f4b53cSBarry Smith DMGetNumFields - Get the number of fields in the `DM` 4928689b5837SMatthew G. Knepley 492920f4b53cSBarry Smith Not Collective 4930689b5837SMatthew G. Knepley 4931689b5837SMatthew G. Knepley Input Parameter: 493220f4b53cSBarry Smith . dm - The `DM` 4933689b5837SMatthew G. Knepley 4934689b5837SMatthew G. Knepley Output Parameter: 493560225df5SJacob Faibussowitsch . numFields - The number of fields 4936689b5837SMatthew G. Knepley 4937689b5837SMatthew G. Knepley Level: intermediate 4938689b5837SMatthew G. Knepley 49391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetNumFields()`, `DMSetField()` 4940689b5837SMatthew G. Knepley @*/ 4941d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 4942d71ae5a4SJacob Faibussowitsch { 49430f21e855SMatthew G. Knepley PetscFunctionBegin; 49440f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49454f572ea9SToby Isaac PetscAssertPointer(numFields, 2); 494644a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 49473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4948af122d2aSMatthew G Knepley } 4949af122d2aSMatthew G Knepley 4950689b5837SMatthew G. Knepley /*@ 495120f4b53cSBarry Smith DMSetNumFields - Set the number of fields in the `DM` 4952689b5837SMatthew G. Knepley 495320f4b53cSBarry Smith Logically Collective 4954689b5837SMatthew G. Knepley 4955689b5837SMatthew G. Knepley Input Parameters: 495620f4b53cSBarry Smith + dm - The `DM` 495760225df5SJacob Faibussowitsch - numFields - The number of fields 4958689b5837SMatthew G. Knepley 4959689b5837SMatthew G. Knepley Level: intermediate 4960689b5837SMatthew G. Knepley 49611cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumFields()`, `DMSetField()` 4962689b5837SMatthew G. Knepley @*/ 4963d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4964d71ae5a4SJacob Faibussowitsch { 49650f21e855SMatthew G. Knepley PetscInt Nf, f; 4966af122d2aSMatthew G Knepley 4967af122d2aSMatthew G Knepley PetscFunctionBegin; 4968af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49699566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 49700f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 49710f21e855SMatthew G. Knepley PetscContainer obj; 49720f21e855SMatthew G. Knepley 49739566063dSJacob Faibussowitsch PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)dm), &obj)); 49749566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject)obj)); 49759566063dSJacob Faibussowitsch PetscCall(PetscContainerDestroy(&obj)); 4976af122d2aSMatthew G Knepley } 49773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4978af122d2aSMatthew G Knepley } 4979af122d2aSMatthew G Knepley 4980c1929be8SMatthew G. Knepley /*@ 4981bb7acecfSBarry Smith DMGetField - Return the `DMLabel` and discretization object for a given `DM` field 4982c1929be8SMatthew G. Knepley 498320f4b53cSBarry Smith Not Collective 4984c1929be8SMatthew G. Knepley 4985c1929be8SMatthew G. Knepley Input Parameters: 4986bb7acecfSBarry Smith + dm - The `DM` 4987c1929be8SMatthew G. Knepley - f - The field number 4988c1929be8SMatthew G. Knepley 498944a7f3ddSMatthew G. Knepley Output Parameters: 499020f4b53cSBarry Smith + label - The label indicating the support of the field, or `NULL` for the entire mesh (pass in `NULL` if not needed) 499120f4b53cSBarry Smith - disc - The discretization object (pass in `NULL` if not needed) 4992c1929be8SMatthew G. Knepley 499344a7f3ddSMatthew G. Knepley Level: intermediate 4994c1929be8SMatthew G. Knepley 49951cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()` 4996c1929be8SMatthew G. Knepley @*/ 4997d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *disc) 4998d71ae5a4SJacob Faibussowitsch { 4999af122d2aSMatthew G Knepley PetscFunctionBegin; 5000af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 50014f572ea9SToby Isaac PetscAssertPointer(disc, 4); 50027a8be351SBarry 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); 500344a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 5004bb7acecfSBarry Smith if (disc) *disc = dm->fields[f].disc; 50053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5006decb47aaSMatthew G. Knepley } 5007decb47aaSMatthew G. Knepley 5008083401c6SMatthew G. Knepley /* Does not clear the DS */ 5009d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject disc) 5010d71ae5a4SJacob Faibussowitsch { 5011083401c6SMatthew G. Knepley PetscFunctionBegin; 50129566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, f + 1)); 50139566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 50149566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 5015083401c6SMatthew G. Knepley dm->fields[f].label = label; 5016bb7acecfSBarry Smith dm->fields[f].disc = disc; 50179566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5018bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 50193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5020083401c6SMatthew G. Knepley } 5021083401c6SMatthew G. Knepley 502246560f82SMatthew G. Knepley /*@C 5023bb7acecfSBarry Smith DMSetField - Set the discretization object for a given `DM` field. Usually one would call `DMAddField()` which automatically handles 5024bb7acecfSBarry Smith the field numbering. 5025c1929be8SMatthew G. Knepley 502620f4b53cSBarry Smith Logically Collective 5027c1929be8SMatthew G. Knepley 5028c1929be8SMatthew G. Knepley Input Parameters: 5029bb7acecfSBarry Smith + dm - The `DM` 5030c1929be8SMatthew G. Knepley . f - The field number 503120f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 5032bb7acecfSBarry Smith - disc - The discretization object 5033c1929be8SMatthew G. Knepley 503444a7f3ddSMatthew G. Knepley Level: intermediate 5035c1929be8SMatthew G. Knepley 50361cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMGetField()` 5037c1929be8SMatthew G. Knepley @*/ 5038d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject disc) 5039d71ae5a4SJacob Faibussowitsch { 5040decb47aaSMatthew G. Knepley PetscFunctionBegin; 5041decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5042e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 5043bb7acecfSBarry Smith PetscValidHeader(disc, 4); 50447a8be351SBarry Smith PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f); 5045bb7acecfSBarry Smith PetscCall(DMSetField_Internal(dm, f, label, disc)); 5046bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, f, disc)); 50479566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 50483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 504944a7f3ddSMatthew G. Knepley } 505044a7f3ddSMatthew G. Knepley 505146560f82SMatthew G. Knepley /*@C 5052bb7acecfSBarry 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) 5053bb7acecfSBarry Smith and a discretization object that defines the function space associated with those points. 505444a7f3ddSMatthew G. Knepley 505520f4b53cSBarry Smith Logically Collective 505644a7f3ddSMatthew G. Knepley 505744a7f3ddSMatthew G. Knepley Input Parameters: 5058bb7acecfSBarry Smith + dm - The `DM` 505920f4b53cSBarry Smith . label - The label indicating the support of the field, or `NULL` for the entire mesh 5060bb7acecfSBarry Smith - disc - The discretization object 506144a7f3ddSMatthew G. Knepley 506244a7f3ddSMatthew G. Knepley Level: intermediate 506344a7f3ddSMatthew G. Knepley 5064bb7acecfSBarry Smith Notes: 5065bb7acecfSBarry Smith The label already exists or will be added to the `DM` with `DMSetLabel()`. 5066bb7acecfSBarry Smith 5067da81f932SPierre Jolivet For example, a piecewise continuous pressure field can be defined by coefficients at the cell centers of a mesh and piecewise constant functions 5068bb7acecfSBarry 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 5069bb7acecfSBarry Smith geometry entities, a `DMLabel` indicating a subset of those geometric entities, and a discretization object, such as a `PetscFE`. 5070bb7acecfSBarry Smith 50711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetLabel()`, `DMSetField()`, `DMGetField()`, `PetscFE` 507244a7f3ddSMatthew G. Knepley @*/ 5073d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject disc) 5074d71ae5a4SJacob Faibussowitsch { 507544a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 507644a7f3ddSMatthew G. Knepley 507744a7f3ddSMatthew G. Knepley PetscFunctionBegin; 507844a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5079064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5080bb7acecfSBarry Smith PetscValidHeader(disc, 3); 50819566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, Nf + 1)); 508244a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 5083bb7acecfSBarry Smith dm->fields[Nf].disc = disc; 50849566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 5085bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject)disc)); 5086bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, Nf, disc)); 50879566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 50883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5089af122d2aSMatthew G Knepley } 50906636e97aSMatthew G Knepley 5091e5e52638SMatthew G. Knepley /*@ 5092e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 5093e0b68406SMatthew Knepley 509420f4b53cSBarry Smith Logically Collective 5095e0b68406SMatthew Knepley 5096e0b68406SMatthew Knepley Input Parameters: 5097bb7acecfSBarry Smith + dm - The `DM` 5098e0b68406SMatthew Knepley . f - The field index 5099bb7acecfSBarry Smith - avoidTensor - `PETSC_TRUE` to skip defining the field on tensor cells 5100e0b68406SMatthew Knepley 5101e0b68406SMatthew Knepley Level: intermediate 5102e0b68406SMatthew Knepley 51031cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5104e0b68406SMatthew Knepley @*/ 5105d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5106d71ae5a4SJacob Faibussowitsch { 5107e0b68406SMatthew Knepley PetscFunctionBegin; 510863a3b9bcSJacob Faibussowitsch PetscCheck((f >= 0) && (f < dm->Nf), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", f, dm->Nf); 5109e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 51103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5111e0b68406SMatthew Knepley } 5112e0b68406SMatthew Knepley 5113e0b68406SMatthew Knepley /*@ 5114e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5115e0b68406SMatthew Knepley 511620f4b53cSBarry Smith Not Collective 5117e0b68406SMatthew Knepley 5118e0b68406SMatthew Knepley Input Parameters: 5119bb7acecfSBarry Smith + dm - The `DM` 5120e0b68406SMatthew Knepley - f - The field index 5121e0b68406SMatthew Knepley 5122e0b68406SMatthew Knepley Output Parameter: 5123e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5124e0b68406SMatthew Knepley 5125e0b68406SMatthew Knepley Level: intermediate 5126e0b68406SMatthew Knepley 512760225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMAddField()`, `DMSetField()`, `DMGetField()`, `DMSetFieldAvoidTensor()` 5128e0b68406SMatthew Knepley @*/ 5129d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5130d71ae5a4SJacob Faibussowitsch { 5131e0b68406SMatthew Knepley PetscFunctionBegin; 513263a3b9bcSJacob 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); 5133e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 51343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5135e0b68406SMatthew Knepley } 5136e0b68406SMatthew Knepley 5137e0b68406SMatthew Knepley /*@ 5138bb7acecfSBarry Smith DMCopyFields - Copy the discretizations for the `DM` into another `DM` 5139e5e52638SMatthew G. Knepley 514020f4b53cSBarry Smith Collective 5141e5e52638SMatthew G. Knepley 5142e5e52638SMatthew G. Knepley Input Parameter: 5143bb7acecfSBarry Smith . dm - The `DM` 5144e5e52638SMatthew G. Knepley 5145e5e52638SMatthew G. Knepley Output Parameter: 5146bb7acecfSBarry Smith . newdm - The `DM` 5147e5e52638SMatthew G. Knepley 5148e5e52638SMatthew G. Knepley Level: advanced 5149e5e52638SMatthew G. Knepley 51501cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetField()`, `DMSetField()`, `DMAddField()`, `DMCopyDS()`, `DMGetDS()`, `DMGetCellDS()` 5151e5e52638SMatthew G. Knepley @*/ 5152d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyFields(DM dm, DM newdm) 5153d71ae5a4SJacob Faibussowitsch { 5154e5e52638SMatthew G. Knepley PetscInt Nf, f; 5155e5e52638SMatthew G. Knepley 5156e5e52638SMatthew G. Knepley PetscFunctionBegin; 51573ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 51589566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51599566063dSJacob Faibussowitsch PetscCall(DMClearFields(newdm)); 5160e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5161e5e52638SMatthew G. Knepley DMLabel label; 5162e5e52638SMatthew G. Knepley PetscObject field; 516334aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5164e5e52638SMatthew G. Knepley 51659566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, &label, &field)); 51669566063dSJacob Faibussowitsch PetscCall(DMSetField(newdm, f, label, field)); 51679566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, f, &useCone, &useClosure)); 51689566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(newdm, f, useCone, useClosure)); 516934aa8a36SMatthew G. Knepley } 51703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 517134aa8a36SMatthew G. Knepley } 517234aa8a36SMatthew G. Knepley 517334aa8a36SMatthew G. Knepley /*@ 517434aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 517534aa8a36SMatthew G. Knepley 517620f4b53cSBarry Smith Not Collective 517734aa8a36SMatthew G. Knepley 517834aa8a36SMatthew G. Knepley Input Parameters: 517920f4b53cSBarry Smith + dm - The `DM` object 518020f4b53cSBarry Smith - f - The field number, or `PETSC_DEFAULT` for the default adjacency 518134aa8a36SMatthew G. Knepley 5182d8d19677SJose E. Roman Output Parameters: 518334aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 518434aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 518534aa8a36SMatthew G. Knepley 518634aa8a36SMatthew G. Knepley Level: developer 518734aa8a36SMatthew G. Knepley 518820f4b53cSBarry Smith Notes: 518920f4b53cSBarry Smith .vb 519020f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 519120f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 519220f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 519320f4b53cSBarry Smith .ve 519420f4b53cSBarry Smith Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 519520f4b53cSBarry Smith 51961cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetAdjacency()`, `DMGetField()`, `DMSetField()` 519734aa8a36SMatthew G. Knepley @*/ 5198d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 5199d71ae5a4SJacob Faibussowitsch { 520034aa8a36SMatthew G. Knepley PetscFunctionBegin; 520134aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52024f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 3); 52034f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 4); 520434aa8a36SMatthew G. Knepley if (f < 0) { 520534aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 520634aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 520734aa8a36SMatthew G. Knepley } else { 520834aa8a36SMatthew G. Knepley PetscInt Nf; 520934aa8a36SMatthew G. Knepley 52109566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 52117a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 521234aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 521334aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 521434aa8a36SMatthew G. Knepley } 52153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 521634aa8a36SMatthew G. Knepley } 521734aa8a36SMatthew G. Knepley 521834aa8a36SMatthew G. Knepley /*@ 521934aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 522034aa8a36SMatthew G. Knepley 522120f4b53cSBarry Smith Not Collective 522234aa8a36SMatthew G. Knepley 522334aa8a36SMatthew G. Knepley Input Parameters: 522420f4b53cSBarry Smith + dm - The `DM` object 522534aa8a36SMatthew G. Knepley . f - The field number 522634aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 522734aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 522834aa8a36SMatthew G. Knepley 522934aa8a36SMatthew G. Knepley Level: developer 523034aa8a36SMatthew G. Knepley 523120f4b53cSBarry Smith Notes: 523220f4b53cSBarry Smith .vb 523320f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 523420f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 523520f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 523620f4b53cSBarry Smith .ve 523720f4b53cSBarry Smith Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 523820f4b53cSBarry Smith 52391cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetAdjacency()`, `DMGetField()`, `DMSetField()` 524034aa8a36SMatthew G. Knepley @*/ 5241d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 5242d71ae5a4SJacob Faibussowitsch { 524334aa8a36SMatthew G. Knepley PetscFunctionBegin; 524434aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 524534aa8a36SMatthew G. Knepley if (f < 0) { 524634aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 524734aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 524834aa8a36SMatthew G. Knepley } else { 524934aa8a36SMatthew G. Knepley PetscInt Nf; 525034aa8a36SMatthew G. Knepley 52519566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 52527a8be351SBarry Smith PetscCheck(f < Nf, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 525334aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 525434aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5255e5e52638SMatthew G. Knepley } 52563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5257e5e52638SMatthew G. Knepley } 5258e5e52638SMatthew G. Knepley 5259b0441da4SMatthew G. Knepley /*@ 5260b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5261b0441da4SMatthew G. Knepley 5262b0441da4SMatthew G. Knepley Not collective 5263b0441da4SMatthew G. Knepley 5264f899ff85SJose E. Roman Input Parameter: 526520f4b53cSBarry Smith . dm - The `DM` object 5266b0441da4SMatthew G. Knepley 5267d8d19677SJose E. Roman Output Parameters: 5268b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5269b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5270b0441da4SMatthew G. Knepley 5271b0441da4SMatthew G. Knepley Level: developer 5272b0441da4SMatthew G. Knepley 527320f4b53cSBarry Smith Notes: 527420f4b53cSBarry Smith .vb 527520f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 527620f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 527720f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 527820f4b53cSBarry Smith .ve 527920f4b53cSBarry Smith 52801cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5281b0441da4SMatthew G. Knepley @*/ 5282d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5283d71ae5a4SJacob Faibussowitsch { 5284b0441da4SMatthew G. Knepley PetscInt Nf; 5285b0441da4SMatthew G. Knepley 5286b0441da4SMatthew G. Knepley PetscFunctionBegin; 5287b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52884f572ea9SToby Isaac if (useCone) PetscAssertPointer(useCone, 2); 52894f572ea9SToby Isaac if (useClosure) PetscAssertPointer(useClosure, 3); 52909566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5291b0441da4SMatthew G. Knepley if (!Nf) { 52929566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5293b0441da4SMatthew G. Knepley } else { 52949566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, 0, useCone, useClosure)); 5295b0441da4SMatthew G. Knepley } 52963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5297b0441da4SMatthew G. Knepley } 5298b0441da4SMatthew G. Knepley 5299b0441da4SMatthew G. Knepley /*@ 5300b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5301b0441da4SMatthew G. Knepley 530220f4b53cSBarry Smith Not Collective 5303b0441da4SMatthew G. Knepley 5304b0441da4SMatthew G. Knepley Input Parameters: 530520f4b53cSBarry Smith + dm - The `DM` object 5306b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5307b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5308b0441da4SMatthew G. Knepley 5309b0441da4SMatthew G. Knepley Level: developer 5310b0441da4SMatthew G. Knepley 531120f4b53cSBarry Smith Notes: 531220f4b53cSBarry Smith .vb 531320f4b53cSBarry Smith FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 531420f4b53cSBarry Smith FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 531520f4b53cSBarry Smith FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 531620f4b53cSBarry Smith .ve 531720f4b53cSBarry Smith 53181cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5319b0441da4SMatthew G. Knepley @*/ 5320d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5321d71ae5a4SJacob Faibussowitsch { 5322b0441da4SMatthew G. Knepley PetscInt Nf; 5323b0441da4SMatthew G. Knepley 5324b0441da4SMatthew G. Knepley PetscFunctionBegin; 5325b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 53269566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5327b0441da4SMatthew G. Knepley if (!Nf) { 53289566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5329b0441da4SMatthew G. Knepley } else { 53309566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, 0, useCone, useClosure)); 5331e5e52638SMatthew G. Knepley } 53323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5333e5e52638SMatthew G. Knepley } 5334e5e52638SMatthew G. Knepley 5335d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompleteBCLabels_Internal(DM dm) 5336d71ae5a4SJacob Faibussowitsch { 5337799db056SMatthew G. Knepley DM plex; 5338799db056SMatthew G. Knepley DMLabel *labels, *glabels; 5339799db056SMatthew G. Knepley const char **names; 5340799db056SMatthew G. Knepley char *sendNames, *recvNames; 5341799db056SMatthew G. Knepley PetscInt Nds, s, maxLabels = 0, maxLen = 0, gmaxLen, Nl = 0, gNl, l, gl, m; 5342799db056SMatthew G. Knepley size_t len; 5343799db056SMatthew G. Knepley MPI_Comm comm; 5344799db056SMatthew G. Knepley PetscMPIInt rank, size, p, *counts, *displs; 5345783e2ec8SMatthew G. Knepley 5346783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5347799db056SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5348799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 5349799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5350799db056SMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 5351799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5352799db056SMatthew G. Knepley PetscDS dsBC; 5353799db056SMatthew G. Knepley PetscInt numBd; 5354799db056SMatthew G. Knepley 535507218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5356799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5357799db056SMatthew G. Knepley maxLabels += numBd; 5358799db056SMatthew G. Knepley } 5359799db056SMatthew G. Knepley PetscCall(PetscCalloc1(maxLabels, &labels)); 5360799db056SMatthew G. Knepley /* Get list of labels to be completed */ 5361799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5362799db056SMatthew G. Knepley PetscDS dsBC; 5363799db056SMatthew G. Knepley PetscInt numBd, bd; 5364799db056SMatthew G. Knepley 536507218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC, NULL)); 5366799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5367799db056SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5368799db056SMatthew G. Knepley DMLabel label; 5369799db056SMatthew G. Knepley PetscInt field; 5370799db056SMatthew G. Knepley PetscObject obj; 5371799db056SMatthew G. Knepley PetscClassId id; 5372799db056SMatthew G. Knepley 5373799db056SMatthew G. Knepley PetscCall(PetscDSGetBoundary(dsBC, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 53749566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, field, NULL, &obj)); 53759566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(obj, &id)); 5376799db056SMatthew G. Knepley if (!(id == PETSCFE_CLASSID) || !label) continue; 53779371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 53789371c9d4SSatish Balay if (labels[l] == label) break; 5379799db056SMatthew G. Knepley if (l == Nl) labels[Nl++] = label; 5380783e2ec8SMatthew G. Knepley } 5381799db056SMatthew G. Knepley } 5382799db056SMatthew G. Knepley /* Get label names */ 5383799db056SMatthew G. Knepley PetscCall(PetscMalloc1(Nl, &names)); 5384799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscObjectGetName((PetscObject)labels[l], &names[l])); 53859371c9d4SSatish Balay for (l = 0; l < Nl; ++l) { 53869371c9d4SSatish Balay PetscCall(PetscStrlen(names[l], &len)); 53879371c9d4SSatish Balay maxLen = PetscMax(maxLen, (PetscInt)len + 2); 53889371c9d4SSatish Balay } 5389799db056SMatthew G. Knepley PetscCall(PetscFree(labels)); 5390712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&maxLen, &gmaxLen, 1, MPIU_INT, MPI_MAX, comm)); 5391799db056SMatthew G. Knepley PetscCall(PetscCalloc1(Nl * gmaxLen, &sendNames)); 5392c6a7a370SJeremy L Thompson for (l = 0; l < Nl; ++l) PetscCall(PetscStrncpy(&sendNames[gmaxLen * l], names[l], gmaxLen)); 5393799db056SMatthew G. Knepley PetscCall(PetscFree(names)); 5394799db056SMatthew G. Knepley /* Put all names on all processes */ 5395799db056SMatthew G. Knepley PetscCall(PetscCalloc2(size, &counts, size + 1, &displs)); 5396799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgather(&Nl, 1, MPI_INT, counts, 1, MPI_INT, comm)); 5397799db056SMatthew G. Knepley for (p = 0; p < size; ++p) displs[p + 1] = displs[p] + counts[p]; 5398799db056SMatthew G. Knepley gNl = displs[size]; 53999371c9d4SSatish Balay for (p = 0; p < size; ++p) { 54009371c9d4SSatish Balay counts[p] *= gmaxLen; 54019371c9d4SSatish Balay displs[p] *= gmaxLen; 54029371c9d4SSatish Balay } 5403799db056SMatthew G. Knepley PetscCall(PetscCalloc2(gNl * gmaxLen, &recvNames, gNl, &glabels)); 5404799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgatherv(sendNames, counts[rank], MPI_CHAR, recvNames, counts, displs, MPI_CHAR, comm)); 5405799db056SMatthew G. Knepley PetscCall(PetscFree2(counts, displs)); 5406799db056SMatthew G. Knepley PetscCall(PetscFree(sendNames)); 5407799db056SMatthew G. Knepley for (l = 0, gl = 0; l < gNl; ++l) { 5408799db056SMatthew G. Knepley PetscCall(DMGetLabel(dm, &recvNames[l * gmaxLen], &glabels[gl])); 5409799db056SMatthew G. Knepley PetscCheck(glabels[gl], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Label %s missing on rank %d", &recvNames[l * gmaxLen], rank); 54109371c9d4SSatish Balay for (m = 0; m < gl; ++m) 54119371c9d4SSatish Balay if (glabels[m] == glabels[gl]) continue; 54129566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 5413799db056SMatthew G. Knepley PetscCall(DMPlexLabelComplete(plex, glabels[gl])); 54149566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5415799db056SMatthew G. Knepley ++gl; 5416783e2ec8SMatthew G. Knepley } 5417799db056SMatthew G. Knepley PetscCall(PetscFree2(recvNames, glabels)); 54183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5419783e2ec8SMatthew G. Knepley } 5420783e2ec8SMatthew G. Knepley 5421d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5422d71ae5a4SJacob Faibussowitsch { 5423e5e52638SMatthew G. Knepley DMSpace *tmpd; 5424e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5425e5e52638SMatthew G. Knepley 5426e5e52638SMatthew G. Knepley PetscFunctionBegin; 54273ba16761SJacob Faibussowitsch if (Nds >= NdsNew) PetscFunctionReturn(PETSC_SUCCESS); 54289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NdsNew, &tmpd)); 5429e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 54309371c9d4SSatish Balay for (s = Nds; s < NdsNew; ++s) { 54319371c9d4SSatish Balay tmpd[s].ds = NULL; 54329371c9d4SSatish Balay tmpd[s].label = NULL; 54339371c9d4SSatish Balay tmpd[s].fields = NULL; 54349371c9d4SSatish Balay } 54359566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5436e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5437e5e52638SMatthew G. Knepley dm->probs = tmpd; 54383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5439e5e52638SMatthew G. Knepley } 5440e5e52638SMatthew G. Knepley 5441e5e52638SMatthew G. Knepley /*@ 544220f4b53cSBarry Smith DMGetNumDS - Get the number of discrete systems in the `DM` 5443e5e52638SMatthew G. Knepley 544420f4b53cSBarry Smith Not Collective 5445e5e52638SMatthew G. Knepley 5446e5e52638SMatthew G. Knepley Input Parameter: 544720f4b53cSBarry Smith . dm - The `DM` 5448e5e52638SMatthew G. Knepley 5449e5e52638SMatthew G. Knepley Output Parameter: 545020f4b53cSBarry Smith . Nds - The number of `PetscDS` objects 5451e5e52638SMatthew G. Knepley 5452e5e52638SMatthew G. Knepley Level: intermediate 5453e5e52638SMatthew G. Knepley 54541cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMGetCellDS()` 5455e5e52638SMatthew G. Knepley @*/ 5456d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5457d71ae5a4SJacob Faibussowitsch { 5458e5e52638SMatthew G. Knepley PetscFunctionBegin; 5459e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54604f572ea9SToby Isaac PetscAssertPointer(Nds, 2); 5461e5e52638SMatthew G. Knepley *Nds = dm->Nds; 54623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5463e5e52638SMatthew G. Knepley } 5464e5e52638SMatthew G. Knepley 5465e5e52638SMatthew G. Knepley /*@ 546620f4b53cSBarry Smith DMClearDS - Remove all discrete systems from the `DM` 5467e5e52638SMatthew G. Knepley 546820f4b53cSBarry Smith Logically Collective 5469e5e52638SMatthew G. Knepley 5470e5e52638SMatthew G. Knepley Input Parameter: 547120f4b53cSBarry Smith . dm - The `DM` 5472e5e52638SMatthew G. Knepley 5473e5e52638SMatthew G. Knepley Level: intermediate 5474e5e52638SMatthew G. Knepley 54751cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetNumDS()`, `DMGetDS()`, `DMSetField()` 5476e5e52638SMatthew G. Knepley @*/ 5477d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearDS(DM dm) 5478d71ae5a4SJacob Faibussowitsch { 5479e5e52638SMatthew G. Knepley PetscInt s; 5480e5e52638SMatthew G. Knepley 5481e5e52638SMatthew G. Knepley PetscFunctionBegin; 5482e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5483e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 54849566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 548507218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 54869566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[s].label)); 54879566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[s].fields)); 5488e5e52638SMatthew G. Knepley } 54899566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5490e5e52638SMatthew G. Knepley dm->probs = NULL; 5491e5e52638SMatthew G. Knepley dm->Nds = 0; 54923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5493e5e52638SMatthew G. Knepley } 5494e5e52638SMatthew G. Knepley 5495e5e52638SMatthew G. Knepley /*@ 549620f4b53cSBarry Smith DMGetDS - Get the default `PetscDS` 5497e5e52638SMatthew G. Knepley 549820f4b53cSBarry Smith Not Collective 5499e5e52638SMatthew G. Knepley 5500e5e52638SMatthew G. Knepley Input Parameter: 550120f4b53cSBarry Smith . dm - The `DM` 5502e5e52638SMatthew G. Knepley 5503e5e52638SMatthew G. Knepley Output Parameter: 550407218a29SMatthew G. Knepley . ds - The default `PetscDS` 5505e5e52638SMatthew G. Knepley 5506e5e52638SMatthew G. Knepley Level: intermediate 5507e5e52638SMatthew G. Knepley 55081cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCellDS()`, `DMGetRegionDS()` 5509e5e52638SMatthew G. Knepley @*/ 551007218a29SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *ds) 5511d71ae5a4SJacob Faibussowitsch { 5512e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5513e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55144f572ea9SToby Isaac PetscAssertPointer(ds, 2); 551507218a29SMatthew G. Knepley PetscCheck(dm->Nds > 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Need to call DMCreateDS() before calling DMGetDS()"); 551607218a29SMatthew G. Knepley *ds = dm->probs[0].ds; 55173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5518e5e52638SMatthew G. Knepley } 5519e5e52638SMatthew G. Knepley 5520e5e52638SMatthew G. Knepley /*@ 552120f4b53cSBarry Smith DMGetCellDS - Get the `PetscDS` defined on a given cell 5522e5e52638SMatthew G. Knepley 552320f4b53cSBarry Smith Not Collective 5524e5e52638SMatthew G. Knepley 5525e5e52638SMatthew G. Knepley Input Parameters: 552620f4b53cSBarry Smith + dm - The `DM` 552720f4b53cSBarry Smith - point - Cell for the `PetscDS` 5528e5e52638SMatthew G. Knepley 552907218a29SMatthew G. Knepley Output Parameters: 553007218a29SMatthew G. Knepley + ds - The `PetscDS` defined on the given cell 553107218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or NULL if the same ds 5532e5e52638SMatthew G. Knepley 5533e5e52638SMatthew G. Knepley Level: developer 5534e5e52638SMatthew G. Knepley 55351cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDS()`, `DMSetRegionDS()` 5536e5e52638SMatthew G. Knepley @*/ 553707218a29SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *ds, PetscDS *dsIn) 5538d71ae5a4SJacob Faibussowitsch { 553907218a29SMatthew G. Knepley PetscDS dsDef = NULL; 5540e5e52638SMatthew G. Knepley PetscInt s; 5541e5e52638SMatthew G. Knepley 5542e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5543e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55444f572ea9SToby Isaac if (ds) PetscAssertPointer(ds, 3); 55454f572ea9SToby Isaac if (dsIn) PetscAssertPointer(dsIn, 4); 554663a3b9bcSJacob Faibussowitsch PetscCheck(point >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %" PetscInt_FMT, point); 554707218a29SMatthew G. Knepley if (ds) *ds = NULL; 554807218a29SMatthew G. Knepley if (dsIn) *dsIn = NULL; 5549e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5550e5e52638SMatthew G. Knepley PetscInt val; 5551e5e52638SMatthew G. Knepley 55529371c9d4SSatish Balay if (!dm->probs[s].label) { 555307218a29SMatthew G. Knepley dsDef = dm->probs[s].ds; 55549371c9d4SSatish Balay } else { 55559566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dm->probs[s].label, point, &val)); 55569371c9d4SSatish Balay if (val >= 0) { 555707218a29SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 555807218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 55599371c9d4SSatish Balay break; 55609371c9d4SSatish Balay } 5561e5e52638SMatthew G. Knepley } 5562e5e52638SMatthew G. Knepley } 556307218a29SMatthew G. Knepley if (ds && !*ds) *ds = dsDef; 55643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5565e5e52638SMatthew G. Knepley } 5566e5e52638SMatthew G. Knepley 5567e5e52638SMatthew G. Knepley /*@ 556820f4b53cSBarry Smith DMGetRegionDS - Get the `PetscDS` for a given mesh region, defined by a `DMLabel` 5569e5e52638SMatthew G. Knepley 557020f4b53cSBarry Smith Not Collective 5571e5e52638SMatthew G. Knepley 5572e5e52638SMatthew G. Knepley Input Parameters: 557320f4b53cSBarry Smith + dm - The `DM` 557420f4b53cSBarry Smith - label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 5575e5e52638SMatthew G. Knepley 5576b3cf3223SMatthew G. Knepley Output Parameters: 557720f4b53cSBarry Smith + fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 557807218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 557907218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5580e5e52638SMatthew G. Knepley 5581e5e52638SMatthew G. Knepley Level: advanced 5582e5e52638SMatthew G. Knepley 558320f4b53cSBarry Smith Note: 558420f4b53cSBarry Smith If a non-`NULL` label is given, but there is no `PetscDS` on that specific label, 558520f4b53cSBarry Smith the `PetscDS` for the full domain (if present) is returned. Returns with 558607218a29SMatthew G. Knepley fields = `NULL` and ds = `NULL` if there is no `PetscDS` for the full domain. 558720f4b53cSBarry Smith 55881cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5589e5e52638SMatthew G. Knepley @*/ 559007218a29SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5591d71ae5a4SJacob Faibussowitsch { 5592e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5593e5e52638SMatthew G. Knepley 5594e5e52638SMatthew G. Knepley PetscFunctionBegin; 5595e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5596e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 55979371c9d4SSatish Balay if (fields) { 55984f572ea9SToby Isaac PetscAssertPointer(fields, 3); 55999371c9d4SSatish Balay *fields = NULL; 56009371c9d4SSatish Balay } 56019371c9d4SSatish Balay if (ds) { 56024f572ea9SToby Isaac PetscAssertPointer(ds, 4); 56039371c9d4SSatish Balay *ds = NULL; 56049371c9d4SSatish Balay } 560507218a29SMatthew G. Knepley if (dsIn) { 56064f572ea9SToby Isaac PetscAssertPointer(dsIn, 5); 560707218a29SMatthew G. Knepley *dsIn = NULL; 560807218a29SMatthew G. Knepley } 5609e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5610154ca461SJed Brown if (dm->probs[s].label == label || !dm->probs[s].label) { 5611b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5612b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 561307218a29SMatthew G. Knepley if (dsIn) *dsIn = dm->probs[s].dsIn; 56143ba16761SJacob Faibussowitsch if (dm->probs[s].label) PetscFunctionReturn(PETSC_SUCCESS); 5615b3cf3223SMatthew G. Knepley } 5616e5e52638SMatthew G. Knepley } 56173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5618e5e52638SMatthew G. Knepley } 5619e5e52638SMatthew G. Knepley 5620e5e52638SMatthew G. Knepley /*@ 5621bb7acecfSBarry Smith DMSetRegionDS - Set the `PetscDS` for a given mesh region, defined by a `DMLabel` 5622083401c6SMatthew G. Knepley 562320f4b53cSBarry Smith Collective 5624083401c6SMatthew G. Knepley 5625083401c6SMatthew G. Knepley Input Parameters: 5626bb7acecfSBarry Smith + dm - The `DM` 562720f4b53cSBarry Smith . label - The `DMLabel` defining the mesh region, or `NULL` for the entire mesh 562807218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` for all fields 562907218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region 563007218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5631083401c6SMatthew G. Knepley 563220f4b53cSBarry Smith Level: advanced 563320f4b53cSBarry Smith 5634bb7acecfSBarry Smith Note: 5635bb7acecfSBarry 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, 5636083401c6SMatthew G. Knepley the fields argument is ignored. 5637083401c6SMatthew G. Knepley 56381cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionNumDS()`, `DMGetDS()`, `DMGetCellDS()` 5639083401c6SMatthew G. Knepley @*/ 564007218a29SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5641d71ae5a4SJacob Faibussowitsch { 5642083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5643083401c6SMatthew G. Knepley 5644083401c6SMatthew G. Knepley PetscFunctionBegin; 5645083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5646083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 564707218a29SMatthew G. Knepley if (fields) PetscValidHeaderSpecific(fields, IS_CLASSID, 3); 5648064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 564907218a29SMatthew G. Knepley if (dsIn) PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 5); 5650083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5651083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 56529566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 565307218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[s].dsIn)); 5654083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 565507218a29SMatthew G. Knepley dm->probs[s].dsIn = dsIn; 56563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5657083401c6SMatthew G. Knepley } 5658083401c6SMatthew G. Knepley } 56599566063dSJacob Faibussowitsch PetscCall(DMDSEnlarge_Static(dm, Nds + 1)); 56609566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 56619566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 56629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 566307218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 5664083401c6SMatthew G. Knepley if (!label) { 5665083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5666083401c6SMatthew G. Knepley for (s = Nds - 1; s >= 0; --s) dm->probs[s + 1] = dm->probs[s]; 5667083401c6SMatthew G. Knepley Nds = 0; 5668083401c6SMatthew G. Knepley } 5669083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5670083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5671083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 567207218a29SMatthew G. Knepley dm->probs[Nds].dsIn = dsIn; 56733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5674083401c6SMatthew G. Knepley } 5675083401c6SMatthew G. Knepley 5676083401c6SMatthew G. Knepley /*@ 567720f4b53cSBarry Smith DMGetRegionNumDS - Get the `PetscDS` for a given mesh region, defined by the region number 5678e5e52638SMatthew G. Knepley 567920f4b53cSBarry Smith Not Collective 5680e5e52638SMatthew G. Knepley 5681e5e52638SMatthew G. Knepley Input Parameters: 568220f4b53cSBarry Smith + dm - The `DM` 5683e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5684e5e52638SMatthew G. Knepley 5685e5e52638SMatthew G. Knepley Output Parameters: 568620f4b53cSBarry Smith + label - The region label, or `NULL` 568720f4b53cSBarry Smith . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` 568807218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` 568907218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input in the given region, or `NULL` 5690e5e52638SMatthew G. Knepley 5691e5e52638SMatthew G. Knepley Level: advanced 5692e5e52638SMatthew G. Knepley 56931cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5694e5e52638SMatthew G. Knepley @*/ 569507218a29SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds, PetscDS *dsIn) 5696d71ae5a4SJacob Faibussowitsch { 5697e5e52638SMatthew G. Knepley PetscInt Nds; 5698e5e52638SMatthew G. Knepley 5699e5e52638SMatthew G. Knepley PetscFunctionBegin; 5700e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57019566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 570263a3b9bcSJacob 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); 5703e5e52638SMatthew G. Knepley if (label) { 57044f572ea9SToby Isaac PetscAssertPointer(label, 3); 5705e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5706e5e52638SMatthew G. Knepley } 5707b3cf3223SMatthew G. Knepley if (fields) { 57084f572ea9SToby Isaac PetscAssertPointer(fields, 4); 5709b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5710b3cf3223SMatthew G. Knepley } 5711e5e52638SMatthew G. Knepley if (ds) { 57124f572ea9SToby Isaac PetscAssertPointer(ds, 5); 5713e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5714e5e52638SMatthew G. Knepley } 571507218a29SMatthew G. Knepley if (dsIn) { 57164f572ea9SToby Isaac PetscAssertPointer(dsIn, 6); 571707218a29SMatthew G. Knepley *dsIn = dm->probs[num].dsIn; 571807218a29SMatthew G. Knepley } 57193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5720e5e52638SMatthew G. Knepley } 5721e5e52638SMatthew G. Knepley 5722e5e52638SMatthew G. Knepley /*@ 572320f4b53cSBarry Smith DMSetRegionNumDS - Set the `PetscDS` for a given mesh region, defined by the region number 5724e5e52638SMatthew G. Knepley 572520f4b53cSBarry Smith Not Collective 5726e5e52638SMatthew G. Knepley 5727e5e52638SMatthew G. Knepley Input Parameters: 572820f4b53cSBarry Smith + dm - The `DM` 5729083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 573020f4b53cSBarry Smith . label - The region label, or `NULL` 573107218a29SMatthew G. Knepley . fields - The `IS` containing the `DM` field numbers for the fields in this `PetscDS`, or `NULL` to prevent setting 573207218a29SMatthew G. Knepley . ds - The `PetscDS` defined on the given region, or `NULL` to prevent setting 573307218a29SMatthew G. Knepley - dsIn - The `PetscDS` for input on the given cell, or `NULL` if it is the same `PetscDS` 5734e5e52638SMatthew G. Knepley 5735e5e52638SMatthew G. Knepley Level: advanced 5736e5e52638SMatthew G. Knepley 57371cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5738e5e52638SMatthew G. Knepley @*/ 573907218a29SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 5740d71ae5a4SJacob Faibussowitsch { 5741083401c6SMatthew G. Knepley PetscInt Nds; 5742e5e52638SMatthew G. Knepley 5743e5e52638SMatthew G. Knepley PetscFunctionBegin; 5744e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5745ad540459SPierre Jolivet if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 57469566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 574763a3b9bcSJacob 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); 57489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 57499566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[num].label)); 5750083401c6SMatthew G. Knepley dm->probs[num].label = label; 5751083401c6SMatthew G. Knepley if (fields) { 5752083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 57539566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fields)); 57549566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[num].fields)); 5755083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5756e5e52638SMatthew G. Knepley } 5757083401c6SMatthew G. Knepley if (ds) { 5758083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 57599566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ds)); 57609566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[num].ds)); 5761083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5762083401c6SMatthew G. Knepley } 576307218a29SMatthew G. Knepley if (dsIn) { 576407218a29SMatthew G. Knepley PetscValidHeaderSpecific(dsIn, PETSCDS_CLASSID, 6); 576507218a29SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)dsIn)); 576607218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dm->probs[num].dsIn)); 576707218a29SMatthew G. Knepley dm->probs[num].dsIn = dsIn; 576807218a29SMatthew G. Knepley } 57693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5770e5e52638SMatthew G. Knepley } 5771e5e52638SMatthew G. Knepley 5772e5e52638SMatthew G. Knepley /*@ 577320f4b53cSBarry Smith DMFindRegionNum - Find the region number for a given `PetscDS`, or -1 if it is not found. 57741d3af9e0SMatthew G. Knepley 577520f4b53cSBarry Smith Not Collective 57761d3af9e0SMatthew G. Knepley 57771d3af9e0SMatthew G. Knepley Input Parameters: 577820f4b53cSBarry Smith + dm - The `DM` 577920f4b53cSBarry Smith - ds - The `PetscDS` defined on the given region 57801d3af9e0SMatthew G. Knepley 57811d3af9e0SMatthew G. Knepley Output Parameter: 57821d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 57831d3af9e0SMatthew G. Knepley 57841d3af9e0SMatthew G. Knepley Level: advanced 57851d3af9e0SMatthew G. Knepley 57861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetRegionNumDS()`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 57871d3af9e0SMatthew G. Knepley @*/ 5788d71ae5a4SJacob Faibussowitsch PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 5789d71ae5a4SJacob Faibussowitsch { 57901d3af9e0SMatthew G. Knepley PetscInt Nds, n; 57911d3af9e0SMatthew G. Knepley 57921d3af9e0SMatthew G. Knepley PetscFunctionBegin; 57931d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57941d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 57954f572ea9SToby Isaac PetscAssertPointer(num, 3); 57969566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 57979371c9d4SSatish Balay for (n = 0; n < Nds; ++n) 57989371c9d4SSatish Balay if (ds == dm->probs[n].ds) break; 57991d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 58001d3af9e0SMatthew G. Knepley else *num = n; 58013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58021d3af9e0SMatthew G. Knepley } 58031d3af9e0SMatthew G. Knepley 58042df84da0SMatthew G. Knepley /*@C 5805bb7acecfSBarry Smith DMCreateFEDefault - Create a `PetscFE` based on the celltype for the mesh 58062df84da0SMatthew G. Knepley 580720f4b53cSBarry Smith Not Collective 58082df84da0SMatthew G. Knepley 5809f1a722f8SMatthew G. Knepley Input Parameters: 5810bb7acecfSBarry Smith + dm - The `DM` 58112df84da0SMatthew G. Knepley . Nc - The number of components for the field 581220f4b53cSBarry Smith . prefix - The options prefix for the output `PetscFE`, or `NULL` 5813bb7acecfSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 58142df84da0SMatthew G. Knepley 58152df84da0SMatthew G. Knepley Output Parameter: 5816bb7acecfSBarry Smith . fem - The `PetscFE` 58172df84da0SMatthew G. Knepley 581820f4b53cSBarry Smith Level: intermediate 581920f4b53cSBarry Smith 5820bb7acecfSBarry Smith Note: 5821bb7acecfSBarry Smith This is a convenience method that just calls `PetscFECreateByCell()` underneath. 58222df84da0SMatthew G. Knepley 58231cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscFECreateByCell()`, `DMAddField()`, `DMCreateDS()`, `DMGetCellDS()`, `DMGetRegionDS()` 58242df84da0SMatthew G. Knepley @*/ 5825d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFEDefault(DM dm, PetscInt Nc, const char prefix[], PetscInt qorder, PetscFE *fem) 5826d71ae5a4SJacob Faibussowitsch { 58272df84da0SMatthew G. Knepley DMPolytopeType ct; 58282df84da0SMatthew G. Knepley PetscInt dim, cStart; 58292df84da0SMatthew G. Knepley 58302df84da0SMatthew G. Knepley PetscFunctionBegin; 58312df84da0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58322df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 2); 58334f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 3); 58342df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, qorder, 4); 58354f572ea9SToby Isaac PetscAssertPointer(fem, 5); 58369566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 58379566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 58389566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 58399566063dSJacob Faibussowitsch PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, Nc, ct, prefix, qorder, fem)); 58403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58412df84da0SMatthew G. Knepley } 58422df84da0SMatthew G. Knepley 58431d3af9e0SMatthew G. Knepley /*@ 5844bb7acecfSBarry Smith DMCreateDS - Create the discrete systems for the `DM` based upon the fields added to the `DM` 5845e5e52638SMatthew G. Knepley 584620f4b53cSBarry Smith Collective 5847e5e52638SMatthew G. Knepley 5848e5e52638SMatthew G. Knepley Input Parameter: 5849bb7acecfSBarry Smith . dm - The `DM` 5850e5e52638SMatthew G. Knepley 585120f4b53cSBarry Smith Options Database Key: 5852bb7acecfSBarry Smith . -dm_petscds_view - View all the `PetscDS` objects in this `DM` 585345480ffeSMatthew G. Knepley 585420f4b53cSBarry Smith Level: intermediate 585520f4b53cSBarry Smith 58561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetField`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 5857e5e52638SMatthew G. Knepley @*/ 5858d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateDS(DM dm) 5859d71ae5a4SJacob Faibussowitsch { 5860e5e52638SMatthew G. Knepley MPI_Comm comm; 5861083401c6SMatthew G. Knepley PetscDS dsDef; 5862083401c6SMatthew G. Knepley DMLabel *labelSet; 5863f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5864f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5865e5e52638SMatthew G. Knepley 5866e5e52638SMatthew G. Knepley PetscFunctionBegin; 5867e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58683ba16761SJacob Faibussowitsch if (!dm->fields) PetscFunctionReturn(PETSC_SUCCESS); 58699566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 58709566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dE)); 5871083401c6SMatthew G. Knepley /* Determine how many regions we have */ 58729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &labelSet)); 5873083401c6SMatthew G. Knepley Nl = 0; 5874083401c6SMatthew G. Knepley Ndef = 0; 5875083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5876083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5877083401c6SMatthew G. Knepley PetscInt l; 5878083401c6SMatthew G. Knepley 5879f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5880f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5881f918ec44SMatthew G. Knepley { 5882f918ec44SMatthew G. Knepley PetscClassId id; 5883f918ec44SMatthew G. Knepley 58849566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(dm->fields[f].disc, &id)); 5885f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5886f918ec44SMatthew G. Knepley Ceed ceed; 5887f918ec44SMatthew G. Knepley 58889566063dSJacob Faibussowitsch PetscCall(DMGetCeed(dm, &ceed)); 58899566063dSJacob Faibussowitsch PetscCall(PetscFESetCeed((PetscFE)dm->fields[f].disc, ceed)); 5890f918ec44SMatthew G. Knepley } 5891f918ec44SMatthew G. Knepley } 5892f918ec44SMatthew G. Knepley #endif 58939371c9d4SSatish Balay if (!label) { 58949371c9d4SSatish Balay ++Ndef; 58959371c9d4SSatish Balay continue; 58969371c9d4SSatish Balay } 58979371c9d4SSatish Balay for (l = 0; l < Nl; ++l) 58989371c9d4SSatish Balay if (label == labelSet[l]) break; 5899083401c6SMatthew G. Knepley if (l < Nl) continue; 5900083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5901083401c6SMatthew G. Knepley } 5902083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 590307218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 5904083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5905b3cf3223SMatthew G. Knepley IS fields; 5906b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5907b3cf3223SMatthew G. Knepley 59089371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59099371c9d4SSatish Balay if (!dm->fields[f].label) ++nf; 59107a8be351SBarry Smith PetscCheck(nf, comm, PETSC_ERR_PLIB, "All fields have labels, but we are trying to create a default DS"); 59119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 59129371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59139371c9d4SSatish Balay if (!dm->fields[f].label) fld[nf++] = f; 59149566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 59159566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 59169566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 59179566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 591888f0c812SMatthew G. Knepley 59199566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 592007218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, NULL, fields, dsDef, NULL)); 59219566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 59229566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 59232df9ee95SMatthew G. Knepley } 592407218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef, NULL)); 59259566063dSJacob Faibussowitsch if (dsDef) PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 5926083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5927083401c6SMatthew G. Knepley if (Ndef && Nl) { 59280122748bSMatthew G. Knepley DM plex; 5929083401c6SMatthew G. Knepley DMLabel cellLabel; 5930083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5931083401c6SMatthew G. Knepley PetscInt *fields; 5932083401c6SMatthew G. Knepley const PetscInt *cells; 5933083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 59340122748bSMatthew G. Knepley 59359566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 59369566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(plex, &depth)); 59379566063dSJacob Faibussowitsch PetscCall(DMGetStratumIS(plex, "dim", depth, &allcellIS)); 59389566063dSJacob Faibussowitsch if (!allcellIS) PetscCall(DMGetStratumIS(plex, "depth", depth, &allcellIS)); 59395fedec97SMatthew G. Knepley /* TODO This looks like it only works for one label */ 5940083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5941083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5942083401c6SMatthew G. Knepley IS pointIS; 5943083401c6SMatthew G. Knepley 59449566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 59459566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, 1, &pointIS)); 59469566063dSJacob Faibussowitsch PetscCall(ISDifference(allcellIS, pointIS, &defcellIS)); 59479566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointIS)); 5948083401c6SMatthew G. Knepley } 59499566063dSJacob Faibussowitsch PetscCall(ISDestroy(&allcellIS)); 5950083401c6SMatthew G. Knepley 59519566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel)); 59529566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(defcellIS, &n)); 59539566063dSJacob Faibussowitsch PetscCall(ISGetIndices(defcellIS, &cells)); 59549566063dSJacob Faibussowitsch for (c = 0; c < n; ++c) PetscCall(DMLabelSetValue(cellLabel, cells[c], 1)); 59559566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(defcellIS, &cells)); 59569566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 59579566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(plex, cellLabel)); 5958083401c6SMatthew G. Knepley 59599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Ndef, &fields)); 59609371c9d4SSatish Balay for (f = 0; f < Nf; ++f) 59619371c9d4SSatish Balay if (!dm->fields[f].label) fields[nf++] = f; 59629566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fieldIS)); 59639566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fieldIS, "dm_fields_")); 59649566063dSJacob Faibussowitsch PetscCall(ISSetType(fieldIS, ISGENERAL)); 59659566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER)); 5966083401c6SMatthew G. Knepley 59679566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 596807218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, cellLabel, fieldIS, dsDef, NULL)); 59699566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 59709566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&cellLabel)); 59719566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 59729566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fieldIS)); 59739566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5974083401c6SMatthew G. Knepley } 5975083401c6SMatthew G. Knepley /* Create label DSes 5976083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5977083401c6SMatthew G. Knepley */ 5978083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5979083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5980083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 598107218a29SMatthew G. Knepley PetscDS ds, dsIn = NULL; 5982083401c6SMatthew G. Knepley IS fields; 5983083401c6SMatthew G. Knepley PetscInt *fld, nf; 5984083401c6SMatthew G. Knepley 59859566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 59869371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59879371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 59889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 59899371c9d4SSatish Balay for (f = 0, nf = 0; f < Nf; ++f) 59909371c9d4SSatish Balay if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 59919566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 59929566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fields, "dm_fields_")); 59939566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 59949566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 59959566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(ds, dE)); 5996083401c6SMatthew G. Knepley { 5997083401c6SMatthew G. Knepley DMPolytopeType ct; 5998083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 59995fedec97SMatthew G. Knepley PetscBool isCohesiveLocal = PETSC_FALSE, isCohesive; 60000122748bSMatthew G. Knepley 60019566063dSJacob Faibussowitsch PetscCall(DMLabelGetBounds(label, &lStart, &lEnd)); 6002665f567fSMatthew G. Knepley if (lStart >= 0) { 60039566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, lStart, &ct)); 6004412e9a14SMatthew G. Knepley switch (ct) { 6005412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 6006412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 6007412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 6008d71ae5a4SJacob Faibussowitsch case DM_POLYTOPE_QUAD_PRISM_TENSOR: 6009d71ae5a4SJacob Faibussowitsch isCohesiveLocal = PETSC_TRUE; 6010d71ae5a4SJacob Faibussowitsch break; 6011d71ae5a4SJacob Faibussowitsch default: 6012d71ae5a4SJacob Faibussowitsch break; 6013412e9a14SMatthew G. Knepley } 6014665f567fSMatthew G. Knepley } 6015712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(&isCohesiveLocal, &isCohesive, 1, MPIU_BOOL, MPI_LOR, comm)); 601607218a29SMatthew G. Knepley if (isCohesive) { 601707218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsIn)); 601807218a29SMatthew G. Knepley PetscCall(PetscDSSetCoordinateDimension(dsIn, dE)); 601907218a29SMatthew G. Knepley } 60205fedec97SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) { 60215fedec97SMatthew G. Knepley if (label == dm->fields[f].label || !dm->fields[f].label) { 60225fedec97SMatthew G. Knepley if (label == dm->fields[f].label) { 60239566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, nf, NULL)); 60249566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(ds, nf, isCohesive)); 602507218a29SMatthew G. Knepley if (dsIn) { 602607218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, nf, NULL)); 602707218a29SMatthew G. Knepley PetscCall(PetscDSSetCohesive(dsIn, nf, isCohesive)); 602807218a29SMatthew G. Knepley } 60295fedec97SMatthew G. Knepley } 60305fedec97SMatthew G. Knepley ++nf; 60315fedec97SMatthew G. Knepley } 60325fedec97SMatthew G. Knepley } 6033e5e52638SMatthew G. Knepley } 603407218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, ds, dsIn)); 603507218a29SMatthew G. Knepley PetscCall(ISDestroy(&fields)); 60369566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 603707218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsIn)); 6038e5e52638SMatthew G. Knepley } 60399566063dSJacob Faibussowitsch PetscCall(PetscFree(labelSet)); 6040e5e52638SMatthew G. Knepley /* Set fields in DSes */ 6041083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 6042083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 604307218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 6044083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 6045083401c6SMatthew G. Knepley const PetscInt *fld; 60465fedec97SMatthew G. Knepley PetscInt nf, dsnf; 60475fedec97SMatthew G. Knepley PetscBool isCohesive; 6048e5e52638SMatthew G. Knepley 60499566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsnf)); 60509566063dSJacob Faibussowitsch PetscCall(PetscDSIsCohesive(ds, &isCohesive)); 60519566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(fields, &nf)); 60529566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fields, &fld)); 6053083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 6054083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 60555fedec97SMatthew G. Knepley PetscBool isCohesiveField; 6056e5e52638SMatthew G. Knepley PetscClassId id; 6057e5e52638SMatthew G. Knepley 60585fedec97SMatthew G. Knepley /* Handle DS with no fields */ 60599566063dSJacob Faibussowitsch if (dsnf) PetscCall(PetscDSGetCohesive(ds, f, &isCohesiveField)); 60605fedec97SMatthew G. Knepley /* If this is a cohesive cell, then regular fields need the lower dimensional discretization */ 606107218a29SMatthew G. Knepley if (isCohesive) { 606207218a29SMatthew G. Knepley if (!isCohesiveField) { 606307218a29SMatthew G. Knepley PetscObject bdDisc; 606407218a29SMatthew G. Knepley 606507218a29SMatthew G. Knepley PetscCall(PetscFEGetHeightSubspace((PetscFE)disc, 1, (PetscFE *)&bdDisc)); 606607218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, bdDisc)); 606707218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 606807218a29SMatthew G. Knepley } else { 60699566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, f, disc)); 607007218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(dsIn, f, disc)); 607107218a29SMatthew G. Knepley } 607207218a29SMatthew G. Knepley } else { 607307218a29SMatthew G. Knepley PetscCall(PetscDSSetDiscretization(ds, f, disc)); 607407218a29SMatthew G. Knepley } 6075083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 60769566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 6077e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 6078e5e52638SMatthew G. Knepley } 60799566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fields, &fld)); 6080e5e52638SMatthew G. Knepley } 6081f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 60829566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)dm)->prefix, "-dm_ds_jet_degree", &k, &flg)); 6083f9244615SMatthew G. Knepley if (flg) { 60843b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 60853b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 608607218a29SMatthew G. Knepley PetscDS dsIn = dm->probs[s].dsIn; 60873b4aee56SMatthew G. Knepley PetscInt Nf, f; 60883b4aee56SMatthew G. Knepley 60899566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 609007218a29SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 609107218a29SMatthew G. Knepley PetscCall(PetscDSSetJetDegree(ds, f, k)); 609207218a29SMatthew G. Knepley if (dsIn) PetscCall(PetscDSSetJetDegree(dsIn, f, k)); 609307218a29SMatthew G. Knepley } 60943b4aee56SMatthew G. Knepley } 6095f9244615SMatthew G. Knepley } 6096e5e52638SMatthew G. Knepley /* Setup DSes */ 6097e5e52638SMatthew G. Knepley if (doSetup) { 609807218a29SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 6099cf1363e4SMatthew G. Knepley if (dm->setfromoptionscalled) { 6100cf1363e4SMatthew G. Knepley PetscCall(PetscDSSetFromOptions(dm->probs[s].ds)); 6101cf1363e4SMatthew G. Knepley if (dm->probs[s].dsIn) PetscCall(PetscDSSetFromOptions(dm->probs[s].dsIn)); 6102cf1363e4SMatthew G. Knepley } 610307218a29SMatthew G. Knepley PetscCall(PetscDSSetUp(dm->probs[s].ds)); 610407218a29SMatthew G. Knepley if (dm->probs[s].dsIn) PetscCall(PetscDSSetUp(dm->probs[s].dsIn)); 610507218a29SMatthew G. Knepley } 6106e5e52638SMatthew G. Knepley } 61073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6108e5e52638SMatthew G. Knepley } 6109e5e52638SMatthew G. Knepley 6110e5e52638SMatthew G. Knepley /*@ 6111d2b2dc1eSMatthew G. Knepley DMUseTensorOrder - Use a tensor product closure ordering for the default section 6112d2b2dc1eSMatthew G. Knepley 6113d2b2dc1eSMatthew G. Knepley Input Parameters: 6114d2b2dc1eSMatthew G. Knepley + dm - The DM 6115d2b2dc1eSMatthew G. Knepley - tensor - Flag for tensor order 6116d2b2dc1eSMatthew G. Knepley 6117d2b2dc1eSMatthew G. Knepley Level: developer 6118d2b2dc1eSMatthew G. Knepley 6119d2b2dc1eSMatthew G. Knepley .seealso: `DMPlexSetClosurePermutationTensor()`, `PetscSectionResetClosurePermutation()` 6120d2b2dc1eSMatthew G. Knepley @*/ 6121d2b2dc1eSMatthew G. Knepley PetscErrorCode DMUseTensorOrder(DM dm, PetscBool tensor) 6122d2b2dc1eSMatthew G. Knepley { 6123d2b2dc1eSMatthew G. Knepley PetscInt Nf; 6124d2b2dc1eSMatthew G. Knepley PetscBool reorder = PETSC_TRUE, isPlex; 6125d2b2dc1eSMatthew G. Knepley 6126d2b2dc1eSMatthew G. Knepley PetscFunctionBegin; 6127d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMPLEX, &isPlex)); 6128d2b2dc1eSMatthew G. Knepley PetscCall(DMGetNumFields(dm, &Nf)); 6129d2b2dc1eSMatthew G. Knepley for (PetscInt f = 0; f < Nf; ++f) { 6130d2b2dc1eSMatthew G. Knepley PetscObject obj; 6131d2b2dc1eSMatthew G. Knepley PetscClassId id; 6132d2b2dc1eSMatthew G. Knepley 6133d2b2dc1eSMatthew G. Knepley PetscCall(DMGetField(dm, f, NULL, &obj)); 6134d2b2dc1eSMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 6135d2b2dc1eSMatthew G. Knepley if (id == PETSCFE_CLASSID) { 6136d2b2dc1eSMatthew G. Knepley PetscSpace sp; 6137d2b2dc1eSMatthew G. Knepley PetscBool tensor; 6138d2b2dc1eSMatthew G. Knepley 6139d2b2dc1eSMatthew G. Knepley PetscCall(PetscFEGetBasisSpace((PetscFE)obj, &sp)); 6140d2b2dc1eSMatthew G. Knepley PetscCall(PetscSpacePolynomialGetTensor(sp, &tensor)); 6141d2b2dc1eSMatthew G. Knepley reorder = reorder && tensor ? PETSC_TRUE : PETSC_FALSE; 6142d2b2dc1eSMatthew G. Knepley } else reorder = PETSC_FALSE; 6143d2b2dc1eSMatthew G. Knepley } 6144d2b2dc1eSMatthew G. Knepley if (tensor) { 6145d2b2dc1eSMatthew G. Knepley if (reorder && isPlex) PetscCall(DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, NULL)); 6146d2b2dc1eSMatthew G. Knepley } else { 6147d2b2dc1eSMatthew G. Knepley PetscSection s; 6148d2b2dc1eSMatthew G. Knepley 6149d2b2dc1eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm, &s)); 6150d2b2dc1eSMatthew G. Knepley if (s) PetscCall(PetscSectionResetClosurePermutation(s)); 6151d2b2dc1eSMatthew G. Knepley } 6152d2b2dc1eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 6153d2b2dc1eSMatthew G. Knepley } 6154d2b2dc1eSMatthew G. Knepley 6155d2b2dc1eSMatthew G. Knepley /*@ 6156bb7acecfSBarry Smith DMComputeExactSolution - Compute the exact solution for a given `DM`, using the `PetscDS` information. 61577f96f943SMatthew G. Knepley 615820f4b53cSBarry Smith Collective 6159f2cacb80SMatthew G. Knepley 61607f96f943SMatthew G. Knepley Input Parameters: 6161bb7acecfSBarry Smith + dm - The `DM` 61627f96f943SMatthew G. Knepley - time - The time 61637f96f943SMatthew G. Knepley 61647f96f943SMatthew G. Knepley Output Parameters: 616520f4b53cSBarry Smith + u - The vector will be filled with exact solution values, or `NULL` 616620f4b53cSBarry Smith - u_t - The vector will be filled with the time derivative of exact solution values, or `NULL` 616720f4b53cSBarry Smith 616820f4b53cSBarry Smith Level: developer 61697f96f943SMatthew G. Knepley 6170bb7acecfSBarry Smith Note: 6171bb7acecfSBarry Smith The user must call `PetscDSSetExactSolution()` before using this routine 61727f96f943SMatthew G. Knepley 61731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscDSSetExactSolution()` 61747f96f943SMatthew G. Knepley @*/ 6175d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 6176d71ae5a4SJacob Faibussowitsch { 61777f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 61787f96f943SMatthew G. Knepley void **ectxs; 6179f60fa741SMatthew G. Knepley Vec locu, locu_t; 61807f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 61817f96f943SMatthew G. Knepley 61827f96f943SMatthew G. Knepley PetscFunctionBegin; 6183f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6184f60fa741SMatthew G. Knepley if (u) { 6185f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 6186f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu)); 6187f60fa741SMatthew G. Knepley PetscCall(VecSet(locu, 0.)); 6188f60fa741SMatthew G. Knepley } 6189f60fa741SMatthew G. Knepley if (u_t) { 6190f60fa741SMatthew G. Knepley PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 6191f60fa741SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &locu_t)); 6192f60fa741SMatthew G. Knepley PetscCall(VecSet(locu_t, 0.)); 6193f60fa741SMatthew G. Knepley } 61949566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 61959566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exacts, Nf, &ectxs)); 61969566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 61977f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 61987f96f943SMatthew G. Knepley PetscDS ds; 61997f96f943SMatthew G. Knepley DMLabel label; 62007f96f943SMatthew G. Knepley IS fieldIS; 62017f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 62027f96f943SMatthew G. Knepley PetscInt dsNf, f; 62037f96f943SMatthew G. Knepley 620407218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 62059566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 62069566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fieldIS, &fields)); 62079566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 62089566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6209f2cacb80SMatthew G. Knepley if (u) { 6210f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolution(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6211f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu)); 6212f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu)); 62137f96f943SMatthew G. Knepley } 6214f2cacb80SMatthew G. Knepley if (u_t) { 62159566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 62169566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 6217f60fa741SMatthew G. Knepley for (f = 0; f < dsNf; ++f) PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, fields[f], &exacts[fields[f]], &ectxs[fields[f]])); 6218f60fa741SMatthew G. Knepley if (label) PetscCall(DMProjectFunctionLabelLocal(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6219f60fa741SMatthew G. Knepley else PetscCall(DMProjectFunctionLocal(dm, time, exacts, ectxs, INSERT_ALL_VALUES, locu_t)); 6220f2cacb80SMatthew G. Knepley } 62219566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 6222f2cacb80SMatthew G. Knepley } 6223f2cacb80SMatthew G. Knepley if (u) { 62249566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution")); 62259566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u, "exact_")); 6226f2cacb80SMatthew G. Knepley } 6227f2cacb80SMatthew G. Knepley if (u_t) { 62289566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)u, "Exact Solution Time Derivative")); 62299566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)u_t, "exact_t_")); 6230f2cacb80SMatthew G. Knepley } 62319566063dSJacob Faibussowitsch PetscCall(PetscFree2(exacts, ectxs)); 6232f60fa741SMatthew G. Knepley if (u) { 6233f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu, INSERT_ALL_VALUES, u)); 6234f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu, INSERT_ALL_VALUES, u)); 6235f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu)); 6236f60fa741SMatthew G. Knepley } 6237f60fa741SMatthew G. Knepley if (u_t) { 6238f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6239f60fa741SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, locu_t, INSERT_ALL_VALUES, u_t)); 6240f60fa741SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &locu_t)); 6241f60fa741SMatthew G. Knepley } 62423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62437f96f943SMatthew G. Knepley } 62447f96f943SMatthew G. Knepley 624507218a29SMatthew G. Knepley static PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscDS ds, PetscDS dsIn) 6246d71ae5a4SJacob Faibussowitsch { 624707218a29SMatthew G. Knepley PetscDS dsNew, dsInNew = NULL; 624845480ffeSMatthew G. Knepley 624945480ffeSMatthew G. Knepley PetscFunctionBegin; 62509566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)ds), &dsNew)); 625107218a29SMatthew G. Knepley PetscCall(PetscDSCopy(ds, dm, dsNew)); 625207218a29SMatthew G. Knepley if (dsIn) { 625307218a29SMatthew G. Knepley PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)dsIn), &dsInNew)); 625407218a29SMatthew G. Knepley PetscCall(PetscDSCopy(dsIn, dm, dsInNew)); 625545480ffeSMatthew G. Knepley } 625607218a29SMatthew G. Knepley PetscCall(DMSetRegionDS(dm, label, fields, dsNew, dsInNew)); 62579566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsNew)); 625807218a29SMatthew G. Knepley PetscCall(PetscDSDestroy(&dsInNew)); 62593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 626045480ffeSMatthew G. Knepley } 626145480ffeSMatthew G. Knepley 62627f96f943SMatthew G. Knepley /*@ 6263bb7acecfSBarry Smith DMCopyDS - Copy the discrete systems for the `DM` into another `DM` 6264e5e52638SMatthew G. Knepley 626520f4b53cSBarry Smith Collective 6266e5e52638SMatthew G. Knepley 6267e5e52638SMatthew G. Knepley Input Parameter: 6268bb7acecfSBarry Smith . dm - The `DM` 6269e5e52638SMatthew G. Knepley 6270e5e52638SMatthew G. Knepley Output Parameter: 6271bb7acecfSBarry Smith . newdm - The `DM` 6272e5e52638SMatthew G. Knepley 6273e5e52638SMatthew G. Knepley Level: advanced 6274e5e52638SMatthew G. Knepley 62751cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 6276e5e52638SMatthew G. Knepley @*/ 6277d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDS(DM dm, DM newdm) 6278d71ae5a4SJacob Faibussowitsch { 6279e5e52638SMatthew G. Knepley PetscInt Nds, s; 6280e5e52638SMatthew G. Knepley 6281e5e52638SMatthew G. Knepley PetscFunctionBegin; 62823ba16761SJacob Faibussowitsch if (dm == newdm) PetscFunctionReturn(PETSC_SUCCESS); 62839566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 62849566063dSJacob Faibussowitsch PetscCall(DMClearDS(newdm)); 6285e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6286e5e52638SMatthew G. Knepley DMLabel label; 6287b3cf3223SMatthew G. Knepley IS fields; 628807218a29SMatthew G. Knepley PetscDS ds, dsIn, newds; 6289783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6290e5e52638SMatthew G. Knepley 629107218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fields, &ds, &dsIn)); 6292b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 629307218a29SMatthew G. Knepley PetscCall(DMTransferDS_Internal(newdm, label, fields, ds, dsIn)); 6294d5b43468SJose E. Roman /* Complete new labels in the new DS */ 629507218a29SMatthew G. Knepley PetscCall(DMGetRegionDS(newdm, label, NULL, &newds, NULL)); 62969566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumBoundary(newds, &Nbd)); 6297783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6298b8025e53SMatthew G. Knepley PetscWeakForm wf; 629945480ffeSMatthew G. Knepley DMLabel label; 6300783e2ec8SMatthew G. Knepley PetscInt field; 6301783e2ec8SMatthew G. Knepley 63029566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 63039566063dSJacob Faibussowitsch PetscCall(PetscWeakFormReplaceLabel(wf, label)); 6304783e2ec8SMatthew G. Knepley } 6305e5e52638SMatthew G. Knepley } 6306799db056SMatthew G. Knepley PetscCall(DMCompleteBCLabels_Internal(newdm)); 63073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6308e5e52638SMatthew G. Knepley } 6309e5e52638SMatthew G. Knepley 6310e5e52638SMatthew G. Knepley /*@ 6311bb7acecfSBarry Smith DMCopyDisc - Copy the fields and discrete systems for the `DM` into another `DM` 6312e5e52638SMatthew G. Knepley 631320f4b53cSBarry Smith Collective 6314e5e52638SMatthew G. Knepley 6315e5e52638SMatthew G. Knepley Input Parameter: 6316bb7acecfSBarry Smith . dm - The `DM` 6317e5e52638SMatthew G. Knepley 6318e5e52638SMatthew G. Knepley Output Parameter: 6319bb7acecfSBarry Smith . newdm - The `DM` 6320e5e52638SMatthew G. Knepley 6321e5e52638SMatthew G. Knepley Level: advanced 6322e5e52638SMatthew G. Knepley 632373ff1848SBarry Smith Developer Note: 6324bb7acecfSBarry Smith Really ugly name, nothing in PETSc is called a `Disc` plus it is an ugly abbreviation 6325bb7acecfSBarry Smith 63261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCopyFields()`, `DMCopyDS()` 6327e5e52638SMatthew G. Knepley @*/ 6328d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6329d71ae5a4SJacob Faibussowitsch { 6330e5e52638SMatthew G. Knepley PetscFunctionBegin; 63319566063dSJacob Faibussowitsch PetscCall(DMCopyFields(dm, newdm)); 63329566063dSJacob Faibussowitsch PetscCall(DMCopyDS(dm, newdm)); 63333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6334e5e52638SMatthew G. Knepley } 6335e5e52638SMatthew G. Knepley 6336c73cfb54SMatthew G. Knepley /*@ 6337bb7acecfSBarry Smith DMGetDimension - Return the topological dimension of the `DM` 6338c73cfb54SMatthew G. Knepley 633920f4b53cSBarry Smith Not Collective 6340c73cfb54SMatthew G. Knepley 6341c73cfb54SMatthew G. Knepley Input Parameter: 6342bb7acecfSBarry Smith . dm - The `DM` 6343c73cfb54SMatthew G. Knepley 6344c73cfb54SMatthew G. Knepley Output Parameter: 6345c73cfb54SMatthew G. Knepley . dim - The topological dimension 6346c73cfb54SMatthew G. Knepley 6347c73cfb54SMatthew G. Knepley Level: beginner 6348c73cfb54SMatthew G. Knepley 63491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetDimension()`, `DMCreate()` 6350c73cfb54SMatthew G. Knepley @*/ 6351d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6352d71ae5a4SJacob Faibussowitsch { 6353c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6354c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 63554f572ea9SToby Isaac PetscAssertPointer(dim, 2); 6356c73cfb54SMatthew G. Knepley *dim = dm->dim; 63573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6358c73cfb54SMatthew G. Knepley } 6359c73cfb54SMatthew G. Knepley 6360c73cfb54SMatthew G. Knepley /*@ 6361bb7acecfSBarry Smith DMSetDimension - Set the topological dimension of the `DM` 6362c73cfb54SMatthew G. Knepley 636320f4b53cSBarry Smith Collective 6364c73cfb54SMatthew G. Knepley 6365c73cfb54SMatthew G. Knepley Input Parameters: 6366bb7acecfSBarry Smith + dm - The `DM` 6367c73cfb54SMatthew G. Knepley - dim - The topological dimension 6368c73cfb54SMatthew G. Knepley 6369c73cfb54SMatthew G. Knepley Level: beginner 6370c73cfb54SMatthew G. Knepley 63711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetDimension()`, `DMCreate()` 6372c73cfb54SMatthew G. Knepley @*/ 6373d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6374d71ae5a4SJacob Faibussowitsch { 6375e5e52638SMatthew G. Knepley PetscDS ds; 637645480ffeSMatthew G. Knepley PetscInt Nds, n; 6377f17e8794SMatthew G. Knepley 6378c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6379c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6380c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6381c73cfb54SMatthew G. Knepley dm->dim = dim; 6382d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 63839566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 638445480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 638507218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds, NULL)); 63869566063dSJacob Faibussowitsch if (ds->dimEmbed < 0) PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 638745480ffeSMatthew G. Knepley } 6388d17bd122SMatthew G. Knepley } 63893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6390c73cfb54SMatthew G. Knepley } 6391c73cfb54SMatthew G. Knepley 6392793f3fe5SMatthew G. Knepley /*@ 6393793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6394793f3fe5SMatthew G. Knepley 639520f4b53cSBarry Smith Collective 6396793f3fe5SMatthew G. Knepley 6397793f3fe5SMatthew G. Knepley Input Parameters: 6398bb7acecfSBarry Smith + dm - the `DM` 6399793f3fe5SMatthew G. Knepley - dim - the dimension 6400793f3fe5SMatthew G. Knepley 6401793f3fe5SMatthew G. Knepley Output Parameters: 6402793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6403aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6404793f3fe5SMatthew G. Knepley 640520f4b53cSBarry Smith Level: intermediate 640620f4b53cSBarry Smith 6407793f3fe5SMatthew G. Knepley Note: 6408793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6409a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6410793f3fe5SMatthew G. Knepley then the interval is empty. 6411793f3fe5SMatthew G. Knepley 64121cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPLEX`, `DMPlexGetDepthStratum()`, `DMPlexGetHeightStratum()` 6413793f3fe5SMatthew G. Knepley @*/ 6414d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6415d71ae5a4SJacob Faibussowitsch { 6416793f3fe5SMatthew G. Knepley PetscInt d; 6417793f3fe5SMatthew G. Knepley 6418793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6419793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64209566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &d)); 64217a8be351SBarry Smith PetscCheck((dim >= 0) && (dim <= d), PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %" PetscInt_FMT, dim); 6422dbbe0bcdSBarry Smith PetscUseTypeMethod(dm, getdimpoints, dim, pStart, pEnd); 64233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6424793f3fe5SMatthew G. Knepley } 6425793f3fe5SMatthew G. Knepley 64266636e97aSMatthew G Knepley /*@ 6427bb7acecfSBarry Smith DMGetOutputDM - Retrieve the `DM` associated with the layout for output 6428f4d763aaSMatthew G. Knepley 642920f4b53cSBarry Smith Collective 64308f700142SStefano Zampini 6431f4d763aaSMatthew G. Knepley Input Parameter: 6432bb7acecfSBarry Smith . dm - The original `DM` 6433f4d763aaSMatthew G. Knepley 6434f4d763aaSMatthew G. Knepley Output Parameter: 6435bb7acecfSBarry Smith . odm - The `DM` which provides the layout for output 6436f4d763aaSMatthew G. Knepley 6437f4d763aaSMatthew G. Knepley Level: intermediate 6438f4d763aaSMatthew G. Knepley 6439bb7acecfSBarry Smith Note: 6440bb7acecfSBarry Smith In some situations the vector obtained with `DMCreateGlobalVector()` excludes points for degrees of freedom that are associated with fixed (Dirichelet) boundary 6441bb7acecfSBarry 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 6442bb7acecfSBarry Smith locations for those dof so that they can be output to a file or other viewer along with the unconstrained dof. 6443bb7acecfSBarry Smith 64441cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()`, `DMGetGlobalSection()`, `DMCreateGlobalVector()`, `PetscSectionHasConstraints()`, `DMSetGlobalSection()` 6445f4d763aaSMatthew G. Knepley @*/ 6446d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 6447d71ae5a4SJacob Faibussowitsch { 6448c26acbdeSMatthew G. Knepley PetscSection section; 6449eb9d3e4dSMatthew G. Knepley IS perm; 6450eb9d3e4dSMatthew G. Knepley PetscBool hasConstraints, newDM, gnewDM; 645114f150ffSMatthew G. Knepley 645214f150ffSMatthew G. Knepley PetscFunctionBegin; 645314f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64544f572ea9SToby Isaac PetscAssertPointer(odm, 2); 64559566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 64569566063dSJacob Faibussowitsch PetscCall(PetscSectionHasConstraints(section, &hasConstraints)); 6457eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionGetPermutation(section, &perm)); 6458eb9d3e4dSMatthew G. Knepley newDM = hasConstraints || perm ? PETSC_TRUE : PETSC_FALSE; 6459eb9d3e4dSMatthew G. Knepley PetscCall(MPIU_Allreduce(&newDM, &gnewDM, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)dm))); 6460eb9d3e4dSMatthew G. Knepley if (!gnewDM) { 6461c26acbdeSMatthew G. Knepley *odm = dm; 64623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6463c26acbdeSMatthew G. Knepley } 646414f150ffSMatthew G. Knepley if (!dm->dmBC) { 6465c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 646614f150ffSMatthew G. Knepley PetscSF sf; 6467eb9d3e4dSMatthew G. Knepley PetscBool usePerm = dm->ignorePermOutput ? PETSC_FALSE : PETSC_TRUE; 646814f150ffSMatthew G. Knepley 64699566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->dmBC)); 64709566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, dm->dmBC)); 64719566063dSJacob Faibussowitsch PetscCall(PetscSectionClone(section, &newSection)); 64729566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm->dmBC, newSection)); 64739566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&newSection)); 64749566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm->dmBC, &sf)); 6475eb9d3e4dSMatthew G. Knepley PetscCall(PetscSectionCreateGlobalSection(section, sf, usePerm, PETSC_TRUE, PETSC_FALSE, &gsection)); 64769566063dSJacob Faibussowitsch PetscCall(DMSetGlobalSection(dm->dmBC, gsection)); 64779566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&gsection)); 647814f150ffSMatthew G. Knepley } 647914f150ffSMatthew G. Knepley *odm = dm->dmBC; 64803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 648114f150ffSMatthew G. Knepley } 6482f4d763aaSMatthew G. Knepley 6483f4d763aaSMatthew G. Knepley /*@ 6484cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 6485f4d763aaSMatthew G. Knepley 6486f4d763aaSMatthew G. Knepley Input Parameter: 6487bb7acecfSBarry Smith . dm - The original `DM` 6488f4d763aaSMatthew G. Knepley 6489cdb7a50dSMatthew G. Knepley Output Parameters: 6490cdb7a50dSMatthew G. Knepley + num - The output sequence number 6491cdb7a50dSMatthew G. Knepley - val - The output sequence value 6492f4d763aaSMatthew G. Knepley 6493f4d763aaSMatthew G. Knepley Level: intermediate 6494f4d763aaSMatthew G. Knepley 6495bb7acecfSBarry Smith Note: 6496bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6497bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6498bb7acecfSBarry Smith 649973ff1848SBarry Smith Developer Note: 6500bb7acecfSBarry Smith The `DM` serves as a convenient place to store the current iteration value. The iteration is not 6501bb7acecfSBarry Smith not directly related to the `DM`. 6502f4d763aaSMatthew G. Knepley 65031cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6504f4d763aaSMatthew G. Knepley @*/ 6505d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 6506d71ae5a4SJacob Faibussowitsch { 6507f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6508f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65099371c9d4SSatish Balay if (num) { 65104f572ea9SToby Isaac PetscAssertPointer(num, 2); 65119371c9d4SSatish Balay *num = dm->outputSequenceNum; 65129371c9d4SSatish Balay } 65139371c9d4SSatish Balay if (val) { 65144f572ea9SToby Isaac PetscAssertPointer(val, 3); 65159371c9d4SSatish Balay *val = dm->outputSequenceVal; 65169371c9d4SSatish Balay } 65173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6518f4d763aaSMatthew G. Knepley } 6519f4d763aaSMatthew G. Knepley 6520f4d763aaSMatthew G. Knepley /*@ 6521cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 6522f4d763aaSMatthew G. Knepley 6523f4d763aaSMatthew G. Knepley Input Parameters: 6524bb7acecfSBarry Smith + dm - The original `DM` 6525cdb7a50dSMatthew G. Knepley . num - The output sequence number 6526cdb7a50dSMatthew G. Knepley - val - The output sequence value 6527f4d763aaSMatthew G. Knepley 6528f4d763aaSMatthew G. Knepley Level: intermediate 6529f4d763aaSMatthew G. Knepley 6530bb7acecfSBarry Smith Note: 6531bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6532bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6533f4d763aaSMatthew G. Knepley 65341cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `VecView()` 6535f4d763aaSMatthew G. Knepley @*/ 6536d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 6537d71ae5a4SJacob Faibussowitsch { 6538f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6539f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6540f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 6541cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 65423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6543cdb7a50dSMatthew G. Knepley } 6544cdb7a50dSMatthew G. Knepley 6545cdb7a50dSMatthew G. Knepley /*@C 6546bb7acecfSBarry Smith DMOutputSequenceLoad - Retrieve the sequence value from a `PetscViewer` 6547cdb7a50dSMatthew G. Knepley 6548cdb7a50dSMatthew G. Knepley Input Parameters: 6549bb7acecfSBarry Smith + dm - The original `DM` 6550a4e35b19SJacob Faibussowitsch . viewer - The viewer to get it from 6551cdb7a50dSMatthew G. Knepley . name - The sequence name 6552cdb7a50dSMatthew G. Knepley - num - The output sequence number 6553cdb7a50dSMatthew G. Knepley 6554cdb7a50dSMatthew G. Knepley Output Parameter: 6555cdb7a50dSMatthew G. Knepley . val - The output sequence value 6556cdb7a50dSMatthew G. Knepley 6557cdb7a50dSMatthew G. Knepley Level: intermediate 6558cdb7a50dSMatthew G. Knepley 6559bb7acecfSBarry Smith Note: 6560bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6561bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6562bb7acecfSBarry Smith 656373ff1848SBarry Smith Developer Note: 6564bb7acecfSBarry Smith It is unclear at the user API level why a `DM` is needed as input 6565cdb7a50dSMatthew G. Knepley 65661cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6567cdb7a50dSMatthew G. Knepley @*/ 6568d71ae5a4SJacob Faibussowitsch PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 6569d71ae5a4SJacob Faibussowitsch { 6570cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 6571cdb7a50dSMatthew G. Knepley 6572cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 6573cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6574cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 65754f572ea9SToby Isaac PetscAssertPointer(val, 5); 65769566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 6577cdb7a50dSMatthew G. Knepley if (ishdf5) { 6578cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6579cdb7a50dSMatthew G. Knepley PetscScalar value; 6580cdb7a50dSMatthew G. Knepley 65819566063dSJacob Faibussowitsch PetscCall(DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer)); 65824aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 6583cdb7a50dSMatthew G. Knepley #endif 6584cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 65853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6586f4d763aaSMatthew G. Knepley } 65878e4ac7eaSMatthew G. Knepley 65888e4ac7eaSMatthew G. Knepley /*@ 6589bb7acecfSBarry Smith DMGetUseNatural - Get the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 65908e4ac7eaSMatthew G. Knepley 659120f4b53cSBarry Smith Not Collective 65928e4ac7eaSMatthew G. Knepley 65938e4ac7eaSMatthew G. Knepley Input Parameter: 6594bb7acecfSBarry Smith . dm - The `DM` 65958e4ac7eaSMatthew G. Knepley 65968e4ac7eaSMatthew G. Knepley Output Parameter: 6597bb7acecfSBarry Smith . useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 65988e4ac7eaSMatthew G. Knepley 65998e4ac7eaSMatthew G. Knepley Level: beginner 66008e4ac7eaSMatthew G. Knepley 66011cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetUseNatural()`, `DMCreate()` 66028e4ac7eaSMatthew G. Knepley @*/ 6603d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 6604d71ae5a4SJacob Faibussowitsch { 66058e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 66068e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66074f572ea9SToby Isaac PetscAssertPointer(useNatural, 2); 66088e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 66093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66108e4ac7eaSMatthew G. Knepley } 66118e4ac7eaSMatthew G. Knepley 66128e4ac7eaSMatthew G. Knepley /*@ 6613bb7acecfSBarry Smith DMSetUseNatural - Set the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 66148e4ac7eaSMatthew G. Knepley 661520f4b53cSBarry Smith Collective 66168e4ac7eaSMatthew G. Knepley 66178e4ac7eaSMatthew G. Knepley Input Parameters: 6618bb7acecfSBarry Smith + dm - The `DM` 6619bb7acecfSBarry Smith - useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 66208e4ac7eaSMatthew G. Knepley 662173ff1848SBarry Smith Level: beginner 662273ff1848SBarry Smith 6623bb7acecfSBarry Smith Note: 6624bb7acecfSBarry Smith This also causes the map to be build after `DMCreateSubDM()` and `DMCreateSuperDM()` 66255d3b26e6SMatthew G. Knepley 66261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetUseNatural()`, `DMCreate()`, `DMPlexDistribute()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 66278e4ac7eaSMatthew G. Knepley @*/ 6628d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 6629d71ae5a4SJacob Faibussowitsch { 66308e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 66318e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66328833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 66338e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 66343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66358e4ac7eaSMatthew G. Knepley } 6636c58f1c22SToby Isaac 6637c58f1c22SToby Isaac /*@C 6638bb7acecfSBarry Smith DMCreateLabel - Create a label of the given name if it does not already exist in the `DM` 6639c58f1c22SToby Isaac 6640c58f1c22SToby Isaac Not Collective 6641c58f1c22SToby Isaac 6642c58f1c22SToby Isaac Input Parameters: 6643bb7acecfSBarry Smith + dm - The `DM` object 6644c58f1c22SToby Isaac - name - The label name 6645c58f1c22SToby Isaac 6646c58f1c22SToby Isaac Level: intermediate 6647c58f1c22SToby Isaac 66481cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6649c58f1c22SToby Isaac @*/ 6650d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabel(DM dm, const char name[]) 6651d71ae5a4SJacob Faibussowitsch { 66525d80c0bfSVaclav Hapla PetscBool flg; 66535d80c0bfSVaclav Hapla DMLabel label; 6654c58f1c22SToby Isaac 6655c58f1c22SToby Isaac PetscFunctionBegin; 6656c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66574f572ea9SToby Isaac PetscAssertPointer(name, 2); 66589566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 6659c58f1c22SToby Isaac if (!flg) { 66609566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 66619566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 66629566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 6663c58f1c22SToby Isaac } 66643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6665c58f1c22SToby Isaac } 6666c58f1c22SToby Isaac 6667c58f1c22SToby Isaac /*@C 6668bb7acecfSBarry 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. 66690fdc7489SMatthew Knepley 66700fdc7489SMatthew Knepley Not Collective 66710fdc7489SMatthew Knepley 66720fdc7489SMatthew Knepley Input Parameters: 6673bb7acecfSBarry Smith + dm - The `DM` object 66740fdc7489SMatthew Knepley . l - The index for the label 66750fdc7489SMatthew Knepley - name - The label name 66760fdc7489SMatthew Knepley 66770fdc7489SMatthew Knepley Level: intermediate 66780fdc7489SMatthew Knepley 66791cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMCreateLabel()`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 66800fdc7489SMatthew Knepley @*/ 6681d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 6682d71ae5a4SJacob Faibussowitsch { 66830fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 66840fdc7489SMatthew Knepley DMLabel label; 66850fdc7489SMatthew Knepley PetscInt Nl, m; 66860fdc7489SMatthew Knepley PetscBool flg, match; 66870fdc7489SMatthew Knepley const char *lname; 66880fdc7489SMatthew Knepley 66890fdc7489SMatthew Knepley PetscFunctionBegin; 66900fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 66914f572ea9SToby Isaac PetscAssertPointer(name, 3); 66929566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 66930fdc7489SMatthew Knepley if (!flg) { 66949566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 66959566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 66969566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 66970fdc7489SMatthew Knepley } 66989566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 669963a3b9bcSJacob Faibussowitsch PetscCheck(l < Nl, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", l, Nl); 67000fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 67019566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)orig->label, &lname)); 67029566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &match)); 67030fdc7489SMatthew Knepley if (match) break; 67040fdc7489SMatthew Knepley } 67053ba16761SJacob Faibussowitsch if (m == l) PetscFunctionReturn(PETSC_SUCCESS); 67060fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 67070fdc7489SMatthew Knepley else prev->next = orig->next; 67080fdc7489SMatthew Knepley if (!l) { 67090fdc7489SMatthew Knepley orig->next = dm->labels; 67100fdc7489SMatthew Knepley dm->labels = orig; 67110fdc7489SMatthew Knepley } else { 6712fbccb6d4SPierre Jolivet for (m = 0, prev = dm->labels; m < l - 1; ++m, prev = prev->next); 67130fdc7489SMatthew Knepley orig->next = prev->next; 67140fdc7489SMatthew Knepley prev->next = orig; 67150fdc7489SMatthew Knepley } 67163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 67170fdc7489SMatthew Knepley } 67180fdc7489SMatthew Knepley 67190fdc7489SMatthew Knepley /*@C 6720bb7acecfSBarry Smith DMGetLabelValue - Get the value in a `DMLabel` for the given point, with -1 as the default 6721c58f1c22SToby Isaac 6722c58f1c22SToby Isaac Not Collective 6723c58f1c22SToby Isaac 6724c58f1c22SToby Isaac Input Parameters: 6725bb7acecfSBarry Smith + dm - The `DM` object 6726c58f1c22SToby Isaac . name - The label name 6727c58f1c22SToby Isaac - point - The mesh point 6728c58f1c22SToby Isaac 6729c58f1c22SToby Isaac Output Parameter: 6730c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 6731c58f1c22SToby Isaac 6732c58f1c22SToby Isaac Level: beginner 6733c58f1c22SToby Isaac 67341cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6735c58f1c22SToby Isaac @*/ 6736d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 6737d71ae5a4SJacob Faibussowitsch { 6738c58f1c22SToby Isaac DMLabel label; 6739c58f1c22SToby Isaac 6740c58f1c22SToby Isaac PetscFunctionBegin; 6741c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67424f572ea9SToby Isaac PetscAssertPointer(name, 2); 67439566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 67447a8be351SBarry Smith PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 67459566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, point, value)); 67463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6747c58f1c22SToby Isaac } 6748c58f1c22SToby Isaac 6749c58f1c22SToby Isaac /*@C 6750bb7acecfSBarry Smith DMSetLabelValue - Add a point to a `DMLabel` with given value 6751c58f1c22SToby Isaac 6752c58f1c22SToby Isaac Not Collective 6753c58f1c22SToby Isaac 6754c58f1c22SToby Isaac Input Parameters: 6755bb7acecfSBarry Smith + dm - The `DM` object 6756c58f1c22SToby Isaac . name - The label name 6757c58f1c22SToby Isaac . point - The mesh point 6758c58f1c22SToby Isaac - value - The label value for this point 6759c58f1c22SToby Isaac 6760c58f1c22SToby Isaac Output Parameter: 6761c58f1c22SToby Isaac 6762c58f1c22SToby Isaac Level: beginner 6763c58f1c22SToby Isaac 67641cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelSetValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6765c58f1c22SToby Isaac @*/ 6766d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6767d71ae5a4SJacob Faibussowitsch { 6768c58f1c22SToby Isaac DMLabel label; 6769c58f1c22SToby Isaac 6770c58f1c22SToby Isaac PetscFunctionBegin; 6771c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67724f572ea9SToby Isaac PetscAssertPointer(name, 2); 67739566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6774c58f1c22SToby Isaac if (!label) { 67759566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 67769566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6777c58f1c22SToby Isaac } 67789566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, point, value)); 67793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6780c58f1c22SToby Isaac } 6781c58f1c22SToby Isaac 6782c58f1c22SToby Isaac /*@C 6783bb7acecfSBarry Smith DMClearLabelValue - Remove a point from a `DMLabel` with given value 6784c58f1c22SToby Isaac 6785c58f1c22SToby Isaac Not Collective 6786c58f1c22SToby Isaac 6787c58f1c22SToby Isaac Input Parameters: 6788bb7acecfSBarry Smith + dm - The `DM` object 6789c58f1c22SToby Isaac . name - The label name 6790c58f1c22SToby Isaac . point - The mesh point 6791c58f1c22SToby Isaac - value - The label value for this point 6792c58f1c22SToby Isaac 6793c58f1c22SToby Isaac Level: beginner 6794c58f1c22SToby Isaac 67951cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelClearValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6796c58f1c22SToby Isaac @*/ 6797d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6798d71ae5a4SJacob Faibussowitsch { 6799c58f1c22SToby Isaac DMLabel label; 6800c58f1c22SToby Isaac 6801c58f1c22SToby Isaac PetscFunctionBegin; 6802c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68034f572ea9SToby Isaac PetscAssertPointer(name, 2); 68049566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 68053ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68069566063dSJacob Faibussowitsch PetscCall(DMLabelClearValue(label, point, value)); 68073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6808c58f1c22SToby Isaac } 6809c58f1c22SToby Isaac 6810c58f1c22SToby Isaac /*@C 6811bb7acecfSBarry Smith DMGetLabelSize - Get the value of `DMLabelGetNumValues()` of a `DMLabel` in the `DM` 6812c58f1c22SToby Isaac 6813c58f1c22SToby Isaac Not Collective 6814c58f1c22SToby Isaac 6815c58f1c22SToby Isaac Input Parameters: 6816bb7acecfSBarry Smith + dm - The `DM` object 6817c58f1c22SToby Isaac - name - The label name 6818c58f1c22SToby Isaac 6819c58f1c22SToby Isaac Output Parameter: 6820c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 6821c58f1c22SToby Isaac 6822c58f1c22SToby Isaac Level: beginner 6823c58f1c22SToby Isaac 682473ff1848SBarry Smith Developer Note: 6825bb7acecfSBarry Smith This should be renamed to something like `DMGetLabelNumValues()` or removed. 6826bb7acecfSBarry Smith 68271cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetNumValues()`, `DMSetLabelValue()`, `DMGetLabel()` 6828c58f1c22SToby Isaac @*/ 6829d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 6830d71ae5a4SJacob Faibussowitsch { 6831c58f1c22SToby Isaac DMLabel label; 6832c58f1c22SToby Isaac 6833c58f1c22SToby Isaac PetscFunctionBegin; 6834c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68354f572ea9SToby Isaac PetscAssertPointer(name, 2); 68364f572ea9SToby Isaac PetscAssertPointer(size, 3); 68379566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6838c58f1c22SToby Isaac *size = 0; 68393ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 68409566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, size)); 68413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6842c58f1c22SToby Isaac } 6843c58f1c22SToby Isaac 6844c58f1c22SToby Isaac /*@C 6845bb7acecfSBarry Smith DMGetLabelIdIS - Get the `DMLabelGetValueIS()` from a `DMLabel` in the `DM` 6846c58f1c22SToby Isaac 6847c58f1c22SToby Isaac Not Collective 6848c58f1c22SToby Isaac 6849c58f1c22SToby Isaac Input Parameters: 685060225df5SJacob Faibussowitsch + dm - The `DM` object 6851c58f1c22SToby Isaac - name - The label name 6852c58f1c22SToby Isaac 6853c58f1c22SToby Isaac Output Parameter: 685420f4b53cSBarry Smith . ids - The integer ids, or `NULL` if the label does not exist 6855c58f1c22SToby Isaac 6856c58f1c22SToby Isaac Level: beginner 6857c58f1c22SToby Isaac 68581cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetValueIS()`, `DMGetLabelSize()` 6859c58f1c22SToby Isaac @*/ 6860d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 6861d71ae5a4SJacob Faibussowitsch { 6862c58f1c22SToby Isaac DMLabel label; 6863c58f1c22SToby Isaac 6864c58f1c22SToby Isaac PetscFunctionBegin; 6865c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 68664f572ea9SToby Isaac PetscAssertPointer(name, 2); 68674f572ea9SToby Isaac PetscAssertPointer(ids, 3); 68689566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6869c58f1c22SToby Isaac *ids = NULL; 6870dab2e251SBlaise Bourdin if (label) { 68719566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, ids)); 6872dab2e251SBlaise Bourdin } else { 6873dab2e251SBlaise Bourdin /* returning an empty IS */ 68749566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, 0, NULL, PETSC_USE_POINTER, ids)); 6875dab2e251SBlaise Bourdin } 68763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6877c58f1c22SToby Isaac } 6878c58f1c22SToby Isaac 6879c58f1c22SToby Isaac /*@C 6880c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 6881c58f1c22SToby Isaac 6882c58f1c22SToby Isaac Not Collective 6883c58f1c22SToby Isaac 6884c58f1c22SToby Isaac Input Parameters: 6885bb7acecfSBarry Smith + dm - The `DM` object 6886c58f1c22SToby Isaac . name - The label name 6887c58f1c22SToby Isaac - value - The stratum value 6888c58f1c22SToby Isaac 6889c58f1c22SToby Isaac Output Parameter: 6890bb7acecfSBarry Smith . size - The number of points, also called the stratum size 6891c58f1c22SToby Isaac 6892c58f1c22SToby Isaac Level: beginner 6893c58f1c22SToby Isaac 68941cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumSize()`, `DMGetLabelSize()`, `DMGetLabelIds()` 6895c58f1c22SToby Isaac @*/ 6896d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 6897d71ae5a4SJacob Faibussowitsch { 6898c58f1c22SToby Isaac DMLabel label; 6899c58f1c22SToby Isaac 6900c58f1c22SToby Isaac PetscFunctionBegin; 6901c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69024f572ea9SToby Isaac PetscAssertPointer(name, 2); 69034f572ea9SToby Isaac PetscAssertPointer(size, 4); 69049566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6905c58f1c22SToby Isaac *size = 0; 69063ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69079566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, value, size)); 69083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6909c58f1c22SToby Isaac } 6910c58f1c22SToby Isaac 6911c58f1c22SToby Isaac /*@C 6912c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 6913c58f1c22SToby Isaac 6914c58f1c22SToby Isaac Not Collective 6915c58f1c22SToby Isaac 6916c58f1c22SToby Isaac Input Parameters: 6917bb7acecfSBarry Smith + dm - The `DM` object 6918c58f1c22SToby Isaac . name - The label name 6919c58f1c22SToby Isaac - value - The stratum value 6920c58f1c22SToby Isaac 6921c58f1c22SToby Isaac Output Parameter: 692220f4b53cSBarry Smith . points - The stratum points, or `NULL` if the label does not exist or does not have that value 6923c58f1c22SToby Isaac 6924c58f1c22SToby Isaac Level: beginner 6925c58f1c22SToby Isaac 69261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabelGetStratumIS()`, `DMGetStratumSize()` 6927c58f1c22SToby Isaac @*/ 6928d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 6929d71ae5a4SJacob Faibussowitsch { 6930c58f1c22SToby Isaac DMLabel label; 6931c58f1c22SToby Isaac 6932c58f1c22SToby Isaac PetscFunctionBegin; 6933c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69344f572ea9SToby Isaac PetscAssertPointer(name, 2); 69354f572ea9SToby Isaac PetscAssertPointer(points, 4); 69369566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6937c58f1c22SToby Isaac *points = NULL; 69383ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69399566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, value, points)); 69403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6941c58f1c22SToby Isaac } 6942c58f1c22SToby Isaac 69434de306b1SToby Isaac /*@C 69449044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 69454de306b1SToby Isaac 69464de306b1SToby Isaac Not Collective 69474de306b1SToby Isaac 69484de306b1SToby Isaac Input Parameters: 6949bb7acecfSBarry Smith + dm - The `DM` object 69504de306b1SToby Isaac . name - The label name 69514de306b1SToby Isaac . value - The stratum value 69524de306b1SToby Isaac - points - The stratum points 69534de306b1SToby Isaac 69544de306b1SToby Isaac Level: beginner 69554de306b1SToby Isaac 69561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMClearLabelStratum()`, `DMLabelClearStratum()`, `DMLabelSetStratumIS()`, `DMGetStratumSize()` 69574de306b1SToby Isaac @*/ 6958d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 6959d71ae5a4SJacob Faibussowitsch { 69604de306b1SToby Isaac DMLabel label; 69614de306b1SToby Isaac 69624de306b1SToby Isaac PetscFunctionBegin; 69634de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69644f572ea9SToby Isaac PetscAssertPointer(name, 2); 6965292bffcbSToby Isaac PetscValidHeaderSpecific(points, IS_CLASSID, 4); 69669566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 69673ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69689566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, points)); 69693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 69704de306b1SToby Isaac } 69714de306b1SToby Isaac 6972c58f1c22SToby Isaac /*@C 6973bb7acecfSBarry Smith DMClearLabelStratum - Remove all points from a stratum from a `DMLabel` 6974c58f1c22SToby Isaac 6975c58f1c22SToby Isaac Not Collective 6976c58f1c22SToby Isaac 6977c58f1c22SToby Isaac Input Parameters: 6978bb7acecfSBarry Smith + dm - The `DM` object 6979c58f1c22SToby Isaac . name - The label name 6980c58f1c22SToby Isaac - value - The label value for this point 6981c58f1c22SToby Isaac 6982c58f1c22SToby Isaac Output Parameter: 6983c58f1c22SToby Isaac 6984c58f1c22SToby Isaac Level: beginner 6985c58f1c22SToby Isaac 69861cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMLabelClearStratum()`, `DMSetLabelValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6987c58f1c22SToby Isaac @*/ 6988d71ae5a4SJacob Faibussowitsch PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 6989d71ae5a4SJacob Faibussowitsch { 6990c58f1c22SToby Isaac DMLabel label; 6991c58f1c22SToby Isaac 6992c58f1c22SToby Isaac PetscFunctionBegin; 6993c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69944f572ea9SToby Isaac PetscAssertPointer(name, 2); 69959566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 69963ba16761SJacob Faibussowitsch if (!label) PetscFunctionReturn(PETSC_SUCCESS); 69979566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 69983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6999c58f1c22SToby Isaac } 7000c58f1c22SToby Isaac 7001c58f1c22SToby Isaac /*@ 7002bb7acecfSBarry Smith DMGetNumLabels - Return the number of labels defined by on the `DM` 7003c58f1c22SToby Isaac 7004c58f1c22SToby Isaac Not Collective 7005c58f1c22SToby Isaac 7006c58f1c22SToby Isaac Input Parameter: 7007bb7acecfSBarry Smith . dm - The `DM` object 7008c58f1c22SToby Isaac 7009c58f1c22SToby Isaac Output Parameter: 7010c58f1c22SToby Isaac . numLabels - the number of Labels 7011c58f1c22SToby Isaac 7012c58f1c22SToby Isaac Level: intermediate 7013c58f1c22SToby Isaac 70141cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabelName()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7015c58f1c22SToby Isaac @*/ 7016d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 7017d71ae5a4SJacob Faibussowitsch { 70185d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7019c58f1c22SToby Isaac PetscInt n = 0; 7020c58f1c22SToby Isaac 7021c58f1c22SToby Isaac PetscFunctionBegin; 7022c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70234f572ea9SToby Isaac PetscAssertPointer(numLabels, 2); 70249371c9d4SSatish Balay while (next) { 70259371c9d4SSatish Balay ++n; 70269371c9d4SSatish Balay next = next->next; 70279371c9d4SSatish Balay } 7028c58f1c22SToby Isaac *numLabels = n; 70293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7030c58f1c22SToby Isaac } 7031c58f1c22SToby Isaac 7032c58f1c22SToby Isaac /*@C 7033c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 7034c58f1c22SToby Isaac 7035c58f1c22SToby Isaac Not Collective 7036c58f1c22SToby Isaac 7037c58f1c22SToby Isaac Input Parameters: 7038bb7acecfSBarry Smith + dm - The `DM` object 7039c58f1c22SToby Isaac - n - the label number 7040c58f1c22SToby Isaac 7041c58f1c22SToby Isaac Output Parameter: 7042c58f1c22SToby Isaac . name - the label name 7043c58f1c22SToby Isaac 7044c58f1c22SToby Isaac Level: intermediate 7045c58f1c22SToby Isaac 704673ff1848SBarry Smith Developer Note: 7047bb7acecfSBarry Smith Some of the functions that appropriate on labels using their number have the suffix ByNum, others do not. 7048bb7acecfSBarry Smith 70491cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabelByNum()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7050c58f1c22SToby Isaac @*/ 7051d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 7052d71ae5a4SJacob Faibussowitsch { 70535d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7054c58f1c22SToby Isaac PetscInt l = 0; 7055c58f1c22SToby Isaac 7056c58f1c22SToby Isaac PetscFunctionBegin; 7057c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70584f572ea9SToby Isaac PetscAssertPointer(name, 3); 7059c58f1c22SToby Isaac while (next) { 7060c58f1c22SToby Isaac if (l == n) { 70619566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, name)); 70623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7063c58f1c22SToby Isaac } 7064c58f1c22SToby Isaac ++l; 7065c58f1c22SToby Isaac next = next->next; 7066c58f1c22SToby Isaac } 706763a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7068c58f1c22SToby Isaac } 7069c58f1c22SToby Isaac 7070c58f1c22SToby Isaac /*@C 7071bb7acecfSBarry Smith DMHasLabel - Determine whether the `DM` has a label of a given name 7072c58f1c22SToby Isaac 7073c58f1c22SToby Isaac Not Collective 7074c58f1c22SToby Isaac 7075c58f1c22SToby Isaac Input Parameters: 7076bb7acecfSBarry Smith + dm - The `DM` object 7077c58f1c22SToby Isaac - name - The label name 7078c58f1c22SToby Isaac 7079c58f1c22SToby Isaac Output Parameter: 7080bb7acecfSBarry Smith . hasLabel - `PETSC_TRUE` if the label is present 7081c58f1c22SToby Isaac 7082c58f1c22SToby Isaac Level: intermediate 7083c58f1c22SToby Isaac 70841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetLabel()`, `DMGetLabelByNum()`, `DMCreateLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7085c58f1c22SToby Isaac @*/ 7086d71ae5a4SJacob Faibussowitsch PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 7087d71ae5a4SJacob Faibussowitsch { 70885d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7089d67d17b1SMatthew G. Knepley const char *lname; 7090c58f1c22SToby Isaac 7091c58f1c22SToby Isaac PetscFunctionBegin; 7092c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70934f572ea9SToby Isaac PetscAssertPointer(name, 2); 70944f572ea9SToby Isaac PetscAssertPointer(hasLabel, 3); 7095c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 7096c58f1c22SToby Isaac while (next) { 70979566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 70989566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, hasLabel)); 7099c58f1c22SToby Isaac if (*hasLabel) break; 7100c58f1c22SToby Isaac next = next->next; 7101c58f1c22SToby Isaac } 71023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7103c58f1c22SToby Isaac } 7104c58f1c22SToby Isaac 7105a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7106c58f1c22SToby Isaac /*@C 710720f4b53cSBarry Smith DMGetLabel - Return the label of a given name, or `NULL`, from a `DM` 7108c58f1c22SToby Isaac 7109c58f1c22SToby Isaac Not Collective 7110c58f1c22SToby Isaac 7111c58f1c22SToby Isaac Input Parameters: 7112bb7acecfSBarry Smith + dm - The `DM` object 7113c58f1c22SToby Isaac - name - The label name 7114c58f1c22SToby Isaac 7115c58f1c22SToby Isaac Output Parameter: 711620f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent 7117c58f1c22SToby Isaac 7118bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7119bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7120bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7121bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7122bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7123bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7124bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 71256d7c9049SMatthew G. Knepley 7126c58f1c22SToby Isaac Level: intermediate 7127c58f1c22SToby Isaac 712860225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMHasLabel()`, `DMGetLabelByNum()`, `DMAddLabel()`, `DMCreateLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 7129c58f1c22SToby Isaac @*/ 7130d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 7131d71ae5a4SJacob Faibussowitsch { 71325d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7133c58f1c22SToby Isaac PetscBool hasLabel; 7134d67d17b1SMatthew G. Knepley const char *lname; 7135c58f1c22SToby Isaac 7136c58f1c22SToby Isaac PetscFunctionBegin; 7137c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71384f572ea9SToby Isaac PetscAssertPointer(name, 2); 71394f572ea9SToby Isaac PetscAssertPointer(label, 3); 7140c58f1c22SToby Isaac *label = NULL; 7141c58f1c22SToby Isaac while (next) { 71429566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 71439566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7144c58f1c22SToby Isaac if (hasLabel) { 7145c58f1c22SToby Isaac *label = next->label; 7146c58f1c22SToby Isaac break; 7147c58f1c22SToby Isaac } 7148c58f1c22SToby Isaac next = next->next; 7149c58f1c22SToby Isaac } 71503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7151c58f1c22SToby Isaac } 7152c58f1c22SToby Isaac 7153c58f1c22SToby Isaac /*@C 7154bb7acecfSBarry Smith DMGetLabelByNum - Return the nth label on a `DM` 7155c58f1c22SToby Isaac 7156c58f1c22SToby Isaac Not Collective 7157c58f1c22SToby Isaac 7158c58f1c22SToby Isaac Input Parameters: 7159bb7acecfSBarry Smith + dm - The `DM` object 7160c58f1c22SToby Isaac - n - the label number 7161c58f1c22SToby Isaac 7162c58f1c22SToby Isaac Output Parameter: 7163c58f1c22SToby Isaac . label - the label 7164c58f1c22SToby Isaac 7165c58f1c22SToby Isaac Level: intermediate 7166c58f1c22SToby Isaac 71671cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7168c58f1c22SToby Isaac @*/ 7169d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 7170d71ae5a4SJacob Faibussowitsch { 71715d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7172c58f1c22SToby Isaac PetscInt l = 0; 7173c58f1c22SToby Isaac 7174c58f1c22SToby Isaac PetscFunctionBegin; 7175c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71764f572ea9SToby Isaac PetscAssertPointer(label, 3); 7177c58f1c22SToby Isaac while (next) { 7178c58f1c22SToby Isaac if (l == n) { 7179c58f1c22SToby Isaac *label = next->label; 71803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7181c58f1c22SToby Isaac } 7182c58f1c22SToby Isaac ++l; 7183c58f1c22SToby Isaac next = next->next; 7184c58f1c22SToby Isaac } 718563a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 7186c58f1c22SToby Isaac } 7187c58f1c22SToby Isaac 7188c58f1c22SToby Isaac /*@C 7189bb7acecfSBarry Smith DMAddLabel - Add the label to this `DM` 7190c58f1c22SToby Isaac 7191c58f1c22SToby Isaac Not Collective 7192c58f1c22SToby Isaac 7193c58f1c22SToby Isaac Input Parameters: 7194bb7acecfSBarry Smith + dm - The `DM` object 7195bb7acecfSBarry Smith - label - The `DMLabel` 7196c58f1c22SToby Isaac 7197c58f1c22SToby Isaac Level: developer 7198c58f1c22SToby Isaac 719960225df5SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7200c58f1c22SToby Isaac @*/ 7201d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAddLabel(DM dm, DMLabel label) 7202d71ae5a4SJacob Faibussowitsch { 72035d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 7204c58f1c22SToby Isaac PetscBool hasLabel; 7205d67d17b1SMatthew G. Knepley const char *lname; 72065d80c0bfSVaclav Hapla PetscBool flg; 7207c58f1c22SToby Isaac 7208c58f1c22SToby Isaac PetscFunctionBegin; 7209c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72109566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 72119566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, lname, &hasLabel)); 72127a8be351SBarry Smith PetscCheck(!hasLabel, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 72139566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(1, &tmpLabel)); 7214c58f1c22SToby Isaac tmpLabel->label = label; 7215c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 72165d80c0bfSVaclav Hapla for (p = &dm->labels; (l = *p); p = &l->next) { } 72175d80c0bfSVaclav Hapla *p = tmpLabel; 72189566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 72199566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 72205d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 72219566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 7222ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 72233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7224c58f1c22SToby Isaac } 7225c58f1c22SToby Isaac 7226a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown 7227c58f1c22SToby Isaac /*@C 72284a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 72294a7ee7d0SMatthew G. Knepley 72304a7ee7d0SMatthew G. Knepley Not Collective 72314a7ee7d0SMatthew G. Knepley 72324a7ee7d0SMatthew G. Knepley Input Parameters: 7233bb7acecfSBarry Smith + dm - The `DM` object 7234bb7acecfSBarry Smith - label - The `DMLabel`, having the same name, to substitute 72354a7ee7d0SMatthew G. Knepley 7236bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7237bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7238bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7239bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7240bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7241bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7242bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 72434a7ee7d0SMatthew G. Knepley 72444a7ee7d0SMatthew G. Knepley Level: intermediate 72454a7ee7d0SMatthew G. Knepley 72461cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 72474a7ee7d0SMatthew G. Knepley @*/ 7248d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabel(DM dm, DMLabel label) 7249d71ae5a4SJacob Faibussowitsch { 72504a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 72514a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 72524a7ee7d0SMatthew G. Knepley const char *name, *lname; 72534a7ee7d0SMatthew G. Knepley 72544a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 72554a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72564a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 72579566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 72584a7ee7d0SMatthew G. Knepley while (next) { 72599566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 72609566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 72614a7ee7d0SMatthew G. Knepley if (hasLabel) { 72629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 72639566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 72644a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 72659566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 72664a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 72679566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 72684a7ee7d0SMatthew G. Knepley next->label = label; 72694a7ee7d0SMatthew G. Knepley break; 72704a7ee7d0SMatthew G. Knepley } 72714a7ee7d0SMatthew G. Knepley next = next->next; 72724a7ee7d0SMatthew G. Knepley } 72733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 72744a7ee7d0SMatthew G. Knepley } 72754a7ee7d0SMatthew G. Knepley 72764a7ee7d0SMatthew G. Knepley /*@C 7277bb7acecfSBarry Smith DMRemoveLabel - Remove the label given by name from this `DM` 7278c58f1c22SToby Isaac 7279c58f1c22SToby Isaac Not Collective 7280c58f1c22SToby Isaac 7281c58f1c22SToby Isaac Input Parameters: 7282bb7acecfSBarry Smith + dm - The `DM` object 7283c58f1c22SToby Isaac - name - The label name 7284c58f1c22SToby Isaac 7285c58f1c22SToby Isaac Output Parameter: 728620f4b53cSBarry Smith . label - The `DMLabel`, or `NULL` if the label is absent. Pass in `NULL` to call `DMLabelDestroy()` on the label, otherwise the 7287bb7acecfSBarry Smith caller is responsible for calling `DMLabelDestroy()`. 7288c58f1c22SToby Isaac 7289c58f1c22SToby Isaac Level: developer 7290c58f1c22SToby Isaac 72911cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabelBySelf()` 7292c58f1c22SToby Isaac @*/ 7293d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7294d71ae5a4SJacob Faibussowitsch { 729595d578d6SVaclav Hapla DMLabelLink link, *pnext; 7296c58f1c22SToby Isaac PetscBool hasLabel; 7297d67d17b1SMatthew G. Knepley const char *lname; 7298c58f1c22SToby Isaac 7299c58f1c22SToby Isaac PetscFunctionBegin; 7300c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73014f572ea9SToby Isaac PetscAssertPointer(name, 2); 7302e5472504SVaclav Hapla if (label) { 73034f572ea9SToby Isaac PetscAssertPointer(label, 3); 7304c58f1c22SToby Isaac *label = NULL; 7305e5472504SVaclav Hapla } 73065d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 73079566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)link->label, &lname)); 73089566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7309c58f1c22SToby Isaac if (hasLabel) { 731095d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 73119566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &hasLabel)); 731295d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 73139566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &hasLabel)); 7314ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 731595d578d6SVaclav Hapla if (label) *label = link->label; 73169566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&link->label)); 73179566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7318c58f1c22SToby Isaac break; 7319c58f1c22SToby Isaac } 7320c58f1c22SToby Isaac } 73213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7322c58f1c22SToby Isaac } 7323c58f1c22SToby Isaac 7324306894acSVaclav Hapla /*@ 7325bb7acecfSBarry Smith DMRemoveLabelBySelf - Remove the label from this `DM` 7326306894acSVaclav Hapla 7327306894acSVaclav Hapla Not Collective 7328306894acSVaclav Hapla 7329306894acSVaclav Hapla Input Parameters: 7330bb7acecfSBarry Smith + dm - The `DM` object 7331bb7acecfSBarry Smith . label - The `DMLabel` to be removed from the `DM` 733220f4b53cSBarry Smith - failNotFound - Should it fail if the label is not found in the `DM`? 7333306894acSVaclav Hapla 7334306894acSVaclav Hapla Level: developer 7335306894acSVaclav Hapla 7336bb7acecfSBarry Smith Note: 7337306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7338bb7acecfSBarry Smith If the `DM` has an exclusive reference to the label, the label gets destroyed and 7339306894acSVaclav Hapla *label nullified. 7340306894acSVaclav Hapla 73411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()` `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabel()` 7342306894acSVaclav Hapla @*/ 7343d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7344d71ae5a4SJacob Faibussowitsch { 734543e45a93SVaclav Hapla DMLabelLink link, *pnext; 7346306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7347306894acSVaclav Hapla 7348306894acSVaclav Hapla PetscFunctionBegin; 7349306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73504f572ea9SToby Isaac PetscAssertPointer(label, 2); 73513ba16761SJacob Faibussowitsch if (!*label && !failNotFound) PetscFunctionReturn(PETSC_SUCCESS); 7352306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7353306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm, failNotFound, 3); 73545d80c0bfSVaclav Hapla for (pnext = &dm->labels; (link = *pnext); pnext = &link->next) { 735543e45a93SVaclav Hapla if (*label == link->label) { 7356306894acSVaclav Hapla hasLabel = PETSC_TRUE; 735743e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7358306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7359ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 736043e45a93SVaclav Hapla if (((PetscObject)link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 73619566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&link->label)); 73629566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7363306894acSVaclav Hapla break; 7364306894acSVaclav Hapla } 7365306894acSVaclav Hapla } 73667a8be351SBarry Smith PetscCheck(hasLabel || !failNotFound, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 73673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7368306894acSVaclav Hapla } 7369306894acSVaclav Hapla 7370c58f1c22SToby Isaac /*@C 7371c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7372c58f1c22SToby Isaac 7373c58f1c22SToby Isaac Not Collective 7374c58f1c22SToby Isaac 7375c58f1c22SToby Isaac Input Parameters: 7376bb7acecfSBarry Smith + dm - The `DM` object 7377c58f1c22SToby Isaac - name - The label name 7378c58f1c22SToby Isaac 7379c58f1c22SToby Isaac Output Parameter: 7380c58f1c22SToby Isaac . output - The flag for output 7381c58f1c22SToby Isaac 7382c58f1c22SToby Isaac Level: developer 7383c58f1c22SToby Isaac 73841cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMSetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7385c58f1c22SToby Isaac @*/ 7386d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7387d71ae5a4SJacob Faibussowitsch { 73885d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7389d67d17b1SMatthew G. Knepley const char *lname; 7390c58f1c22SToby Isaac 7391c58f1c22SToby Isaac PetscFunctionBegin; 7392c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73934f572ea9SToby Isaac PetscAssertPointer(name, 2); 73944f572ea9SToby Isaac PetscAssertPointer(output, 3); 7395c58f1c22SToby Isaac while (next) { 7396c58f1c22SToby Isaac PetscBool flg; 7397c58f1c22SToby Isaac 73989566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 73999566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 74009371c9d4SSatish Balay if (flg) { 74019371c9d4SSatish Balay *output = next->output; 74023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74039371c9d4SSatish Balay } 7404c58f1c22SToby Isaac next = next->next; 7405c58f1c22SToby Isaac } 740698921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7407c58f1c22SToby Isaac } 7408c58f1c22SToby Isaac 7409c58f1c22SToby Isaac /*@C 7410bb7acecfSBarry Smith DMSetLabelOutput - Set if a given label should be saved to a `PetscViewer` in calls to `DMView()` 7411c58f1c22SToby Isaac 7412c58f1c22SToby Isaac Not Collective 7413c58f1c22SToby Isaac 7414c58f1c22SToby Isaac Input Parameters: 7415bb7acecfSBarry Smith + dm - The `DM` object 7416c58f1c22SToby Isaac . name - The label name 7417bb7acecfSBarry Smith - output - `PETSC_TRUE` to save the label to the viewer 7418c58f1c22SToby Isaac 7419c58f1c22SToby Isaac Level: developer 7420c58f1c22SToby Isaac 74211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMGetOutputFlag()`, `DMGetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7422c58f1c22SToby Isaac @*/ 7423d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7424d71ae5a4SJacob Faibussowitsch { 74255d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7426d67d17b1SMatthew G. Knepley const char *lname; 7427c58f1c22SToby Isaac 7428c58f1c22SToby Isaac PetscFunctionBegin; 7429c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 74304f572ea9SToby Isaac PetscAssertPointer(name, 2); 7431c58f1c22SToby Isaac while (next) { 7432c58f1c22SToby Isaac PetscBool flg; 7433c58f1c22SToby Isaac 74349566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)next->label, &lname)); 74359566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 74369371c9d4SSatish Balay if (flg) { 74379371c9d4SSatish Balay next->output = output; 74383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74399371c9d4SSatish Balay } 7440c58f1c22SToby Isaac next = next->next; 7441c58f1c22SToby Isaac } 744298921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7443c58f1c22SToby Isaac } 7444c58f1c22SToby Isaac 7445c58f1c22SToby Isaac /*@ 7446bb7acecfSBarry Smith DMCopyLabels - Copy labels from one `DM` mesh to another `DM` with a superset of the points 7447c58f1c22SToby Isaac 744820f4b53cSBarry Smith Collective 7449c58f1c22SToby Isaac 7450d8d19677SJose E. Roman Input Parameters: 7451bb7acecfSBarry Smith + dmA - The `DM` object with initial labels 7452bb7acecfSBarry Smith . dmB - The `DM` object to which labels are copied 7453bb7acecfSBarry Smith . mode - Copy labels by pointers (`PETSC_OWN_POINTER`) or duplicate them (`PETSC_COPY_VALUES`) 7454bb7acecfSBarry Smith . all - Copy all labels including "depth", "dim", and "celltype" (`PETSC_TRUE`) which are otherwise ignored (`PETSC_FALSE`) 7455bb7acecfSBarry Smith - emode - How to behave when a `DMLabel` in the source and destination `DM`s with the same name is encountered (see `DMCopyLabelsMode`) 7456c58f1c22SToby Isaac 7457c58f1c22SToby Isaac Level: intermediate 7458c58f1c22SToby Isaac 7459bb7acecfSBarry Smith Note: 74602cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 7461c58f1c22SToby Isaac 74621cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode` 7463c58f1c22SToby Isaac @*/ 7464d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 7465d71ae5a4SJacob Faibussowitsch { 74662cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 7467c58f1c22SToby Isaac const char *name; 7468c58f1c22SToby Isaac PetscBool flg; 74695d80c0bfSVaclav Hapla DMLabelLink link; 7470c58f1c22SToby Isaac 74715d80c0bfSVaclav Hapla PetscFunctionBegin; 74725d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 74735d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 74745d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode, 3); 74755d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 74767a8be351SBarry Smith PetscCheck(mode != PETSC_USE_POINTER, PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 74773ba16761SJacob Faibussowitsch if (dmA == dmB) PetscFunctionReturn(PETSC_SUCCESS); 74785d80c0bfSVaclav Hapla for (link = dmA->labels; link; link = link->next) { 74795d80c0bfSVaclav Hapla label = link->label; 74809566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 74815d80c0bfSVaclav Hapla if (!all) { 74829566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &flg)); 7483c58f1c22SToby Isaac if (flg) continue; 74849566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "dim", &flg)); 74857d5acc75SStefano Zampini if (flg) continue; 74869566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &flg)); 7487ba2698f1SMatthew G. Knepley if (flg) continue; 74885d80c0bfSVaclav Hapla } 74899566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmB, name, &labelOld)); 74902cbb9b06SVaclav Hapla if (labelOld) { 74912cbb9b06SVaclav Hapla switch (emode) { 7492d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_KEEP: 7493d71ae5a4SJacob Faibussowitsch continue; 7494d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_REPLACE: 7495d71ae5a4SJacob Faibussowitsch PetscCall(DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE)); 7496d71ae5a4SJacob Faibussowitsch break; 7497d71ae5a4SJacob Faibussowitsch case DM_COPY_LABELS_FAIL: 7498d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 7499d71ae5a4SJacob Faibussowitsch default: 7500d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", (int)emode); 75012cbb9b06SVaclav Hapla } 75022cbb9b06SVaclav Hapla } 75035d80c0bfSVaclav Hapla if (mode == PETSC_COPY_VALUES) { 75049566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, &labelNew)); 75055d80c0bfSVaclav Hapla } else { 75065d80c0bfSVaclav Hapla labelNew = label; 75075d80c0bfSVaclav Hapla } 75089566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmB, labelNew)); 75099566063dSJacob Faibussowitsch if (mode == PETSC_COPY_VALUES) PetscCall(DMLabelDestroy(&labelNew)); 7510c58f1c22SToby Isaac } 75113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7512c58f1c22SToby Isaac } 7513461a15a0SLisandro Dalcin 7514609dae6eSVaclav Hapla /*@C 7515b4028c23SStefano Zampini DMCompareLabels - Compare labels between two `DM` objects 7516609dae6eSVaclav Hapla 751720f4b53cSBarry Smith Collective; No Fortran Support 7518609dae6eSVaclav Hapla 7519609dae6eSVaclav Hapla Input Parameters: 7520bb7acecfSBarry Smith + dm0 - First `DM` object 7521bb7acecfSBarry Smith - dm1 - Second `DM` object 7522609dae6eSVaclav Hapla 7523a4e35b19SJacob Faibussowitsch Output Parameters: 75245efe38ccSVaclav Hapla + equal - (Optional) Flag whether labels of dm0 and dm1 are the same 752520f4b53cSBarry Smith - message - (Optional) Message describing the difference, or `NULL` if there is no difference 7526609dae6eSVaclav Hapla 7527609dae6eSVaclav Hapla Level: intermediate 7528609dae6eSVaclav Hapla 7529609dae6eSVaclav Hapla Notes: 7530bb7acecfSBarry Smith The output flag equal will be the same on all processes. 7531bb7acecfSBarry Smith 753220f4b53cSBarry Smith If equal is passed as `NULL` and difference is found, an error is thrown on all processes. 7533bb7acecfSBarry Smith 753420f4b53cSBarry Smith Make sure to pass equal is `NULL` on all processes or none of them. 7535609dae6eSVaclav Hapla 75365efe38ccSVaclav Hapla The output message is set independently on each rank. 7537bb7acecfSBarry Smith 7538bb7acecfSBarry Smith message must be freed with `PetscFree()` 7539bb7acecfSBarry Smith 754020f4b53cSBarry Smith If message is passed as `NULL` and a difference is found, the difference description is printed to stderr in synchronized manner. 7541bb7acecfSBarry Smith 754220f4b53cSBarry Smith Make sure to pass message as `NULL` on all processes or no processes. 7543609dae6eSVaclav Hapla 7544609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 7545bb7acecfSBarry Smith `DMLabelCompare()` is used to compare each pair of labels with the same name. 7546609dae6eSVaclav Hapla 75471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode`, `DMLabelCompare()` 7548609dae6eSVaclav Hapla @*/ 7549d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *equal, char **message) 7550d71ae5a4SJacob Faibussowitsch { 75515efe38ccSVaclav Hapla PetscInt n, i; 7552609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 75535efe38ccSVaclav Hapla PetscBool eq; 7554609dae6eSVaclav Hapla MPI_Comm comm; 75555efe38ccSVaclav Hapla PetscMPIInt rank; 7556609dae6eSVaclav Hapla 7557609dae6eSVaclav Hapla PetscFunctionBegin; 7558609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0, DM_CLASSID, 1); 7559609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1, DM_CLASSID, 2); 7560609dae6eSVaclav Hapla PetscCheckSameComm(dm0, 1, dm1, 2); 75614f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 3); 75624f572ea9SToby Isaac if (message) PetscAssertPointer(message, 4); 75639566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm0, &comm)); 75649566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 75655efe38ccSVaclav Hapla { 75665efe38ccSVaclav Hapla PetscInt n1; 75675efe38ccSVaclav Hapla 75689566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm0, &n)); 75699566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm1, &n1)); 75705efe38ccSVaclav Hapla eq = (PetscBool)(n == n1); 757148a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %" PetscInt_FMT " != %" PetscInt_FMT " = Number of labels in dm1", n, n1)); 7572712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 75735efe38ccSVaclav Hapla if (!eq) goto finish; 75745efe38ccSVaclav Hapla } 75755efe38ccSVaclav Hapla for (i = 0; i < n; i++) { 7576609dae6eSVaclav Hapla DMLabel l0, l1; 7577609dae6eSVaclav Hapla const char *name; 7578609dae6eSVaclav Hapla char *msgInner; 7579609dae6eSVaclav Hapla 7580609dae6eSVaclav Hapla /* Ignore label order */ 75819566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm0, i, &l0)); 75829566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name)); 75839566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm1, name, &l1)); 7584609dae6eSVaclav Hapla if (!l1) { 758563a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%" PetscInt_FMT " in dm0) not found in dm1", name, i)); 75865efe38ccSVaclav Hapla eq = PETSC_FALSE; 75875efe38ccSVaclav Hapla break; 7588609dae6eSVaclav Hapla } 75899566063dSJacob Faibussowitsch PetscCall(DMLabelCompare(comm, l0, l1, &eq, &msgInner)); 75909566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(msg, msgInner, sizeof(msg))); 75919566063dSJacob Faibussowitsch PetscCall(PetscFree(msgInner)); 75925efe38ccSVaclav Hapla if (!eq) break; 7593609dae6eSVaclav Hapla } 7594712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 7595609dae6eSVaclav Hapla finish: 75965efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 7597609dae6eSVaclav Hapla if (message) { 7598609dae6eSVaclav Hapla *message = NULL; 759948a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 76005efe38ccSVaclav Hapla } else { 760148a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 76029566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 76035efe38ccSVaclav Hapla } 76045efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 76055efe38ccSVaclav Hapla if (equal) *equal = eq; 76067a8be351SBarry Smith else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels are not the same in dm0 and dm1"); 76073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7608609dae6eSVaclav Hapla } 7609609dae6eSVaclav Hapla 7610d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 7611d71ae5a4SJacob Faibussowitsch { 7612461a15a0SLisandro Dalcin PetscFunctionBegin; 76134f572ea9SToby Isaac PetscAssertPointer(label, 2); 7614461a15a0SLisandro Dalcin if (!*label) { 76159566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 76169566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, label)); 7617461a15a0SLisandro Dalcin } 76189566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(*label, point, value)); 76193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7620461a15a0SLisandro Dalcin } 7621461a15a0SLisandro Dalcin 76220fdc7489SMatthew Knepley /* 76230fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 76240fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 76250fdc7489SMatthew Knepley (label, id) pair in the DM. 76260fdc7489SMatthew Knepley 76270fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 76280fdc7489SMatthew Knepley each label. 76290fdc7489SMatthew Knepley */ 7630d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 7631d71ae5a4SJacob Faibussowitsch { 76320fdc7489SMatthew Knepley DMUniversalLabel ul; 76330fdc7489SMatthew Knepley PetscBool *active; 76340fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 76350fdc7489SMatthew Knepley 76360fdc7489SMatthew Knepley PetscFunctionBegin; 76379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &ul)); 76389566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label)); 76399566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 76409566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nl, &active)); 76410fdc7489SMatthew Knepley ul->Nl = 0; 76420fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 76430fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 76440fdc7489SMatthew Knepley const char *name; 76450fdc7489SMatthew Knepley 76469566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 76479566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "depth", 6, &isdepth)); 76489566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "celltype", 9, &iscelltype)); 76490fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 76500fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 76510fdc7489SMatthew Knepley } 76529566063dSJacob 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)); 76530fdc7489SMatthew Knepley ul->Nv = 0; 76540fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 76550fdc7489SMatthew Knepley DMLabel label; 76560fdc7489SMatthew Knepley PetscInt nv; 76570fdc7489SMatthew Knepley const char *name; 76580fdc7489SMatthew Knepley 76590fdc7489SMatthew Knepley if (!active[l]) continue; 76609566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 76619566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 76629566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 76639566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &ul->names[m])); 76640fdc7489SMatthew Knepley ul->indices[m] = l; 76650fdc7489SMatthew Knepley ul->Nv += nv; 76660fdc7489SMatthew Knepley ul->offsets[m + 1] = nv; 76670fdc7489SMatthew Knepley ul->bits[m + 1] = PetscCeilReal(PetscLog2Real(nv + 1)); 76680fdc7489SMatthew Knepley ++m; 76690fdc7489SMatthew Knepley } 76700fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 76710fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l - 1] + ul->offsets[l]; 76720fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l - 1] + ul->bits[l]; 76730fdc7489SMatthew Knepley } 76740fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 76750fdc7489SMatthew Knepley PetscInt b; 76760fdc7489SMatthew Knepley 76770fdc7489SMatthew Knepley ul->masks[l] = 0; 76780fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l + 1]; ++b) ul->masks[l] |= 1 << b; 76790fdc7489SMatthew Knepley } 76809566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ul->Nv, &ul->values)); 76810fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 76820fdc7489SMatthew Knepley DMLabel label; 76830fdc7489SMatthew Knepley IS valueIS; 76840fdc7489SMatthew Knepley const PetscInt *varr; 76850fdc7489SMatthew Knepley PetscInt nv, v; 76860fdc7489SMatthew Knepley 76870fdc7489SMatthew Knepley if (!active[l]) continue; 76889566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 76899566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 76909566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &valueIS)); 76919566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &varr)); 7692ad540459SPierre Jolivet for (v = 0; v < nv; ++v) ul->values[ul->offsets[m] + v] = varr[v]; 76939566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(valueIS, &varr)); 76949566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valueIS)); 76959566063dSJacob Faibussowitsch PetscCall(PetscSortInt(nv, &ul->values[ul->offsets[m]])); 76960fdc7489SMatthew Knepley ++m; 76970fdc7489SMatthew Knepley } 76989566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 76990fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 77000fdc7489SMatthew Knepley PetscInt uval = 0; 77010fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 77020fdc7489SMatthew Knepley 77030fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 77040fdc7489SMatthew Knepley DMLabel label; 77050649b39aSStefano Zampini PetscInt val, defval, loc, nv; 77060fdc7489SMatthew Knepley 77070fdc7489SMatthew Knepley if (!active[l]) continue; 77089566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 77099566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &val)); 77109566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &defval)); 77119371c9d4SSatish Balay if (val == defval) { 77129371c9d4SSatish Balay ++m; 77139371c9d4SSatish Balay continue; 77149371c9d4SSatish Balay } 77150649b39aSStefano Zampini nv = ul->offsets[m + 1] - ul->offsets[m]; 77160fdc7489SMatthew Knepley marked = PETSC_TRUE; 77179566063dSJacob Faibussowitsch PetscCall(PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc)); 771863a3b9bcSJacob Faibussowitsch PetscCheck(loc >= 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %" PetscInt_FMT " not found in compression array", val); 77190fdc7489SMatthew Knepley uval += (loc + 1) << ul->bits[m]; 77200fdc7489SMatthew Knepley ++m; 77210fdc7489SMatthew Knepley } 77229566063dSJacob Faibussowitsch if (marked) PetscCall(DMLabelSetValue(ul->label, p, uval)); 77230fdc7489SMatthew Knepley } 77249566063dSJacob Faibussowitsch PetscCall(PetscFree(active)); 77250fdc7489SMatthew Knepley *universal = ul; 77263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77270fdc7489SMatthew Knepley } 77280fdc7489SMatthew Knepley 7729d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 7730d71ae5a4SJacob Faibussowitsch { 77310fdc7489SMatthew Knepley PetscInt l; 77320fdc7489SMatthew Knepley 77330fdc7489SMatthew Knepley PetscFunctionBegin; 77349566063dSJacob Faibussowitsch for (l = 0; l < (*universal)->Nl; ++l) PetscCall(PetscFree((*universal)->names[l])); 77359566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&(*universal)->label)); 77369566063dSJacob Faibussowitsch PetscCall(PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks)); 77379566063dSJacob Faibussowitsch PetscCall(PetscFree((*universal)->values)); 77389566063dSJacob Faibussowitsch PetscCall(PetscFree(*universal)); 77390fdc7489SMatthew Knepley *universal = NULL; 77403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77410fdc7489SMatthew Knepley } 77420fdc7489SMatthew Knepley 7743d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 7744d71ae5a4SJacob Faibussowitsch { 77450fdc7489SMatthew Knepley PetscFunctionBegin; 77464f572ea9SToby Isaac PetscAssertPointer(ulabel, 2); 77470fdc7489SMatthew Knepley *ulabel = ul->label; 77483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77490fdc7489SMatthew Knepley } 77500fdc7489SMatthew Knepley 7751d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 7752d71ae5a4SJacob Faibussowitsch { 77530fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 77540fdc7489SMatthew Knepley 77550fdc7489SMatthew Knepley PetscFunctionBegin; 7756064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 77570fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 77589566063dSJacob Faibussowitsch if (preserveOrder) PetscCall(DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l])); 77599566063dSJacob Faibussowitsch else PetscCall(DMCreateLabel(dm, ul->names[l])); 77600fdc7489SMatthew Knepley } 77610fdc7489SMatthew Knepley if (preserveOrder) { 77620fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 77630fdc7489SMatthew Knepley const char *name; 77640fdc7489SMatthew Knepley PetscBool match; 77650fdc7489SMatthew Knepley 77669566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, ul->indices[l], &name)); 77679566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, ul->names[l], &match)); 776863a3b9bcSJacob 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]); 77690fdc7489SMatthew Knepley } 77700fdc7489SMatthew Knepley } 77713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77720fdc7489SMatthew Knepley } 77730fdc7489SMatthew Knepley 7774d71ae5a4SJacob Faibussowitsch PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 7775d71ae5a4SJacob Faibussowitsch { 77760fdc7489SMatthew Knepley PetscInt l; 77770fdc7489SMatthew Knepley 77780fdc7489SMatthew Knepley PetscFunctionBegin; 77790fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 77800fdc7489SMatthew Knepley DMLabel label; 77810fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 77820fdc7489SMatthew Knepley 77830fdc7489SMatthew Knepley if (lval) { 77849566063dSJacob Faibussowitsch if (useIndex) PetscCall(DMGetLabelByNum(dm, ul->indices[l], &label)); 77859566063dSJacob Faibussowitsch else PetscCall(DMGetLabel(dm, ul->names[l], &label)); 77869566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, p, ul->values[ul->offsets[l] + lval - 1])); 77870fdc7489SMatthew Knepley } 77880fdc7489SMatthew Knepley } 77893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77900fdc7489SMatthew Knepley } 7791a8fb8f29SToby Isaac 7792a8fb8f29SToby Isaac /*@ 7793bb7acecfSBarry Smith DMGetCoarseDM - Get the coarse `DM`from which this `DM` was obtained by refinement 7794bb7acecfSBarry Smith 779520f4b53cSBarry Smith Not Collective 7796a8fb8f29SToby Isaac 7797a8fb8f29SToby Isaac Input Parameter: 7798bb7acecfSBarry Smith . dm - The `DM` object 7799a8fb8f29SToby Isaac 7800a8fb8f29SToby Isaac Output Parameter: 7801bb7acecfSBarry Smith . cdm - The coarse `DM` 7802a8fb8f29SToby Isaac 7803a8fb8f29SToby Isaac Level: intermediate 7804a8fb8f29SToby Isaac 78051cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetCoarseDM()`, `DMCoarsen()` 7806a8fb8f29SToby Isaac @*/ 7807d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 7808d71ae5a4SJacob Faibussowitsch { 7809a8fb8f29SToby Isaac PetscFunctionBegin; 7810a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78114f572ea9SToby Isaac PetscAssertPointer(cdm, 2); 7812a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 78133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7814a8fb8f29SToby Isaac } 7815a8fb8f29SToby Isaac 7816a8fb8f29SToby Isaac /*@ 7817bb7acecfSBarry Smith DMSetCoarseDM - Set the coarse `DM` from which this `DM` was obtained by refinement 7818a8fb8f29SToby Isaac 7819a8fb8f29SToby Isaac Input Parameters: 7820bb7acecfSBarry Smith + dm - The `DM` object 7821bb7acecfSBarry Smith - cdm - The coarse `DM` 7822a8fb8f29SToby Isaac 7823a8fb8f29SToby Isaac Level: intermediate 7824a8fb8f29SToby Isaac 7825bb7acecfSBarry Smith Note: 7826bb7acecfSBarry Smith Normally this is set automatically by `DMRefine()` 7827bb7acecfSBarry Smith 78281cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetCoarseDM()`, `DMCoarsen()`, `DMSetRefine()`, `DMSetFineDM()` 7829a8fb8f29SToby Isaac @*/ 7830d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 7831d71ae5a4SJacob Faibussowitsch { 7832a8fb8f29SToby Isaac PetscFunctionBegin; 7833a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7834a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 783589d734beSBarry Smith if (dm == cdm) cdm = NULL; 78369566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cdm)); 78379566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->coarseMesh)); 7838a8fb8f29SToby Isaac dm->coarseMesh = cdm; 78393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7840a8fb8f29SToby Isaac } 7841a8fb8f29SToby Isaac 784288bdff64SToby Isaac /*@ 7843bb7acecfSBarry Smith DMGetFineDM - Get the fine mesh from which this `DM` was obtained by coarsening 784488bdff64SToby Isaac 784588bdff64SToby Isaac Input Parameter: 7846bb7acecfSBarry Smith . dm - The `DM` object 784788bdff64SToby Isaac 784888bdff64SToby Isaac Output Parameter: 7849bb7acecfSBarry Smith . fdm - The fine `DM` 785088bdff64SToby Isaac 785188bdff64SToby Isaac Level: intermediate 785288bdff64SToby Isaac 78531cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMSetFineDM()`, `DMCoarsen()`, `DMRefine()` 785488bdff64SToby Isaac @*/ 7855d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 7856d71ae5a4SJacob Faibussowitsch { 785788bdff64SToby Isaac PetscFunctionBegin; 785888bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78594f572ea9SToby Isaac PetscAssertPointer(fdm, 2); 786088bdff64SToby Isaac *fdm = dm->fineMesh; 78613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 786288bdff64SToby Isaac } 786388bdff64SToby Isaac 786488bdff64SToby Isaac /*@ 7865bb7acecfSBarry Smith DMSetFineDM - Set the fine mesh from which this was obtained by coarsening 786688bdff64SToby Isaac 786788bdff64SToby Isaac Input Parameters: 7868bb7acecfSBarry Smith + dm - The `DM` object 7869bb7acecfSBarry Smith - fdm - The fine `DM` 787088bdff64SToby Isaac 7871bb7acecfSBarry Smith Level: developer 787288bdff64SToby Isaac 7873bb7acecfSBarry Smith Note: 7874bb7acecfSBarry Smith Normally this is set automatically by `DMCoarsen()` 7875bb7acecfSBarry Smith 78761cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMGetFineDM()`, `DMCoarsen()`, `DMRefine()` 787788bdff64SToby Isaac @*/ 7878d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetFineDM(DM dm, DM fdm) 7879d71ae5a4SJacob Faibussowitsch { 788088bdff64SToby Isaac PetscFunctionBegin; 788188bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 788288bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 788389d734beSBarry Smith if (dm == fdm) fdm = NULL; 78849566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fdm)); 78859566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->fineMesh)); 788688bdff64SToby Isaac dm->fineMesh = fdm; 78873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 788888bdff64SToby Isaac } 788988bdff64SToby Isaac 7890a6ba4734SToby Isaac /*@C 7891bb7acecfSBarry Smith DMAddBoundary - Add a boundary condition to a model represented by a `DM` 7892a6ba4734SToby Isaac 789320f4b53cSBarry Smith Collective 7894783e2ec8SMatthew G. Knepley 7895a6ba4734SToby Isaac Input Parameters: 7896bb7acecfSBarry Smith + dm - The `DM`, with a `PetscDS` that matches the problem being constrained 7897bb7acecfSBarry Smith . type - The type of condition, e.g. `DM_BC_ESSENTIAL_ANALYTIC`, `DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann) 7898a6ba4734SToby Isaac . name - The BC name 789945480ffeSMatthew G. Knepley . label - The label defining constrained points 7900bb7acecfSBarry Smith . Nv - The number of `DMLabel` values for constrained points 790145480ffeSMatthew G. Knepley . values - An array of values for constrained points 7902a6ba4734SToby Isaac . field - The field to constrain 790345480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 7904a6ba4734SToby Isaac . comps - An array of constrained component numbers 7905a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 790656cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 7907a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 7908a6ba4734SToby Isaac 790945480ffeSMatthew G. Knepley Output Parameter: 791045480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 791145480ffeSMatthew G. Knepley 7912a6ba4734SToby Isaac Options Database Keys: 7913a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 7914a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 7915a6ba4734SToby Isaac 791620f4b53cSBarry Smith Level: intermediate 791720f4b53cSBarry Smith 7918bb7acecfSBarry Smith Notes: 791937fdd005SBarry 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\: 792073ff1848SBarry Smith .vb 792173ff1848SBarry Smith void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 792273ff1848SBarry Smith .ve 792356cf3b9cSMatthew G. Knepley 7924a4e35b19SJacob Faibussowitsch If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\: 792556cf3b9cSMatthew G. Knepley 792620f4b53cSBarry Smith .vb 792720f4b53cSBarry Smith void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 792820f4b53cSBarry Smith const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 792920f4b53cSBarry Smith const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 793020f4b53cSBarry Smith PetscReal time, const PetscReal x[], PetscScalar bcval[]) 793120f4b53cSBarry Smith .ve 793256cf3b9cSMatthew G. Knepley + dim - the spatial dimension 793356cf3b9cSMatthew G. Knepley . Nf - the number of fields 793456cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 793556cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 793656cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 793756cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 793856cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 793956cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 794056cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 794156cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 794256cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 794356cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 794456cf3b9cSMatthew G. Knepley . t - current time 794556cf3b9cSMatthew G. Knepley . x - coordinates of the current point 794656cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 794756cf3b9cSMatthew G. Knepley . constants - constant parameters 794856cf3b9cSMatthew G. Knepley - bcval - output values at the current point 794956cf3b9cSMatthew G. Knepley 79501cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DSGetBoundary()`, `PetscDSAddBoundary()` 7951a6ba4734SToby Isaac @*/ 7952d71ae5a4SJacob 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) 7953d71ae5a4SJacob Faibussowitsch { 7954e5e52638SMatthew G. Knepley PetscDS ds; 7955a6ba4734SToby Isaac 7956a6ba4734SToby Isaac PetscFunctionBegin; 7957a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7958783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 795945480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 796045480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 796145480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 796245480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 796301a5d20dSJed Brown PetscCheck(!dm->localSection, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot add boundary to DM after creating local section"); 79649566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7965799db056SMatthew G. Knepley /* Complete label */ 7966799db056SMatthew G. Knepley if (label) { 7967799db056SMatthew G. Knepley PetscObject obj; 7968799db056SMatthew G. Knepley PetscClassId id; 7969799db056SMatthew G. Knepley 7970799db056SMatthew G. Knepley PetscCall(DMGetField(dm, field, NULL, &obj)); 7971799db056SMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 7972799db056SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 7973799db056SMatthew G. Knepley DM plex; 7974799db056SMatthew G. Knepley 7975799db056SMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 7976799db056SMatthew G. Knepley if (plex) PetscCall(DMPlexLabelComplete(plex, label)); 7977799db056SMatthew G. Knepley PetscCall(DMDestroy(&plex)); 7978799db056SMatthew G. Knepley } 7979799db056SMatthew G. Knepley } 79809566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd)); 79813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7982a6ba4734SToby Isaac } 7983a6ba4734SToby Isaac 798445480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 7985d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPopulateBoundary(DM dm) 7986d71ae5a4SJacob Faibussowitsch { 7987e5e52638SMatthew G. Knepley PetscDS ds; 7988dff059c6SToby Isaac DMBoundary *lastnext; 7989e6f8dbb6SToby Isaac DSBoundary dsbound; 7990e6f8dbb6SToby Isaac 7991e6f8dbb6SToby Isaac PetscFunctionBegin; 79929566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7993e5e52638SMatthew G. Knepley dsbound = ds->boundary; 799447a1f5adSToby Isaac if (dm->boundary) { 799547a1f5adSToby Isaac DMBoundary next = dm->boundary; 799647a1f5adSToby Isaac 799747a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 79983ba16761SJacob Faibussowitsch if (next->dsboundary == dsbound) PetscFunctionReturn(PETSC_SUCCESS); 799947a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 800047a1f5adSToby Isaac while (next) { 800147a1f5adSToby Isaac DMBoundary b = next; 800247a1f5adSToby Isaac 800347a1f5adSToby Isaac next = b->next; 80049566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 8005a6ba4734SToby Isaac } 800647a1f5adSToby Isaac dm->boundary = NULL; 8007a6ba4734SToby Isaac } 800847a1f5adSToby Isaac 8009f4f49eeaSPierre Jolivet lastnext = &dm->boundary; 8010e6f8dbb6SToby Isaac while (dsbound) { 8011e6f8dbb6SToby Isaac DMBoundary dmbound; 8012e6f8dbb6SToby Isaac 80139566063dSJacob Faibussowitsch PetscCall(PetscNew(&dmbound)); 8014e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 801545480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 801647a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 8017dff059c6SToby Isaac *lastnext = dmbound; 8018f4f49eeaSPierre Jolivet lastnext = &dmbound->next; 8019dff059c6SToby Isaac dsbound = dsbound->next; 8020a6ba4734SToby Isaac } 80213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8022a6ba4734SToby Isaac } 8023a6ba4734SToby Isaac 8024bb7acecfSBarry Smith /* TODO: missing manual page */ 8025d71ae5a4SJacob Faibussowitsch PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 8026d71ae5a4SJacob Faibussowitsch { 8027b95f2879SToby Isaac DMBoundary b; 8028a6ba4734SToby Isaac 8029a6ba4734SToby Isaac PetscFunctionBegin; 8030a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 80314f572ea9SToby Isaac PetscAssertPointer(isBd, 3); 8032a6ba4734SToby Isaac *isBd = PETSC_FALSE; 80339566063dSJacob Faibussowitsch PetscCall(DMPopulateBoundary(dm)); 8034b95f2879SToby Isaac b = dm->boundary; 8035a6ba4734SToby Isaac while (b && !(*isBd)) { 8036e6f8dbb6SToby Isaac DMLabel label = b->label; 8037e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 8038a6ba4734SToby Isaac PetscInt i; 8039a6ba4734SToby Isaac 804045480ffeSMatthew G. Knepley if (label) { 80419566063dSJacob Faibussowitsch for (i = 0; i < dsb->Nv && !(*isBd); ++i) PetscCall(DMLabelStratumHasPoint(label, dsb->values[i], point, isBd)); 8042a6ba4734SToby Isaac } 8043a6ba4734SToby Isaac b = b->next; 8044a6ba4734SToby Isaac } 80453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8046a6ba4734SToby Isaac } 80474d6f44ffSToby Isaac 80484d6f44ffSToby Isaac /*@C 8049bb7acecfSBarry Smith DMProjectFunction - This projects the given function into the function space provided by a `DM`, putting the coefficients in a global vector. 8050a6e0b375SMatthew G. Knepley 805120f4b53cSBarry Smith Collective 80524d6f44ffSToby Isaac 80534d6f44ffSToby Isaac Input Parameters: 8054bb7acecfSBarry Smith + dm - The `DM` 80550709b2feSToby Isaac . time - The time 80564d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 80574d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 80584d6f44ffSToby Isaac - mode - The insertion mode for values 80594d6f44ffSToby Isaac 80604d6f44ffSToby Isaac Output Parameter: 80614d6f44ffSToby Isaac . X - vector 80624d6f44ffSToby Isaac 806320f4b53cSBarry Smith Calling sequence of `funcs`: 80644d6f44ffSToby Isaac + dim - The spatial dimension 80658ec8862eSJed Brown . time - The time at which to sample 80664d6f44ffSToby Isaac . x - The coordinates 806777b739a6SMatthew Knepley . Nc - The number of components 80684d6f44ffSToby Isaac . u - The output field values 80694d6f44ffSToby Isaac - ctx - optional user-defined function context 80704d6f44ffSToby Isaac 80714d6f44ffSToby Isaac Level: developer 80724d6f44ffSToby Isaac 8073bb7acecfSBarry Smith Developer Notes: 8074bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8075bb7acecfSBarry Smith 8076bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8077bb7acecfSBarry Smith 80781cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 80794d6f44ffSToby Isaac @*/ 8080a4e35b19SJacob 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) 8081d71ae5a4SJacob Faibussowitsch { 80824d6f44ffSToby Isaac Vec localX; 80834d6f44ffSToby Isaac 80844d6f44ffSToby Isaac PetscFunctionBegin; 80854d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8086708be2fdSJed Brown PetscCall(PetscLogEventBegin(DM_ProjectFunction, dm, X, 0, 0)); 80879566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8088f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 80899566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX)); 80909566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 80919566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 80929566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 8093708be2fdSJed Brown PetscCall(PetscLogEventEnd(DM_ProjectFunction, dm, X, 0, 0)); 80943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80954d6f44ffSToby Isaac } 80964d6f44ffSToby Isaac 8097a6e0b375SMatthew G. Knepley /*@C 8098bb7acecfSBarry Smith DMProjectFunctionLocal - This projects the given function into the function space provided by a `DM`, putting the coefficients in a local vector. 8099a6e0b375SMatthew G. Knepley 810020f4b53cSBarry Smith Not Collective 8101a6e0b375SMatthew G. Knepley 8102a6e0b375SMatthew G. Knepley Input Parameters: 8103bb7acecfSBarry Smith + dm - The `DM` 8104a6e0b375SMatthew G. Knepley . time - The time 8105a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8106a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8107a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8108a6e0b375SMatthew G. Knepley 8109a6e0b375SMatthew G. Knepley Output Parameter: 8110a6e0b375SMatthew G. Knepley . localX - vector 8111a6e0b375SMatthew G. Knepley 811220f4b53cSBarry Smith Calling sequence of `funcs`: 8113a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8114a4e35b19SJacob Faibussowitsch . time - The current timestep 8115a6e0b375SMatthew G. Knepley . x - The coordinates 811677b739a6SMatthew Knepley . Nc - The number of components 8117a6e0b375SMatthew G. Knepley . u - The output field values 8118a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8119a6e0b375SMatthew G. Knepley 8120a6e0b375SMatthew G. Knepley Level: developer 8121a6e0b375SMatthew G. Knepley 8122bb7acecfSBarry Smith Developer Notes: 8123bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8124bb7acecfSBarry Smith 8125bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8126bb7acecfSBarry Smith 81271cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8128a6e0b375SMatthew G. Knepley @*/ 8129a4e35b19SJacob 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) 8130d71ae5a4SJacob Faibussowitsch { 81314d6f44ffSToby Isaac PetscFunctionBegin; 81324d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8133064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 8134fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfunctionlocal, time, funcs, ctxs, mode, localX); 81353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81364d6f44ffSToby Isaac } 81374d6f44ffSToby Isaac 8138a6e0b375SMatthew G. Knepley /*@C 8139bb7acecfSBarry 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. 8140a6e0b375SMatthew G. Knepley 814120f4b53cSBarry Smith Collective 8142a6e0b375SMatthew G. Knepley 8143a6e0b375SMatthew G. Knepley Input Parameters: 8144bb7acecfSBarry Smith + dm - The `DM` 8145a6e0b375SMatthew G. Knepley . time - The time 8146a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8147a4e35b19SJacob Faibussowitsch . ids - The ids 8148a4e35b19SJacob Faibussowitsch . Nc - The number of components 8149a4e35b19SJacob Faibussowitsch . comps - The components 8150bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8151a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8152bb7acecfSBarry Smith . ctxs - Optional array of contexts to pass to each coordinate function. ctxs may be null. 8153a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8154a6e0b375SMatthew G. Knepley 8155a6e0b375SMatthew G. Knepley Output Parameter: 8156a6e0b375SMatthew G. Knepley . X - vector 8157a6e0b375SMatthew G. Knepley 815820f4b53cSBarry Smith Calling sequence of `funcs`: 8159a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8160a4e35b19SJacob Faibussowitsch . time - The current timestep 8161a6e0b375SMatthew G. Knepley . x - The coordinates 816277b739a6SMatthew Knepley . Nc - The number of components 8163a6e0b375SMatthew G. Knepley . u - The output field values 8164a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8165a6e0b375SMatthew G. Knepley 8166a6e0b375SMatthew G. Knepley Level: developer 8167a6e0b375SMatthew G. Knepley 8168bb7acecfSBarry Smith Developer Notes: 8169bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8170bb7acecfSBarry Smith 8171bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8172bb7acecfSBarry Smith 81731cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabelLocal()`, `DMComputeL2Diff()` 8174a6e0b375SMatthew G. Knepley @*/ 8175a4e35b19SJacob 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) 8176d71ae5a4SJacob Faibussowitsch { 81772c53366bSMatthew G. Knepley Vec localX; 81782c53366bSMatthew G. Knepley 81792c53366bSMatthew G. Knepley PetscFunctionBegin; 81802c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 81819566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 8182f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 81839566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 81849566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 81859566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 81869566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 81873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81882c53366bSMatthew G. Knepley } 81892c53366bSMatthew G. Knepley 8190a6e0b375SMatthew G. Knepley /*@C 8191bb7acecfSBarry 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. 8192a6e0b375SMatthew G. Knepley 819320f4b53cSBarry Smith Not Collective 8194a6e0b375SMatthew G. Knepley 8195a6e0b375SMatthew G. Knepley Input Parameters: 8196bb7acecfSBarry Smith + dm - The `DM` 8197a6e0b375SMatthew G. Knepley . time - The time 8198bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 8199a4e35b19SJacob Faibussowitsch . numIds - The number of ids 8200a4e35b19SJacob Faibussowitsch . ids - The ids 8201a4e35b19SJacob Faibussowitsch . Nc - The number of components 8202a4e35b19SJacob Faibussowitsch . comps - The components 8203a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 8204a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 8205a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8206a6e0b375SMatthew G. Knepley 8207a6e0b375SMatthew G. Knepley Output Parameter: 8208a6e0b375SMatthew G. Knepley . localX - vector 8209a6e0b375SMatthew G. Knepley 821020f4b53cSBarry Smith Calling sequence of `funcs`: 8211a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8212a4e35b19SJacob Faibussowitsch . time - The current time 8213a6e0b375SMatthew G. Knepley . x - The coordinates 821477b739a6SMatthew Knepley . Nc - The number of components 8215a6e0b375SMatthew G. Knepley . u - The output field values 8216a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 8217a6e0b375SMatthew G. Knepley 8218a6e0b375SMatthew G. Knepley Level: developer 8219a6e0b375SMatthew G. Knepley 8220bb7acecfSBarry Smith Developer Notes: 8221bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8222bb7acecfSBarry Smith 8223bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8224bb7acecfSBarry Smith 82251cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 8226a6e0b375SMatthew G. Knepley @*/ 8227a4e35b19SJacob 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) 8228d71ae5a4SJacob Faibussowitsch { 82294d6f44ffSToby Isaac PetscFunctionBegin; 82304d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8231064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8232fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfunctionlabellocal, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX); 82333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82344d6f44ffSToby Isaac } 82352716604bSToby Isaac 8236a6e0b375SMatthew G. Knepley /*@C 8237bb7acecfSBarry 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. 8238a6e0b375SMatthew G. Knepley 823920f4b53cSBarry Smith Not Collective 8240a6e0b375SMatthew G. Knepley 8241a6e0b375SMatthew G. Knepley Input Parameters: 8242bb7acecfSBarry Smith + dm - The `DM` 8243a6e0b375SMatthew G. Knepley . time - The time 824420f4b53cSBarry Smith . localU - The input field vector; may be `NULL` if projection is defined purely by coordinates 8245a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8246a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8247a6e0b375SMatthew G. Knepley 8248a6e0b375SMatthew G. Knepley Output Parameter: 8249a6e0b375SMatthew G. Knepley . localX - The output vector 8250a6e0b375SMatthew G. Knepley 825120f4b53cSBarry Smith Calling sequence of `funcs`: 8252a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8253a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8254a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8255a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8256a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8257a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8258a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8259a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8260a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8261a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8262a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8263a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8264a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8265a6e0b375SMatthew G. Knepley . t - The current time 8266a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8267a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8268a6e0b375SMatthew G. Knepley . constants - The value of each constant 8269a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8270a6e0b375SMatthew G. Knepley 827173ff1848SBarry Smith Level: intermediate 827273ff1848SBarry Smith 8273bb7acecfSBarry Smith Note: 8274bb7acecfSBarry 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. 8275bb7acecfSBarry 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 8276bb7acecfSBarry 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 8277a6e0b375SMatthew 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. 8278a6e0b375SMatthew G. Knepley 8279bb7acecfSBarry Smith Developer Notes: 8280bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8281bb7acecfSBarry Smith 8282bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8283bb7acecfSBarry Smith 8284a4e35b19SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, 8285a4e35b19SJacob Faibussowitsch `DMProjectFunction()`, `DMComputeL2Diff()` 8286a6e0b375SMatthew G. Knepley @*/ 8287a4e35b19SJacob 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) 8288d71ae5a4SJacob Faibussowitsch { 82898c6c5593SMatthew G. Knepley PetscFunctionBegin; 82908c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8291eb8f539aSJed Brown if (localU) PetscValidHeaderSpecific(localU, VEC_CLASSID, 3); 82928c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX, VEC_CLASSID, 6); 8293fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfieldlocal, time, localU, funcs, mode, localX); 82943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82958c6c5593SMatthew G. Knepley } 82968c6c5593SMatthew G. Knepley 8297a6e0b375SMatthew G. Knepley /*@C 8298a6e0b375SMatthew 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. 8299a6e0b375SMatthew G. Knepley 830020f4b53cSBarry Smith Not Collective 8301a6e0b375SMatthew G. Knepley 8302a6e0b375SMatthew G. Knepley Input Parameters: 8303bb7acecfSBarry Smith + dm - The `DM` 8304a6e0b375SMatthew G. Knepley . time - The time 8305bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8306a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8307a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8308bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 830920f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8310a6e0b375SMatthew G. Knepley . localU - The input field vector 8311a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8312a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8313a6e0b375SMatthew G. Knepley 8314a6e0b375SMatthew G. Knepley Output Parameter: 8315a6e0b375SMatthew G. Knepley . localX - The output vector 8316a6e0b375SMatthew G. Knepley 831720f4b53cSBarry Smith Calling sequence of `funcs`: 8318a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8319a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8320a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8321a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8322a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8323a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8324a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8325a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8326a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8327a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8328a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8329a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8330a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8331a6e0b375SMatthew G. Knepley . t - The current time 8332a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8333a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8334a6e0b375SMatthew G. Knepley . constants - The value of each constant 8335a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8336a6e0b375SMatthew G. Knepley 833773ff1848SBarry Smith Level: intermediate 833873ff1848SBarry Smith 8339bb7acecfSBarry Smith Note: 8340bb7acecfSBarry 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. 8341bb7acecfSBarry 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 8342bb7acecfSBarry 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 8343a6e0b375SMatthew 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. 8344a6e0b375SMatthew G. Knepley 8345bb7acecfSBarry Smith Developer Notes: 8346bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8347bb7acecfSBarry Smith 8348bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8349bb7acecfSBarry Smith 83501cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabel()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8351a6e0b375SMatthew G. Knepley @*/ 8352a4e35b19SJacob 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) 8353d71ae5a4SJacob Faibussowitsch { 83548c6c5593SMatthew G. Knepley PetscFunctionBegin; 83558c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8356064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8357064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8358fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectfieldlabellocal, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX); 83593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83608c6c5593SMatthew G. Knepley } 83618c6c5593SMatthew G. Knepley 83622716604bSToby Isaac /*@C 8363d29d7c6eSMatthew 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. 8364d29d7c6eSMatthew G. Knepley 836520f4b53cSBarry Smith Not Collective 8366d29d7c6eSMatthew G. Knepley 8367d29d7c6eSMatthew G. Knepley Input Parameters: 8368bb7acecfSBarry Smith + dm - The `DM` 8369d29d7c6eSMatthew G. Knepley . time - The time 8370bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8371d29d7c6eSMatthew G. Knepley . numIds - The number of label ids to use 8372d29d7c6eSMatthew G. Knepley . ids - The label ids to use for marking 8373bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 837420f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8375d29d7c6eSMatthew G. Knepley . U - The input field vector 8376d29d7c6eSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8377d29d7c6eSMatthew G. Knepley - mode - The insertion mode for values 8378d29d7c6eSMatthew G. Knepley 8379d29d7c6eSMatthew G. Knepley Output Parameter: 8380d29d7c6eSMatthew G. Knepley . X - The output vector 8381d29d7c6eSMatthew G. Knepley 838220f4b53cSBarry Smith Calling sequence of `funcs`: 8383d29d7c6eSMatthew G. Knepley + dim - The spatial dimension 8384d29d7c6eSMatthew G. Knepley . Nf - The number of input fields 8385d29d7c6eSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8386d29d7c6eSMatthew G. Knepley . uOff - The offset of each field in u[] 8387d29d7c6eSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8388d29d7c6eSMatthew G. Knepley . u - The field values at this point in space 8389d29d7c6eSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8390d29d7c6eSMatthew G. Knepley . u_x - The field derivatives at this point in space 8391d29d7c6eSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8392d29d7c6eSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8393d29d7c6eSMatthew G. Knepley . a - The auxiliary field values at this point in space 8394d29d7c6eSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8395d29d7c6eSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8396d29d7c6eSMatthew G. Knepley . t - The current time 8397d29d7c6eSMatthew G. Knepley . x - The coordinates of this point 8398d29d7c6eSMatthew G. Knepley . numConstants - The number of constants 8399d29d7c6eSMatthew G. Knepley . constants - The value of each constant 8400d29d7c6eSMatthew G. Knepley - f - The value of the function at this point in space 8401d29d7c6eSMatthew G. Knepley 840273ff1848SBarry Smith Level: intermediate 840373ff1848SBarry Smith 8404bb7acecfSBarry Smith 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 8408d29d7c6eSMatthew 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. 8409d29d7c6eSMatthew G. Knepley 8410bb7acecfSBarry Smith Developer Notes: 8411bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8412bb7acecfSBarry Smith 8413bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8414bb7acecfSBarry Smith 84151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8416d29d7c6eSMatthew G. Knepley @*/ 8417a4e35b19SJacob 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) 8418d71ae5a4SJacob Faibussowitsch { 8419d29d7c6eSMatthew G. Knepley DM dmIn; 8420d29d7c6eSMatthew G. Knepley Vec localU, localX; 8421d29d7c6eSMatthew G. Knepley 8422d29d7c6eSMatthew G. Knepley PetscFunctionBegin; 8423d29d7c6eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8424d29d7c6eSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn)); 8425d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dmIn, &localU)); 8426d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &localX)); 8427f60fa741SMatthew G. Knepley PetscCall(VecSet(localX, 0.)); 842872fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dmIn, U, mode, localU)); 842972fc1ce5SMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dmIn, U, mode, localU)); 8430d29d7c6eSMatthew G. Knepley PetscCall(DMProjectFieldLabelLocal(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8431d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 8432d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 8433d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &localX)); 8434d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dmIn, &localU)); 84353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8436d29d7c6eSMatthew G. Knepley } 8437d29d7c6eSMatthew G. Knepley 8438d29d7c6eSMatthew G. Knepley /*@C 8439ece3a9fcSMatthew 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. 8440ece3a9fcSMatthew G. Knepley 844120f4b53cSBarry Smith Not Collective 8442ece3a9fcSMatthew G. Knepley 8443ece3a9fcSMatthew G. Knepley Input Parameters: 8444bb7acecfSBarry Smith + dm - The `DM` 8445ece3a9fcSMatthew G. Knepley . time - The time 8446bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain boundary to output 8447ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8448ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8449bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 845020f4b53cSBarry Smith . comps - The components to set in the output, or `NULL` for all components 8451ece3a9fcSMatthew G. Knepley . localU - The input field vector 8452ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8453ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8454ece3a9fcSMatthew G. Knepley 8455ece3a9fcSMatthew G. Knepley Output Parameter: 8456ece3a9fcSMatthew G. Knepley . localX - The output vector 8457ece3a9fcSMatthew G. Knepley 845820f4b53cSBarry Smith Calling sequence of `funcs`: 8459ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8460ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8461ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8462ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8463ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8464ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8465ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8466ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8467ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8468ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8469ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8470ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8471ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8472ece3a9fcSMatthew G. Knepley . t - The current time 8473ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8474ece3a9fcSMatthew G. Knepley . n - The face normal 8475ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8476ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8477ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8478ece3a9fcSMatthew G. Knepley 847973ff1848SBarry Smith Level: intermediate 848073ff1848SBarry Smith 8481ece3a9fcSMatthew G. Knepley Note: 8482bb7acecfSBarry 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. 8483bb7acecfSBarry 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 8484bb7acecfSBarry 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 8485ece3a9fcSMatthew 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. 8486ece3a9fcSMatthew G. Knepley 8487bb7acecfSBarry Smith Developer Notes: 8488bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8489bb7acecfSBarry Smith 8490bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8491bb7acecfSBarry Smith 84921cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8493ece3a9fcSMatthew G. Knepley @*/ 8494a4e35b19SJacob 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) 8495d71ae5a4SJacob Faibussowitsch { 8496ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8497ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8498064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU, VEC_CLASSID, 8); 8499064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX, VEC_CLASSID, 11); 8500fa1e479aSStefano Zampini PetscUseTypeMethod(dm, projectbdfieldlabellocal, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX); 85013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8502ece3a9fcSMatthew G. Knepley } 8503ece3a9fcSMatthew G. Knepley 8504ece3a9fcSMatthew G. Knepley /*@C 85052716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 85062716604bSToby Isaac 850720f4b53cSBarry Smith Collective 8508bb7acecfSBarry Smith 85092716604bSToby Isaac Input Parameters: 8510bb7acecfSBarry Smith + dm - The `DM` 85110709b2feSToby Isaac . time - The time 85122716604bSToby Isaac . funcs - The functions to evaluate for each field component 85132716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8514574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 85152716604bSToby Isaac 85162716604bSToby Isaac Output Parameter: 85172716604bSToby Isaac . diff - The diff ||u - u_h||_2 85182716604bSToby Isaac 85192716604bSToby Isaac Level: developer 85202716604bSToby Isaac 8521bb7acecfSBarry Smith Developer Notes: 8522bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8523bb7acecfSBarry Smith 8524bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8525bb7acecfSBarry Smith 85261cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 85272716604bSToby Isaac @*/ 8528d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 8529d71ae5a4SJacob Faibussowitsch { 85302716604bSToby Isaac PetscFunctionBegin; 85312716604bSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8532b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8533fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2diff, time, funcs, ctxs, X, diff); 85343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85352716604bSToby Isaac } 8536b698f381SToby Isaac 8537b698f381SToby Isaac /*@C 8538b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8539b698f381SToby Isaac 854020f4b53cSBarry Smith Collective 8541d083f849SBarry Smith 8542b698f381SToby Isaac Input Parameters: 8543bb7acecfSBarry Smith + dm - The `DM` 8544a4e35b19SJacob Faibussowitsch . time - The time 8545b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8546b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8547574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8548b698f381SToby Isaac - n - The vector to project along 8549b698f381SToby Isaac 8550b698f381SToby Isaac Output Parameter: 8551b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8552b698f381SToby Isaac 8553b698f381SToby Isaac Level: developer 8554b698f381SToby Isaac 8555bb7acecfSBarry Smith Developer Notes: 8556bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8557bb7acecfSBarry Smith 8558bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8559bb7acecfSBarry Smith 85601cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2Diff()`, `DMComputeL2FieldDiff()` 8561b698f381SToby Isaac @*/ 8562d71ae5a4SJacob 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) 8563d71ae5a4SJacob Faibussowitsch { 8564b698f381SToby Isaac PetscFunctionBegin; 8565b698f381SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8566b698f381SToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8567fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2gradientdiff, time, funcs, ctxs, X, n, diff); 85683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8569b698f381SToby Isaac } 8570b698f381SToby Isaac 85712a16baeaSToby Isaac /*@C 85722a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 85732a16baeaSToby Isaac 857420f4b53cSBarry Smith Collective 8575d083f849SBarry Smith 85762a16baeaSToby Isaac Input Parameters: 8577bb7acecfSBarry Smith + dm - The `DM` 85782a16baeaSToby Isaac . time - The time 85792a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 85802a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8581574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 85822a16baeaSToby Isaac 85832a16baeaSToby Isaac Output Parameter: 85842a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 85852a16baeaSToby Isaac 85862a16baeaSToby Isaac Level: developer 85872a16baeaSToby Isaac 8588bb7acecfSBarry Smith Developer Notes: 8589bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8590bb7acecfSBarry Smith 8591bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8592bb7acecfSBarry Smith 859342747ad1SJacob Faibussowitsch .seealso: [](ch_dmbase), `DM`, `DMProjectFunction()`, `DMComputeL2GradientDiff()` 85942a16baeaSToby Isaac @*/ 8595d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 8596d71ae5a4SJacob Faibussowitsch { 85972a16baeaSToby Isaac PetscFunctionBegin; 85982a16baeaSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 85992a16baeaSToby Isaac PetscValidHeaderSpecific(X, VEC_CLASSID, 5); 8600fa1e479aSStefano Zampini PetscUseTypeMethod(dm, computel2fielddiff, time, funcs, ctxs, X, diff); 86013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86022a16baeaSToby Isaac } 86032a16baeaSToby Isaac 8604df0b854cSToby Isaac /*@C 8605bb7acecfSBarry Smith DMGetNeighbors - Gets an array containing the MPI ranks of all the processes neighbors 8606502a2867SDave May 8607502a2867SDave May Not Collective 8608502a2867SDave May 8609502a2867SDave May Input Parameter: 8610bb7acecfSBarry Smith . dm - The `DM` 8611502a2867SDave May 86120a19bb7dSprj- Output Parameters: 86130a19bb7dSprj- + nranks - the number of neighbours 86140a19bb7dSprj- - ranks - the neighbors ranks 8615502a2867SDave May 86169bdbcad8SBarry Smith Level: beginner 86179bdbcad8SBarry Smith 8618bb7acecfSBarry Smith Note: 8619bb7acecfSBarry Smith Do not free the array, it is freed when the `DM` is destroyed. 8620502a2867SDave May 86211cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDAGetNeighbors()`, `PetscSFGetRootRanks()` 8622502a2867SDave May @*/ 8623d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNeighbors(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[]) 8624d71ae5a4SJacob Faibussowitsch { 8625502a2867SDave May PetscFunctionBegin; 8626502a2867SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8627fa1e479aSStefano Zampini PetscUseTypeMethod(dm, getneighbors, nranks, ranks); 86283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8629502a2867SDave May } 8630502a2867SDave May 8631531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 8632531c7667SBarry Smith 8633531c7667SBarry Smith /* 8634531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 86352b6f951bSStefano Zampini This must be a different function because it requires DM which is not defined in the Mat library 8636531c7667SBarry Smith */ 863766976f2fSJacob Faibussowitsch static PetscErrorCode MatFDColoringApply_AIJDM(Mat J, MatFDColoring coloring, Vec x1, void *sctx) 8638d71ae5a4SJacob Faibussowitsch { 8639531c7667SBarry Smith PetscFunctionBegin; 8640531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8641531c7667SBarry Smith Vec x1local; 8642531c7667SBarry Smith DM dm; 86439566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 86447a8be351SBarry Smith PetscCheck(dm, PetscObjectComm((PetscObject)J), PETSC_ERR_ARG_INCOMP, "IS_COLORING_LOCAL requires a DM"); 86459566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &x1local)); 86469566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, x1, INSERT_VALUES, x1local)); 86479566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, x1, INSERT_VALUES, x1local)); 8648531c7667SBarry Smith x1 = x1local; 8649531c7667SBarry Smith } 86509566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply_AIJ(J, coloring, x1, sctx)); 8651531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8652531c7667SBarry Smith DM dm; 86539566063dSJacob Faibussowitsch PetscCall(MatGetDM(J, &dm)); 86549566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &x1)); 8655531c7667SBarry Smith } 86563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8657531c7667SBarry Smith } 8658531c7667SBarry Smith 8659531c7667SBarry Smith /*@ 8660bb7acecfSBarry Smith MatFDColoringUseDM - allows a `MatFDColoring` object to use the `DM` associated with the matrix to compute a `IS_COLORING_LOCAL` coloring 8661531c7667SBarry Smith 8662a4e35b19SJacob Faibussowitsch Input Parameters: 8663a4e35b19SJacob Faibussowitsch + coloring - The matrix to get the `DM` from 8664a4e35b19SJacob Faibussowitsch - fdcoloring - the `MatFDColoring` object 8665531c7667SBarry Smith 86669bdbcad8SBarry Smith Level: advanced 86679bdbcad8SBarry Smith 866873ff1848SBarry Smith Developer Note: 866973ff1848SBarry Smith This routine exists because the PETSc `Mat` library does not know about the `DM` objects 8670531c7667SBarry Smith 86711cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `MatFDColoring`, `MatFDColoringCreate()`, `ISColoringType` 8672531c7667SBarry Smith @*/ 8673d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFDColoringUseDM(Mat coloring, MatFDColoring fdcoloring) 8674d71ae5a4SJacob Faibussowitsch { 8675531c7667SBarry Smith PetscFunctionBegin; 8676531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 86773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8678531c7667SBarry Smith } 86798320bc6fSPatrick Sanan 86808320bc6fSPatrick Sanan /*@ 8681bb7acecfSBarry Smith DMGetCompatibility - determine if two `DM`s are compatible 86828320bc6fSPatrick Sanan 86838320bc6fSPatrick Sanan Collective 86848320bc6fSPatrick Sanan 86858320bc6fSPatrick Sanan Input Parameters: 8686bb7acecfSBarry Smith + dm1 - the first `DM` 8687bb7acecfSBarry Smith - dm2 - the second `DM` 86888320bc6fSPatrick Sanan 86898320bc6fSPatrick Sanan Output Parameters: 8690bb7acecfSBarry Smith + compatible - whether or not the two `DM`s are compatible 8691bb7acecfSBarry Smith - set - whether or not the compatible value was actually determined and set 86928320bc6fSPatrick Sanan 869320f4b53cSBarry Smith Level: advanced 869420f4b53cSBarry Smith 86958320bc6fSPatrick Sanan Notes: 8696bb7acecfSBarry Smith Two `DM`s are deemed compatible if they represent the same parallel decomposition 86973d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 86988320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 8699bb7acecfSBarry Smith Loosely speaking, compatible `DM`s represent the same domain and parallel 87003d862458SPatrick Sanan decomposition, but hold different data. 87018320bc6fSPatrick Sanan 87028320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 8703bb7acecfSBarry Smith over a pair of vectors obtained from different `DM`s. 87048320bc6fSPatrick Sanan 8705bb7acecfSBarry Smith For example, two `DMDA` objects are compatible if they have the same local 87068320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 87078320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 8708bb7acecfSBarry Smith either `DM` in bounds for a loop over vectors derived from either `DM`. 87098320bc6fSPatrick Sanan 8710bb7acecfSBarry Smith Consider the operation of summing data living on a 2-dof `DMDA` to data living 8711bb7acecfSBarry Smith on a 1-dof `DMDA`, which should be compatible, as in the following snippet. 87128320bc6fSPatrick Sanan .vb 87138320bc6fSPatrick Sanan ... 87149566063dSJacob Faibussowitsch PetscCall(DMGetCompatibility(da1,da2,&compatible,&set)); 87158320bc6fSPatrick Sanan if (set && compatible) { 87169566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1)); 87179566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2)); 87189566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL)); 87198320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 87208320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 87218320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 87228320bc6fSPatrick Sanan } 87238320bc6fSPatrick Sanan } 87249566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1)); 87259566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2)); 87268320bc6fSPatrick Sanan } else { 87278320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 87288320bc6fSPatrick Sanan } 87298320bc6fSPatrick Sanan ... 87308320bc6fSPatrick Sanan .ve 87318320bc6fSPatrick Sanan 8732bb7acecfSBarry Smith Checking compatibility might be expensive for a given implementation of `DM`, 87338320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 87348320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 87358320bc6fSPatrick Sanan always check the "set" output parameter. 87368320bc6fSPatrick Sanan 8737bb7acecfSBarry Smith A `DM` is always compatible with itself. 87388320bc6fSPatrick Sanan 8739bb7acecfSBarry Smith In the current implementation, `DM`s which live on "unequal" communicators 87408320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 87418320bc6fSPatrick Sanan incompatible. 87428320bc6fSPatrick Sanan 87438320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 8744bb7acecfSBarry Smith is required on each rank. However, in `DM` implementations which store all this 87458320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 87468320bc6fSPatrick Sanan 874773ff1848SBarry Smith Developer Note: 8748bb7acecfSBarry Smith Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B 87493d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 8750a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 8751bb7acecfSBarry Smith compatibility. It is left to `DM` implementers to ensure that symmetry is 87528320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 87533d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 8754bb7acecfSBarry Smith of other `DM` types and let *set = PETSC_FALSE if found. 87558320bc6fSPatrick Sanan 87561cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()` 87578320bc6fSPatrick Sanan @*/ 8758d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetCompatibility(DM dm1, DM dm2, PetscBool *compatible, PetscBool *set) 8759d71ae5a4SJacob Faibussowitsch { 87608320bc6fSPatrick Sanan PetscMPIInt compareResult; 87618320bc6fSPatrick Sanan DMType type, type2; 87628320bc6fSPatrick Sanan PetscBool sameType; 87638320bc6fSPatrick Sanan 87648320bc6fSPatrick Sanan PetscFunctionBegin; 8765a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 87668320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 87678320bc6fSPatrick Sanan 87688320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 8769a5bc1bf3SBarry Smith if (dm1 == dm2) { 87708320bc6fSPatrick Sanan *set = PETSC_TRUE; 87718320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 87723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 87738320bc6fSPatrick Sanan } 87748320bc6fSPatrick Sanan 87758320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 87768320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 87778320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 87788320bc6fSPatrick Sanan determined by the implementation-specific logic */ 87799566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)dm1), PetscObjectComm((PetscObject)dm2), &compareResult)); 87808320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 87818320bc6fSPatrick Sanan *set = PETSC_TRUE; 87828320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 87833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 87848320bc6fSPatrick Sanan } 87858320bc6fSPatrick Sanan 87868320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 8787a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 8788dbbe0bcdSBarry Smith PetscUseTypeMethod(dm1, getcompatibility, dm2, compatible, set); 87893ba16761SJacob Faibussowitsch if (*set) PetscFunctionReturn(PETSC_SUCCESS); 87908320bc6fSPatrick Sanan } 87918320bc6fSPatrick Sanan 8792a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 87938320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 87949566063dSJacob Faibussowitsch PetscCall(DMGetType(dm1, &type)); 87959566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2, &type2)); 87969566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type, type2, &sameType)); 87978320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 8798dbbe0bcdSBarry Smith PetscUseTypeMethod(dm2, getcompatibility, dm1, compatible, set); /* Note argument order */ 87998320bc6fSPatrick Sanan } else { 88008320bc6fSPatrick Sanan *set = PETSC_FALSE; 88018320bc6fSPatrick Sanan } 88023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 88038320bc6fSPatrick Sanan } 8804c0f0dcc3SMatthew G. Knepley 8805c0f0dcc3SMatthew G. Knepley /*@C 8806bb7acecfSBarry Smith DMMonitorSet - Sets an additional monitor function that is to be used after a solve to monitor discretization performance. 8807c0f0dcc3SMatthew G. Knepley 880820f4b53cSBarry Smith Logically Collective 8809c0f0dcc3SMatthew G. Knepley 8810c0f0dcc3SMatthew G. Knepley Input Parameters: 881160225df5SJacob Faibussowitsch + dm - the `DM` 8812c0f0dcc3SMatthew G. Knepley . f - the monitor function 881320f4b53cSBarry Smith . mctx - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired) 881420f4b53cSBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`) 8815c0f0dcc3SMatthew G. Knepley 881620f4b53cSBarry Smith Options Database Key: 881760225df5SJacob Faibussowitsch . -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `DMMonitorSet()`, but 8818c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 8819c0f0dcc3SMatthew G. Knepley 88209bdbcad8SBarry Smith Level: intermediate 88219bdbcad8SBarry Smith 8822bb7acecfSBarry Smith Note: 8823c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 8824bb7acecfSBarry Smith `DMMonitorSet()` multiple times or with `DMMonitorSetFromOptions()`; all will be called in the 8825c0f0dcc3SMatthew G. Knepley order in which they were set. 8826c0f0dcc3SMatthew G. Knepley 882773ff1848SBarry Smith Fortran Note: 8828bb7acecfSBarry Smith Only a single monitor function can be set for each `DM` object 8829bb7acecfSBarry Smith 883073ff1848SBarry Smith Developer Note: 8831bb7acecfSBarry Smith This API has a generic name but seems specific to a very particular aspect of the use of `DM` 8832c0f0dcc3SMatthew G. Knepley 88331cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorCancel()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8834c0f0dcc3SMatthew G. Knepley @*/ 8835d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 8836d71ae5a4SJacob Faibussowitsch { 8837c0f0dcc3SMatthew G. Knepley PetscInt m; 8838c0f0dcc3SMatthew G. Knepley 8839c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8840c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8841c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 8842c0f0dcc3SMatthew G. Knepley PetscBool identical; 8843c0f0dcc3SMatthew G. Knepley 88449566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical)); 88453ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 8846c0f0dcc3SMatthew G. Knepley } 88477a8be351SBarry Smith PetscCheck(dm->numbermonitors < MAXDMMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 8848c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 8849c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 8850c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *)mctx; 88513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8852c0f0dcc3SMatthew G. Knepley } 8853c0f0dcc3SMatthew G. Knepley 8854c0f0dcc3SMatthew G. Knepley /*@ 8855bb7acecfSBarry Smith DMMonitorCancel - Clears all the monitor functions for a `DM` object. 8856c0f0dcc3SMatthew G. Knepley 885720f4b53cSBarry Smith Logically Collective 8858c0f0dcc3SMatthew G. Knepley 8859c0f0dcc3SMatthew G. Knepley Input Parameter: 8860c0f0dcc3SMatthew G. Knepley . dm - the DM 8861c0f0dcc3SMatthew G. Knepley 8862c0f0dcc3SMatthew G. Knepley Options Database Key: 8863c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 8864bb7acecfSBarry Smith into a code by calls to `DMonitorSet()`, but does not cancel those 8865c0f0dcc3SMatthew G. Knepley set via the options database 8866c0f0dcc3SMatthew G. Knepley 88679bdbcad8SBarry Smith Level: intermediate 88689bdbcad8SBarry Smith 8869bb7acecfSBarry Smith Note: 8870bb7acecfSBarry Smith There is no way to clear one specific monitor from a `DM` object. 8871c0f0dcc3SMatthew G. Knepley 88721cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8873c0f0dcc3SMatthew G. Knepley @*/ 8874d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorCancel(DM dm) 8875d71ae5a4SJacob Faibussowitsch { 8876c0f0dcc3SMatthew G. Knepley PetscInt m; 8877c0f0dcc3SMatthew G. Knepley 8878c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8879c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8880c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 88819566063dSJacob Faibussowitsch if (dm->monitordestroy[m]) PetscCall((*dm->monitordestroy[m])(&dm->monitorcontext[m])); 8882c0f0dcc3SMatthew G. Knepley } 8883c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 88843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8885c0f0dcc3SMatthew G. Knepley } 8886c0f0dcc3SMatthew G. Knepley 8887c0f0dcc3SMatthew G. Knepley /*@C 8888c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 8889c0f0dcc3SMatthew G. Knepley 889020f4b53cSBarry Smith Collective 8891c0f0dcc3SMatthew G. Knepley 8892c0f0dcc3SMatthew G. Knepley Input Parameters: 8893bb7acecfSBarry Smith + dm - `DM` object you wish to monitor 8894c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 8895c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 8896c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 8897c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 8898bb7acecfSBarry 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 8899c0f0dcc3SMatthew G. Knepley 8900c0f0dcc3SMatthew G. Knepley Output Parameter: 8901c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 8902c0f0dcc3SMatthew G. Knepley 8903c0f0dcc3SMatthew G. Knepley Level: developer 8904c0f0dcc3SMatthew G. Knepley 89051cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 8906db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 890760225df5SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 8908db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 8909c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 8910db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 8911bb7acecfSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `DMMonitor()`, `DMMonitorSet()` 8912c0f0dcc3SMatthew G. Knepley @*/ 8913d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 8914d71ae5a4SJacob Faibussowitsch { 8915c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 8916c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 8917c0f0dcc3SMatthew G. Knepley 8918c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8919c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89209566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)dm), ((PetscObject)dm)->options, ((PetscObject)dm)->prefix, name, &viewer, &format, flg)); 8921c0f0dcc3SMatthew G. Knepley if (*flg) { 8922c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 8923c0f0dcc3SMatthew G. Knepley 89249566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 8925cd791dc2SBarry Smith PetscCall(PetscOptionsRestoreViewer(&viewer)); 89269566063dSJacob Faibussowitsch if (monitorsetup) PetscCall((*monitorsetup)(dm, vf)); 89279566063dSJacob Faibussowitsch PetscCall(DMMonitorSet(dm, (PetscErrorCode(*)(DM, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 8928c0f0dcc3SMatthew G. Knepley } 89293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8930c0f0dcc3SMatthew G. Knepley } 8931c0f0dcc3SMatthew G. Knepley 8932c0f0dcc3SMatthew G. Knepley /*@ 8933c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 8934c0f0dcc3SMatthew G. Knepley 893520f4b53cSBarry Smith Collective 8936c0f0dcc3SMatthew G. Knepley 89372fe279fdSBarry Smith Input Parameter: 8938bb7acecfSBarry Smith . dm - The `DM` 8939c0f0dcc3SMatthew G. Knepley 8940c0f0dcc3SMatthew G. Knepley Level: developer 8941c0f0dcc3SMatthew G. Knepley 894273ff1848SBarry Smith Developer Note: 8943a4e35b19SJacob Faibussowitsch Note should indicate when during the life of the `DM` the monitor is run. It appears to be 8944a4e35b19SJacob Faibussowitsch related to the discretization process seems rather specialized since some `DM` have no 8945a4e35b19SJacob Faibussowitsch concept of discretization. 8946bb7acecfSBarry Smith 89471cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMMonitorSetFromOptions()` 8948c0f0dcc3SMatthew G. Knepley @*/ 8949d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMonitor(DM dm) 8950d71ae5a4SJacob Faibussowitsch { 8951c0f0dcc3SMatthew G. Knepley PetscInt m; 8952c0f0dcc3SMatthew G. Knepley 8953c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 89543ba16761SJacob Faibussowitsch if (!dm) PetscFunctionReturn(PETSC_SUCCESS); 8955c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 895648a46eb9SPierre Jolivet for (m = 0; m < dm->numbermonitors; ++m) PetscCall((*dm->monitor[m])(dm, dm->monitorcontext[m])); 89573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8958c0f0dcc3SMatthew G. Knepley } 89592e4af2aeSMatthew G. Knepley 89602e4af2aeSMatthew G. Knepley /*@ 8961bb7acecfSBarry Smith DMComputeError - Computes the error assuming the user has provided the exact solution functions 89622e4af2aeSMatthew G. Knepley 896320f4b53cSBarry Smith Collective 89642e4af2aeSMatthew G. Knepley 89652e4af2aeSMatthew G. Knepley Input Parameters: 8966bb7acecfSBarry Smith + dm - The `DM` 89676b867d5aSJose E. Roman - sol - The solution vector 89682e4af2aeSMatthew G. Knepley 89696b867d5aSJose E. Roman Input/Output Parameter: 897020f4b53cSBarry Smith . errors - An array of length Nf, the number of fields, or `NULL` for no output; on output 89716b867d5aSJose E. Roman contains the error in each field 89726b867d5aSJose E. Roman 89736b867d5aSJose E. Roman Output Parameter: 897420f4b53cSBarry Smith . errorVec - A vector to hold the cellwise error (may be `NULL`) 897520f4b53cSBarry Smith 897620f4b53cSBarry Smith Level: developer 89772e4af2aeSMatthew G. Knepley 8978bb7acecfSBarry Smith Note: 8979bb7acecfSBarry Smith The exact solutions come from the `PetscDS` object, and the time comes from `DMGetOutputSequenceNumber()`. 89802e4af2aeSMatthew G. Knepley 89811cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMMonitorSet()`, `DMGetRegionNumDS()`, `PetscDSGetExactSolution()`, `DMGetOutputSequenceNumber()` 89822e4af2aeSMatthew G. Knepley @*/ 8983d71ae5a4SJacob Faibussowitsch PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 8984d71ae5a4SJacob Faibussowitsch { 89852e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 89862e4af2aeSMatthew G. Knepley void **ctxs; 89872e4af2aeSMatthew G. Knepley PetscReal time; 89882e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 89892e4af2aeSMatthew G. Knepley 89902e4af2aeSMatthew G. Knepley PetscFunctionBegin; 89919566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 89929566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nf, &exactSol, Nf, &ctxs)); 89939566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 89942e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 89952e4af2aeSMatthew G. Knepley PetscDS ds; 89962e4af2aeSMatthew G. Knepley DMLabel label; 89972e4af2aeSMatthew G. Knepley IS fieldIS; 89982e4af2aeSMatthew G. Knepley const PetscInt *fields; 89992e4af2aeSMatthew G. Knepley PetscInt dsNf; 90002e4af2aeSMatthew G. Knepley 900107218a29SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds, NULL)); 90029566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 90039566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISGetIndices(fieldIS, &fields)); 90042e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 90052e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 90069566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field])); 90072e4af2aeSMatthew G. Knepley } 90089566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISRestoreIndices(fieldIS, &fields)); 90092e4af2aeSMatthew G. Knepley } 9010ad540459SPierre 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); 90119566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, NULL, &time)); 90129566063dSJacob Faibussowitsch if (errors) PetscCall(DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors)); 90132e4af2aeSMatthew G. Knepley if (errorVec) { 90142e4af2aeSMatthew G. Knepley DM edm; 90152e4af2aeSMatthew G. Knepley DMPolytopeType ct; 90162e4af2aeSMatthew G. Knepley PetscBool simplex; 90172e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 90182e4af2aeSMatthew G. Knepley 90199566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &edm)); 90209566063dSJacob Faibussowitsch PetscCall(DMGetDimension(edm, &dim)); 90219566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 90229566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 90232e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 90249566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 90252e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 90262e4af2aeSMatthew G. Knepley PetscFE fe, efe; 90272e4af2aeSMatthew G. Knepley PetscQuadrature q; 90282e4af2aeSMatthew G. Knepley const char *name; 90292e4af2aeSMatthew G. Knepley 90309566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, (PetscObject *)&fe)); 90319566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe)); 90329566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)fe, &name)); 90339566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)efe, name)); 90349566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 90359566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(efe, q)); 90369566063dSJacob Faibussowitsch PetscCall(DMSetField(edm, f, NULL, (PetscObject)efe)); 90379566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&efe)); 90382e4af2aeSMatthew G. Knepley } 90399566063dSJacob Faibussowitsch PetscCall(DMCreateDS(edm)); 90402e4af2aeSMatthew G. Knepley 90419566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(edm, errorVec)); 90429566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*errorVec, "Error")); 90439566063dSJacob Faibussowitsch PetscCall(DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec)); 90449566063dSJacob Faibussowitsch PetscCall(DMDestroy(&edm)); 90452e4af2aeSMatthew G. Knepley } 90469566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, ctxs)); 90473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 90482e4af2aeSMatthew G. Knepley } 90499a2a23afSMatthew G. Knepley 90509a2a23afSMatthew G. Knepley /*@ 9051bb7acecfSBarry Smith DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this `DM` 90529a2a23afSMatthew G. Knepley 905320f4b53cSBarry Smith Not Collective 90549a2a23afSMatthew G. Knepley 90559a2a23afSMatthew G. Knepley Input Parameter: 9056bb7acecfSBarry Smith . dm - The `DM` 90579a2a23afSMatthew G. Knepley 90589a2a23afSMatthew G. Knepley Output Parameter: 9059a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 90609a2a23afSMatthew G. Knepley 90619a2a23afSMatthew G. Knepley Level: advanced 90629a2a23afSMatthew G. Knepley 9063e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMGetAuxiliaryVec()` 90649a2a23afSMatthew G. Knepley @*/ 9065d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 9066d71ae5a4SJacob Faibussowitsch { 90679a2a23afSMatthew G. Knepley PetscFunctionBegin; 90689a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90699566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize(dm->auxData, numAux)); 90703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 90719a2a23afSMatthew G. Knepley } 90729a2a23afSMatthew G. Knepley 90739a2a23afSMatthew G. Knepley /*@ 9074ac17215fSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value, and equation part 90759a2a23afSMatthew G. Knepley 907620f4b53cSBarry Smith Not Collective 90779a2a23afSMatthew G. Knepley 90789a2a23afSMatthew G. Knepley Input Parameters: 9079bb7acecfSBarry Smith + dm - The `DM` 9080bb7acecfSBarry Smith . label - The `DMLabel` 9081ac17215fSMatthew G. Knepley . value - The label value indicating the region 9082ac17215fSMatthew G. Knepley - part - The equation part, or 0 if unused 90839a2a23afSMatthew G. Knepley 90849a2a23afSMatthew G. Knepley Output Parameter: 9085bb7acecfSBarry Smith . aux - The `Vec` holding auxiliary field data 90869a2a23afSMatthew G. Knepley 90879bdbcad8SBarry Smith Level: advanced 90889bdbcad8SBarry Smith 9089bb7acecfSBarry Smith Note: 9090bb7acecfSBarry Smith If no auxiliary vector is found for this (label, value), (NULL, 0, 0) is checked as well. 909104c51a94SMatthew G. Knepley 9092e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryLabels()` 90939a2a23afSMatthew G. Knepley @*/ 9094d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec *aux) 9095d71ae5a4SJacob Faibussowitsch { 9096ac17215fSMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0, 0}; 909704c51a94SMatthew G. Knepley PetscBool has; 90989a2a23afSMatthew G. Knepley 90999a2a23afSMatthew G. Knepley PetscFunctionBegin; 91009a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 91019a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 91029a2a23afSMatthew G. Knepley key.label = label; 91039a2a23afSMatthew G. Knepley key.value = value; 9104ac17215fSMatthew G. Knepley key.part = part; 91059566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxHas(dm->auxData, key, &has)); 91069566063dSJacob Faibussowitsch if (has) PetscCall(PetscHMapAuxGet(dm->auxData, key, aux)); 91079566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxGet(dm->auxData, wild, aux)); 91083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91099a2a23afSMatthew G. Knepley } 91109a2a23afSMatthew G. Knepley 91119a2a23afSMatthew G. Knepley /*@ 9112bb7acecfSBarry Smith DMSetAuxiliaryVec - Set an auxiliary vector for region specified by the given label and value, and equation part 91139a2a23afSMatthew G. Knepley 911420f4b53cSBarry Smith Not Collective because auxiliary vectors are not parallel 91159a2a23afSMatthew G. Knepley 91169a2a23afSMatthew G. Knepley Input Parameters: 9117bb7acecfSBarry Smith + dm - The `DM` 9118bb7acecfSBarry Smith . label - The `DMLabel` 91199a2a23afSMatthew G. Knepley . value - The label value indicating the region 9120ac17215fSMatthew G. Knepley . part - The equation part, or 0 if unused 9121bb7acecfSBarry Smith - aux - The `Vec` holding auxiliary field data 91229a2a23afSMatthew G. Knepley 91239a2a23afSMatthew G. Knepley Level: advanced 91249a2a23afSMatthew G. Knepley 9125e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMCopyAuxiliaryVec()` 91269a2a23afSMatthew G. Knepley @*/ 9127d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec aux) 9128d71ae5a4SJacob Faibussowitsch { 91299a2a23afSMatthew G. Knepley Vec old; 91309a2a23afSMatthew G. Knepley PetscHashAuxKey key; 91319a2a23afSMatthew G. Knepley 91329a2a23afSMatthew G. Knepley PetscFunctionBegin; 91339a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 91349a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 91359a2a23afSMatthew G. Knepley key.label = label; 91369a2a23afSMatthew G. Knepley key.value = value; 9137ac17215fSMatthew G. Knepley key.part = part; 91389566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGet(dm->auxData, key, &old)); 91399566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)aux)); 91409566063dSJacob Faibussowitsch if (!aux) PetscCall(PetscHMapAuxDel(dm->auxData, key)); 91419566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxSet(dm->auxData, key, aux)); 9142d705d0eaSStefano Zampini PetscCall(VecDestroy(&old)); 91433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91449a2a23afSMatthew G. Knepley } 91459a2a23afSMatthew G. Knepley 91469a2a23afSMatthew G. Knepley /*@C 9147bb7acecfSBarry Smith DMGetAuxiliaryLabels - Get the labels, values, and parts for all auxiliary vectors in this `DM` 91489a2a23afSMatthew G. Knepley 914920f4b53cSBarry Smith Not Collective 91509a2a23afSMatthew G. Knepley 91519a2a23afSMatthew G. Knepley Input Parameter: 9152bb7acecfSBarry Smith . dm - The `DM` 91539a2a23afSMatthew G. Knepley 91549a2a23afSMatthew G. Knepley Output Parameters: 9155bb7acecfSBarry Smith + labels - The `DMLabel`s for each `Vec` 9156bb7acecfSBarry Smith . values - The label values for each `Vec` 9157bb7acecfSBarry Smith - parts - The equation parts for each `Vec` 91589a2a23afSMatthew G. Knepley 91599bdbcad8SBarry Smith Level: advanced 91609bdbcad8SBarry Smith 9161bb7acecfSBarry Smith Note: 9162bb7acecfSBarry Smith The arrays passed in must be at least as large as `DMGetNumAuxiliaryVec()`. 91639a2a23afSMatthew G. Knepley 9164e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()`, `DMCopyAuxiliaryVec()` 91659a2a23afSMatthew G. Knepley @*/ 9166d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[], PetscInt parts[]) 9167d71ae5a4SJacob Faibussowitsch { 91689a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 91699a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 91709a2a23afSMatthew G. Knepley 91719a2a23afSMatthew G. Knepley PetscFunctionBegin; 91729a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 91734f572ea9SToby Isaac PetscAssertPointer(labels, 2); 91744f572ea9SToby Isaac PetscAssertPointer(values, 3); 91754f572ea9SToby Isaac PetscAssertPointer(parts, 4); 91769566063dSJacob Faibussowitsch PetscCall(DMGetNumAuxiliaryVec(dm, &n)); 91779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &keys)); 91789566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetKeys(dm->auxData, &off, keys)); 91799371c9d4SSatish Balay for (i = 0; i < n; ++i) { 91809371c9d4SSatish Balay labels[i] = keys[i].label; 91819371c9d4SSatish Balay values[i] = keys[i].value; 91829371c9d4SSatish Balay parts[i] = keys[i].part; 91839371c9d4SSatish Balay } 91849566063dSJacob Faibussowitsch PetscCall(PetscFree(keys)); 91853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91869a2a23afSMatthew G. Knepley } 91879a2a23afSMatthew G. Knepley 91889a2a23afSMatthew G. Knepley /*@ 9189bb7acecfSBarry Smith DMCopyAuxiliaryVec - Copy the auxiliary vector data on a `DM` to a new `DM` 91909a2a23afSMatthew G. Knepley 919120f4b53cSBarry Smith Not Collective 91929a2a23afSMatthew G. Knepley 91939a2a23afSMatthew G. Knepley Input Parameter: 9194bb7acecfSBarry Smith . dm - The `DM` 91959a2a23afSMatthew G. Knepley 91969a2a23afSMatthew G. Knepley Output Parameter: 9197bb7acecfSBarry Smith . dmNew - The new `DM`, now with the same auxiliary data 91989a2a23afSMatthew G. Knepley 91999a2a23afSMatthew G. Knepley Level: advanced 92009a2a23afSMatthew G. Knepley 9201bb7acecfSBarry Smith Note: 9202bb7acecfSBarry Smith This is a shallow copy of the auxiliary vectors 9203bb7acecfSBarry Smith 9204e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMClearAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 92059a2a23afSMatthew G. Knepley @*/ 9206d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 9207d71ae5a4SJacob Faibussowitsch { 92089a2a23afSMatthew G. Knepley PetscFunctionBegin; 92099a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9210d705d0eaSStefano Zampini PetscValidHeaderSpecific(dmNew, DM_CLASSID, 2); 9211d705d0eaSStefano Zampini if (dm == dmNew) PetscFunctionReturn(PETSC_SUCCESS); 9212e4d5475eSStefano Zampini PetscCall(DMClearAuxiliaryVec(dmNew)); 9213e4d5475eSStefano Zampini 9214e4d5475eSStefano Zampini PetscCall(PetscHMapAuxDestroy(&dmNew->auxData)); 92159566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData)); 9216d705d0eaSStefano Zampini { 9217d705d0eaSStefano Zampini Vec *auxData; 9218d705d0eaSStefano Zampini PetscInt n, i, off = 0; 9219d705d0eaSStefano Zampini 9220d705d0eaSStefano Zampini PetscCall(PetscHMapAuxGetSize(dmNew->auxData, &n)); 9221d705d0eaSStefano Zampini PetscCall(PetscMalloc1(n, &auxData)); 9222d705d0eaSStefano Zampini PetscCall(PetscHMapAuxGetVals(dmNew->auxData, &off, auxData)); 9223d705d0eaSStefano Zampini for (i = 0; i < n; ++i) PetscCall(PetscObjectReference((PetscObject)auxData[i])); 9224d705d0eaSStefano Zampini PetscCall(PetscFree(auxData)); 9225e4d5475eSStefano Zampini } 9226e4d5475eSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 9227e4d5475eSStefano Zampini } 9228e4d5475eSStefano Zampini 9229e4d5475eSStefano Zampini /*@ 9230e4d5475eSStefano Zampini DMClearAuxiliaryVec - Destroys the auxiliary vector information and creates a new empty one 9231e4d5475eSStefano Zampini 9232e4d5475eSStefano Zampini Not Collective 9233e4d5475eSStefano Zampini 9234e4d5475eSStefano Zampini Input Parameter: 9235e4d5475eSStefano Zampini . dm - The `DM` 9236e4d5475eSStefano Zampini 9237e4d5475eSStefano Zampini Level: advanced 9238e4d5475eSStefano Zampini 9239e4d5475eSStefano Zampini .seealso: [](ch_dmbase), `DM`, `DMCopyAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 9240e4d5475eSStefano Zampini @*/ 9241e4d5475eSStefano Zampini PetscErrorCode DMClearAuxiliaryVec(DM dm) 9242e4d5475eSStefano Zampini { 9243e4d5475eSStefano Zampini Vec *auxData; 9244e4d5475eSStefano Zampini PetscInt n, i, off = 0; 9245e4d5475eSStefano Zampini 9246e4d5475eSStefano Zampini PetscFunctionBegin; 9247e4d5475eSStefano Zampini PetscCall(PetscHMapAuxGetSize(dm->auxData, &n)); 9248d705d0eaSStefano Zampini PetscCall(PetscMalloc1(n, &auxData)); 9249e4d5475eSStefano Zampini PetscCall(PetscHMapAuxGetVals(dm->auxData, &off, auxData)); 9250d705d0eaSStefano Zampini for (i = 0; i < n; ++i) PetscCall(VecDestroy(&auxData[i])); 9251d705d0eaSStefano Zampini PetscCall(PetscFree(auxData)); 9252e4d5475eSStefano Zampini PetscCall(PetscHMapAuxDestroy(&dm->auxData)); 9253e4d5475eSStefano Zampini PetscCall(PetscHMapAuxCreate(&dm->auxData)); 92543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92559a2a23afSMatthew G. Knepley } 9256b5a892a1SMatthew G. Knepley 9257b5a892a1SMatthew G. Knepley /*@C 9258bb7acecfSBarry Smith DMPolytopeMatchOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9259b5a892a1SMatthew G. Knepley 926020f4b53cSBarry Smith Not Collective 9261b5a892a1SMatthew G. Knepley 9262b5a892a1SMatthew G. Knepley Input Parameters: 9263bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9264b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9265b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9266b5a892a1SMatthew G. Knepley 9267b5a892a1SMatthew G. Knepley Output Parameters: 9268bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9269b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9270b5a892a1SMatthew G. Knepley 9271b5a892a1SMatthew G. Knepley Level: advanced 9272b5a892a1SMatthew G. Knepley 9273bb7acecfSBarry Smith Note: 9274bb7acecfSBarry Smith An arrangement is a face order combined with an orientation for each face 9275bb7acecfSBarry Smith 927685036b15SMatthew G. Knepley Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangements(ct)`/2 to `DMPolytopeTypeGetNumArrangements(ct)`/2 9277bb7acecfSBarry Smith that labels each arrangement (face ordering plus orientation for each face). 9278bb7acecfSBarry Smith 9279bb7acecfSBarry Smith See `DMPolytopeMatchVertexOrientation()` to find a new vertex orientation that takes the source vertex arrangement to the target vertex arrangement 9280bb7acecfSBarry Smith 92811cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetVertexOrientation()` 9282b5a892a1SMatthew G. Knepley @*/ 9283d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9284d71ae5a4SJacob Faibussowitsch { 9285b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 928685036b15SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangements(ct) / 2; 9287b5a892a1SMatthew G. Knepley PetscInt o, c; 9288b5a892a1SMatthew G. Knepley 9289b5a892a1SMatthew G. Knepley PetscFunctionBegin; 92909371c9d4SSatish Balay if (!nO) { 92919371c9d4SSatish Balay *ornt = 0; 92929371c9d4SSatish Balay *found = PETSC_TRUE; 92933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92949371c9d4SSatish Balay } 9295b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 929685036b15SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangement(ct, o); 9297b5a892a1SMatthew G. Knepley 92989371c9d4SSatish Balay for (c = 0; c < cS; ++c) 92999371c9d4SSatish Balay if (sourceCone[arr[c * 2]] != targetCone[c]) break; 93009371c9d4SSatish Balay if (c == cS) { 93019371c9d4SSatish Balay *ornt = o; 93029371c9d4SSatish Balay break; 93039371c9d4SSatish Balay } 9304b5a892a1SMatthew G. Knepley } 9305b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 93063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9307b5a892a1SMatthew G. Knepley } 9308b5a892a1SMatthew G. Knepley 9309b5a892a1SMatthew G. Knepley /*@C 9310bb7acecfSBarry Smith DMPolytopeGetOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9311b5a892a1SMatthew G. Knepley 931220f4b53cSBarry Smith Not Collective 9313b5a892a1SMatthew G. Knepley 9314b5a892a1SMatthew G. Knepley Input Parameters: 9315bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9316b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9317b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9318b5a892a1SMatthew G. Knepley 93192fe279fdSBarry Smith Output Parameter: 9320bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9321b5a892a1SMatthew G. Knepley 9322b5a892a1SMatthew G. Knepley Level: advanced 9323b5a892a1SMatthew G. Knepley 9324bb7acecfSBarry Smith Note: 9325bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchOrientation()` except it will generate an error if no suitable orientation can be found. 9326bb7acecfSBarry Smith 932773ff1848SBarry Smith Developer Note: 9328bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchOrientation()` and error if none is found 9329bb7acecfSBarry Smith 93301cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchOrientation()`, `DMPolytopeGetVertexOrientation()`, `DMPolytopeMatchVertexOrientation()` 9331b5a892a1SMatthew G. Knepley @*/ 9332d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9333d71ae5a4SJacob Faibussowitsch { 9334b5a892a1SMatthew G. Knepley PetscBool found; 9335b5a892a1SMatthew G. Knepley 9336b5a892a1SMatthew G. Knepley PetscFunctionBegin; 93379566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found)); 93387a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 93393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9340b5a892a1SMatthew G. Knepley } 9341b5a892a1SMatthew G. Knepley 9342b5a892a1SMatthew G. Knepley /*@C 9343bb7acecfSBarry Smith DMPolytopeMatchVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9344b5a892a1SMatthew G. Knepley 934520f4b53cSBarry Smith Not Collective 9346b5a892a1SMatthew G. Knepley 9347b5a892a1SMatthew G. Knepley Input Parameters: 9348bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9349b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 9350b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 9351b5a892a1SMatthew G. Knepley 9352b5a892a1SMatthew G. Knepley Output Parameters: 9353bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9354b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9355b5a892a1SMatthew G. Knepley 9356b5a892a1SMatthew G. Knepley Level: advanced 9357b5a892a1SMatthew G. Knepley 935873ff1848SBarry Smith Notes: 9359bb7acecfSBarry Smith An arrangement is a vertex order 9360bb7acecfSBarry Smith 936185036b15SMatthew G. Knepley Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangements(ct)`/2 to `DMPolytopeTypeGetNumArrangements(ct)`/2 9362bb7acecfSBarry Smith that labels each arrangement (vertex ordering). 9363bb7acecfSBarry Smith 9364bb7acecfSBarry Smith See `DMPolytopeMatchOrientation()` to find a new face orientation that takes the source face arrangement to the target face arrangement 9365bb7acecfSBarry Smith 936685036b15SMatthew G. Knepley .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchOrientation()`, `DMPolytopeTypeGetNumVertices()`, `DMPolytopeTypeGetVertexArrangement()` 9367b5a892a1SMatthew G. Knepley @*/ 9368d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 9369d71ae5a4SJacob Faibussowitsch { 9370b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 937185036b15SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangements(ct) / 2; 9372b5a892a1SMatthew G. Knepley PetscInt o, c; 9373b5a892a1SMatthew G. Knepley 9374b5a892a1SMatthew G. Knepley PetscFunctionBegin; 93759371c9d4SSatish Balay if (!nO) { 93769371c9d4SSatish Balay *ornt = 0; 93779371c9d4SSatish Balay *found = PETSC_TRUE; 93783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 93799371c9d4SSatish Balay } 9380b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 938185036b15SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangement(ct, o); 9382b5a892a1SMatthew G. Knepley 93839371c9d4SSatish Balay for (c = 0; c < cS; ++c) 93849371c9d4SSatish Balay if (sourceVert[arr[c]] != targetVert[c]) break; 93859371c9d4SSatish Balay if (c == cS) { 93869371c9d4SSatish Balay *ornt = o; 93879371c9d4SSatish Balay break; 93889371c9d4SSatish Balay } 9389b5a892a1SMatthew G. Knepley } 9390b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 93913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9392b5a892a1SMatthew G. Knepley } 9393b5a892a1SMatthew G. Knepley 9394b5a892a1SMatthew G. Knepley /*@C 9395bb7acecfSBarry Smith DMPolytopeGetVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9396b5a892a1SMatthew G. Knepley 939720f4b53cSBarry Smith Not Collective 9398b5a892a1SMatthew G. Knepley 9399b5a892a1SMatthew G. Knepley Input Parameters: 9400bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9401b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 9402b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 9403b5a892a1SMatthew G. Knepley 94042fe279fdSBarry Smith Output Parameter: 9405bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9406b5a892a1SMatthew G. Knepley 9407b5a892a1SMatthew G. Knepley Level: advanced 9408b5a892a1SMatthew G. Knepley 9409bb7acecfSBarry Smith Note: 9410bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchVertexOrientation()` except it errors if not orientation is possible. 9411bb7acecfSBarry Smith 941273ff1848SBarry Smith Developer Note: 9413bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchVertexOrientation()` and error if none is found 9414bb7acecfSBarry Smith 94151cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetOrientation()` 9416b5a892a1SMatthew G. Knepley @*/ 9417d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9418d71ae5a4SJacob Faibussowitsch { 9419b5a892a1SMatthew G. Knepley PetscBool found; 9420b5a892a1SMatthew G. Knepley 9421b5a892a1SMatthew G. Knepley PetscFunctionBegin; 94229566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found)); 94237a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 94243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9425b5a892a1SMatthew G. Knepley } 9426012bc364SMatthew G. Knepley 9427012bc364SMatthew G. Knepley /*@C 9428012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 9429012bc364SMatthew G. Knepley 943020f4b53cSBarry Smith Not Collective 9431012bc364SMatthew G. Knepley 9432012bc364SMatthew G. Knepley Input Parameters: 9433bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9434012bc364SMatthew G. Knepley - point - Coordinates of the point 9435012bc364SMatthew G. Knepley 94362fe279fdSBarry Smith Output Parameter: 9437012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 9438012bc364SMatthew G. Knepley 9439012bc364SMatthew G. Knepley Level: advanced 9440012bc364SMatthew G. Knepley 94411cc06b55SBarry Smith .seealso: [](ch_dmbase), `DM`, `DMPolytopeType`, `DMLocatePoints()` 9442012bc364SMatthew G. Knepley @*/ 9443d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 9444d71ae5a4SJacob Faibussowitsch { 9445012bc364SMatthew G. Knepley PetscReal sum = 0.0; 9446012bc364SMatthew G. Knepley PetscInt d; 9447012bc364SMatthew G. Knepley 9448012bc364SMatthew G. Knepley PetscFunctionBegin; 9449012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 9450012bc364SMatthew G. Knepley switch (ct) { 9451012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 9452012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 9453012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 94549371c9d4SSatish Balay if (point[d] < -1.0) { 94559371c9d4SSatish Balay *inside = PETSC_FALSE; 94569371c9d4SSatish Balay break; 94579371c9d4SSatish Balay } 9458012bc364SMatthew G. Knepley sum += point[d]; 9459012bc364SMatthew G. Knepley } 94609371c9d4SSatish Balay if (sum > PETSC_SMALL) { 94619371c9d4SSatish Balay *inside = PETSC_FALSE; 94629371c9d4SSatish Balay break; 94639371c9d4SSatish Balay } 9464012bc364SMatthew G. Knepley break; 9465012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 9466012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 9467012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 94689371c9d4SSatish Balay if (PetscAbsReal(point[d]) > 1. + PETSC_SMALL) { 94699371c9d4SSatish Balay *inside = PETSC_FALSE; 9470012bc364SMatthew G. Knepley break; 94719371c9d4SSatish Balay } 94729371c9d4SSatish Balay break; 9473d71ae5a4SJacob Faibussowitsch default: 9474d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 9475012bc364SMatthew G. Knepley } 94763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9477012bc364SMatthew G. Knepley } 9478adc21957SMatthew G. Knepley 9479adc21957SMatthew G. Knepley /*@ 9480adc21957SMatthew G. Knepley DMReorderSectionSetDefault - Set flag indicating whether the local section should be reordered by default 9481adc21957SMatthew G. Knepley 9482adc21957SMatthew G. Knepley Logically collective 9483adc21957SMatthew G. Knepley 9484adc21957SMatthew G. Knepley Input Parameters: 9485adc21957SMatthew G. Knepley + dm - The DM 9486adc21957SMatthew G. Knepley - reorder - Flag for reordering 9487adc21957SMatthew G. Knepley 9488adc21957SMatthew G. Knepley Level: intermediate 9489adc21957SMatthew G. Knepley 9490adc21957SMatthew G. Knepley .seealso: `DMReorderSectionGetDefault()` 9491adc21957SMatthew G. Knepley @*/ 9492adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionSetDefault(DM dm, DMReorderDefaultFlag reorder) 9493adc21957SMatthew G. Knepley { 9494adc21957SMatthew G. Knepley PetscFunctionBegin; 9495adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9496adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionSetDefault_C", (DM, DMReorderDefaultFlag), (dm, reorder)); 9497adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9498adc21957SMatthew G. Knepley } 9499adc21957SMatthew G. Knepley 9500adc21957SMatthew G. Knepley /*@ 9501adc21957SMatthew G. Knepley DMReorderSectionGetDefault - Get flag indicating whether the local section should be reordered by default 9502adc21957SMatthew G. Knepley 9503adc21957SMatthew G. Knepley Not collective 9504adc21957SMatthew G. Knepley 9505adc21957SMatthew G. Knepley Input Parameter: 9506adc21957SMatthew G. Knepley . dm - The DM 9507adc21957SMatthew G. Knepley 9508adc21957SMatthew G. Knepley Output Parameter: 9509adc21957SMatthew G. Knepley . reorder - Flag for reordering 9510adc21957SMatthew G. Knepley 9511adc21957SMatthew G. Knepley Level: intermediate 9512adc21957SMatthew G. Knepley 9513adc21957SMatthew G. Knepley .seealso: `DMReorderSetDefault()` 9514adc21957SMatthew G. Knepley @*/ 9515adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionGetDefault(DM dm, DMReorderDefaultFlag *reorder) 9516adc21957SMatthew G. Knepley { 9517adc21957SMatthew G. Knepley PetscFunctionBegin; 9518adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9519adc21957SMatthew G. Knepley PetscAssertPointer(reorder, 2); 9520adc21957SMatthew G. Knepley *reorder = DM_REORDER_DEFAULT_NOTSET; 9521adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionGetDefault_C", (DM, DMReorderDefaultFlag *), (dm, reorder)); 9522adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9523adc21957SMatthew G. Knepley } 9524adc21957SMatthew G. Knepley 9525adc21957SMatthew G. Knepley /*@C 9526adc21957SMatthew G. Knepley DMReorderSectionSetType - Set the type of local section reordering 9527adc21957SMatthew G. Knepley 9528adc21957SMatthew G. Knepley Logically collective 9529adc21957SMatthew G. Knepley 9530adc21957SMatthew G. Knepley Input Parameters: 9531adc21957SMatthew G. Knepley + dm - The DM 9532adc21957SMatthew G. Knepley - reorder - The reordering method 9533adc21957SMatthew G. Knepley 9534adc21957SMatthew G. Knepley Level: intermediate 9535adc21957SMatthew G. Knepley 9536adc21957SMatthew G. Knepley .seealso: `DMReorderSectionGetType()`, `DMReorderSectionSetDefault()` 9537adc21957SMatthew G. Knepley @*/ 9538adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionSetType(DM dm, MatOrderingType reorder) 9539adc21957SMatthew G. Knepley { 9540adc21957SMatthew G. Knepley PetscFunctionBegin; 9541adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9542adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionSetType_C", (DM, MatOrderingType), (dm, reorder)); 9543adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9544adc21957SMatthew G. Knepley } 9545adc21957SMatthew G. Knepley 9546adc21957SMatthew G. Knepley /*@C 9547adc21957SMatthew G. Knepley DMReorderSectionGetType - Get the reordering type for the local section 9548adc21957SMatthew G. Knepley 9549adc21957SMatthew G. Knepley Not collective 9550adc21957SMatthew G. Knepley 9551adc21957SMatthew G. Knepley Input Parameter: 9552adc21957SMatthew G. Knepley . dm - The DM 9553adc21957SMatthew G. Knepley 9554adc21957SMatthew G. Knepley Output Parameter: 9555adc21957SMatthew G. Knepley . reorder - The reordering method 9556adc21957SMatthew G. Knepley 9557adc21957SMatthew G. Knepley Level: intermediate 9558adc21957SMatthew G. Knepley 9559adc21957SMatthew G. Knepley .seealso: `DMReorderSetDefault()`, `DMReorderSectionGetDefault()` 9560adc21957SMatthew G. Knepley @*/ 9561adc21957SMatthew G. Knepley PetscErrorCode DMReorderSectionGetType(DM dm, MatOrderingType *reorder) 9562adc21957SMatthew G. Knepley { 9563adc21957SMatthew G. Knepley PetscFunctionBegin; 9564adc21957SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9565adc21957SMatthew G. Knepley PetscAssertPointer(reorder, 2); 9566adc21957SMatthew G. Knepley *reorder = NULL; 9567adc21957SMatthew G. Knepley PetscTryMethod(dm, "DMReorderSectionGetType_C", (DM, MatOrderingType *), (dm, reorder)); 9568adc21957SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 9569adc21957SMatthew G. Knepley } 9570