1d0295fc0SJunchao Zhang #include <petscvec.h> 2af0996ceSBarry Smith #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 3c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 4e6f8dbb6SToby Isaac #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/ 53e922f36SToby Isaac #include <petscdmplex.h> 6f19dbd58SToby Isaac #include <petscdmfield.h> 70c312b8eSJed Brown #include <petscsf.h> 82764a2aaSMatthew G. Knepley #include <petscds.h> 947c6ae99SBarry Smith 10f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 11f918ec44SMatthew G. Knepley #include <petscfeceed.h> 12f918ec44SMatthew G. Knepley #endif 13f918ec44SMatthew G. Knepley 14cea3dcb8SSatish Balay #if !defined(PETSC_HAVE_WINDOWS_COMPILERS) 15cea3dcb8SSatish Balay #include <petsc/private/valgrind/memcheck.h> 1600d952a4SJed Brown #endif 1700d952a4SJed Brown 18732e2eb9SMatthew G Knepley PetscClassId DM_CLASSID; 19d67d17b1SMatthew G. Knepley PetscClassId DMLABEL_CLASSID; 205b8ffe73SMark Adams PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction, DM_CreateInjection, DM_CreateMatrix, DM_CreateMassMatrix, DM_Load, DM_AdaptInterpolator; 2167a56275SMatthew G Knepley 22ea78f98cSLisandro Dalcin const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DMBoundaryType","DM_BOUNDARY_", NULL}; 23d1b3049bSMatthew G. Knepley const char *const DMBoundaryConditionTypes[] = {"INVALID","ESSENTIAL","NATURAL","INVALID","INVALID","ESSENTIAL_FIELD","NATURAL_FIELD","INVALID","INVALID","ESSENTIAL_BD_FIELD","NATURAL_RIEMANN","DMBoundaryConditionType","DM_BC_", NULL}; 24da9060c4SMatthew G. Knepley const char *const DMPolytopeTypes[] = {"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", "unknown", "invalid", "DMPolytopeType", "DM_POLYTOPE_", NULL}; 252cbb9b06SVaclav Hapla const char *const DMCopyLabelsModes[] = {"replace","keep","fail","DMCopyLabelsMode","DM_COPY_LABELS_", NULL}; 2660c22052SBarry Smith 27a4121054SBarry Smith /*@ 28bb7acecfSBarry Smith DMCreate - Creates an empty `DM` object. `DM`s are the abstract objects in PETSc that mediate between meshes and discretizations and the 29bb7acecfSBarry Smith algebraic solvers, time integrators, and optimization algorithms. 30a4121054SBarry Smith 31d083f849SBarry Smith Collective 32a4121054SBarry Smith 33a4121054SBarry Smith Input Parameter: 34bb7acecfSBarry Smith . comm - The communicator for the `DM` object 35a4121054SBarry Smith 36a4121054SBarry Smith Output Parameter: 37bb7acecfSBarry Smith . dm - The `DM` object 38a4121054SBarry Smith 39a4121054SBarry Smith Level: beginner 40a4121054SBarry Smith 41bb7acecfSBarry Smith Notes: 42bb7acecfSBarry Smith See `DMType` for a brief summary of available `DM`. 43bb7acecfSBarry Smith 44bb7acecfSBarry Smith The type must then be set with `DMSetType()`. If you never call `DMSetType()` it will generate an 45bb7acecfSBarry Smith error when you try to use the dm. 46bb7acecfSBarry Smith 47bb7acecfSBarry Smith .seealso: `DMSetType()`, `DMType`, `DMDACreate()`, `DMDA`, `DMSLICED`, `DMCOMPOSITE`, `DMPLEX`, `DMMOAB`, `DMNETWORK` 48a4121054SBarry Smith @*/ 497087cfbeSBarry Smith PetscErrorCode DMCreate(MPI_Comm comm,DM *dm) 50a4121054SBarry Smith { 51a4121054SBarry Smith DM v; 52e5e52638SMatthew G. Knepley PetscDS ds; 53a4121054SBarry Smith 54a4121054SBarry Smith PetscFunctionBegin; 551411c6eeSJed Brown PetscValidPointer(dm,2); 560298fd71SBarry Smith *dm = NULL; 579566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 58a4121054SBarry Smith 599566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView)); 60e7c4fc90SDmitry Karpeev 6149be4549SMatthew G. Knepley v->setupcalled = PETSC_FALSE; 6249be4549SMatthew G. Knepley v->setfromoptionscalled = PETSC_FALSE; 630298fd71SBarry Smith v->ltogmap = NULL; 64a4ea9b21SRichard Tran Mills v->bind_below = 0; 651411c6eeSJed Brown v->bs = 1; 66171400e9SBarry Smith v->coloringtype = IS_COLORING_GLOBAL; 679566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sf)); 689566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &v->sectionSF)); 69c58f1c22SToby Isaac v->labels = NULL; 7034aa8a36SMatthew G. Knepley v->adjacency[0] = PETSC_FALSE; 7134aa8a36SMatthew G. Knepley v->adjacency[1] = PETSC_TRUE; 72c58f1c22SToby Isaac v->depthLabel = NULL; 73ba2698f1SMatthew G. Knepley v->celltypeLabel = NULL; 741bb6d2a8SBarry Smith v->localSection = NULL; 751bb6d2a8SBarry Smith v->globalSection = NULL; 763b8ba7d1SJed Brown v->defaultConstraint.section = NULL; 773b8ba7d1SJed Brown v->defaultConstraint.mat = NULL; 7879769bd5SJed Brown v->defaultConstraint.bias = NULL; 796858538eSMatthew G. Knepley v->coordinates[0].dim = PETSC_DEFAULT; 806858538eSMatthew G. Knepley v->coordinates[1].dim = PETSC_DEFAULT; 816858538eSMatthew G. Knepley v->sparseLocalize = PETSC_TRUE; 8296173672SStefano Zampini v->dim = PETSC_DETERMINE; 83435a35e8SMatthew G Knepley { 84435a35e8SMatthew G Knepley PetscInt i; 85435a35e8SMatthew G Knepley for (i = 0; i < 10; ++i) { 860298fd71SBarry Smith v->nullspaceConstructors[i] = NULL; 87f9d4088aSMatthew G. Knepley v->nearnullspaceConstructors[i] = NULL; 88435a35e8SMatthew G Knepley } 89435a35e8SMatthew G Knepley } 909566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 919566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(v, NULL, NULL, ds)); 929566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 939566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxCreate(&v->auxData)); 9414f150ffSMatthew G. Knepley v->dmBC = NULL; 95a8fb8f29SToby Isaac v->coarseMesh = NULL; 96f4d763aaSMatthew G. Knepley v->outputSequenceNum = -1; 97cdb7a50dSMatthew G. Knepley v->outputSequenceVal = 0.0; 989566063dSJacob Faibussowitsch PetscCall(DMSetVecType(v,VECSTANDARD)); 999566063dSJacob Faibussowitsch PetscCall(DMSetMatType(v,MATAIJ)); 1004a7a4c06SLawrence Mitchell 1011411c6eeSJed Brown *dm = v; 102a4121054SBarry Smith PetscFunctionReturn(0); 103a4121054SBarry Smith } 104a4121054SBarry Smith 10538221697SMatthew G. Knepley /*@ 106bb7acecfSBarry Smith DMClone - Creates a `DM` object with the same topology as the original. 10738221697SMatthew G. Knepley 108d083f849SBarry Smith Collective 10938221697SMatthew G. Knepley 11038221697SMatthew G. Knepley Input Parameter: 111bb7acecfSBarry Smith . dm - The original `DM` object 11238221697SMatthew G. Knepley 11338221697SMatthew G. Knepley Output Parameter: 114bb7acecfSBarry Smith . newdm - The new `DM` object 11538221697SMatthew G. Knepley 11638221697SMatthew G. Knepley Level: beginner 11738221697SMatthew G. Knepley 1181cb8cacdSPatrick Sanan Notes: 119bb7acecfSBarry Smith For some `DM` implementations this is a shallow clone, the result of which may share (reference counted) information with its parent. For example, 120bb7acecfSBarry Smith `DMClone()` applied to a `DMPLEX` object will result in a new `DMPLEX` that shares the topology with the original `DMPLEX`. It does not 121bb7acecfSBarry Smith share the `PetscSection` of the original `DM`. 1221bb6d2a8SBarry Smith 123bb7acecfSBarry Smith The clone is considered set up if the original has been set up. 12489706ed2SPatrick Sanan 125bb7acecfSBarry Smith Use `DMConvert()` for a general way to create new `DM` from a given `DM` 126bb7acecfSBarry Smith 127bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMCreate()`, `DMSetType()`, `DMSetLocalSection()`, `DMSetGlobalSection()`, `DMPLEX`, `DMSetType()`, `DMConvert()` 1281bb6d2a8SBarry Smith 12938221697SMatthew G. Knepley @*/ 13038221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm) 13138221697SMatthew G. Knepley { 13238221697SMatthew G. Knepley PetscSF sf; 13338221697SMatthew G. Knepley Vec coords; 13438221697SMatthew G. Knepley void *ctx; 1356858538eSMatthew G. Knepley PetscInt dim, cdim, i; 13638221697SMatthew G. Knepley 13738221697SMatthew G. Knepley PetscFunctionBegin; 13838221697SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 13938221697SMatthew G. Knepley PetscValidPointer(newdm,2); 1409566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject) dm), newdm)); 1419566063dSJacob Faibussowitsch PetscCall(DMCopyLabels(dm, *newdm, PETSC_COPY_VALUES, PETSC_TRUE, DM_COPY_LABELS_FAIL)); 142ddf8437dSMatthew G. Knepley (*newdm)->leveldown = dm->leveldown; 143ddf8437dSMatthew G. Knepley (*newdm)->levelup = dm->levelup; 144c8a6034eSMark (*newdm)->prealloc_only = dm->prealloc_only; 1459566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->vectype)); 1469566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype,(char**)&(*newdm)->vectype)); 1479566063dSJacob Faibussowitsch PetscCall(PetscFree((*newdm)->mattype)); 1489566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype,(char**)&(*newdm)->mattype)); 1499566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1509566063dSJacob Faibussowitsch PetscCall(DMSetDimension(*newdm, dim)); 151*dbbe0bcdSBarry Smith PetscTryTypeMethod(dm,clone, newdm); 1523f22bcbcSToby Isaac (*newdm)->setupcalled = dm->setupcalled; 1539566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm, &sf)); 1549566063dSJacob Faibussowitsch PetscCall(DMSetPointSF(*newdm, sf)); 1559566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dm, &ctx)); 1569566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(*newdm, ctx)); 1576858538eSMatthew G. Knepley for (i = 0; i < 2; ++i) { 1586858538eSMatthew G. Knepley if (dm->coordinates[i].dm) { 159be4c1c3eSMatthew G. Knepley DM ncdm; 160be4c1c3eSMatthew G. Knepley PetscSection cs; 1615a0206caSToby Isaac PetscInt pEnd = -1, pEndMax = -1; 162be4c1c3eSMatthew G. Knepley 1636858538eSMatthew G. Knepley PetscCall(DMGetLocalSection(dm->coordinates[i].dm, &cs)); 1649566063dSJacob Faibussowitsch if (cs) PetscCall(PetscSectionGetChart(cs, NULL, &pEnd)); 1659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&pEnd, &pEndMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm))); 1665a0206caSToby Isaac if (pEndMax >= 0) { 1676858538eSMatthew G. Knepley PetscCall(DMClone(dm->coordinates[i].dm, &ncdm)); 1686858538eSMatthew G. Knepley PetscCall(DMCopyDisc(dm->coordinates[i].dm, ncdm)); 1699566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(ncdm, cs)); 1706858538eSMatthew G. Knepley if (i) PetscCall(DMSetCellCoordinateDM(*newdm, ncdm)); 1716858538eSMatthew G. Knepley else PetscCall(DMSetCoordinateDM(*newdm, ncdm)); 1729566063dSJacob Faibussowitsch PetscCall(DMDestroy(&ncdm)); 173be4c1c3eSMatthew G. Knepley } 174be4c1c3eSMatthew G. Knepley } 1756858538eSMatthew G. Knepley } 1769566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 1779566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateDim(*newdm, cdim)); 1789566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coords)); 17938221697SMatthew G. Knepley if (coords) { 1809566063dSJacob Faibussowitsch PetscCall(DMSetCoordinatesLocal(*newdm, coords)); 18138221697SMatthew G. Knepley } else { 1829566063dSJacob Faibussowitsch PetscCall(DMGetCoordinates(dm, &coords)); 1839566063dSJacob Faibussowitsch if (coords) PetscCall(DMSetCoordinates(*newdm, coords)); 18438221697SMatthew G. Knepley } 1856858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &coords)); 1866858538eSMatthew G. Knepley if (coords) { 1876858538eSMatthew G. Knepley PetscCall(DMSetCellCoordinatesLocal(*newdm, coords)); 1886858538eSMatthew G. Knepley } else { 1896858538eSMatthew G. Knepley PetscCall(DMGetCellCoordinates(dm, &coords)); 1906858538eSMatthew G. Knepley if (coords) PetscCall(DMSetCellCoordinates(*newdm, coords)); 1916858538eSMatthew G. Knepley } 19290b157c4SStefano Zampini { 1934fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 1946858538eSMatthew G. Knepley 1954fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 1964fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*newdm, maxCell, Lstart, L)); 197c6b900c6SMatthew G. Knepley } 19834aa8a36SMatthew G. Knepley { 19934aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 20034aa8a36SMatthew G. Knepley 2019566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure)); 2029566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure)); 20334aa8a36SMatthew G. Knepley } 20438221697SMatthew G. Knepley PetscFunctionReturn(0); 20538221697SMatthew G. Knepley } 20638221697SMatthew G. Knepley 2079a42bb27SBarry Smith /*@C 208bb7acecfSBarry Smith DMSetVecType - Sets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 2099a42bb27SBarry Smith 210d083f849SBarry Smith Logically Collective on da 2119a42bb27SBarry Smith 212147403d9SBarry Smith Input Parameters: 2139a42bb27SBarry Smith + da - initial distributed array 214bb7acecfSBarry Smith - ctype - the vector type, for example `VECSTANDARD`, `VECCUDA`, or `VECVIENNACL` 2159a42bb27SBarry Smith 2169a42bb27SBarry Smith Options Database: 217147403d9SBarry Smith . -dm_vec_type ctype - the type of vector to create 2189a42bb27SBarry Smith 2199a42bb27SBarry Smith Level: intermediate 2209a42bb27SBarry Smith 221bb7acecfSBarry Smith .seealso: `DMCreate()`, `DMDestroy()`, `DM`, `DMDAInterpolationType`, `VecType`, `DMGetVecType()`, `DMSetMatType()`, `DMGetMatType()`, 222bb7acecfSBarry Smith `VECSTANDARD`, `VECCUDA`, `VECVIENNACL`, `DMCreateLocalVector()`, `DMCreateGlobalVector()` 2239a42bb27SBarry Smith @*/ 22419fd82e9SBarry Smith PetscErrorCode DMSetVecType(DM da,VecType ctype) 2259a42bb27SBarry Smith { 2269a42bb27SBarry Smith PetscFunctionBegin; 2279a42bb27SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 2289566063dSJacob Faibussowitsch PetscCall(PetscFree(da->vectype)); 2299566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype,(char**)&da->vectype)); 2309a42bb27SBarry Smith PetscFunctionReturn(0); 2319a42bb27SBarry Smith } 2329a42bb27SBarry Smith 233c0dedaeaSBarry Smith /*@C 234bb7acecfSBarry Smith DMGetVecType - Gets the type of vector created with `DMCreateLocalVector()` and `DMCreateGlobalVector()` 235c0dedaeaSBarry Smith 236d083f849SBarry Smith Logically Collective on da 237c0dedaeaSBarry Smith 238c0dedaeaSBarry Smith Input Parameter: 239c0dedaeaSBarry Smith . da - initial distributed array 240c0dedaeaSBarry Smith 241c0dedaeaSBarry Smith Output Parameter: 242c0dedaeaSBarry Smith . ctype - the vector type 243c0dedaeaSBarry Smith 244c0dedaeaSBarry Smith Level: intermediate 245c0dedaeaSBarry Smith 246db781477SPatrick Sanan .seealso: `DMCreate()`, `DMDestroy()`, `DM`, `DMDAInterpolationType`, `VecType`, `DMSetMatType()`, `DMGetMatType()`, `DMSetVecType()` 247c0dedaeaSBarry Smith @*/ 248c0dedaeaSBarry Smith PetscErrorCode DMGetVecType(DM da,VecType *ctype) 249c0dedaeaSBarry Smith { 250c0dedaeaSBarry Smith PetscFunctionBegin; 251c0dedaeaSBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 252c0dedaeaSBarry Smith *ctype = da->vectype; 253c0dedaeaSBarry Smith PetscFunctionReturn(0); 254c0dedaeaSBarry Smith } 255c0dedaeaSBarry Smith 2565f1ad066SMatthew G Knepley /*@ 257bb7acecfSBarry Smith VecGetDM - Gets the `DM` defining the data layout of the vector 2585f1ad066SMatthew G Knepley 2595f1ad066SMatthew G Knepley Not collective 2605f1ad066SMatthew G Knepley 2615f1ad066SMatthew G Knepley Input Parameter: 262bb7acecfSBarry Smith . v - The `Vec` 2635f1ad066SMatthew G Knepley 2645f1ad066SMatthew G Knepley Output Parameter: 265bb7acecfSBarry Smith . dm - The `DM` 2665f1ad066SMatthew G Knepley 2675f1ad066SMatthew G Knepley Level: intermediate 2685f1ad066SMatthew G Knepley 269bb7acecfSBarry Smith Note: 270bb7acecfSBarry Smith A `Vec` may not have a `DM` associated with it. 271bb7acecfSBarry Smith 272bb7acecfSBarry Smith .seealso: `DM`, `VecSetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 2735f1ad066SMatthew G Knepley @*/ 2745f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm) 2755f1ad066SMatthew G Knepley { 2765f1ad066SMatthew G Knepley PetscFunctionBegin; 2775f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 2785f1ad066SMatthew G Knepley PetscValidPointer(dm,2); 2799566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm)); 2805f1ad066SMatthew G Knepley PetscFunctionReturn(0); 2815f1ad066SMatthew G Knepley } 2825f1ad066SMatthew G Knepley 2835f1ad066SMatthew G Knepley /*@ 284bb7acecfSBarry Smith VecSetDM - Sets the `DM` defining the data layout of the vector. 2855f1ad066SMatthew G Knepley 2865f1ad066SMatthew G Knepley Not collective 2875f1ad066SMatthew G Knepley 2885f1ad066SMatthew G Knepley Input Parameters: 289bb7acecfSBarry Smith + v - The `Vec` 290bb7acecfSBarry Smith - dm - The `DM` 2915f1ad066SMatthew G Knepley 292bb7acecfSBarry Smith Note: 293bb7acecfSBarry Smith This is rarely used, generally one uses `DMGetLocalVector()` or `DMGetGlobalVector()` to create a vector associated with a given `DM` 294d9805387SMatthew G. Knepley 295bb7acecfSBarry 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. 296bb7acecfSBarry Smith 297bb7acecfSBarry Smith Level: developer 2985f1ad066SMatthew G Knepley 299db781477SPatrick Sanan .seealso: `VecGetDM()`, `DMGetLocalVector()`, `DMGetGlobalVector()`, `DMSetVecType()` 3005f1ad066SMatthew G Knepley @*/ 3015f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm) 3025f1ad066SMatthew G Knepley { 3035f1ad066SMatthew G Knepley PetscFunctionBegin; 3045f1ad066SMatthew G Knepley PetscValidHeaderSpecific(v,VEC_CLASSID,1); 305d7f50e27SLisandro Dalcin if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 3069566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm)); 3075f1ad066SMatthew G Knepley PetscFunctionReturn(0); 3085f1ad066SMatthew G Knepley } 3095f1ad066SMatthew G Knepley 310521d9a4cSLisandro Dalcin /*@C 311bb7acecfSBarry Smith DMSetISColoringType - Sets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 3128f1509bcSBarry Smith 313d083f849SBarry Smith Logically Collective on dm 3148f1509bcSBarry Smith 3158f1509bcSBarry Smith Input Parameters: 316bb7acecfSBarry Smith + dm - the `DM` context 3178f1509bcSBarry Smith - ctype - the matrix type 3188f1509bcSBarry Smith 3198f1509bcSBarry Smith Options Database: 3208f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3218f1509bcSBarry Smith 3228f1509bcSBarry Smith Level: intermediate 3238f1509bcSBarry Smith 324db781477SPatrick Sanan .seealso: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 325bb7acecfSBarry Smith `DMGetISColoringType()`, `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3268f1509bcSBarry Smith @*/ 3278f1509bcSBarry Smith PetscErrorCode DMSetISColoringType(DM dm,ISColoringType ctype) 3288f1509bcSBarry Smith { 3298f1509bcSBarry Smith PetscFunctionBegin; 3308f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3318f1509bcSBarry Smith dm->coloringtype = ctype; 3328f1509bcSBarry Smith PetscFunctionReturn(0); 3338f1509bcSBarry Smith } 3348f1509bcSBarry Smith 3358f1509bcSBarry Smith /*@C 336bb7acecfSBarry Smith DMGetISColoringType - Gets the type of coloring, `IS_COLORING_GLOBAL` or `IS_COLORING_LOCAL` that is created by the `DM` 337521d9a4cSLisandro Dalcin 338d083f849SBarry Smith Logically Collective on dm 339521d9a4cSLisandro Dalcin 340521d9a4cSLisandro Dalcin Input Parameter: 341bb7acecfSBarry Smith . dm - the `DM` context 3428f1509bcSBarry Smith 3438f1509bcSBarry Smith Output Parameter: 3448f1509bcSBarry Smith . ctype - the matrix type 3458f1509bcSBarry Smith 3468f1509bcSBarry Smith Options Database: 3478f1509bcSBarry Smith . -dm_is_coloring_type - global or local 3488f1509bcSBarry Smith 3498f1509bcSBarry Smith Level: intermediate 3508f1509bcSBarry Smith 351db781477SPatrick Sanan .seealso: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, 352bb7acecfSBarry Smith `DMGetISColoringType()`, `ISColoringType`, `IS_COLORING_GLOBAL`, `IS_COLORING_LOCAL` 3538f1509bcSBarry Smith @*/ 3548f1509bcSBarry Smith PetscErrorCode DMGetISColoringType(DM dm,ISColoringType *ctype) 3558f1509bcSBarry Smith { 3568f1509bcSBarry Smith PetscFunctionBegin; 3578f1509bcSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3588f1509bcSBarry Smith *ctype = dm->coloringtype; 3598f1509bcSBarry Smith PetscFunctionReturn(0); 3608f1509bcSBarry Smith } 3618f1509bcSBarry Smith 3628f1509bcSBarry Smith /*@C 363bb7acecfSBarry Smith DMSetMatType - Sets the type of matrix created with `DMCreateMatrix()` 3648f1509bcSBarry Smith 365d083f849SBarry Smith Logically Collective on dm 3668f1509bcSBarry Smith 3678f1509bcSBarry Smith Input Parameters: 368bb7acecfSBarry Smith + dm - the `DM` context 369bb7acecfSBarry Smith - ctype - the matrix type, for example `MATMPIAIJ` 370521d9a4cSLisandro Dalcin 371521d9a4cSLisandro Dalcin Options Database: 372bb7acecfSBarry Smith . -dm_mat_type ctype - the type of the matrix to create, for example mpiaij 373521d9a4cSLisandro Dalcin 374521d9a4cSLisandro Dalcin Level: intermediate 375521d9a4cSLisandro Dalcin 376bb7acecfSBarry Smith .seealso: `MatType`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMGetMatType()`, `DMSetMatType()`, `DMGetMatType()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()` 377521d9a4cSLisandro Dalcin @*/ 37819fd82e9SBarry Smith PetscErrorCode DMSetMatType(DM dm,MatType ctype) 379521d9a4cSLisandro Dalcin { 380521d9a4cSLisandro Dalcin PetscFunctionBegin; 381521d9a4cSLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3829566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->mattype)); 3839566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ctype,(char**)&dm->mattype)); 384521d9a4cSLisandro Dalcin PetscFunctionReturn(0); 385521d9a4cSLisandro Dalcin } 386521d9a4cSLisandro Dalcin 387c0dedaeaSBarry Smith /*@C 388bb7acecfSBarry Smith DMGetMatType - Gets the type of matrix created with `DMCreateMatrix()` 389c0dedaeaSBarry Smith 390d083f849SBarry Smith Logically Collective on dm 391c0dedaeaSBarry Smith 392c0dedaeaSBarry Smith Input Parameter: 393bb7acecfSBarry Smith . dm - the `DM` context 394c0dedaeaSBarry Smith 395c0dedaeaSBarry Smith Output Parameter: 396c0dedaeaSBarry Smith . ctype - the matrix type 397c0dedaeaSBarry Smith 398c0dedaeaSBarry Smith Level: intermediate 399c0dedaeaSBarry Smith 400db781477SPatrick Sanan .seealso: `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixPreallocateOnly()`, `MatType`, `DMSetMatType()`, `DMSetMatType()`, `DMGetMatType()` 401c0dedaeaSBarry Smith @*/ 402c0dedaeaSBarry Smith PetscErrorCode DMGetMatType(DM dm,MatType *ctype) 403c0dedaeaSBarry Smith { 404c0dedaeaSBarry Smith PetscFunctionBegin; 405c0dedaeaSBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 406c0dedaeaSBarry Smith *ctype = dm->mattype; 407c0dedaeaSBarry Smith PetscFunctionReturn(0); 408c0dedaeaSBarry Smith } 409c0dedaeaSBarry Smith 410c688c046SMatthew G Knepley /*@ 411bb7acecfSBarry Smith MatGetDM - Gets the `DM` defining the data layout of the matrix 412c688c046SMatthew G Knepley 413c688c046SMatthew G Knepley Not collective 414c688c046SMatthew G Knepley 415c688c046SMatthew G Knepley Input Parameter: 416bb7acecfSBarry Smith . A - The `Mat` 417c688c046SMatthew G Knepley 418c688c046SMatthew G Knepley Output Parameter: 419bb7acecfSBarry Smith . dm - The `DM` 420c688c046SMatthew G Knepley 421c688c046SMatthew G Knepley Level: intermediate 422c688c046SMatthew G Knepley 423bb7acecfSBarry Smith Note: 424bb7acecfSBarry Smith A matrix may not have a `DM` associated with it 425bb7acecfSBarry Smith 426bb7acecfSBarry Smith Developer Note: 427bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with the `Mat` through a `PetscObjectCompose()` operation 4288f1509bcSBarry Smith 429db781477SPatrick Sanan .seealso: `MatSetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 430c688c046SMatthew G Knepley @*/ 431c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm) 432c688c046SMatthew G Knepley { 433c688c046SMatthew G Knepley PetscFunctionBegin; 434c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 435c688c046SMatthew G Knepley PetscValidPointer(dm,2); 4369566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm)); 437c688c046SMatthew G Knepley PetscFunctionReturn(0); 438c688c046SMatthew G Knepley } 439c688c046SMatthew G Knepley 440c688c046SMatthew G Knepley /*@ 441bb7acecfSBarry Smith MatSetDM - Sets the `DM` defining the data layout of the matrix 442c688c046SMatthew G Knepley 443c688c046SMatthew G Knepley Not collective 444c688c046SMatthew G Knepley 445c688c046SMatthew G Knepley Input Parameters: 446c688c046SMatthew G Knepley + A - The Mat 447c688c046SMatthew G Knepley - dm - The DM 448c688c046SMatthew G Knepley 449bb7acecfSBarry Smith Level: developer 450c688c046SMatthew G Knepley 451bb7acecfSBarry Smith Note: 452bb7acecfSBarry Smith This is rarely used in practice, rather `DMCreateMatrix()` is used to create a matrix associated with a particular `DM` 453bb7acecfSBarry Smith 454bb7acecfSBarry Smith Developer Note: 455bb7acecfSBarry Smith Since the `Mat` class doesn't know about the `DM` class the `DM` object is associated with 456bb7acecfSBarry Smith the `Mat` through a `PetscObjectCompose()` operation 4578f1509bcSBarry Smith 458db781477SPatrick Sanan .seealso: `MatGetDM()`, `DMCreateMatrix()`, `DMSetMatType()` 459c688c046SMatthew G Knepley @*/ 460c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm) 461c688c046SMatthew G Knepley { 462c688c046SMatthew G Knepley PetscFunctionBegin; 463c688c046SMatthew G Knepley PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4648865f1eaSKarl Rupp if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2); 4659566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm)); 466c688c046SMatthew G Knepley PetscFunctionReturn(0); 467c688c046SMatthew G Knepley } 468c688c046SMatthew G Knepley 4699a42bb27SBarry Smith /*@C 470bb7acecfSBarry Smith DMSetOptionsPrefix - Sets the prefix prepended to all option names when searching through the options database 4719a42bb27SBarry Smith 472d083f849SBarry Smith Logically Collective on dm 4739a42bb27SBarry Smith 474d8d19677SJose E. Roman Input Parameters: 475bb7acecfSBarry Smith + da - the `DM` context 476bb7acecfSBarry Smith - prefix - the prefix to prepend 4779a42bb27SBarry Smith 4789a42bb27SBarry Smith Notes: 4799a42bb27SBarry Smith A hyphen (-) must NOT be given at the beginning of the prefix name. 4809a42bb27SBarry Smith The first character of all runtime options is AUTOMATICALLY the hyphen. 4819a42bb27SBarry Smith 4829a42bb27SBarry Smith Level: advanced 4839a42bb27SBarry Smith 484bb7acecfSBarry Smith .seealso: `PetscObjectSetOptionsPrefix()`, `DMSetFromOptions()` 4859a42bb27SBarry Smith @*/ 4867087cfbeSBarry Smith PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[]) 4879a42bb27SBarry Smith { 4889a42bb27SBarry Smith PetscFunctionBegin; 4899a42bb27SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 4909566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm,prefix)); 4911baa6e33SBarry Smith if (dm->sf) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix)); 4921baa6e33SBarry Smith if (dm->sectionSF) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dm->sectionSF,prefix)); 4939a42bb27SBarry Smith PetscFunctionReturn(0); 4949a42bb27SBarry Smith } 4959a42bb27SBarry Smith 49631697293SDave May /*@C 497bb7acecfSBarry Smith DMAppendOptionsPrefix - Appends an additional string to an already exising prefix used for searching for 498bb7acecfSBarry Smith `DM` options in the options database. 49931697293SDave May 500d083f849SBarry Smith Logically Collective on dm 50131697293SDave May 50231697293SDave May Input Parameters: 503bb7acecfSBarry Smith + dm - the `DM` context 504bb7acecfSBarry Smith - prefix - the string to append to the current prefix 50531697293SDave May 50631697293SDave May Notes: 507bb7acecfSBarry 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. 50831697293SDave May A hyphen (-) must NOT be given at the beginning of the prefix name. 50931697293SDave May The first character of all runtime options is AUTOMATICALLY the hyphen. 51031697293SDave May 51131697293SDave May Level: advanced 51231697293SDave May 513bb7acecfSBarry Smith .seealso: `DMSetOptionsPrefix()`, `DMGetOptionsPrefix()`, `PetscObjectAppendOptionsPrefix()`, `DMSetFromOptions()` 51431697293SDave May @*/ 51531697293SDave May PetscErrorCode DMAppendOptionsPrefix(DM dm,const char prefix[]) 51631697293SDave May { 51731697293SDave May PetscFunctionBegin; 51831697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5199566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix)); 52031697293SDave May PetscFunctionReturn(0); 52131697293SDave May } 52231697293SDave May 52331697293SDave May /*@C 52431697293SDave May DMGetOptionsPrefix - Gets the prefix used for searching for all 525bb7acecfSBarry Smith DM options in the options database. 52631697293SDave May 52731697293SDave May Not Collective 52831697293SDave May 52931697293SDave May Input Parameters: 530bb7acecfSBarry Smith . dm - the `DM` context 53131697293SDave May 53231697293SDave May Output Parameters: 53331697293SDave May . prefix - pointer to the prefix string used is returned 53431697293SDave May 535bb7acecfSBarry Smith Fortran Note: 53695452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 53731697293SDave May sufficient length to hold the prefix. 53831697293SDave May 53931697293SDave May Level: advanced 54031697293SDave May 541bb7acecfSBarry Smith .seealso: `DMSetOptionsPrefix()`, `DMAppendOptionsPrefix()`, `DMSetFromOptions()` 54231697293SDave May @*/ 54331697293SDave May PetscErrorCode DMGetOptionsPrefix(DM dm,const char *prefix[]) 54431697293SDave May { 54531697293SDave May PetscFunctionBegin; 54631697293SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 5479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm,prefix)); 54831697293SDave May PetscFunctionReturn(0); 54931697293SDave May } 55031697293SDave May 55188bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct) 55288bdff64SToby Isaac { 5536eb26441SStefano Zampini PetscInt refct = ((PetscObject) dm)->refct; 55488bdff64SToby Isaac 55588bdff64SToby Isaac PetscFunctionBegin; 556aab5bcd8SJed Brown *ncrefct = 0; 55788bdff64SToby Isaac if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) { 55888bdff64SToby Isaac refct--; 55988bdff64SToby Isaac if (recurseCoarse) { 56088bdff64SToby Isaac PetscInt coarseCount; 56188bdff64SToby Isaac 5629566063dSJacob Faibussowitsch PetscCall(DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount)); 56388bdff64SToby Isaac refct += coarseCount; 56488bdff64SToby Isaac } 56588bdff64SToby Isaac } 56688bdff64SToby Isaac if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) { 56788bdff64SToby Isaac refct--; 56888bdff64SToby Isaac if (recurseFine) { 56988bdff64SToby Isaac PetscInt fineCount; 57088bdff64SToby Isaac 5719566063dSJacob Faibussowitsch PetscCall(DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount)); 57288bdff64SToby Isaac refct += fineCount; 57388bdff64SToby Isaac } 57488bdff64SToby Isaac } 57588bdff64SToby Isaac *ncrefct = refct; 57688bdff64SToby Isaac PetscFunctionReturn(0); 57788bdff64SToby Isaac } 57888bdff64SToby Isaac 579f4cdcedcSVaclav Hapla PetscErrorCode DMDestroyLabelLinkList_Internal(DM dm) 580354557abSToby Isaac { 5815d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 582354557abSToby Isaac 583354557abSToby Isaac PetscFunctionBegin; 584354557abSToby Isaac /* destroy the labels */ 585354557abSToby Isaac while (next) { 586354557abSToby Isaac DMLabelLink tmp = next->next; 587354557abSToby Isaac 5885d80c0bfSVaclav Hapla if (next->label == dm->depthLabel) dm->depthLabel = NULL; 589ba2698f1SMatthew G. Knepley if (next->label == dm->celltypeLabel) dm->celltypeLabel = NULL; 5909566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 5919566063dSJacob Faibussowitsch PetscCall(PetscFree(next)); 592354557abSToby Isaac next = tmp; 593354557abSToby Isaac } 5945d80c0bfSVaclav Hapla dm->labels = NULL; 595354557abSToby Isaac PetscFunctionReturn(0); 596354557abSToby Isaac } 597354557abSToby Isaac 5986858538eSMatthew G. Knepley PetscErrorCode DMDestroyCoordinates_Private(DMCoordinates *c) 5996858538eSMatthew G. Knepley { 6006858538eSMatthew G. Knepley PetscFunctionBegin; 6016858538eSMatthew G. Knepley c->dim = PETSC_DEFAULT; 6026858538eSMatthew G. Knepley PetscCall(DMDestroy(&c->dm)); 6036858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->x)); 6046858538eSMatthew G. Knepley PetscCall(VecDestroy(&c->xl)); 6056858538eSMatthew G. Knepley PetscCall(DMFieldDestroy(&c->field)); 6066858538eSMatthew G. Knepley PetscFunctionReturn(0); 6076858538eSMatthew G. Knepley } 6086858538eSMatthew G. Knepley 6091fb7b255SJunchao Zhang /*@C 610bb7acecfSBarry Smith DMDestroy - Destroys a `DM`. 61147c6ae99SBarry Smith 612d083f849SBarry Smith Collective on dm 61347c6ae99SBarry Smith 61447c6ae99SBarry Smith Input Parameter: 615bb7acecfSBarry Smith . dm - the `DM` object to destroy 61647c6ae99SBarry Smith 61747c6ae99SBarry Smith Level: developer 61847c6ae99SBarry Smith 619bb7acecfSBarry Smith .seealso: `DMCreate()`, `DMType`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 62047c6ae99SBarry Smith 62147c6ae99SBarry Smith @*/ 622fcfd50ebSBarry Smith PetscErrorCode DMDestroy(DM *dm) 62347c6ae99SBarry Smith { 6246eb26441SStefano Zampini PetscInt cnt; 625dfe15315SJed Brown DMNamedVecLink nlink,nnext; 62647c6ae99SBarry Smith 62747c6ae99SBarry Smith PetscFunctionBegin; 6286bf464f9SBarry Smith if (!*dm) PetscFunctionReturn(0); 6296bf464f9SBarry Smith PetscValidHeaderSpecific((*dm),DM_CLASSID,1); 63087e657c6SBarry Smith 63188bdff64SToby Isaac /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */ 6329566063dSJacob Faibussowitsch PetscCall(DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt)); 63388bdff64SToby Isaac --((PetscObject)(*dm))->refct; 634ea78f98cSLisandro Dalcin if (--cnt > 0) {*dm = NULL; PetscFunctionReturn(0);} 6356bf464f9SBarry Smith if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0); 6366bf464f9SBarry Smith ((PetscObject)(*dm))->refct = 0; 6376eb26441SStefano Zampini 6389566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(*dm)); 6399566063dSJacob Faibussowitsch PetscCall(DMClearLocalVectors(*dm)); 6406eb26441SStefano Zampini 641f490541aSPeter Brune nnext=(*dm)->namedglobal; 6420298fd71SBarry Smith (*dm)->namedglobal = NULL; 643f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */ 6442348bcf4SPeter Brune nnext = nlink->next; 6457a8be351SBarry Smith PetscCheck(nlink->status == DMVEC_STATUS_IN,((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name); 6469566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink->name)); 6479566063dSJacob Faibussowitsch PetscCall(VecDestroy(&nlink->X)); 6489566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink)); 6492348bcf4SPeter Brune } 650f490541aSPeter Brune nnext=(*dm)->namedlocal; 6510298fd71SBarry Smith (*dm)->namedlocal = NULL; 652f490541aSPeter Brune for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */ 653f490541aSPeter Brune nnext = nlink->next; 6547a8be351SBarry Smith PetscCheck(nlink->status == DMVEC_STATUS_IN,((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name); 6559566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink->name)); 6569566063dSJacob Faibussowitsch PetscCall(VecDestroy(&nlink->X)); 6579566063dSJacob Faibussowitsch PetscCall(PetscFree(nlink)); 658f490541aSPeter Brune } 6592348bcf4SPeter Brune 660b17ce1afSJed Brown /* Destroy the list of hooks */ 661c833c3b5SJed Brown { 662c833c3b5SJed Brown DMCoarsenHookLink link,next; 663b17ce1afSJed Brown for (link=(*dm)->coarsenhook; link; link=next) { 664b17ce1afSJed Brown next = link->next; 6659566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 666b17ce1afSJed Brown } 6670298fd71SBarry Smith (*dm)->coarsenhook = NULL; 668c833c3b5SJed Brown } 669c833c3b5SJed Brown { 670c833c3b5SJed Brown DMRefineHookLink link,next; 671c833c3b5SJed Brown for (link=(*dm)->refinehook; link; link=next) { 672c833c3b5SJed Brown next = link->next; 6739566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 674c833c3b5SJed Brown } 6750298fd71SBarry Smith (*dm)->refinehook = NULL; 676c833c3b5SJed Brown } 677be081cd6SPeter Brune { 678be081cd6SPeter Brune DMSubDomainHookLink link,next; 679be081cd6SPeter Brune for (link=(*dm)->subdomainhook; link; link=next) { 680be081cd6SPeter Brune next = link->next; 6819566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 682be081cd6SPeter Brune } 6830298fd71SBarry Smith (*dm)->subdomainhook = NULL; 684be081cd6SPeter Brune } 685baf369e7SPeter Brune { 686baf369e7SPeter Brune DMGlobalToLocalHookLink link,next; 687baf369e7SPeter Brune for (link=(*dm)->gtolhook; link; link=next) { 688baf369e7SPeter Brune next = link->next; 6899566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 690baf369e7SPeter Brune } 6910298fd71SBarry Smith (*dm)->gtolhook = NULL; 692baf369e7SPeter Brune } 693d4d07f1eSToby Isaac { 694d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,next; 695d4d07f1eSToby Isaac for (link=(*dm)->ltoghook; link; link=next) { 696d4d07f1eSToby Isaac next = link->next; 6979566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 698d4d07f1eSToby Isaac } 699d4d07f1eSToby Isaac (*dm)->ltoghook = NULL; 700d4d07f1eSToby Isaac } 701aa1993deSMatthew G Knepley /* Destroy the work arrays */ 702aa1993deSMatthew G Knepley { 703aa1993deSMatthew G Knepley DMWorkLink link,next; 7047a8be351SBarry Smith PetscCheck(!(*dm)->workout,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out"); 705aa1993deSMatthew G Knepley for (link=(*dm)->workin; link; link=next) { 706aa1993deSMatthew G Knepley next = link->next; 7079566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 7089566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 709aa1993deSMatthew G Knepley } 7100298fd71SBarry Smith (*dm)->workin = NULL; 711aa1993deSMatthew G Knepley } 712c58f1c22SToby Isaac /* destroy the labels */ 7139566063dSJacob Faibussowitsch PetscCall(DMDestroyLabelLinkList_Internal(*dm)); 714f4cdcedcSVaclav Hapla /* destroy the fields */ 7159566063dSJacob Faibussowitsch PetscCall(DMClearFields(*dm)); 716f4cdcedcSVaclav Hapla /* destroy the boundaries */ 717e6f8dbb6SToby Isaac { 718e6f8dbb6SToby Isaac DMBoundary next = (*dm)->boundary; 719e6f8dbb6SToby Isaac while (next) { 720e6f8dbb6SToby Isaac DMBoundary b = next; 721e6f8dbb6SToby Isaac 722e6f8dbb6SToby Isaac next = b->next; 7239566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 724e6f8dbb6SToby Isaac } 725e6f8dbb6SToby Isaac } 726b17ce1afSJed Brown 7279566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmksp)); 7289566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmsnes)); 7299566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&(*dm)->dmts)); 73052536dc3SBarry Smith 7311a266240SBarry Smith if ((*dm)->ctx && (*dm)->ctxdestroy) { 7329566063dSJacob Faibussowitsch PetscCall((*(*dm)->ctxdestroy)(&(*dm)->ctx)); 7331a266240SBarry Smith } 7349566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&(*dm)->fd)); 7359566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap)); 7369566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->vectype)); 7379566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->mattype)); 73888ed4aceSMatthew G Knepley 7399566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->localSection)); 7409566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->globalSection)); 7419566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&(*dm)->map)); 7429566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&(*dm)->defaultConstraint.section)); 7439566063dSJacob Faibussowitsch PetscCall(MatDestroy(&(*dm)->defaultConstraint.mat)); 7449566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sf)); 7459566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sectionSF)); 746736995cdSBlaise Bourdin if ((*dm)->useNatural) { 747736995cdSBlaise Bourdin if ((*dm)->sfNatural) { 7489566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&(*dm)->sfNatural)); 749736995cdSBlaise Bourdin } 7509566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject) (*dm)->sfMigration)); 751736995cdSBlaise Bourdin } 7529a2a23afSMatthew G. Knepley { 7539a2a23afSMatthew G. Knepley Vec *auxData; 7549a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 7559a2a23afSMatthew G. Knepley 7569566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize((*dm)->auxData, &n)); 7579566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &auxData)); 7589566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetVals((*dm)->auxData, &off, auxData)); 7599566063dSJacob Faibussowitsch for (i = 0; i < n; ++i) PetscCall(VecDestroy(&auxData[i])); 7609566063dSJacob Faibussowitsch PetscCall(PetscFree(auxData)); 7619566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&(*dm)->auxData)); 7629a2a23afSMatthew G. Knepley } 76388bdff64SToby Isaac if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) { 7649566063dSJacob Faibussowitsch PetscCall(DMSetFineDM((*dm)->coarseMesh,NULL)); 76588bdff64SToby Isaac } 7666eb26441SStefano Zampini 7679566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->coarseMesh)); 76888bdff64SToby Isaac if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) { 7699566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM((*dm)->fineMesh,NULL)); 77088bdff64SToby Isaac } 7719566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->fineMesh)); 7724fb89dddSMatthew G. Knepley PetscCall(PetscFree((*dm)->Lstart)); 7739566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->L)); 7749566063dSJacob Faibussowitsch PetscCall(PetscFree((*dm)->maxCell)); 7756858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[0])); 7766858538eSMatthew G. Knepley PetscCall(DMDestroyCoordinates_Private(&(*dm)->coordinates[1])); 7779566063dSJacob Faibussowitsch if ((*dm)->transformDestroy) PetscCall((*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx)); 7789566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->transformDM)); 7799566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*dm)->transform)); 7806636e97aSMatthew G Knepley 7819566063dSJacob Faibussowitsch PetscCall(DMClearDS(*dm)); 7829566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*dm)->dmBC)); 783e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 7849566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*dm)); 785732e2eb9SMatthew G Knepley 786ed3c66a1SDave May if ((*dm)->ops->destroy) { 7879566063dSJacob Faibussowitsch PetscCall((*(*dm)->ops->destroy)(*dm)); 788ed3c66a1SDave May } 7899566063dSJacob Faibussowitsch PetscCall(DMMonitorCancel(*dm)); 790f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 7919566063dSJacob Faibussowitsch PetscCallCEED(CeedElemRestrictionDestroy(&(*dm)->ceedERestrict)); 7929566063dSJacob Faibussowitsch PetscCallCEED(CeedDestroy(&(*dm)->ceed)); 793f918ec44SMatthew G. Knepley #endif 794435a35e8SMatthew G Knepley /* We do not destroy (*dm)->data here so that we can reference count backend objects */ 7959566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(dm)); 79647c6ae99SBarry Smith PetscFunctionReturn(0); 79747c6ae99SBarry Smith } 79847c6ae99SBarry Smith 799d7bf68aeSBarry Smith /*@ 800bb7acecfSBarry Smith DMSetUp - sets up the data structures inside a `DM` object 801d7bf68aeSBarry Smith 802d083f849SBarry Smith Collective on dm 803d7bf68aeSBarry Smith 804d7bf68aeSBarry Smith Input Parameter: 805bb7acecfSBarry Smith . dm - the `DM` object to setup 806d7bf68aeSBarry Smith 807bb7acecfSBarry Smith Level: intermediate 808d7bf68aeSBarry Smith 809bb7acecfSBarry Smith Note: 810bb7acecfSBarry Smith This is usually called after various parameter setting operations and `DMSetFromOptions()` are called on the `DM` 811bb7acecfSBarry Smith 812bb7acecfSBarry Smith .seealso: `DM`, `DMCreate()`, `DMSetType()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 813d7bf68aeSBarry Smith 814d7bf68aeSBarry Smith @*/ 8157087cfbeSBarry Smith PetscErrorCode DMSetUp(DM dm) 816d7bf68aeSBarry Smith { 817d7bf68aeSBarry Smith PetscFunctionBegin; 818171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8198387afaaSJed Brown if (dm->setupcalled) PetscFunctionReturn(0); 820*dbbe0bcdSBarry Smith PetscTryTypeMethod(dm,setup); 8218387afaaSJed Brown dm->setupcalled = PETSC_TRUE; 822d7bf68aeSBarry Smith PetscFunctionReturn(0); 823d7bf68aeSBarry Smith } 824d7bf68aeSBarry Smith 825d7bf68aeSBarry Smith /*@ 826bb7acecfSBarry Smith DMSetFromOptions - sets parameters in a `DM` from the options database 827d7bf68aeSBarry Smith 828d083f849SBarry Smith Collective on dm 829d7bf68aeSBarry Smith 830d7bf68aeSBarry Smith Input Parameter: 831bb7acecfSBarry Smith . dm - the `DM` object to set options for 832d7bf68aeSBarry Smith 833732e2eb9SMatthew G Knepley Options Database: 834bb7acecfSBarry Smith + -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 835bb7acecfSBarry Smith . -dm_vec_type <type> - type of vector to create inside `DM` 836bb7acecfSBarry Smith . -dm_mat_type <type> - type of matrix to create inside `DM` 837a4ea9b21SRichard Tran Mills . -dm_is_coloring_type - <global or local> 838bb7acecfSBarry 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` 839732e2eb9SMatthew G Knepley 8409318fe57SMatthew G. Knepley DMPLEX Specific creation options 8419318fe57SMatthew G. Knepley + -dm_plex_filename <str> - File containing a mesh 8429318fe57SMatthew G. Knepley . -dm_plex_boundary_filename <str> - File containing a mesh boundary 843cd7e8a5eSksagiyam . -dm_plex_name <str> - Name of the mesh in the file 844bb7acecfSBarry Smith . -dm_plex_shape <shape> - The domain shape, such as `DM_SHAPE_BOX`, `DM_SHAPE_SPHERE`, etc. 8459318fe57SMatthew G. Knepley . -dm_plex_cell <ct> - Cell shape 8469318fe57SMatthew G. Knepley . -dm_plex_reference_cell_domain <bool> - Use a reference cell domain 8479318fe57SMatthew G. Knepley . -dm_plex_dim <dim> - Set the topological dimension 848bb7acecfSBarry Smith . -dm_plex_simplex <bool> - `PETSC_TRUE` for simplex elements, `PETSC_FALSE` for tensor elements 849bb7acecfSBarry Smith . -dm_plex_interpolate <bool> - `PETSC_TRUE` turns on topological interpolation (creating edges and faces) 8509318fe57SMatthew G. Knepley . -dm_plex_scale <sc> - Scale factor for mesh coordinates 8519318fe57SMatthew G. Knepley . -dm_plex_box_faces <m,n,p> - Number of faces along each dimension 8529318fe57SMatthew G. Knepley . -dm_plex_box_lower <x,y,z> - Specify lower-left-bottom coordinates for the box 8539318fe57SMatthew G. Knepley . -dm_plex_box_upper <x,y,z> - Specify upper-right-top coordinates for the box 854bb7acecfSBarry Smith . -dm_plex_box_bd <bx,by,bz> - Specify the `DMBoundaryType `for each direction 8559318fe57SMatthew G. Knepley . -dm_plex_sphere_radius <r> - The sphere radius 8569318fe57SMatthew G. Knepley . -dm_plex_ball_radius <r> - Radius of the ball 8579318fe57SMatthew G. Knepley . -dm_plex_cylinder_bd <bz> - Boundary type in the z direction 8589318fe57SMatthew G. Knepley . -dm_plex_cylinder_num_wedges <n> - Number of wedges around the cylinder 859bdf63967SMatthew G. Knepley . -dm_plex_reorder <order> - Reorder the mesh using the specified algorithm 8609318fe57SMatthew G. Knepley . -dm_refine_pre <n> - The number of refinements before distribution 8619318fe57SMatthew G. Knepley . -dm_refine_uniform_pre <bool> - Flag for uniform refinement before distribution 8629318fe57SMatthew G. Knepley . -dm_refine_volume_limit_pre <v> - The maximum cell volume after refinement before distribution 8639318fe57SMatthew G. Knepley . -dm_refine <n> - The number of refinements after distribution 864bdf63967SMatthew G. Knepley . -dm_extrude <l> - Activate extrusion and specify the number of layers to extrude 865d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers 866d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding 867d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface 868d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction 869d410b0cfSMatthew G. Knepley . -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer 870909dfd52SMatthew G. Knepley . -dm_plex_create_fv_ghost_cells - Flag to create finite volume ghost cells on the boundary 871909dfd52SMatthew G. Knepley . -dm_plex_fv_ghost_cells_label <name> - Label name for ghost cells boundary 8729318fe57SMatthew G. Knepley . -dm_distribute <bool> - Flag to redistribute a mesh among processes 8739318fe57SMatthew G. Knepley . -dm_distribute_overlap <n> - The size of the overlap halo 8749318fe57SMatthew G. Knepley . -dm_plex_adj_cone <bool> - Set adjacency direction 8759318fe57SMatthew G. Knepley - -dm_plex_adj_closure <bool> - Set adjacency size 8769318fe57SMatthew G. Knepley 877384a6580SVaclav Hapla DMPLEX Specific Checks 878bb7acecfSBarry Smith + -dm_plex_check_symmetry - Check that the adjacency information in the mesh is symmetric - `DMPlexCheckSymmetry()` 879bb7acecfSBarry Smith . -dm_plex_check_skeleton - Check that each cell has the correct number of vertices (only for homogeneous simplex or tensor meshes) - `DMPlexCheckSkeleton()` 880bb7acecfSBarry 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()` 881bb7acecfSBarry Smith . -dm_plex_check_geometry - Check that cells have positive volume - `DMPlexCheckGeometry()` 882bb7acecfSBarry Smith . -dm_plex_check_pointsf - Check some necessary conditions for `PointSF` - `DMPlexCheckPointSF()` 883bb7acecfSBarry Smith . -dm_plex_check_interface_cones - Check points on inter-partition interfaces have conforming order of cone points - `DMPlexCheckInterfaceCones()` 884384a6580SVaclav Hapla - -dm_plex_check_all - Perform all the checks above 885d7bf68aeSBarry Smith 88695eb5ee5SVaclav Hapla Level: intermediate 88795eb5ee5SVaclav Hapla 888bb7acecfSBarry Smith .seealso: `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 889bb7acecfSBarry Smith `DMPlexCheckSymmetry()`, `DMPlexCheckSkeleton()`, `DMPlexCheckFaces()`, `DMPlexCheckGeometry()`, `DMPlexCheckPointSF()`, `DMPlexCheckInterfaceCones()`, 890bb7acecfSBarry Smith `DMSetOptionsPrefix()`, `DM`, `DMType`, `DMPLEX`, `DMDA` 891d7bf68aeSBarry Smith 892d7bf68aeSBarry Smith @*/ 8937087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm) 894d7bf68aeSBarry Smith { 8957781c08eSBarry Smith char typeName[256]; 896ca266f36SBarry Smith PetscBool flg; 897d7bf68aeSBarry Smith 898d7bf68aeSBarry Smith PetscFunctionBegin; 899171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 90049be4549SMatthew G. Knepley dm->setfromoptionscalled = PETSC_TRUE; 9019566063dSJacob Faibussowitsch if (dm->sf) PetscCall(PetscSFSetFromOptions(dm->sf)); 9029566063dSJacob Faibussowitsch if (dm->sectionSF) PetscCall(PetscSFSetFromOptions(dm->sectionSF)); 903d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)dm); 9049566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,NULL)); 9059566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg)); 9061baa6e33SBarry Smith if (flg) PetscCall(DMSetVecType(dm,typeName)); 9079566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype ? dm->mattype : typeName,typeName,sizeof(typeName),&flg)); 9081baa6e33SBarry Smith if (flg) PetscCall(DMSetMatType(dm,typeName)); 9099566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL)); 9109566063dSJacob 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)); 911*dbbe0bcdSBarry Smith PetscTryTypeMethod(dm,setfromoptions,PetscOptionsObject); 912f9ba7244SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 913*dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject) dm,PetscOptionsObject)); 914d0609cedSBarry Smith PetscOptionsEnd(); 915d7bf68aeSBarry Smith PetscFunctionReturn(0); 916d7bf68aeSBarry Smith } 917d7bf68aeSBarry Smith 918fc9bc008SSatish Balay /*@C 919bb7acecfSBarry Smith DMViewFromOptions - View a `DM` in a particular way based on a request in the options database 920fe2efc57SMark 921bb7acecfSBarry Smith Collective on dm 922fe2efc57SMark 923fe2efc57SMark Input Parameters: 924bb7acecfSBarry Smith + dm - the `DM` object 925bb7acecfSBarry Smith . obj - optional object that provides the prefix for the options database (if NULL then the prefix in obj is used) 926bb7acecfSBarry Smith - optionname - option string that is used to activate viewing 927fe2efc57SMark 928fe2efc57SMark Level: intermediate 929bb7acecfSBarry Smith 930bb7acecfSBarry Smith Note: 931bb7acecfSBarry Smith See `PetscObjectViewFromOptions()` for a list of values that can be provided in the options database to determine how the `DM` is viewed 932bb7acecfSBarry Smith 933bb7acecfSBarry Smith .seealso: `DM`, `DMView()`, `PetscObjectViewFromOptions()`, `DMCreate()`, `PetscObjectViewFromOptions()` 934fe2efc57SMark @*/ 935fe2efc57SMark PetscErrorCode DMViewFromOptions(DM dm,PetscObject obj,const char name[]) 936fe2efc57SMark { 937fe2efc57SMark PetscFunctionBegin; 938fe2efc57SMark PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9399566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)dm,obj,name)); 940fe2efc57SMark PetscFunctionReturn(0); 941fe2efc57SMark } 942fe2efc57SMark 943fe2efc57SMark /*@C 944bb7acecfSBarry 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 945bb7acecfSBarry Smith save the `DM` in a binary file to be loaded later or create a visualization of the `DM` 94647c6ae99SBarry Smith 947d083f849SBarry Smith Collective on dm 94847c6ae99SBarry Smith 949d8d19677SJose E. Roman Input Parameters: 950bb7acecfSBarry Smith + dm - the `DM` object to view 95147c6ae99SBarry Smith - v - the viewer 95247c6ae99SBarry Smith 953cd7e8a5eSksagiyam Notes: 954bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` as the `PetscViewerFormat` one can save multiple `DMPLEX` 955bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 956bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 957cd7e8a5eSksagiyam 958224748a4SBarry Smith Level: beginner 95947c6ae99SBarry Smith 960bb7acecfSBarry Smith .seealso: `PetscViewer`, `PetscViewerFormat`, `PetscViewerSetFormat`(), `DMDestroy()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMLoad()`, `PetscObjectSetName()` 96147c6ae99SBarry Smith 96247c6ae99SBarry Smith @*/ 9637087cfbeSBarry Smith PetscErrorCode DMView(DM dm,PetscViewer v) 96447c6ae99SBarry Smith { 96532c0f0efSBarry Smith PetscBool isbinary; 96676a8abe0SBarry Smith PetscMPIInt size; 96776a8abe0SBarry Smith PetscViewerFormat format; 96847c6ae99SBarry Smith 96947c6ae99SBarry Smith PetscFunctionBegin; 970171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 9713014e516SBarry Smith if (!v) { 9729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v)); 9733014e516SBarry Smith } 974b1b135c8SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,2); 97574903a4fSStefano Zampini /* Ideally, we would like to have this test on. 97674903a4fSStefano Zampini However, it currently breaks socket viz via GLVis. 97774903a4fSStefano Zampini During DMView(parallel_mesh,glvis_viewer), each 97874903a4fSStefano Zampini process opens a sequential ASCII socket to visualize 97974903a4fSStefano Zampini the local mesh, and PetscObjectView(dm,local_socket) 98074903a4fSStefano Zampini is internally called inside VecView_GLVis, incurring 98174903a4fSStefano Zampini in an error here */ 98274903a4fSStefano Zampini /* PetscCheckSameComm(dm,1,v,2); */ 9839566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckWritable(v)); 984b1b135c8SBarry Smith 9859566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(v,&format)); 9869566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size)); 98776a8abe0SBarry Smith if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 9889566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)dm,v)); 9899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary)); 99032c0f0efSBarry Smith if (isbinary) { 99155849f57SBarry Smith PetscInt classid = DM_FILE_CLASSID; 99232c0f0efSBarry Smith char type[256]; 99332c0f0efSBarry Smith 9949566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v,&classid,1,PETSC_INT)); 9959566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type,((PetscObject)dm)->type_name,256)); 9969566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(v,type,256,PETSC_CHAR)); 99732c0f0efSBarry Smith } 998*dbbe0bcdSBarry Smith PetscTryTypeMethod(dm,view,v); 99947c6ae99SBarry Smith PetscFunctionReturn(0); 100047c6ae99SBarry Smith } 100147c6ae99SBarry Smith 100247c6ae99SBarry Smith /*@ 1003bb7acecfSBarry 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, 1004bb7acecfSBarry Smith that is it has no ghost locations. 100547c6ae99SBarry Smith 1006d083f849SBarry Smith Collective on dm 100747c6ae99SBarry Smith 100847c6ae99SBarry Smith Input Parameter: 1009bb7acecfSBarry Smith . dm - the `DM` object 101047c6ae99SBarry Smith 101147c6ae99SBarry Smith Output Parameter: 101247c6ae99SBarry Smith . vec - the global vector 101347c6ae99SBarry Smith 1014073dac72SJed Brown Level: beginner 101547c6ae99SBarry Smith 1016bb7acecfSBarry Smith .seealso: `Vec`, `DMCreateLocalVector()`, `DMGetGlobalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1017bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 101847c6ae99SBarry Smith 101947c6ae99SBarry Smith @*/ 10207087cfbeSBarry Smith PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec) 102147c6ae99SBarry Smith { 102247c6ae99SBarry Smith PetscFunctionBegin; 1023171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1024b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 1025*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,createglobalvector ,vec); 102676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1027c6b011d8SStefano Zampini DM vdm; 1028c6b011d8SStefano Zampini 10299566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec,&vdm)); 10307a8be351SBarry Smith PetscCheck(vdm,PETSC_COMM_SELF,PETSC_ERR_PLIB,"DM type '%s' did not attach the DM to the vector",((PetscObject)dm)->type_name); 1031c6b011d8SStefano Zampini } 103247c6ae99SBarry Smith PetscFunctionReturn(0); 103347c6ae99SBarry Smith } 103447c6ae99SBarry Smith 103547c6ae99SBarry Smith /*@ 1036bb7acecfSBarry Smith DMCreateLocalVector - Creates a local vector from a `DM` object. 103747c6ae99SBarry Smith 103847c6ae99SBarry Smith Not Collective 103947c6ae99SBarry Smith 104047c6ae99SBarry Smith Input Parameter: 1041bb7acecfSBarry Smith . dm - the `DM` object 104247c6ae99SBarry Smith 104347c6ae99SBarry Smith Output Parameter: 104447c6ae99SBarry Smith . vec - the local vector 104547c6ae99SBarry Smith 1046073dac72SJed Brown Level: beginner 104747c6ae99SBarry Smith 1048bb7acecfSBarry Smith Notes: 1049bb7acecfSBarry 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. 1050bb7acecfSBarry Smith 1051bb7acecfSBarry Smith .seealso: `Vec`, `DMCreateGlobalVector()`, `DMGetLocalVector()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()` 1052bb7acecfSBarry Smith `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()` 105347c6ae99SBarry Smith 105447c6ae99SBarry Smith @*/ 10557087cfbeSBarry Smith PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec) 105647c6ae99SBarry Smith { 105747c6ae99SBarry Smith PetscFunctionBegin; 1058171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1059b9d85ea2SLisandro Dalcin PetscValidPointer(vec,2); 1060*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,createlocalvector ,vec); 106176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1062c6b011d8SStefano Zampini DM vdm; 1063c6b011d8SStefano Zampini 10649566063dSJacob Faibussowitsch PetscCall(VecGetDM(*vec,&vdm)); 10657a8be351SBarry Smith PetscCheck(vdm,PETSC_COMM_SELF,PETSC_ERR_LIB,"DM type '%s' did not attach the DM to the vector",((PetscObject)dm)->type_name); 1066c6b011d8SStefano Zampini } 106747c6ae99SBarry Smith PetscFunctionReturn(0); 106847c6ae99SBarry Smith } 106947c6ae99SBarry Smith 10701411c6eeSJed Brown /*@ 1071bb7acecfSBarry Smith DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a `DM`. 10721411c6eeSJed Brown 1073d083f849SBarry Smith Collective on dm 10741411c6eeSJed Brown 10751411c6eeSJed Brown Input Parameter: 1076bb7acecfSBarry Smith . dm - the `DM` that provides the mapping 10771411c6eeSJed Brown 10781411c6eeSJed Brown Output Parameter: 10791411c6eeSJed Brown . ltog - the mapping 10801411c6eeSJed Brown 1081bb7acecfSBarry Smith Level: advanced 10821411c6eeSJed Brown 10831411c6eeSJed Brown Notes: 1084bb7acecfSBarry Smith The global to local mapping allows one to set values into the global vector or matrix using `VecSetValuesLocal()` and `MatSetValuesLocal()` 10851411c6eeSJed Brown 1086bb7acecfSBarry Smith Vectors obtained with `DMCreateGlobalVector()` and matrices obtained with `DMCreateMatrix()` already contain the global mapping so you do 1087bb7acecfSBarry Smith need to use this function with those objects. 1088bb7acecfSBarry Smith 1089bb7acecfSBarry Smith This mapping can then be used by `VecSetLocalToGlobalMapping()` or `MatSetLocalToGlobalMapping()`. 1090bb7acecfSBarry Smith 1091bb7acecfSBarry Smith .seealso: `DMCreateLocalVector()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `VecSetLocalToGlobalMapping()`, `MatSetLocalToGlobalMapping()`, 1092bb7acecfSBarry Smith `DMCreateMatrix()` 10931411c6eeSJed Brown @*/ 10947087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog) 10951411c6eeSJed Brown { 10960be3e97aSMatthew G. Knepley PetscInt bs = -1, bsLocal[2], bsMinMax[2]; 10971411c6eeSJed Brown 10981411c6eeSJed Brown PetscFunctionBegin; 10991411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 11001411c6eeSJed Brown PetscValidPointer(ltog,2); 11011411c6eeSJed Brown if (!dm->ltogmap) { 110237d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 110337d0c07bSMatthew G Knepley 11049566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 110537d0c07bSMatthew G Knepley if (section) { 1106a974ec88SMatthew G. Knepley const PetscInt *cdofs; 110737d0c07bSMatthew G Knepley PetscInt *ltog; 1108ccf3bd66SMatthew G. Knepley PetscInt pStart, pEnd, n, p, k, l; 110937d0c07bSMatthew G Knepley 11109566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 11119566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(section, &pStart, &pEnd)); 11129566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(section, &n)); 11139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, <og)); /* We want the local+overlap size */ 111437d0c07bSMatthew G Knepley for (p = pStart, l = 0; p < pEnd; ++p) { 1115e6befd46SJed Brown PetscInt bdof, cdof, dof, off, c, cind; 111637d0c07bSMatthew G Knepley 111737d0c07bSMatthew G Knepley /* Should probably use constrained dofs */ 11189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(section, p, &dof)); 11199566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(section, p, &cdof)); 11209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(section, p, &cdofs)); 11219566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &off)); 11221a7dc684SMatthew G. Knepley /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */ 11231a7dc684SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 11241a7dc684SMatthew G. Knepley if (dof) { 11255b8243e1SJed Brown bs = bs < 0 ? bdof : PetscGCD(bs, bdof); 11261a7dc684SMatthew G. Knepley } 11275227eafbSStefano Zampini 1128e6befd46SJed Brown for (c = 0, cind = 0; c < dof; ++c, ++l) { 11295227eafbSStefano Zampini if (cind < cdof && c == cdofs[cind]) { 1130e6befd46SJed Brown ltog[l] = off < 0 ? off-c : -(off+c+1); 1131e6befd46SJed Brown cind++; 1132e6befd46SJed Brown } else { 11335227eafbSStefano Zampini ltog[l] = (off < 0 ? -(off+1) : off) + c - cind; 1134e6befd46SJed Brown } 113537d0c07bSMatthew G Knepley } 113637d0c07bSMatthew G Knepley } 1137bff27382SMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 11380be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 11399566063dSJacob Faibussowitsch PetscCall(PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax)); 11400be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 11410be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 11427591dbb2SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 11437591dbb2SMatthew G. Knepley /* Must reduce indices by blocksize */ 1144ccf3bd66SMatthew G. Knepley if (bs > 1) { 1145ca469d19SJed Brown for (l = 0, k = 0; l < n; l += bs, ++k) { 1146ca469d19SJed Brown // Integer division of negative values truncates toward zero(!), not toward negative infinity 1147ca469d19SJed Brown ltog[k] = ltog[l] >= 0 ? ltog[l]/bs : -(-(ltog[l]+1)/bs + 1); 1148ca469d19SJed Brown } 1149ccf3bd66SMatthew G. Knepley n /= bs; 1150ccf3bd66SMatthew G. Knepley } 11519566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap)); 11529566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap)); 1153*dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm,getlocaltoglobalmapping); 115437d0c07bSMatthew G Knepley } 11551411c6eeSJed Brown *ltog = dm->ltogmap; 11561411c6eeSJed Brown PetscFunctionReturn(0); 11571411c6eeSJed Brown } 11581411c6eeSJed Brown 11591411c6eeSJed Brown /*@ 1160bb7acecfSBarry Smith DMGetBlockSize - Gets the inherent block size associated with a `DM` 11611411c6eeSJed Brown 11621411c6eeSJed Brown Not Collective 11631411c6eeSJed Brown 11641411c6eeSJed Brown Input Parameter: 1165bb7acecfSBarry Smith . dm - the `DM` with block structure 11661411c6eeSJed Brown 11671411c6eeSJed Brown Output Parameter: 11681411c6eeSJed Brown . bs - the block size, 1 implies no exploitable block structure 11691411c6eeSJed Brown 11701411c6eeSJed Brown Level: intermediate 11711411c6eeSJed Brown 1172bb7acecfSBarry Smith Note: 1173bb7acecfSBarry Smith This might be the number of degrees of freedom at each grid point for a structured grid. 1174bb7acecfSBarry Smith 1175bb7acecfSBarry Smith Complex `DM` that represent multiphysics or staggered grids or mixed-methods do not generally have a single inherent block size, but 1176bb7acecfSBarry Smith rather different locations in the vectors may have a different block size. 1177bb7acecfSBarry Smith 1178db781477SPatrick Sanan .seealso: `ISCreateBlock()`, `VecSetBlockSize()`, `MatSetBlockSize()`, `DMGetLocalToGlobalMapping()` 11791411c6eeSJed Brown @*/ 11807087cfbeSBarry Smith PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs) 11811411c6eeSJed Brown { 11821411c6eeSJed Brown PetscFunctionBegin; 11831411c6eeSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1184534a8f05SLisandro Dalcin PetscValidIntPointer(bs,2); 11857a8be351SBarry Smith PetscCheck(dm->bs >= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DM does not have enough information to provide a block size yet"); 11861411c6eeSJed Brown *bs = dm->bs; 11871411c6eeSJed Brown PetscFunctionReturn(0); 11881411c6eeSJed Brown } 11891411c6eeSJed Brown 119048eeb7c8SBarry Smith /*@C 1191bb7acecfSBarry Smith DMCreateInterpolation - Gets the interpolation matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1192bb7acecfSBarry Smith `DMCreateGlobalVector()` on the coarse `DM` to similar vectors on the fine grid `DM`. 119347c6ae99SBarry Smith 1194a5bc1bf3SBarry Smith Collective on dmc 119547c6ae99SBarry Smith 1196d8d19677SJose E. Roman Input Parameters: 1197bb7acecfSBarry Smith + dmc - the `DM` object 1198bb7acecfSBarry Smith - dmf - the second, finer `DM` object 119947c6ae99SBarry Smith 1200d8d19677SJose E. Roman Output Parameters: 120147c6ae99SBarry Smith + mat - the interpolation 1202bb7acecfSBarry Smith - vec - the scaling (optional), see `DMCreateInterpolationScale()` 120347c6ae99SBarry Smith 120447c6ae99SBarry Smith Level: developer 120547c6ae99SBarry Smith 120695452b02SPatrick Sanan Notes: 1207bb7acecfSBarry 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 1208bb7acecfSBarry Smith DMCoarsen(). The coordinates set into the `DMDA` are completely ignored in computing the interpolation. 1209d52bd9f3SBarry Smith 1210bb7acecfSBarry Smith For `DMDA` objects you can use this interpolation (more precisely the interpolation from the `DMGetCoordinateDM()`) to interpolate the mesh coordinate 1211bb7acecfSBarry Smith vectors EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic. 121285afcc9aSBarry Smith 1213bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolationScale()` 121447c6ae99SBarry Smith 121547c6ae99SBarry Smith @*/ 1216a5bc1bf3SBarry Smith PetscErrorCode DMCreateInterpolation(DM dmc,DM dmf,Mat *mat,Vec *vec) 121747c6ae99SBarry Smith { 121847c6ae99SBarry Smith PetscFunctionBegin; 1219a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1220a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 1221c7d20fa0SStefano Zampini PetscValidPointer(mat,3); 12229566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInterpolation,dmc,dmf,0,0)); 1223*dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc,createinterpolation ,dmf,mat,vec); 12249566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInterpolation,dmc,dmf,0,0)); 122547c6ae99SBarry Smith PetscFunctionReturn(0); 122647c6ae99SBarry Smith } 122747c6ae99SBarry Smith 12283ad4599aSBarry Smith /*@ 1229bb7acecfSBarry Smith DMCreateInterpolationScale - Forms L = 1/(R*1) where 1 is the vector of all ones, and R is the transpose of the interpolation between the `DM`. 1230bb7acecfSBarry Smith xcoarse = diag(L)*R*xfine preserves scale and is thus suitable for state (versus residual) restriction. In other words xcoarse is the coarse 1231bb7acecfSBarry Smith representation of xfine. 12322ed6491fSPatrick Sanan 12332ed6491fSPatrick Sanan Input Parameters: 1234bb7acecfSBarry Smith + dac - `DM` that defines a coarse mesh 1235bb7acecfSBarry Smith . daf - `DM` that defines a fine mesh 12362ed6491fSPatrick Sanan - mat - the restriction (or interpolation operator) from fine to coarse 12372ed6491fSPatrick Sanan 12382ed6491fSPatrick Sanan Output Parameter: 12392ed6491fSPatrick Sanan . scale - the scaled vector 12402ed6491fSPatrick Sanan 1241bb7acecfSBarry Smith Level: advanced 12422ed6491fSPatrick Sanan 1243e9c74fd6SRichard Tran Mills Developer Notes: 1244bb7acecfSBarry Smith If the fine-scale `DMDA` has the -dm_bind_below option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 1245e9c74fd6SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 1246e9c74fd6SRichard Tran Mills 1247bb7acecfSBarry Smith .seealso: `MatRestrict()`, `MatInterpolate()`, `DMCreateInterpolation()`, DMCreateRestriction()`, `DMCreateGlobalVector()` 12482ed6491fSPatrick Sanan 12492ed6491fSPatrick Sanan @*/ 12502ed6491fSPatrick Sanan PetscErrorCode DMCreateInterpolationScale(DM dac,DM daf,Mat mat,Vec *scale) 12512ed6491fSPatrick Sanan { 12522ed6491fSPatrick Sanan Vec fine; 12532ed6491fSPatrick Sanan PetscScalar one = 1.0; 12549704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 1255e9c74fd6SRichard Tran Mills PetscBool bindingpropagates,isbound; 12569704db99SRichard Tran Mills #endif 12572ed6491fSPatrick Sanan 12582ed6491fSPatrick Sanan PetscFunctionBegin; 12599566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(daf,&fine)); 12609566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dac,scale)); 12619566063dSJacob Faibussowitsch PetscCall(VecSet(fine,one)); 12629704db99SRichard Tran Mills #if defined(PETSC_HAVE_CUDA) 12639704db99SRichard Tran Mills /* If the 'fine' Vec is bound to the CPU, it makes sense to bind 'mat' as well. 12649704db99SRichard Tran Mills * Note that we only do this for the CUDA case, right now, but if we add support for MatMultTranspose() via ViennaCL, 12659704db99SRichard Tran Mills * we'll need to do it for that case, too.*/ 12669566063dSJacob Faibussowitsch PetscCall(VecGetBindingPropagates(fine,&bindingpropagates)); 1267e9c74fd6SRichard Tran Mills if (bindingpropagates) { 12689566063dSJacob Faibussowitsch PetscCall(MatSetBindingPropagates(mat,PETSC_TRUE)); 12699566063dSJacob Faibussowitsch PetscCall(VecBoundToCPU(fine,&isbound)); 12709566063dSJacob Faibussowitsch PetscCall(MatBindToCPU(mat,isbound)); 127183aa49f4SRichard Tran Mills } 12729704db99SRichard Tran Mills #endif 12739566063dSJacob Faibussowitsch PetscCall(MatRestrict(mat,fine,*scale)); 12749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fine)); 12759566063dSJacob Faibussowitsch PetscCall(VecReciprocal(*scale)); 12762ed6491fSPatrick Sanan PetscFunctionReturn(0); 12772ed6491fSPatrick Sanan } 12782ed6491fSPatrick Sanan 12792ed6491fSPatrick Sanan /*@ 1280bb7acecfSBarry Smith DMCreateRestriction - Gets restriction matrix between two `DM` objects. The resulting matrix map degrees of freedom in the vector obtained by 1281bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine `DM` to similar vectors on the coarse grid `DM`. 12823ad4599aSBarry Smith 1283a5bc1bf3SBarry Smith Collective on dmc 12843ad4599aSBarry Smith 1285d8d19677SJose E. Roman Input Parameters: 1286bb7acecfSBarry Smith + dmc - the `DM` object 1287bb7acecfSBarry Smith - dmf - the second, finer `DM` object 12883ad4599aSBarry Smith 12893ad4599aSBarry Smith Output Parameter: 12903ad4599aSBarry Smith . mat - the restriction 12913ad4599aSBarry Smith 12923ad4599aSBarry Smith Level: developer 12933ad4599aSBarry Smith 1294bb7acecfSBarry Smith Note: 1295bb7acecfSBarry Smith This only works for `DMSTAG`. For many situations either the transpose of the operator obtained with `DMCreateInterpolation()` or that 1296bb7acecfSBarry Smith matrix multiplied by the vector obtained with `DMCreateInterpolationScale()` provides the desired object. 12973ad4599aSBarry Smith 1298bb7acecfSBarry Smith .seealso: `DMRestrict()`, `DMInterpolate()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateInterpolation()` 12993ad4599aSBarry Smith 13003ad4599aSBarry Smith @*/ 1301a5bc1bf3SBarry Smith PetscErrorCode DMCreateRestriction(DM dmc,DM dmf,Mat *mat) 13023ad4599aSBarry Smith { 13033ad4599aSBarry Smith PetscFunctionBegin; 1304a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmc,DM_CLASSID,1); 1305a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dmf,DM_CLASSID,2); 13065a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 13079566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateRestriction,dmc,dmf,0,0)); 1308*dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc,createrestriction ,dmf,mat); 13099566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateRestriction,dmc,dmf,0,0)); 13103ad4599aSBarry Smith PetscFunctionReturn(0); 13113ad4599aSBarry Smith } 13123ad4599aSBarry Smith 131347c6ae99SBarry Smith /*@ 1314bb7acecfSBarry Smith DMCreateInjection - Gets injection matrix between two `DM` objects. This is an operator that applied to a vector obtained with 1315bb7acecfSBarry Smith `DMCreateGlobalVector()` on the fine grid maps the values to a vector on the vector on the coarse `DM` by simply selecting the values 1316bb7acecfSBarry Smith on the coarse grid points. This compares to the operator obtained by `DMCreateRestriction()` or the transpose of the operator obtained 1317bb7acecfSBarry Smith by `DMCreateInterpolation()` that uses a "local weighted average" of the values around the coarse grid point as the coarse grid value. 131847c6ae99SBarry Smith 1319a5bc1bf3SBarry Smith Collective on dac 132047c6ae99SBarry Smith 1321d8d19677SJose E. Roman Input Parameters: 1322bb7acecfSBarry Smith + dac - the `DM` object 1323bb7acecfSBarry Smith - daf - the second, finer `DM` object 132447c6ae99SBarry Smith 132547c6ae99SBarry Smith Output Parameter: 13266dbf9973SLawrence Mitchell . mat - the injection 132747c6ae99SBarry Smith 132847c6ae99SBarry Smith Level: developer 132947c6ae99SBarry Smith 1330bb7acecfSBarry Smith Note: 1331bb7acecfSBarry 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 1332bb7acecfSBarry Smith `DMCoarsen()`. The coordinates set into the `DMDA` are completely ignored in computing the injection. 133385afcc9aSBarry Smith 1334bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateInterpolation()`, 1335bb7acecfSBarry Smith `DMCreateRestriction()`, `MatRestrict()`, `MatInterpolate()` 133647c6ae99SBarry Smith 133747c6ae99SBarry Smith @*/ 1338a5bc1bf3SBarry Smith PetscErrorCode DMCreateInjection(DM dac,DM daf,Mat *mat) 133947c6ae99SBarry Smith { 134047c6ae99SBarry Smith PetscFunctionBegin; 1341a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dac,DM_CLASSID,1); 1342a5bc1bf3SBarry Smith PetscValidHeaderSpecific(daf,DM_CLASSID,2); 13435a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 13449566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateInjection,dac,daf,0,0)); 1345*dbbe0bcdSBarry Smith PetscUseTypeMethod(dac,createinjection ,daf,mat); 13469566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateInjection,dac,daf,0,0)); 134747c6ae99SBarry Smith PetscFunctionReturn(0); 134847c6ae99SBarry Smith } 134947c6ae99SBarry Smith 1350b412c318SBarry Smith /*@ 1351bb7acecfSBarry 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 1352bb7acecfSBarry Smith a Galerkin finite element model on the `DM` 1353bd041c0cSMatthew G. Knepley 1354a5bc1bf3SBarry Smith Collective on dac 1355bd041c0cSMatthew G. Knepley 1356d8d19677SJose E. Roman Input Parameters: 1357bb7acecfSBarry Smith + dmc - the target `DM` object 1358bb7acecfSBarry Smith - dmf - the source `DM` object 1359bd041c0cSMatthew G. Knepley 1360bd041c0cSMatthew G. Knepley Output Parameter: 1361b4937a87SMatthew G. Knepley . mat - the mass matrix 1362bd041c0cSMatthew G. Knepley 1363bd041c0cSMatthew G. Knepley Level: developer 1364bd041c0cSMatthew G. Knepley 1365bb7acecfSBarry Smith Notes: 1366bb7acecfSBarry Smith For `DMPLEX` the finite element model for the `DM` must have been already provided. 1367bb7acecfSBarry Smith 1368bb7acecfSBarry 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()` 1369bb7acecfSBarry Smith 1370bb7acecfSBarry Smith .seealso: `DMCreateMassMatrixLumped()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1371bd041c0cSMatthew G. Knepley @*/ 1372b4937a87SMatthew G. Knepley PetscErrorCode DMCreateMassMatrix(DM dmc, DM dmf, Mat *mat) 1373bd041c0cSMatthew G. Knepley { 1374bd041c0cSMatthew G. Knepley PetscFunctionBegin; 1375b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 1376b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 2); 13775a84ad33SLisandro Dalcin PetscValidPointer(mat,3); 13785b8ffe73SMark Adams PetscCall(PetscLogEventBegin(DM_CreateMassMatrix,0,0,0,0)); 1379*dbbe0bcdSBarry Smith PetscUseTypeMethod(dmc,createmassmatrix , dmf, mat); 13805b8ffe73SMark Adams PetscCall(PetscLogEventEnd(DM_CreateMassMatrix,0,0,0,0)); 1381b4937a87SMatthew G. Knepley PetscFunctionReturn(0); 1382b4937a87SMatthew G. Knepley } 1383b4937a87SMatthew G. Knepley 1384b4937a87SMatthew G. Knepley /*@ 1385bb7acecfSBarry Smith DMCreateMassMatrixLumped - Gets the lumped mass matrix for a given `DM` 1386b4937a87SMatthew G. Knepley 1387b4937a87SMatthew G. Knepley Collective on dm 1388b4937a87SMatthew G. Knepley 1389b4937a87SMatthew G. Knepley Input Parameter: 1390bb7acecfSBarry Smith . dm - the `DM` object 1391b4937a87SMatthew G. Knepley 1392b4937a87SMatthew G. Knepley Output Parameter: 1393bb7acecfSBarry Smith . lm - the lumped mass matrix, which is a diagonal matrix, represented as a vector 1394b4937a87SMatthew G. Knepley 1395b4937a87SMatthew G. Knepley Level: developer 1396b4937a87SMatthew G. Knepley 1397bb7acecfSBarry Smith Note: 1398bb7acecfSBarry Smith See `DMCreateMassMatrix()` for how to create the non-lumped version of the mass matrix. 1399bb7acecfSBarry Smith 1400bb7acecfSBarry Smith .seealso: `DMCreateMassMatrix()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMRefine()`, `DMCoarsen()`, `DMCreateRestriction()`, `DMCreateInterpolation()`, `DMCreateInjection()` 1401b4937a87SMatthew G. Knepley @*/ 1402b4937a87SMatthew G. Knepley PetscErrorCode DMCreateMassMatrixLumped(DM dm, Vec *lm) 1403b4937a87SMatthew G. Knepley { 1404b4937a87SMatthew G. Knepley PetscFunctionBegin; 1405b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1406b4937a87SMatthew G. Knepley PetscValidPointer(lm,2); 1407*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,createmassmatrixlumped , lm); 1408bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 1409bd041c0cSMatthew G. Knepley } 1410bd041c0cSMatthew G. Knepley 1411bd041c0cSMatthew G. Knepley /*@ 1412bb7acecfSBarry Smith DMCreateColoring - Gets coloring of a graph associated with the `DM`. Often the graph represents the operator matrix associated with the discretization 1413bb7acecfSBarry Smith of a PDE on the `DM`. 141447c6ae99SBarry Smith 1415d083f849SBarry Smith Collective on dm 141647c6ae99SBarry Smith 1417d8d19677SJose E. Roman Input Parameters: 1418bb7acecfSBarry Smith + dm - the `DM` object 1419bb7acecfSBarry Smith - ctype - `IS_COLORING_LOCAL` or `IS_COLORING_GLOBAL` 142047c6ae99SBarry Smith 142147c6ae99SBarry Smith Output Parameter: 142247c6ae99SBarry Smith . coloring - the coloring 142347c6ae99SBarry 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()` 1429ec5066bdSBarry Smith 143047c6ae99SBarry Smith Level: developer 143147c6ae99SBarry Smith 1432bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatType()`, `MatColoring`, `MatFDColoringCreate()` 143347c6ae99SBarry Smith 1434aab9d709SJed Brown @*/ 1435b412c318SBarry Smith PetscErrorCode DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring) 143647c6ae99SBarry Smith { 143747c6ae99SBarry Smith PetscFunctionBegin; 1438171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 14395a84ad33SLisandro Dalcin PetscValidPointer(coloring,3); 1440*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,getcoloring ,ctype,coloring); 144147c6ae99SBarry Smith PetscFunctionReturn(0); 144247c6ae99SBarry Smith } 144347c6ae99SBarry Smith 1444b412c318SBarry Smith /*@ 1445bb7acecfSBarry Smith DMCreateMatrix - Gets an empty matrix for a `DM` that is most commonly used to store the Jacobian of a discrete PDE operator. 144647c6ae99SBarry Smith 1447d083f849SBarry Smith Collective on dm 144847c6ae99SBarry Smith 144947c6ae99SBarry Smith Input Parameter: 1450bb7acecfSBarry Smith . dm - the `DM` object 145147c6ae99SBarry Smith 145247c6ae99SBarry Smith Output Parameter: 145347c6ae99SBarry Smith . mat - the empty Jacobian 145447c6ae99SBarry Smith 1455073dac72SJed Brown Level: beginner 145647c6ae99SBarry Smith 1457f27dd7c6SMatthew G. Knepley Options Database Keys: 1458bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()` and `DMCreateMassMatrix()`, but do not fill it with zeros 1459f27dd7c6SMatthew G. Knepley 146095452b02SPatrick Sanan Notes: 146195452b02SPatrick Sanan This properly preallocates the number of nonzeros in the sparse matrix so you 146294013140SBarry Smith do not need to do it yourself. 146394013140SBarry Smith 146494013140SBarry Smith By default it also sets the nonzero structure and puts in the zero entries. To prevent setting 1465bb7acecfSBarry Smith the nonzero pattern call `DMSetMatrixPreallocateOnly()` 146694013140SBarry Smith 1467bb7acecfSBarry Smith For `DMDA`, when you call `MatView()` on this matrix it is displayed using the global natural ordering, NOT in the ordering used 146894013140SBarry Smith internally by PETSc. 146994013140SBarry Smith 1470bb7acecfSBarry Smith For `DMDA`, in general it is easiest to use `MatSetValuesStencil()` or `MatSetValuesLocal()` to put values into the matrix because 1471bb7acecfSBarry Smith `MatSetValues()` requires the indices for the global numbering for the `DMDA` which is complic`ated to compute 147294013140SBarry Smith 1473bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMSetMatType()`, `DMCreateMassMatrix()` 147447c6ae99SBarry Smith 1475aab9d709SJed Brown @*/ 1476b412c318SBarry Smith PetscErrorCode DMCreateMatrix(DM dm,Mat *mat) 147747c6ae99SBarry Smith { 147847c6ae99SBarry Smith PetscFunctionBegin; 1479171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1480064a246eSJacob Faibussowitsch PetscValidPointer(mat,2); 14819566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 14829566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_CreateMatrix,0,0,0,0)); 1483*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,creatematrix ,mat); 148476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1485c6b011d8SStefano Zampini DM mdm; 1486c6b011d8SStefano Zampini 14879566063dSJacob Faibussowitsch PetscCall(MatGetDM(*mat,&mdm)); 14887a8be351SBarry Smith PetscCheck(mdm,PETSC_COMM_SELF,PETSC_ERR_PLIB,"DM type '%s' did not attach the DM to the matrix",((PetscObject)dm)->type_name); 1489c6b011d8SStefano Zampini } 1490e571a35bSMatthew G. Knepley /* Handle nullspace and near nullspace */ 1491e5e52638SMatthew G. Knepley if (dm->Nf) { 1492e571a35bSMatthew G. Knepley MatNullSpace nullSpace; 1493649ef022SMatthew Knepley PetscInt Nf, f; 1494e571a35bSMatthew G. Knepley 14959566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 1496649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1497649ef022SMatthew Knepley if (dm->nullspaceConstructors[f]) { 14989566063dSJacob Faibussowitsch PetscCall((*dm->nullspaceConstructors[f])(dm, f, f, &nullSpace)); 14999566063dSJacob Faibussowitsch PetscCall(MatSetNullSpace(*mat, nullSpace)); 15009566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1501649ef022SMatthew Knepley break; 1502e571a35bSMatthew G. Knepley } 1503649ef022SMatthew Knepley } 1504649ef022SMatthew Knepley for (f = 0; f < Nf; ++f) { 1505649ef022SMatthew Knepley if (dm->nearnullspaceConstructors[f]) { 15069566063dSJacob Faibussowitsch PetscCall((*dm->nearnullspaceConstructors[f])(dm, f, f, &nullSpace)); 15079566063dSJacob Faibussowitsch PetscCall(MatSetNearNullSpace(*mat, nullSpace)); 15089566063dSJacob Faibussowitsch PetscCall(MatNullSpaceDestroy(&nullSpace)); 1509e571a35bSMatthew G. Knepley } 1510e571a35bSMatthew G. Knepley } 1511e571a35bSMatthew G. Knepley } 15129566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_CreateMatrix,0,0,0,0)); 151347c6ae99SBarry Smith PetscFunctionReturn(0); 151447c6ae99SBarry Smith } 151547c6ae99SBarry Smith 1516732e2eb9SMatthew G Knepley /*@ 1517bb7acecfSBarry Smith DMSetMatrixPreallocateSkip - When `DMCreateMatrix()` is called the matrix sizes and `ISLocalToGlobalMapping` will be 1518bb7acecfSBarry Smith properly set, but the data structures to store values in the matrices will not be preallocated. This is most useful to reduce initialization costs when 1519bb7acecfSBarry Smith `MatSetPreallocationCOO()` and `MatSetValuesCOO()` will be used. 1520aa0f6e3cSJed Brown 1521aa0f6e3cSJed Brown Logically Collective on dm 1522aa0f6e3cSJed Brown 1523aa0f6e3cSJed Brown Input Parameters: 1524bb7acecfSBarry Smith + dm - the `DM` 1525bb7acecfSBarry Smith - skip - `PETSC_TRUE` to skip preallocation 1526aa0f6e3cSJed Brown 1527aa0f6e3cSJed Brown Level: developer 1528aa0f6e3cSJed Brown 1529bb7acecfSBarry Smith .seealso: `DMCreateMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateOnly()` 1530aa0f6e3cSJed Brown @*/ 1531aa0f6e3cSJed Brown PetscErrorCode DMSetMatrixPreallocateSkip(DM dm, PetscBool skip) 1532aa0f6e3cSJed Brown { 1533aa0f6e3cSJed Brown PetscFunctionBegin; 1534aa0f6e3cSJed Brown PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1535aa0f6e3cSJed Brown dm->prealloc_skip = skip; 1536aa0f6e3cSJed Brown PetscFunctionReturn(0); 1537aa0f6e3cSJed Brown } 1538aa0f6e3cSJed Brown 1539aa0f6e3cSJed Brown /*@ 1540bb7acecfSBarry Smith DMSetMatrixPreallocateOnly - When `DMCreateMatrix()` is called the matrix will be properly 1541732e2eb9SMatthew G Knepley preallocated but the nonzero structure and zero values will not be set. 1542732e2eb9SMatthew G Knepley 1543d083f849SBarry Smith Logically Collective on dm 1544732e2eb9SMatthew G Knepley 1545d8d19677SJose E. Roman Input Parameters: 1546bb7acecfSBarry Smith + dm - the `DM` 1547bb7acecfSBarry Smith - only - `PETSC_TRUE` if only want preallocation 1548732e2eb9SMatthew G Knepley 1549732e2eb9SMatthew G Knepley Level: developer 1550f27dd7c6SMatthew G. Knepley 1551f27dd7c6SMatthew G. Knepley Options Database Keys: 1552bb7acecfSBarry Smith . -dm_preallocate_only - Only preallocate the matrix for `DMCreateMatrix()`, `DMCreateMassMatrix()`, but do not fill it with zeros 1553f27dd7c6SMatthew G. Knepley 1554bb7acecfSBarry Smith .seealso: `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMSetMatrixStructureOnly()`, `DMSetMatrixPreallocateSkip()` 1555732e2eb9SMatthew G Knepley @*/ 1556732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only) 1557732e2eb9SMatthew G Knepley { 1558732e2eb9SMatthew G Knepley PetscFunctionBegin; 1559732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1560732e2eb9SMatthew G Knepley dm->prealloc_only = only; 1561732e2eb9SMatthew G Knepley PetscFunctionReturn(0); 1562732e2eb9SMatthew G Knepley } 1563732e2eb9SMatthew G Knepley 1564b06ff27eSHong Zhang /*@ 1565bb7acecfSBarry Smith DMSetMatrixStructureOnly - When `DMCreateMatrix()` is called, the matrix structure will be created 1566bb7acecfSBarry Smith but the array for numerical values will not be allocated. 1567b06ff27eSHong Zhang 1568d083f849SBarry Smith Logically Collective on dm 1569b06ff27eSHong Zhang 1570d8d19677SJose E. Roman Input Parameters: 1571bb7acecfSBarry Smith + dm - the `DM` 1572bb7acecfSBarry Smith - only - `PETSC_TRUE` if you only want matrix stucture 1573b06ff27eSHong Zhang 1574b06ff27eSHong Zhang Level: developer 1575bb7acecfSBarry Smith 1576bb7acecfSBarry Smith .seealso: `DMCreateMatrix()`, `DMSetMatrixPreallocateOnly()`, `DMSetMatrixPreallocateSkip()` 1577b06ff27eSHong Zhang @*/ 1578b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only) 1579b06ff27eSHong Zhang { 1580b06ff27eSHong Zhang PetscFunctionBegin; 1581b06ff27eSHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1582b06ff27eSHong Zhang dm->structure_only = only; 1583b06ff27eSHong Zhang PetscFunctionReturn(0); 1584b06ff27eSHong Zhang } 1585b06ff27eSHong Zhang 1586a89ea682SMatthew G Knepley /*@C 1587bb7acecfSBarry Smith DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with `DMRestoreWorkArray()` 1588a89ea682SMatthew G Knepley 1589a89ea682SMatthew G Knepley Not Collective 1590a89ea682SMatthew G Knepley 1591a89ea682SMatthew G Knepley Input Parameters: 1592bb7acecfSBarry Smith + dm - the `DM` object 1593a5b23f4aSJose E. Roman . count - The minimum size 1594bb7acecfSBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, or MPIU_INT) 1595a89ea682SMatthew G Knepley 1596a89ea682SMatthew G Knepley Output Parameter: 1597a89ea682SMatthew G Knepley . array - the work array 1598a89ea682SMatthew G Knepley 1599a89ea682SMatthew G Knepley Level: developer 1600a89ea682SMatthew G Knepley 1601bb7acecfSBarry Smith Note: 1602bb7acecfSBarry Smith A `DM` may stash the array between instantations so using this routine may be more efficient than calling `PetscMalloc()` 1603bb7acecfSBarry Smith 1604bb7acecfSBarry Smith The array may contain nonzero values 1605bb7acecfSBarry Smith 1606bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMCreate()`, `DMRestoreWorkArray()`, `PetscMalloc()` 1607a89ea682SMatthew G Knepley @*/ 160869291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1609a89ea682SMatthew G Knepley { 1610aa1993deSMatthew G Knepley DMWorkLink link; 161169291d52SBarry Smith PetscMPIInt dsize; 1612a89ea682SMatthew G Knepley 1613a89ea682SMatthew G Knepley PetscFunctionBegin; 1614a89ea682SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1615aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1616aa1993deSMatthew G Knepley if (dm->workin) { 1617aa1993deSMatthew G Knepley link = dm->workin; 1618aa1993deSMatthew G Knepley dm->workin = dm->workin->next; 1619aa1993deSMatthew G Knepley } else { 16209566063dSJacob Faibussowitsch PetscCall(PetscNewLog(dm,&link)); 1621a89ea682SMatthew G Knepley } 16229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_size(dtype,&dsize)); 16235056fcd2SBarry Smith if (((size_t)dsize*count) > link->bytes) { 16249566063dSJacob Faibussowitsch PetscCall(PetscFree(link->mem)); 16259566063dSJacob Faibussowitsch PetscCall(PetscMalloc(dsize*count,&link->mem)); 1626854ce69bSBarry Smith link->bytes = dsize*count; 1627aa1993deSMatthew G Knepley } 1628aa1993deSMatthew G Knepley link->next = dm->workout; 1629aa1993deSMatthew G Knepley dm->workout = link; 1630cea3dcb8SSatish Balay #if defined(__MEMCHECK_H) && (defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) || defined(PLAT_amd64_darwin)) 163100d952a4SJed Brown VALGRIND_MAKE_MEM_NOACCESS((char*)link->mem + (size_t)dsize*count, link->bytes - (size_t)dsize*count); 163200d952a4SJed Brown VALGRIND_MAKE_MEM_UNDEFINED(link->mem, (size_t)dsize*count); 163300d952a4SJed Brown #endif 1634aa1993deSMatthew G Knepley *(void**)mem = link->mem; 1635a89ea682SMatthew G Knepley PetscFunctionReturn(0); 1636a89ea682SMatthew G Knepley } 1637a89ea682SMatthew G Knepley 1638aa1993deSMatthew G Knepley /*@C 1639bb7acecfSBarry Smith DMRestoreWorkArray - Restores a work array obtained with `DMCreateWorkArray()` 1640aa1993deSMatthew G Knepley 1641aa1993deSMatthew G Knepley Not Collective 1642aa1993deSMatthew G Knepley 1643aa1993deSMatthew G Knepley Input Parameters: 1644bb7acecfSBarry Smith + dm - the `DM` object 1645a5b23f4aSJose E. Roman . count - The minimum size 164669291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT 1647aa1993deSMatthew G Knepley 1648aa1993deSMatthew G Knepley Output Parameter: 1649aa1993deSMatthew G Knepley . array - the work array 1650aa1993deSMatthew G Knepley 1651aa1993deSMatthew G Knepley Level: developer 1652aa1993deSMatthew G Knepley 165395452b02SPatrick Sanan Developer Notes: 1654bb7acecfSBarry Smith count and dtype are ignored, they are only needed for `DMGetWorkArray()` 1655147403d9SBarry Smith 1656bb7acecfSBarry Smith .seealso: `DMDestroy()`, `DMCreate()`, `DMGetWorkArray()` 1657aa1993deSMatthew G Knepley @*/ 165869291d52SBarry Smith PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem) 1659aa1993deSMatthew G Knepley { 1660aa1993deSMatthew G Knepley DMWorkLink *p,link; 1661aa1993deSMatthew G Knepley 1662aa1993deSMatthew G Knepley PetscFunctionBegin; 1663aa1993deSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 1664aa1993deSMatthew G Knepley PetscValidPointer(mem,4); 1665aa1993deSMatthew G Knepley for (p=&dm->workout; (link=*p); p=&link->next) { 1666aa1993deSMatthew G Knepley if (link->mem == *(void**)mem) { 1667aa1993deSMatthew G Knepley *p = link->next; 1668aa1993deSMatthew G Knepley link->next = dm->workin; 1669aa1993deSMatthew G Knepley dm->workin = link; 16700298fd71SBarry Smith *(void**)mem = NULL; 1671aa1993deSMatthew G Knepley PetscFunctionReturn(0); 1672aa1993deSMatthew G Knepley } 1673aa1993deSMatthew G Knepley } 1674aa1993deSMatthew G Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out"); 1675aa1993deSMatthew G Knepley } 1676e7c4fc90SDmitry Karpeev 16778cda7954SMatthew G. Knepley /*@C 1678bb7acecfSBarry Smith DMSetNullSpaceConstructor - Provide a callback function which constructs the nullspace for a given field, defined with `DMAddField()`, when function spaces 1679bb7acecfSBarry Smith are joined or split, such as in `DMCreateSubDM()` 16808cda7954SMatthew G. Knepley 1681bb7acecfSBarry Smith Logically collective on dm 16828cda7954SMatthew G. Knepley 16838cda7954SMatthew G. Knepley Input Parameters: 1684bb7acecfSBarry Smith + dm - The `DM` 16858cda7954SMatthew G. Knepley . field - The field number for the nullspace 16868cda7954SMatthew G. Knepley - nullsp - A callback to create the nullspace 16878cda7954SMatthew G. Knepley 1688147403d9SBarry Smith Calling sequence of nullsp: 1689147403d9SBarry Smith .vb 1690147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1691147403d9SBarry Smith .ve 1692bb7acecfSBarry Smith + dm - The present `DM` 1693bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1694147403d9SBarry Smith . field - The field number in dm 1695147403d9SBarry Smith - nullSpace - The nullspace for the given field 16968cda7954SMatthew G. Knepley 169749762cbcSSatish Balay Level: intermediate 169849762cbcSSatish Balay 1699bb7acecfSBarry Smith Fortran Notes: 1700bb7acecfSBarry Smith This function is not available from Fortran. 1701bb7acecfSBarry Smith 1702bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1703147403d9SBarry Smith @*/ 1704147403d9SBarry Smith PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM, PetscInt, PetscInt, MatNullSpace*)) 1705435a35e8SMatthew G Knepley { 1706435a35e8SMatthew G Knepley PetscFunctionBegin; 1707435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17087a8be351SBarry Smith PetscCheck(field < 10,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1709435a35e8SMatthew G Knepley dm->nullspaceConstructors[field] = nullsp; 1710435a35e8SMatthew G Knepley PetscFunctionReturn(0); 1711435a35e8SMatthew G Knepley } 1712435a35e8SMatthew G Knepley 17138cda7954SMatthew G. Knepley /*@C 1714bb7acecfSBarry Smith DMGetNullSpaceConstructor - Return the callback function which constructs the nullspace for a given field, defined with `DMAddField()` 17158cda7954SMatthew G. Knepley 17168cda7954SMatthew G. Knepley Not collective 17178cda7954SMatthew G. Knepley 17188cda7954SMatthew G. Knepley Input Parameters: 1719bb7acecfSBarry Smith + dm - The `DM` 17208cda7954SMatthew G. Knepley - field - The field number for the nullspace 17218cda7954SMatthew G. Knepley 17228cda7954SMatthew G. Knepley Output Parameter: 17238cda7954SMatthew G. Knepley . nullsp - A callback to create the nullspace 17248cda7954SMatthew G. Knepley 1725147403d9SBarry Smith Calling sequence of nullsp: 1726147403d9SBarry Smith .vb 1727147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1728147403d9SBarry Smith .ve 1729147403d9SBarry Smith + dm - The present DM 1730147403d9SBarry Smith . origField - The field number given above, in the original DM 1731147403d9SBarry Smith . field - The field number in dm 1732147403d9SBarry Smith - nullSpace - The nullspace for the given field 17338cda7954SMatthew G. Knepley 1734bb7acecfSBarry Smith Fortran Note: 1735bb7acecfSBarry Smith This function is not available from Fortran. 17368cda7954SMatthew G. Knepley 173749762cbcSSatish Balay Level: intermediate 173849762cbcSSatish Balay 1739bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetField()`, `DMSetNullSpaceConstructor()`, `DMSetNearNullSpaceConstructor()`, `DMGetNearNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 1740147403d9SBarry Smith @*/ 1741147403d9SBarry Smith PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM, PetscInt, PetscInt, MatNullSpace *)) 17420a50eb56SMatthew G. Knepley { 17430a50eb56SMatthew G. Knepley PetscFunctionBegin; 17440a50eb56SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1745f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 17467a8be351SBarry Smith PetscCheck(field < 10,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 17470a50eb56SMatthew G. Knepley *nullsp = dm->nullspaceConstructors[field]; 17480a50eb56SMatthew G. Knepley PetscFunctionReturn(0); 17490a50eb56SMatthew G. Knepley } 17500a50eb56SMatthew G. Knepley 17518cda7954SMatthew G. Knepley /*@C 1752bb7acecfSBarry Smith DMSetNearNullSpaceConstructor - Provide a callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 17538cda7954SMatthew G. Knepley 1754bb7acecfSBarry Smith Logically collective on dm 17558cda7954SMatthew G. Knepley 17568cda7954SMatthew G. Knepley Input Parameters: 1757bb7acecfSBarry Smith + dm - The `DM` 17588cda7954SMatthew G. Knepley . field - The field number for the nullspace 17598cda7954SMatthew G. Knepley - nullsp - A callback to create the near-nullspace 17608cda7954SMatthew G. Knepley 1761147403d9SBarry Smith Calling sequence of nullsp: 1762147403d9SBarry Smith .vb 1763147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1764147403d9SBarry Smith .ve 1765bb7acecfSBarry Smith + dm - The present `DM` 1766bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1767147403d9SBarry Smith . field - The field number in dm 1768147403d9SBarry Smith - nullSpace - The nullspace for the given field 17698cda7954SMatthew G. Knepley 1770bb7acecfSBarry Smith Fortran Note: 1771bb7acecfSBarry Smith This function is not available from Fortran. 17728cda7954SMatthew G. Knepley 177349762cbcSSatish Balay Level: intermediate 177449762cbcSSatish Balay 1775bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, `DMCreateSuperDM()`, 1776bb7acecfSBarry Smith `MatNullSpace` 1777147403d9SBarry Smith @*/ 1778147403d9SBarry Smith PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM, PetscInt, PetscInt, MatNullSpace *)) 1779f9d4088aSMatthew G. Knepley { 1780f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1781f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17827a8be351SBarry Smith PetscCheck(field < 10,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1783f9d4088aSMatthew G. Knepley dm->nearnullspaceConstructors[field] = nullsp; 1784f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1785f9d4088aSMatthew G. Knepley } 1786f9d4088aSMatthew G. Knepley 17878cda7954SMatthew G. Knepley /*@C 1788bb7acecfSBarry Smith DMGetNearNullSpaceConstructor - Return the callback function which constructs the near-nullspace for a given field, defined with `DMAddField()` 17898cda7954SMatthew G. Knepley 17908cda7954SMatthew G. Knepley Not collective 17918cda7954SMatthew G. Knepley 17928cda7954SMatthew G. Knepley Input Parameters: 1793bb7acecfSBarry Smith + dm - The `DM` 17948cda7954SMatthew G. Knepley - field - The field number for the nullspace 17958cda7954SMatthew G. Knepley 17968cda7954SMatthew G. Knepley Output Parameter: 17978cda7954SMatthew G. Knepley . nullsp - A callback to create the near-nullspace 17988cda7954SMatthew G. Knepley 1799147403d9SBarry Smith Calling sequence of nullsp: 1800147403d9SBarry Smith .vb 1801147403d9SBarry Smith PetscErrorCode nullsp(DM dm, PetscInt origField, PetscInt field, MatNullSpace *nullSpace) 1802147403d9SBarry Smith .ve 1803bb7acecfSBarry Smith + dm - The present `DM` 1804bb7acecfSBarry Smith . origField - The field number given above, in the original `DM` 1805147403d9SBarry Smith . field - The field number in dm 1806147403d9SBarry Smith - nullSpace - The nullspace for the given field 18078cda7954SMatthew G. Knepley 1808bb7acecfSBarry Smith Fortran Note: 1809bb7acecfSBarry Smith This function is not available from Fortran. 18108cda7954SMatthew G. Knepley 181149762cbcSSatish Balay Level: intermediate 181249762cbcSSatish Balay 1813bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetField()`, `DMSetNearNullSpaceConstructor()`, `DMSetNullSpaceConstructor()`, `DMGetNullSpaceConstructor()`, `DMCreateSubDM()`, 1814bb7acecfSBarry Smith `MatNullSpace`, `DMCreateSuperDM()` 1815147403d9SBarry Smith @*/ 1816147403d9SBarry Smith PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM, PetscInt, PetscInt, MatNullSpace *)) 1817f9d4088aSMatthew G. Knepley { 1818f9d4088aSMatthew G. Knepley PetscFunctionBegin; 1819f9d4088aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1820f9d4088aSMatthew G. Knepley PetscValidPointer(nullsp, 3); 18217a8be351SBarry Smith PetscCheck(field < 10,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %" PetscInt_FMT " >= 10 fields", field); 1822f9d4088aSMatthew G. Knepley *nullsp = dm->nearnullspaceConstructors[field]; 1823f9d4088aSMatthew G. Knepley PetscFunctionReturn(0); 1824f9d4088aSMatthew G. Knepley } 1825f9d4088aSMatthew G. Knepley 18264f3b5142SJed Brown /*@C 1827bb7acecfSBarry Smith DMCreateFieldIS - Creates a set of `IS` objects with the global indices of dofs for each field defined with `DMAddField()` 18284d343eeaSMatthew G Knepley 18294d343eeaSMatthew G Knepley Not collective 18304d343eeaSMatthew G Knepley 18314d343eeaSMatthew G Knepley Input Parameter: 1832bb7acecfSBarry Smith . dm - the `DM` object 18334d343eeaSMatthew G Knepley 18344d343eeaSMatthew G Knepley Output Parameters: 18350298fd71SBarry Smith + numFields - The number of fields (or NULL if not requested) 1836bb7acecfSBarry Smith . fieldNames - The number of each field (or NULL if not requested) 18370298fd71SBarry Smith - fields - The global indices for each field (or NULL if not requested) 18384d343eeaSMatthew G Knepley 18394d343eeaSMatthew G Knepley Level: intermediate 18404d343eeaSMatthew G Knepley 1841bb7acecfSBarry Smith Note: 184221c9b008SJed Brown The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1843bb7acecfSBarry Smith `PetscFree()`, every entry of fields should be destroyed with `ISDestroy()`, and both arrays should be freed with 1844bb7acecfSBarry Smith `PetscFree()`. 184521c9b008SJed Brown 1846bb7acecfSBarry Smith Fortran Note: 1847bb7acecfSBarry Smith Not available in Fortran. 1848bb7acecfSBarry Smith 1849bb7acecfSBarry Smith Developer Note: 1850bb7acecfSBarry Smith It is not clear why both this function and `DMCreateFieldDecomposition()` exist. Having two seems redundant and confusing. This function should 1851bb7acecfSBarry Smith likely be removed. 1852bb7acecfSBarry Smith 1853bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMGetField()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, 1854bb7acecfSBarry Smith `DMCreateFieldDecomposition()` 18554d343eeaSMatthew G Knepley @*/ 185637d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 18574d343eeaSMatthew G Knepley { 185837d0c07bSMatthew G Knepley PetscSection section, sectionGlobal; 18594d343eeaSMatthew G Knepley 18604d343eeaSMatthew G Knepley PetscFunctionBegin; 18614d343eeaSMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 186269ca1f37SDmitry Karpeev if (numFields) { 1863534a8f05SLisandro Dalcin PetscValidIntPointer(numFields,2); 186469ca1f37SDmitry Karpeev *numFields = 0; 186569ca1f37SDmitry Karpeev } 186637d0c07bSMatthew G Knepley if (fieldNames) { 186737d0c07bSMatthew G Knepley PetscValidPointer(fieldNames,3); 18680298fd71SBarry Smith *fieldNames = NULL; 186969ca1f37SDmitry Karpeev } 187069ca1f37SDmitry Karpeev if (fields) { 187169ca1f37SDmitry Karpeev PetscValidPointer(fields,4); 18720298fd71SBarry Smith *fields = NULL; 187369ca1f37SDmitry Karpeev } 18749566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 187537d0c07bSMatthew G Knepley if (section) { 18763a544194SStefano Zampini PetscInt *fieldSizes, *fieldNc, **fieldIndices; 187737d0c07bSMatthew G Knepley PetscInt nF, f, pStart, pEnd, p; 187837d0c07bSMatthew G Knepley 18799566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, §ionGlobal)); 18809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(section, &nF)); 18819566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nF,&fieldSizes,nF,&fieldNc,nF,&fieldIndices)); 18829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(sectionGlobal, &pStart, &pEnd)); 188337d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 188437d0c07bSMatthew G Knepley fieldSizes[f] = 0; 18859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(section, f, &fieldNc[f])); 188637d0c07bSMatthew G Knepley } 188737d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 188837d0c07bSMatthew G Knepley PetscInt gdof; 188937d0c07bSMatthew G Knepley 18909566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 189137d0c07bSMatthew G Knepley if (gdof > 0) { 189237d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 18933a544194SStefano Zampini PetscInt fdof, fcdof, fpdof; 189437d0c07bSMatthew G Knepley 18959566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 18969566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 18973a544194SStefano Zampini fpdof = fdof-fcdof; 18983a544194SStefano Zampini if (fpdof && fpdof != fieldNc[f]) { 18993a544194SStefano Zampini /* Layout does not admit a pointwise block size */ 19003a544194SStefano Zampini fieldNc[f] = 1; 19013a544194SStefano Zampini } 19023a544194SStefano Zampini fieldSizes[f] += fpdof; 190337d0c07bSMatthew G Knepley } 190437d0c07bSMatthew G Knepley } 190537d0c07bSMatthew G Knepley } 190637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fieldSizes[f], &fieldIndices[f])); 190837d0c07bSMatthew G Knepley fieldSizes[f] = 0; 190937d0c07bSMatthew G Knepley } 191037d0c07bSMatthew G Knepley for (p = pStart; p < pEnd; ++p) { 191137d0c07bSMatthew G Knepley PetscInt gdof, goff; 191237d0c07bSMatthew G Knepley 19139566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(sectionGlobal, p, &gdof)); 191437d0c07bSMatthew G Knepley if (gdof > 0) { 19159566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(sectionGlobal, p, &goff)); 191637d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 191737d0c07bSMatthew G Knepley PetscInt fdof, fcdof, fc; 191837d0c07bSMatthew G Knepley 19199566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(section, p, f, &fdof)); 19209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldConstraintDof(section, p, f, &fcdof)); 192137d0c07bSMatthew G Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) { 192237d0c07bSMatthew G Knepley fieldIndices[f][fieldSizes[f]] = goff++; 192337d0c07bSMatthew G Knepley } 192437d0c07bSMatthew G Knepley } 192537d0c07bSMatthew G Knepley } 192637d0c07bSMatthew G Knepley } 19278865f1eaSKarl Rupp if (numFields) *numFields = nF; 192837d0c07bSMatthew G Knepley if (fieldNames) { 19299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fieldNames)); 193037d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 193137d0c07bSMatthew G Knepley const char *fieldName; 193237d0c07bSMatthew G Knepley 19339566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 19349566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f])); 193537d0c07bSMatthew G Knepley } 193637d0c07bSMatthew G Knepley } 193737d0c07bSMatthew G Knepley if (fields) { 19389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nF, fields)); 193937d0c07bSMatthew G Knepley for (f = 0; f < nF; ++f) { 19403a544194SStefano Zampini PetscInt bs, in[2], out[2]; 19413a544194SStefano Zampini 19429566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f])); 19433a544194SStefano Zampini in[0] = -fieldNc[f]; 19443a544194SStefano Zampini in[1] = fieldNc[f]; 19451c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm))); 19463a544194SStefano Zampini bs = (-out[0] == out[1]) ? out[1] : 1; 19479566063dSJacob Faibussowitsch PetscCall(ISSetBlockSize((*fields)[f], bs)); 194837d0c07bSMatthew G Knepley } 194937d0c07bSMatthew G Knepley } 19509566063dSJacob Faibussowitsch PetscCall(PetscFree3(fieldSizes,fieldNc,fieldIndices)); 1951*dbbe0bcdSBarry Smith } else PetscTryTypeMethod(dm,createfieldis, numFields, fieldNames, fields); 19524d343eeaSMatthew G Knepley PetscFunctionReturn(0); 19534d343eeaSMatthew G Knepley } 19544d343eeaSMatthew G Knepley 195516621825SDmitry Karpeev /*@C 1956bb7acecfSBarry Smith DMCreateFieldDecomposition - Returns a list of `IS` objects defining a decomposition of a problem into subproblems 1957bb7acecfSBarry Smith corresponding to different fields: each `IS` contains the global indices of the dofs of the 1958bb7acecfSBarry Smith corresponding field, defined by `DMAddField()`. The optional list of `DM`s define the `DM` for each subproblem. 1959bb7acecfSBarry Smith The same as `DMCreateFieldIS()` but also returns a `DM` for each field. 1960e7c4fc90SDmitry Karpeev 1961e7c4fc90SDmitry Karpeev Not collective 1962e7c4fc90SDmitry Karpeev 1963e7c4fc90SDmitry Karpeev Input Parameter: 1964bb7acecfSBarry Smith . dm - the `DM` object 1965e7c4fc90SDmitry Karpeev 1966e7c4fc90SDmitry Karpeev Output Parameters: 1967bb7acecfSBarry Smith + len - The number of fields (or NULL if not requested) 19680298fd71SBarry Smith . namelist - The name for each field (or NULL if not requested) 19690298fd71SBarry Smith . islist - The global indices for each field (or NULL if not requested) 1970bb7acecfSBarry Smith - dmlist - The `DM`s for each field subproblem (or NULL, if not requested; if NULL is returned, no `DM`s are defined) 1971e7c4fc90SDmitry Karpeev 1972e7c4fc90SDmitry Karpeev Level: intermediate 1973e7c4fc90SDmitry Karpeev 1974bb7acecfSBarry Smith Note: 1975e7c4fc90SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 1976bb7acecfSBarry Smith `PetscFree()`, every entry of is should be destroyed with `ISDestroy()`, every entry of dm should be destroyed with `DMDestroy()`, 1977bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 1978e7c4fc90SDmitry Karpeev 1979bb7acecfSBarry Smith Fortran Note: 1980bb7acecfSBarry Smith Not available in Fortran. 1981bb7acecfSBarry Smith 1982bb7acecfSBarry Smith Developer Note: 1983bb7acecfSBarry Smith It is not clear why this function and `DMCreateFieldIS()` exist. Having two seems redundant and confusing. 1984bb7acecfSBarry Smith 1985bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMCreateFieldIS()`, `DMCreateSubDM()`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 1986e7c4fc90SDmitry Karpeev @*/ 198716621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1988e7c4fc90SDmitry Karpeev { 1989e7c4fc90SDmitry Karpeev PetscFunctionBegin; 1990e7c4fc90SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 19918865f1eaSKarl Rupp if (len) { 1992534a8f05SLisandro Dalcin PetscValidIntPointer(len,2); 19938865f1eaSKarl Rupp *len = 0; 19948865f1eaSKarl Rupp } 19958865f1eaSKarl Rupp if (namelist) { 19968865f1eaSKarl Rupp PetscValidPointer(namelist,3); 1997ea78f98cSLisandro Dalcin *namelist = NULL; 19988865f1eaSKarl Rupp } 19998865f1eaSKarl Rupp if (islist) { 20008865f1eaSKarl Rupp PetscValidPointer(islist,4); 2001ea78f98cSLisandro Dalcin *islist = NULL; 20028865f1eaSKarl Rupp } 20038865f1eaSKarl Rupp if (dmlist) { 20048865f1eaSKarl Rupp PetscValidPointer(dmlist,5); 2005ea78f98cSLisandro Dalcin *dmlist = NULL; 20068865f1eaSKarl Rupp } 2007f3f0edfdSDmitry Karpeev /* 2008f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2009f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2010f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2011f3f0edfdSDmitry Karpeev */ 20127a8be351SBarry Smith PetscCheck(dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 201316621825SDmitry Karpeev if (!dm->ops->createfielddecomposition) { 2014435a35e8SMatthew G Knepley PetscSection section; 2015435a35e8SMatthew G Knepley PetscInt numFields, f; 2016435a35e8SMatthew G Knepley 20179566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 20189566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(section, &numFields)); 2019435a35e8SMatthew G Knepley if (section && numFields && dm->ops->createsubdm) { 2020f25d98f1SMatthew G. Knepley if (len) *len = numFields; 20219566063dSJacob Faibussowitsch if (namelist) PetscCall(PetscMalloc1(numFields,namelist)); 20229566063dSJacob Faibussowitsch if (islist) PetscCall(PetscMalloc1(numFields,islist)); 20239566063dSJacob Faibussowitsch if (dmlist) PetscCall(PetscMalloc1(numFields,dmlist)); 2024435a35e8SMatthew G Knepley for (f = 0; f < numFields; ++f) { 2025435a35e8SMatthew G Knepley const char *fieldName; 2026435a35e8SMatthew G Knepley 20279566063dSJacob Faibussowitsch PetscCall(DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL)); 202803dc3394SMatthew G. Knepley if (namelist) { 20299566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(section, f, &fieldName)); 20309566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fieldName, (char**) &(*namelist)[f])); 2031435a35e8SMatthew G Knepley } 203203dc3394SMatthew G. Knepley } 2033435a35e8SMatthew G Knepley } else { 20349566063dSJacob Faibussowitsch PetscCall(DMCreateFieldIS(dm, len, namelist, islist)); 2035e7c4fc90SDmitry Karpeev /* By default there are no DMs associated with subproblems. */ 20360298fd71SBarry Smith if (dmlist) *dmlist = NULL; 2037e7c4fc90SDmitry Karpeev } 2038*dbbe0bcdSBarry Smith } else PetscUseTypeMethod(dm,createfielddecomposition ,len,namelist,islist,dmlist); 203916621825SDmitry Karpeev PetscFunctionReturn(0); 204016621825SDmitry Karpeev } 204116621825SDmitry Karpeev 2042412a4547SAlexis Marboeuf /*@C 2043412a4547SAlexis Marboeuf DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in. 2044412a4547SAlexis Marboeuf The fields are defined by DMCreateFieldIS(). 2045435a35e8SMatthew G Knepley 2046435a35e8SMatthew G Knepley Not collective 2047435a35e8SMatthew G Knepley 2048435a35e8SMatthew G Knepley Input Parameters: 2049bb7acecfSBarry Smith + dm - The `DM `object 2050bb7acecfSBarry Smith . numFields - The number of fields to select 20512adcc780SMatthew G. Knepley - fields - The field numbers of the selected fields 2052435a35e8SMatthew G Knepley 2053435a35e8SMatthew G Knepley Output Parameters: 2054bb7acecfSBarry Smith + is - The global indices for all the degrees of freedom in the new sub `DM` 2055bb7acecfSBarry Smith - subdm - The `DM` for the subproblem 2056435a35e8SMatthew G Knepley 2057bb7acecfSBarry Smith Note: 2058bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 20595d3b26e6SMatthew G. Knepley 2060435a35e8SMatthew G Knepley Level: intermediate 2061435a35e8SMatthew G Knepley 2062bb7acecfSBarry Smith .seealso: `DMCreateFieldIS()`, `DMCreateFieldDecomposition()`, `DMAddField()`, `DMCreateSuperDM()`, `DM`, `IS`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2063435a35e8SMatthew G Knepley @*/ 206437bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2065435a35e8SMatthew G Knepley { 2066435a35e8SMatthew G Knepley PetscFunctionBegin; 2067435a35e8SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2068dadcf809SJacob Faibussowitsch PetscValidIntPointer(fields,3); 20698865f1eaSKarl Rupp if (is) PetscValidPointer(is,4); 20708865f1eaSKarl Rupp if (subdm) PetscValidPointer(subdm,5); 2071*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,createsubdm , numFields, fields, is, subdm); 2072435a35e8SMatthew G Knepley PetscFunctionReturn(0); 2073435a35e8SMatthew G Knepley } 2074435a35e8SMatthew G Knepley 20752adcc780SMatthew G. Knepley /*@C 2076bb7acecfSBarry Smith DMCreateSuperDM - Returns an arrays of `IS` and `DM` encapsulating a superproblem defined by multiple `DM`s passed in. 20772adcc780SMatthew G. Knepley 20782adcc780SMatthew G. Knepley Not collective 20792adcc780SMatthew G. Knepley 2080d8d19677SJose E. Roman Input Parameters: 2081bb7acecfSBarry Smith + dms - The `DM` objects 2082bb7acecfSBarry Smith - n - The number of `DM`s 20832adcc780SMatthew G. Knepley 20842adcc780SMatthew G. Knepley Output Parameters: 2085bb7acecfSBarry Smith + is - The global indices for each of subproblem within the super `DM`, or NULL 2086bb7acecfSBarry Smith - superdm - The `DM` for the superproblem 20872adcc780SMatthew G. Knepley 2088bb7acecfSBarry Smith Note: 2089bb7acecfSBarry Smith You need to call `DMPlexSetMigrationSF()` on the original `DM` if you want the Global-To-Natural map to be automatically constructed 20905d3b26e6SMatthew G. Knepley 20912adcc780SMatthew G. Knepley Level: intermediate 20922adcc780SMatthew G. Knepley 2093bb7acecfSBarry Smith .seealso: `DM`, `DMCreateSubDM()`, `DMPlexSetMigrationSF()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 20942adcc780SMatthew G. Knepley @*/ 2095bb7acecfSBarry Smith PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt n, IS **is, DM *superdm) 20962adcc780SMatthew G. Knepley { 20972adcc780SMatthew G. Knepley PetscInt i; 20982adcc780SMatthew G. Knepley 20992adcc780SMatthew G. Knepley PetscFunctionBegin; 21002adcc780SMatthew G. Knepley PetscValidPointer(dms,1); 2101bb7acecfSBarry Smith for (i = 0; i < n; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);} 21022adcc780SMatthew G. Knepley if (is) PetscValidPointer(is,3); 2103a42bd24dSMatthew G. Knepley PetscValidPointer(superdm,4); 2104bb7acecfSBarry Smith PetscCheck(n >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %" PetscInt_FMT, n); 2105bb7acecfSBarry Smith if (n) { 2106b9d85ea2SLisandro Dalcin DM dm = dms[0]; 2107*dbbe0bcdSBarry Smith PetscCall((*dm->ops->createsuperdm)(dms, n, is, superdm)); 21082adcc780SMatthew G. Knepley } 21092adcc780SMatthew G. Knepley PetscFunctionReturn(0); 21102adcc780SMatthew G. Knepley } 21112adcc780SMatthew G. Knepley 211216621825SDmitry Karpeev /*@C 2113bb7acecfSBarry Smith DMCreateDomainDecomposition - Returns lists of `IS` objects defining a decomposition of a problem into subproblems 2114bb7acecfSBarry Smith corresponding to restrictions to pairs of nested subdomains: each `IS` contains the global 2115bb7acecfSBarry Smith indices of the dofs of the corresponding subdomains with in the dofs of the original `DM`. 2116bb7acecfSBarry Smith The inner subdomains conceptually define a nonoverlapping covering, while outer subdomains can overlap. 2117bb7acecfSBarry Smith The optional list of `DM`s define a `DM` for each subproblem. 211816621825SDmitry Karpeev 211916621825SDmitry Karpeev Not collective 212016621825SDmitry Karpeev 212116621825SDmitry Karpeev Input Parameter: 2122bb7acecfSBarry Smith . dm - the `DM` object 212316621825SDmitry Karpeev 212416621825SDmitry Karpeev Output Parameters: 2125bb7acecfSBarry Smith + n - The number of subproblems in the domain decomposition (or NULL if not requested) 21260298fd71SBarry Smith . namelist - The name for each subdomain (or NULL if not requested) 21270298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested) 21280298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested) 2129bb7acecfSBarry Smith - dmlist - The `DM`s for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no `DM`s are defined) 213016621825SDmitry Karpeev 213116621825SDmitry Karpeev Level: intermediate 213216621825SDmitry Karpeev 2133bb7acecfSBarry Smith Note: 213416621825SDmitry Karpeev The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with 2135bb7acecfSBarry Smith `PetscFree()`, every entry of is should be destroyed with `ISDestroy()`, every entry of dm should be destroyed with `DMDestroy()`, 2136bb7acecfSBarry Smith and all of the arrays should be freed with `PetscFree()`. 213716621825SDmitry Karpeev 2138bb7acecfSBarry Smith Questions: 2139bb7acecfSBarry Smith The dmlist is for the inner subdomains or the outer subdomains or all subdomains? 2140bb7acecfSBarry Smith 2141bb7acecfSBarry Smith .seealso: `DMCreateFieldDecomposition()`, `DMDestroy()`, `DMCreateDomainDecompositionScatters()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldDecomposition()` 214216621825SDmitry Karpeev @*/ 2143bb7acecfSBarry Smith PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *n, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist) 214416621825SDmitry Karpeev { 2145be081cd6SPeter Brune DMSubDomainHookLink link; 2146be081cd6SPeter Brune PetscInt i,l; 214716621825SDmitry Karpeev 214816621825SDmitry Karpeev PetscFunctionBegin; 214916621825SDmitry Karpeev PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2150bb7acecfSBarry Smith if (n) {PetscValidIntPointer(n,2); *n = 0;} 21510298fd71SBarry Smith if (namelist) {PetscValidPointer(namelist,3); *namelist = NULL;} 21520298fd71SBarry Smith if (innerislist) {PetscValidPointer(innerislist,4); *innerislist = NULL;} 21530298fd71SBarry Smith if (outerislist) {PetscValidPointer(outerislist,5); *outerislist = NULL;} 21540298fd71SBarry Smith if (dmlist) {PetscValidPointer(dmlist,6); *dmlist = NULL;} 2155f3f0edfdSDmitry Karpeev /* 2156f3f0edfdSDmitry Karpeev Is it a good idea to apply the following check across all impls? 2157f3f0edfdSDmitry Karpeev Perhaps some impls can have a well-defined decomposition before DMSetUp? 2158f3f0edfdSDmitry Karpeev This, however, follows the general principle that accessors are not well-behaved until the object is set up. 2159f3f0edfdSDmitry Karpeev */ 21607a8be351SBarry Smith PetscCheck(dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp"); 216116621825SDmitry Karpeev if (dm->ops->createdomaindecomposition) { 2162*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,createdomaindecomposition ,&l,namelist,innerislist,outerislist,dmlist); 216314a18fd3SPeter Brune /* copy subdomain hooks and context over to the subdomain DMs */ 2164f891f5b9SPatrick Sanan if (dmlist && *dmlist) { 2165be081cd6SPeter Brune for (i = 0; i < l; i++) { 2166be081cd6SPeter Brune for (link=dm->subdomainhook; link; link=link->next) { 21679566063dSJacob Faibussowitsch if (link->ddhook) PetscCall((*link->ddhook)(dm,(*dmlist)[i],link->ctx)); 2168be081cd6SPeter Brune } 2169648262bbSPatrick Sanan if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx; 2170e7c4fc90SDmitry Karpeev } 217114a18fd3SPeter Brune } 2172bb7acecfSBarry Smith if (n) *n = l; 217314a18fd3SPeter Brune } 2174e30e807fSPeter Brune PetscFunctionReturn(0); 2175e30e807fSPeter Brune } 2176e30e807fSPeter Brune 2177e30e807fSPeter Brune /*@C 2178e30e807fSPeter Brune DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector 2179e30e807fSPeter Brune 2180e30e807fSPeter Brune Not collective 2181e30e807fSPeter Brune 2182e30e807fSPeter Brune Input Parameters: 2183bb7acecfSBarry Smith + dm - the `DM` object 2184e30e807fSPeter Brune . n - the number of subdomain scatters 2185e30e807fSPeter Brune - subdms - the local subdomains 2186e30e807fSPeter Brune 2187e30e807fSPeter Brune Output Parameters: 21886b867d5aSJose E. Roman + iscat - scatter from global vector to nonoverlapping global vector entries on subdomain 2189e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain 2190e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts) 2191e30e807fSPeter Brune 2192bb7acecfSBarry Smith Note: 2193bb7acecfSBarry Smith This is an alternative to the iis and ois arguments in `DMCreateDomainDecomposition()` that allow for the solution 2194e30e807fSPeter Brune of general nonlinear problems with overlapping subdomain methods. While merely having index sets that enable subsets 2195e30e807fSPeter Brune of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of 2196e30e807fSPeter Brune solution and residual data. 2197e30e807fSPeter Brune 2198bb7acecfSBarry Smith Questions: 2199bb7acecfSBarry Smith Can the subdms input be anything or are they exactly the `DM` obtained from `DMCreateDomainDecomposition()`? 2200bb7acecfSBarry Smith 2201e30e807fSPeter Brune Level: developer 2202e30e807fSPeter Brune 2203bb7acecfSBarry Smith .seealso: `DM`, `DMCreateDomainDecomposition()`, `DMDestroy()`, `DMView()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMCreateFieldIS()` 2204e30e807fSPeter Brune @*/ 2205e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat) 2206e30e807fSPeter Brune { 2207e30e807fSPeter Brune PetscFunctionBegin; 2208e30e807fSPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2209e30e807fSPeter Brune PetscValidPointer(subdms,3); 2210*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,createddscatters ,n,subdms,iscat,oscat,gscat); 2211e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 2212e7c4fc90SDmitry Karpeev } 2213e7c4fc90SDmitry Karpeev 221447c6ae99SBarry Smith /*@ 2215bb7acecfSBarry Smith DMRefine - Refines a `DM` object using a standard nonadaptive refinement of the underlying mesh 221647c6ae99SBarry Smith 2217d083f849SBarry Smith Collective on dm 221847c6ae99SBarry Smith 2219d8d19677SJose E. Roman Input Parameters: 2220bb7acecfSBarry Smith + dm - the `DM` object 2221bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or `MPI_COMM_NULL`) 222247c6ae99SBarry Smith 222347c6ae99SBarry Smith Output Parameter: 2224bb7acecfSBarry Smith . dmf - the refined `D`M, or NULL 2225ae0a1c52SMatthew G Knepley 2226f27dd7c6SMatthew G. Knepley Options Database Keys: 2227412e9a14SMatthew G. Knepley . -dm_plex_cell_refiner <strategy> - chooses the refinement strategy, e.g. regular, tohex 2228412e9a14SMatthew G. Knepley 2229bb7acecfSBarry Smith Note: 2230bb7acecfSBarry Smith If no refinement was done, the return value is NULL 223147c6ae99SBarry Smith 223247c6ae99SBarry Smith Level: developer 223347c6ae99SBarry Smith 2234bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 223547c6ae99SBarry Smith @*/ 22367087cfbeSBarry Smith PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf) 223747c6ae99SBarry Smith { 2238c833c3b5SJed Brown DMRefineHookLink link; 223947c6ae99SBarry Smith 224047c6ae99SBarry Smith PetscFunctionBegin; 2241732e2eb9SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 22429566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Refine,dm,0,0,0)); 2243*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,refine ,comm,dmf); 22444057135bSMatthew G Knepley if (*dmf) { 224543842a1eSJed Brown (*dmf)->ops->creatematrix = dm->ops->creatematrix; 22468865f1eaSKarl Rupp 22479566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf)); 22488865f1eaSKarl Rupp 2249644e2e5bSBarry Smith (*dmf)->ctx = dm->ctx; 22500598a293SJed Brown (*dmf)->leveldown = dm->leveldown; 2251656b349aSBarry Smith (*dmf)->levelup = dm->levelup + 1; 22528865f1eaSKarl Rupp 22539566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmf,dm->mattype)); 2254c833c3b5SJed Brown for (link=dm->refinehook; link; link=link->next) { 22551baa6e33SBarry Smith if (link->refinehook) PetscCall((*link->refinehook)(dm,*dmf,link->ctx)); 2256c833c3b5SJed Brown } 2257c833c3b5SJed Brown } 22589566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Refine,dm,0,0,0)); 2259c833c3b5SJed Brown PetscFunctionReturn(0); 2260c833c3b5SJed Brown } 2261c833c3b5SJed Brown 2262bb9467b5SJed Brown /*@C 2263c833c3b5SJed Brown DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid 2264c833c3b5SJed Brown 2265bb7acecfSBarry Smith Logically Collective on coarse 2266c833c3b5SJed Brown 22674165533cSJose E. Roman Input Parameters: 2268bb7acecfSBarry Smith + coarse - `DM` on which to run a hook when interpolating to a finer level 2269bb7acecfSBarry Smith . refinehook - function to run when setting up the finer level 2270bb7acecfSBarry Smith . interphook - function to run to update data on finer levels (once per `SNESSolve`()) 22710298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2272c833c3b5SJed Brown 2273c833c3b5SJed Brown Calling sequence of refinehook: 2274c833c3b5SJed Brown $ refinehook(DM coarse,DM fine,void *ctx); 2275c833c3b5SJed Brown 2276bb7acecfSBarry Smith + coarse - coarse level `DM` 2277bb7acecfSBarry Smith . fine - fine level `DM` to interpolate problem to 2278c833c3b5SJed Brown - ctx - optional user-defined function context 2279c833c3b5SJed Brown 2280c833c3b5SJed Brown Calling sequence for interphook: 2281c833c3b5SJed Brown $ interphook(DM coarse,Mat interp,DM fine,void *ctx) 2282c833c3b5SJed Brown 2283bb7acecfSBarry Smith + coarse - coarse level `DM` 2284c833c3b5SJed Brown . interp - matrix interpolating a coarse-level solution to the finer grid 2285bb7acecfSBarry Smith . fine - fine level `DM` to update 2286c833c3b5SJed Brown - ctx - optional user-defined function context 2287c833c3b5SJed Brown 2288c833c3b5SJed Brown Level: advanced 2289c833c3b5SJed Brown 2290c833c3b5SJed Brown Notes: 2291bb7acecfSBarry Smith This function is only needed if auxiliary data that is attached to the `DM`s via, for example, `PetscObjectCompose()`, needs to be 2292bb7acecfSBarry Smith passed to fine grids while grid sequencing. 2293bb7acecfSBarry Smith 2294bb7acecfSBarry Smith The actual interpolation is done when `DMInterpolate()` is called. 2295c833c3b5SJed Brown 2296c833c3b5SJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 2297c833c3b5SJed Brown 2298bb7acecfSBarry Smith Fortran Note: 2299bb7acecfSBarry Smith This function is not available from Fortran. 2300bb9467b5SJed Brown 2301bb7acecfSBarry Smith .seealso: `DM`, `DMCoarsenHookAdd()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2302c833c3b5SJed Brown @*/ 2303c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 2304c833c3b5SJed Brown { 2305c833c3b5SJed Brown DMRefineHookLink link,*p; 2306c833c3b5SJed Brown 2307c833c3b5SJed Brown PetscFunctionBegin; 2308c833c3b5SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 23093d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 23103d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0); 23113d8e3701SJed Brown } 23129566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2313c833c3b5SJed Brown link->refinehook = refinehook; 2314c833c3b5SJed Brown link->interphook = interphook; 2315c833c3b5SJed Brown link->ctx = ctx; 23160298fd71SBarry Smith link->next = NULL; 2317c833c3b5SJed Brown *p = link; 2318c833c3b5SJed Brown PetscFunctionReturn(0); 2319c833c3b5SJed Brown } 2320c833c3b5SJed Brown 23213d8e3701SJed Brown /*@C 2322bb7acecfSBarry Smith DMRefineHookRemove - remove a callback from the list of hooks, that have been set with `DMRefineHookAdd()`, to be run when interpolating 2323bb7acecfSBarry Smith a nonlinear problem to a finer grid 23243d8e3701SJed Brown 2325bb7acecfSBarry Smith Logically Collective on coarse 23263d8e3701SJed Brown 23274165533cSJose E. Roman Input Parameters: 2328bb7acecfSBarry Smith + coarse - the `DM` on which to run a hook when restricting to a coarser level 2329bb7acecfSBarry Smith . refinehook - function to run when setting up a finer level 2330bb7acecfSBarry Smith . interphook - function to run to update data on finer levels 23313d8e3701SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 23323d8e3701SJed Brown 23333d8e3701SJed Brown Level: advanced 23343d8e3701SJed Brown 2335bb7acecfSBarry Smith Note: 23363d8e3701SJed Brown This function does nothing if the hook is not in the list. 23373d8e3701SJed Brown 2338bb7acecfSBarry Smith Fortran Note: 2339bb7acecfSBarry Smith This function is not available from Fortran. 23403d8e3701SJed Brown 2341bb7acecfSBarry Smith .seealso: `DMRefineHookAdd()`, `DMCoarsenHookRemove()`, `DMInterpolate()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 23423d8e3701SJed Brown @*/ 23433d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx) 23443d8e3701SJed Brown { 23453d8e3701SJed Brown DMRefineHookLink link,*p; 23463d8e3701SJed Brown 23473d8e3701SJed Brown PetscFunctionBegin; 23483d8e3701SJed Brown PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 23493d8e3701SJed Brown for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 23503d8e3701SJed Brown if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) { 23513d8e3701SJed Brown link = *p; 23523d8e3701SJed Brown *p = link->next; 23539566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 23543d8e3701SJed Brown break; 23553d8e3701SJed Brown } 23563d8e3701SJed Brown } 23573d8e3701SJed Brown PetscFunctionReturn(0); 23583d8e3701SJed Brown } 23593d8e3701SJed Brown 2360c833c3b5SJed Brown /*@ 2361bb7acecfSBarry Smith DMInterpolate - interpolates user-defined problem data attached to a `DM` to a finer `DM` by running hooks registered by `DMRefineHookAdd()` 2362c833c3b5SJed Brown 2363c833c3b5SJed Brown Collective if any hooks are 2364c833c3b5SJed Brown 23654165533cSJose E. Roman Input Parameters: 2366bb7acecfSBarry Smith + coarse - coarser `DM` to use as a base 2367bb7acecfSBarry Smith . interp - interpolation matrix, apply using `MatInterpolate()` 2368bb7acecfSBarry Smith - fine - finer `DM` to update 2369c833c3b5SJed Brown 2370c833c3b5SJed Brown Level: developer 2371c833c3b5SJed Brown 2372bb7acecfSBarry Smith Developer Note: 2373bb7acecfSBarry Smith This routine is called `DMInterpolate()` while the hook is called `DMRefineHookAdd()`. It would be better to have an 2374bb7acecfSBarry Smith an API with consistent terminology. 2375bb7acecfSBarry Smith 2376bb7acecfSBarry Smith .seealso: `DM`, `DMRefineHookAdd()`, `MatInterpolate()` 2377c833c3b5SJed Brown @*/ 2378c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine) 2379c833c3b5SJed Brown { 2380c833c3b5SJed Brown DMRefineHookLink link; 2381c833c3b5SJed Brown 2382c833c3b5SJed Brown PetscFunctionBegin; 2383c833c3b5SJed Brown for (link=fine->refinehook; link; link=link->next) { 23841baa6e33SBarry Smith if (link->interphook) PetscCall((*link->interphook)(coarse,interp,fine,link->ctx)); 23854057135bSMatthew G Knepley } 238647c6ae99SBarry Smith PetscFunctionReturn(0); 238747c6ae99SBarry Smith } 238847c6ae99SBarry Smith 2389eb3f98d2SBarry Smith /*@ 23901f3379b2SToby Isaac DMInterpolateSolution - Interpolates a solution from a coarse mesh to a fine mesh. 23911f3379b2SToby Isaac 2392bb7acecfSBarry Smith Collective on dm 23931f3379b2SToby Isaac 23944165533cSJose E. Roman Input Parameters: 2395bb7acecfSBarry Smith + coarse - coarse `DM` 2396bb7acecfSBarry Smith . fine - fine `DM` 2397bb7acecfSBarry Smith . interp - (optional) the matrix computed by `DMCreateInterpolation()`. Implementations may not need this, but if it 2398bb7acecfSBarry Smith is available it can avoid some recomputation. If it is provided, `MatInterpolate()` will be used if 2399bb7acecfSBarry Smith the coarse `DM` does not have a specialized implementation. 24001f3379b2SToby Isaac - coarseSol - solution on the coarse mesh 24011f3379b2SToby Isaac 24024165533cSJose E. Roman Output Parameter: 24031f3379b2SToby Isaac . fineSol - the interpolation of coarseSol to the fine mesh 24041f3379b2SToby Isaac 24051f3379b2SToby Isaac Level: developer 24061f3379b2SToby Isaac 2407bb7acecfSBarry Smith Note: 2408bb7acecfSBarry Smith This function exists because the interpolation of a solution vector between meshes is not always a linear 24091f3379b2SToby Isaac map. For example, if a boundary value problem has an inhomogeneous Dirichlet boundary condition that is compressed 24101f3379b2SToby Isaac out of the solution vector. Or if interpolation is inherently a nonlinear operation, such as a method using 24111f3379b2SToby Isaac slope-limiting reconstruction. 24121f3379b2SToby Isaac 2413bb7acecfSBarry Smith Developer Note: 2414bb7acecfSBarry Smith This doesn't just interpolate "solutions" so its API name is questionable. 2415bb7acecfSBarry Smith 2416bb7acecfSBarry Smith .seealso: `DMInterpolate()`, `DMCreateInterpolation()` 24171f3379b2SToby Isaac @*/ 24181f3379b2SToby Isaac PetscErrorCode DMInterpolateSolution(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 24191f3379b2SToby Isaac { 24201f3379b2SToby Isaac PetscErrorCode (*interpsol)(DM,DM,Mat,Vec,Vec) = NULL; 24211f3379b2SToby Isaac 24221f3379b2SToby Isaac PetscFunctionBegin; 24231f3379b2SToby Isaac PetscValidHeaderSpecific(coarse,DM_CLASSID,1); 24241f3379b2SToby Isaac if (interp) PetscValidHeaderSpecific(interp,MAT_CLASSID,3); 24251f3379b2SToby Isaac PetscValidHeaderSpecific(coarseSol,VEC_CLASSID,4); 24261f3379b2SToby Isaac PetscValidHeaderSpecific(fineSol,VEC_CLASSID,5); 24271f3379b2SToby Isaac 24289566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)coarse,"DMInterpolateSolution_C", &interpsol)); 24291f3379b2SToby Isaac if (interpsol) { 24309566063dSJacob Faibussowitsch PetscCall((*interpsol)(coarse, fine, interp, coarseSol, fineSol)); 24311f3379b2SToby Isaac } else if (interp) { 24329566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, coarseSol, fineSol)); 243398921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)coarse), PETSC_ERR_SUP, "DM %s does not implement DMInterpolateSolution()", ((PetscObject)coarse)->type_name); 24341f3379b2SToby Isaac PetscFunctionReturn(0); 24351f3379b2SToby Isaac } 24361f3379b2SToby Isaac 24371f3379b2SToby Isaac /*@ 2438bb7acecfSBarry Smith DMGetRefineLevel - Gets the number of refinements that have generated this `DM` from some initial `DM`. 2439eb3f98d2SBarry Smith 2440eb3f98d2SBarry Smith Not Collective 2441eb3f98d2SBarry Smith 2442eb3f98d2SBarry Smith Input Parameter: 2443bb7acecfSBarry Smith . dm - the `DM` object 2444eb3f98d2SBarry Smith 2445eb3f98d2SBarry Smith Output Parameter: 2446eb3f98d2SBarry Smith . level - number of refinements 2447eb3f98d2SBarry Smith 2448eb3f98d2SBarry Smith Level: developer 2449eb3f98d2SBarry Smith 2450bb7acecfSBarry Smith Note: 2451bb7acecfSBarry Smith This can be used, by example, to set the number of coarser levels associated with this `DM` for a multigrid solver. 2452bb7acecfSBarry Smith 2453bb7acecfSBarry Smith .seealso: `DMRefine()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2454eb3f98d2SBarry Smith 2455eb3f98d2SBarry Smith @*/ 2456eb3f98d2SBarry Smith PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level) 2457eb3f98d2SBarry Smith { 2458eb3f98d2SBarry Smith PetscFunctionBegin; 2459eb3f98d2SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2460eb3f98d2SBarry Smith *level = dm->levelup; 2461eb3f98d2SBarry Smith PetscFunctionReturn(0); 2462eb3f98d2SBarry Smith } 2463eb3f98d2SBarry Smith 2464fef3a512SBarry Smith /*@ 2465bb7acecfSBarry Smith DMSetRefineLevel - Sets the number of refinements that have generated this `DM`. 2466fef3a512SBarry Smith 2467fef3a512SBarry Smith Not Collective 2468fef3a512SBarry Smith 2469d8d19677SJose E. Roman Input Parameters: 2470bb7acecfSBarry Smith + dm - the `DM` object 2471fef3a512SBarry Smith - level - number of refinements 2472fef3a512SBarry Smith 2473fef3a512SBarry Smith Level: advanced 2474fef3a512SBarry Smith 247595452b02SPatrick Sanan Notes: 2476bb7acecfSBarry Smith This value is used by `PCMG` to determine how many multigrid levels to use 2477fef3a512SBarry Smith 2478bb7acecfSBarry Smith The values are usually set automatically by the process that is causing the refinements of an initial `DM` by calling this routine. 2479bb7acecfSBarry Smith 2480bb7acecfSBarry Smith .seealso: `DMGetRefineLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 2481fef3a512SBarry Smith 2482fef3a512SBarry Smith @*/ 2483fef3a512SBarry Smith PetscErrorCode DMSetRefineLevel(DM dm,PetscInt level) 2484fef3a512SBarry Smith { 2485fef3a512SBarry Smith PetscFunctionBegin; 2486fef3a512SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2487fef3a512SBarry Smith dm->levelup = level; 2488fef3a512SBarry Smith PetscFunctionReturn(0); 2489fef3a512SBarry Smith } 2490fef3a512SBarry Smith 2491d410b0cfSMatthew G. Knepley /*@ 2492bb7acecfSBarry Smith DMExtrude - Extrude a `DM` object from a surface 2493d410b0cfSMatthew G. Knepley 2494d410b0cfSMatthew G. Knepley Collective on dm 2495d410b0cfSMatthew G. Knepley 2496f1a722f8SMatthew G. Knepley Input Parameters: 2497bb7acecfSBarry Smith + dm - the `DM` object 2498d410b0cfSMatthew G. Knepley - layers - the number of extruded cell layers 2499d410b0cfSMatthew G. Knepley 2500d410b0cfSMatthew G. Knepley Output Parameter: 2501bb7acecfSBarry Smith . dme - the extruded `DM`, or NULL 2502d410b0cfSMatthew G. Knepley 2503bb7acecfSBarry Smith Note: 2504bb7acecfSBarry Smith If no extrusion was done, the return value is NULL 2505d410b0cfSMatthew G. Knepley 2506d410b0cfSMatthew G. Knepley Level: developer 2507d410b0cfSMatthew G. Knepley 2508bb7acecfSBarry Smith .seealso: `DMRefine()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()` 2509d410b0cfSMatthew G. Knepley @*/ 2510d410b0cfSMatthew G. Knepley PetscErrorCode DMExtrude(DM dm, PetscInt layers, DM *dme) 2511d410b0cfSMatthew G. Knepley { 2512d410b0cfSMatthew G. Knepley PetscFunctionBegin; 2513d410b0cfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2514*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,extrude , layers, dme); 2515d410b0cfSMatthew G. Knepley if (*dme) { 2516d410b0cfSMatthew G. Knepley (*dme)->ops->creatematrix = dm->ops->creatematrix; 25179566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject) dm, (PetscObject) *dme)); 2518d410b0cfSMatthew G. Knepley (*dme)->ctx = dm->ctx; 25199566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dme, dm->mattype)); 2520d410b0cfSMatthew G. Knepley } 2521d410b0cfSMatthew G. Knepley PetscFunctionReturn(0); 2522d410b0cfSMatthew G. Knepley } 2523d410b0cfSMatthew G. Knepley 2524ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm) 2525ca3d3a14SMatthew G. Knepley { 2526ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2527ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2528ca3d3a14SMatthew G. Knepley PetscValidPointer(tdm, 2); 2529ca3d3a14SMatthew G. Knepley *tdm = dm->transformDM; 2530ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2531ca3d3a14SMatthew G. Knepley } 2532ca3d3a14SMatthew G. Knepley 2533ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv) 2534ca3d3a14SMatthew G. Knepley { 2535ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2536ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2537ca3d3a14SMatthew G. Knepley PetscValidPointer(tv, 2); 2538ca3d3a14SMatthew G. Knepley *tv = dm->transform; 2539ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2540ca3d3a14SMatthew G. Knepley } 2541ca3d3a14SMatthew G. Knepley 2542ca3d3a14SMatthew G. Knepley /*@ 2543bb7acecfSBarry Smith DMHasBasisTransform - Whether the `DM` employs a basis transformation from functions in global vectors to functions in local vectors 2544ca3d3a14SMatthew G. Knepley 2545ca3d3a14SMatthew G. Knepley Input Parameter: 2546ca3d3a14SMatthew G. Knepley . dm - The DM 2547ca3d3a14SMatthew G. Knepley 2548ca3d3a14SMatthew G. Knepley Output Parameter: 2549ca3d3a14SMatthew G. Knepley . flg - PETSC_TRUE if a basis transformation should be done 2550ca3d3a14SMatthew G. Knepley 2551ca3d3a14SMatthew G. Knepley Level: developer 2552ca3d3a14SMatthew G. Knepley 2553bb7acecfSBarry Smith .seealso: `DM`, `DMPlexGlobalToLocalBasis()`, `DMPlexLocalToGlobalBasis()`, `DMPlexCreateBasisRotation()` 2554ca3d3a14SMatthew G. Knepley @*/ 2555ca3d3a14SMatthew G. Knepley PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg) 2556ca3d3a14SMatthew G. Knepley { 2557ca3d3a14SMatthew G. Knepley Vec tv; 2558ca3d3a14SMatthew G. Knepley 2559ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2560ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2561534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 25629566063dSJacob Faibussowitsch PetscCall(DMGetBasisTransformVec_Internal(dm, &tv)); 2563ca3d3a14SMatthew G. Knepley *flg = tv ? PETSC_TRUE : PETSC_FALSE; 2564ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2565ca3d3a14SMatthew G. Knepley } 2566ca3d3a14SMatthew G. Knepley 2567ca3d3a14SMatthew G. Knepley PetscErrorCode DMConstructBasisTransform_Internal(DM dm) 2568ca3d3a14SMatthew G. Knepley { 2569ca3d3a14SMatthew G. Knepley PetscSection s, ts; 2570ca3d3a14SMatthew G. Knepley PetscScalar *ta; 2571ca3d3a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, p, Nf, f, Nc, dof; 2572ca3d3a14SMatthew G. Knepley 2573ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 25749566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &cdim)); 25759566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 25769566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 25779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 25789566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->transformDM)); 25799566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm->transformDM, &ts)); 25809566063dSJacob Faibussowitsch PetscCall(PetscSectionSetNumFields(ts, Nf)); 25819566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(ts, pStart, pEnd)); 2582ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 25839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldComponents(s, f, &Nc)); 2584ca3d3a14SMatthew G. Knepley /* We could start to label fields by their transformation properties */ 2585ca3d3a14SMatthew G. Knepley if (Nc != cdim) continue; 2586ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 25879566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(s, p, f, &dof)); 2588ca3d3a14SMatthew G. Knepley if (!dof) continue; 25899566063dSJacob Faibussowitsch PetscCall(PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim))); 25909566063dSJacob Faibussowitsch PetscCall(PetscSectionAddDof(ts, p, PetscSqr(cdim))); 2591ca3d3a14SMatthew G. Knepley } 2592ca3d3a14SMatthew G. Knepley } 25939566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(ts)); 25949566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dm->transformDM, &dm->transform)); 25959566063dSJacob Faibussowitsch PetscCall(VecGetArray(dm->transform, &ta)); 2596ca3d3a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 2597ca3d3a14SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 25989566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldDof(ts, p, f, &dof)); 2599ca3d3a14SMatthew G. Knepley if (dof) { 2600ca3d3a14SMatthew G. Knepley PetscReal x[3] = {0.0, 0.0, 0.0}; 2601ca3d3a14SMatthew G. Knepley PetscScalar *tva; 2602ca3d3a14SMatthew G. Knepley const PetscScalar *A; 2603ca3d3a14SMatthew G. Knepley 2604ca3d3a14SMatthew G. Knepley /* TODO Get quadrature point for this dual basis vector for coordinate */ 26059566063dSJacob Faibussowitsch PetscCall((*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx)); 26069566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *) &tva)); 26079566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tva, A, PetscSqr(cdim))); 2608ca3d3a14SMatthew G. Knepley } 2609ca3d3a14SMatthew G. Knepley } 2610ca3d3a14SMatthew G. Knepley } 26119566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(dm->transform, &ta)); 2612ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2613ca3d3a14SMatthew G. Knepley } 2614ca3d3a14SMatthew G. Knepley 2615ca3d3a14SMatthew G. Knepley PetscErrorCode DMCopyTransform(DM dm, DM newdm) 2616ca3d3a14SMatthew G. Knepley { 2617ca3d3a14SMatthew G. Knepley PetscFunctionBegin; 2618ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2619ca3d3a14SMatthew G. Knepley PetscValidHeaderSpecific(newdm, DM_CLASSID, 2); 2620ca3d3a14SMatthew G. Knepley newdm->transformCtx = dm->transformCtx; 2621ca3d3a14SMatthew G. Knepley newdm->transformSetUp = dm->transformSetUp; 2622ca3d3a14SMatthew G. Knepley newdm->transformDestroy = NULL; 2623ca3d3a14SMatthew G. Knepley newdm->transformGetMatrix = dm->transformGetMatrix; 26249566063dSJacob Faibussowitsch if (newdm->transformSetUp) PetscCall(DMConstructBasisTransform_Internal(newdm)); 2625ca3d3a14SMatthew G. Knepley PetscFunctionReturn(0); 2626ca3d3a14SMatthew G. Knepley } 2627ca3d3a14SMatthew G. Knepley 2628bb9467b5SJed Brown /*@C 2629bb7acecfSBarry Smith DMGlobalToLocalHookAdd - adds a callback to be run when `DMGlobalToLocal()` is called 2630baf369e7SPeter Brune 2631bb7acecfSBarry Smith Logically Collective on dm 2632baf369e7SPeter Brune 26334165533cSJose E. Roman Input Parameters: 2634bb7acecfSBarry Smith + dm - the `DM` 2635bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMGlobalToLocalBegin()` 2636bb7acecfSBarry Smith . endhook - function to run after `DMGlobalToLocalEnd()` has completed 26370298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2638baf369e7SPeter Brune 2639baf369e7SPeter Brune Calling sequence for beginhook: 2640baf369e7SPeter Brune $ beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2641baf369e7SPeter Brune 2642baf369e7SPeter Brune + dm - global DM 2643baf369e7SPeter Brune . g - global vector 2644baf369e7SPeter Brune . mode - mode 2645baf369e7SPeter Brune . l - local vector 2646baf369e7SPeter Brune - ctx - optional user-defined function context 2647baf369e7SPeter Brune 2648baf369e7SPeter Brune Calling sequence for endhook: 2649ec4806b8SPeter Brune $ endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx) 2650baf369e7SPeter Brune 2651baf369e7SPeter Brune + global - global DM 2652baf369e7SPeter Brune - ctx - optional user-defined function context 2653baf369e7SPeter Brune 2654baf369e7SPeter Brune Level: advanced 2655baf369e7SPeter Brune 2656bb7acecfSBarry Smith Note: 2657bb7acecfSBarry 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. 2658bb7acecfSBarry Smith 2659bb7acecfSBarry Smith .seealso: `DM`, `DMGlobalToLocal()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2660baf369e7SPeter Brune @*/ 2661baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2662baf369e7SPeter Brune { 2663baf369e7SPeter Brune DMGlobalToLocalHookLink link,*p; 2664baf369e7SPeter Brune 2665baf369e7SPeter Brune PetscFunctionBegin; 2666baf369e7SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2667baf369e7SPeter Brune for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 26689566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2669baf369e7SPeter Brune link->beginhook = beginhook; 2670baf369e7SPeter Brune link->endhook = endhook; 2671baf369e7SPeter Brune link->ctx = ctx; 26720298fd71SBarry Smith link->next = NULL; 2673baf369e7SPeter Brune *p = link; 2674baf369e7SPeter Brune PetscFunctionReturn(0); 2675baf369e7SPeter Brune } 2676baf369e7SPeter Brune 26774c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx) 26784c274da1SToby Isaac { 26794c274da1SToby Isaac Mat cMat; 268079769bd5SJed Brown Vec cVec, cBias; 26814c274da1SToby Isaac PetscSection section, cSec; 26824c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 26834c274da1SToby Isaac 26844c274da1SToby Isaac PetscFunctionBegin; 26854c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 26869566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm,&cSec,&cMat,&cBias)); 26874c274da1SToby Isaac if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) { 26885db9a05bSToby Isaac PetscInt nRows; 26895db9a05bSToby Isaac 26909566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat,&nRows,NULL)); 26915db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 26929566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm,§ion)); 26939566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat,NULL,&cVec)); 26949566063dSJacob Faibussowitsch PetscCall(MatMult(cMat,l,cVec)); 26959566063dSJacob Faibussowitsch if (cBias) PetscCall(VecAXPY(cVec,1.,cBias)); 26969566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec,&pStart,&pEnd)); 26974c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 26989566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec,p,&dof)); 26994c274da1SToby Isaac if (dof) { 27004c274da1SToby Isaac PetscScalar *vals; 27019566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(cVec,cSec,p,&vals)); 27029566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES)); 27034c274da1SToby Isaac } 27044c274da1SToby Isaac } 27059566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 27064c274da1SToby Isaac } 27074c274da1SToby Isaac PetscFunctionReturn(0); 27084c274da1SToby Isaac } 27094c274da1SToby Isaac 271047c6ae99SBarry Smith /*@ 271101729b5cSPatrick Sanan DMGlobalToLocal - update local vectors from global vector 271201729b5cSPatrick Sanan 2713d083f849SBarry Smith Neighbor-wise Collective on dm 271401729b5cSPatrick Sanan 271501729b5cSPatrick Sanan Input Parameters: 2716bb7acecfSBarry Smith + dm - the `DM` object 271701729b5cSPatrick Sanan . g - the global vector 2718bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 271901729b5cSPatrick Sanan - l - the local vector 272001729b5cSPatrick Sanan 272101729b5cSPatrick Sanan Notes: 2722bb7acecfSBarry Smith The communication involved in this update can be overlapped with computation by instead using 2723bb7acecfSBarry Smith `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()`. 2724bb7acecfSBarry Smith 2725bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 272601729b5cSPatrick Sanan 272701729b5cSPatrick Sanan Level: beginner 272801729b5cSPatrick Sanan 2729bb7acecfSBarry Smith .seealso: `DM`, `DMGlobalToLocalHookAdd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, 2730bb7acecfSBarry Smith `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, 2731bb7acecfSBarry Smith `DMGlobalToLocalBegin()` `DMGlobalToLocalEnd()` 273201729b5cSPatrick Sanan 273301729b5cSPatrick Sanan @*/ 273401729b5cSPatrick Sanan PetscErrorCode DMGlobalToLocal(DM dm,Vec g,InsertMode mode,Vec l) 273501729b5cSPatrick Sanan { 273601729b5cSPatrick Sanan PetscFunctionBegin; 27379566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm,g,mode,l)); 27389566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm,g,mode,l)); 273901729b5cSPatrick Sanan PetscFunctionReturn(0); 274001729b5cSPatrick Sanan } 274101729b5cSPatrick Sanan 274201729b5cSPatrick Sanan /*@ 274347c6ae99SBarry Smith DMGlobalToLocalBegin - Begins updating local vectors from global vector 274447c6ae99SBarry Smith 2745d083f849SBarry Smith Neighbor-wise Collective on dm 274647c6ae99SBarry Smith 274747c6ae99SBarry Smith Input Parameters: 2748bb7acecfSBarry Smith + dm - the `DM` object 274947c6ae99SBarry Smith . g - the global vector 2750bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 275147c6ae99SBarry Smith - l - the local vector 275247c6ae99SBarry Smith 275301729b5cSPatrick Sanan Level: intermediate 275447c6ae99SBarry Smith 2755bb7acecfSBarry Smith Notes: 2756bb7acecfSBarry Smith The operation is completed with `DMGlobalToLocalEnd()` 2757bb7acecfSBarry Smith 2758bb7acecfSBarry Smith One can perform local computations between the `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` to overlap communication and computation 2759bb7acecfSBarry Smith 2760bb7acecfSBarry Smith `DMGlobalToLocal()` is a short form of `DMGlobalToLocalBegin()` and `DMGlobalToLocalEnd()` 2761bb7acecfSBarry Smith 2762bb7acecfSBarry Smith `DMGlobalToLocalHookAdd()` may be used to provide additional operations that are performed during the update process. 2763bb7acecfSBarry Smith 2764bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()` 276547c6ae99SBarry Smith 276647c6ae99SBarry Smith @*/ 27677087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 276847c6ae99SBarry Smith { 27697128ae9fSMatthew G Knepley PetscSF sf; 2770baf369e7SPeter Brune DMGlobalToLocalHookLink link; 277147c6ae99SBarry Smith 277247c6ae99SBarry Smith PetscFunctionBegin; 2773171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2774baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 27751baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm,g,mode,l,link->ctx)); 2776baf369e7SPeter Brune } 27779566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 27787128ae9fSMatthew G Knepley if (sf) { 2779ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2780ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2781d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 27827128ae9fSMatthew G Knepley 27837a8be351SBarry Smith PetscCheck(mode != ADD_VALUES,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 27849566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 27859566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 27869566063dSJacob Faibussowitsch PetscCall(PetscSFBcastWithMemTypeBegin(sf, MPIU_SCALAR, gmtype, gArray, lmtype, lArray, MPI_REPLACE)); 27879566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 27889566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 27897128ae9fSMatthew G Knepley } else { 27909566063dSJacob Faibussowitsch PetscCall((*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l)); 27917128ae9fSMatthew G Knepley } 279247c6ae99SBarry Smith PetscFunctionReturn(0); 279347c6ae99SBarry Smith } 279447c6ae99SBarry Smith 279547c6ae99SBarry Smith /*@ 279647c6ae99SBarry Smith DMGlobalToLocalEnd - Ends updating local vectors from global vector 279747c6ae99SBarry Smith 2798d083f849SBarry Smith Neighbor-wise Collective on dm 279947c6ae99SBarry Smith 280047c6ae99SBarry Smith Input Parameters: 2801bb7acecfSBarry Smith + dm - the `DM` object 280247c6ae99SBarry Smith . g - the global vector 2803bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 280447c6ae99SBarry Smith - l - the local vector 280547c6ae99SBarry Smith 280601729b5cSPatrick Sanan Level: intermediate 280747c6ae99SBarry Smith 2808bb7acecfSBarry Smith Note: 2809bb7acecfSBarry Smith See `DMGlobalToLocalBegin()` for details. 2810bb7acecfSBarry Smith 2811bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobal()`, `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()` 281247c6ae99SBarry Smith 281347c6ae99SBarry Smith @*/ 28147087cfbeSBarry Smith PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 281547c6ae99SBarry Smith { 28167128ae9fSMatthew G Knepley PetscSF sf; 2817ae5cfb4aSMatthew G. Knepley const PetscScalar *gArray; 2818ae5cfb4aSMatthew G. Knepley PetscScalar *lArray; 2819ca3d3a14SMatthew G. Knepley PetscBool transform; 2820baf369e7SPeter Brune DMGlobalToLocalHookLink link; 2821d0295fc0SJunchao Zhang PetscMemType lmtype,gmtype; 282247c6ae99SBarry Smith 282347c6ae99SBarry Smith PetscFunctionBegin; 2824171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 28259566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 28269566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 28277128ae9fSMatthew G Knepley if (sf) { 28287a8be351SBarry Smith PetscCheck(mode != ADD_VALUES,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", (int)mode); 28297128ae9fSMatthew G Knepley 28309566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(l, &lArray, &lmtype)); 28319566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(g, &gArray, &gmtype)); 28329566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray,MPI_REPLACE)); 28339566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(l, &lArray)); 28349566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(g, &gArray)); 28359566063dSJacob Faibussowitsch if (transform) PetscCall(DMPlexGlobalToLocalBasis(dm, l)); 28367128ae9fSMatthew G Knepley } else { 28379566063dSJacob Faibussowitsch PetscCall((*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l)); 28387128ae9fSMatthew G Knepley } 28399566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL)); 2840baf369e7SPeter Brune for (link=dm->gtolhook; link; link=link->next) { 28419566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm,g,mode,l,link->ctx)); 2842baf369e7SPeter Brune } 284347c6ae99SBarry Smith PetscFunctionReturn(0); 284447c6ae99SBarry Smith } 284547c6ae99SBarry Smith 2846d4d07f1eSToby Isaac /*@C 2847d4d07f1eSToby Isaac DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called 2848d4d07f1eSToby Isaac 2849bb7acecfSBarry Smith Logically Collective on dm 2850d4d07f1eSToby Isaac 28514165533cSJose E. Roman Input Parameters: 2852bb7acecfSBarry Smith + dm - the `DM` 2853bb7acecfSBarry Smith . beginhook - function to run at the beginning of `DMLocalToGlobalBegin()` 2854bb7acecfSBarry Smith . endhook - function to run after `DMLocalToGlobalEnd()` has completed 2855d4d07f1eSToby Isaac - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 2856d4d07f1eSToby Isaac 2857d4d07f1eSToby Isaac Calling sequence for beginhook: 2858d4d07f1eSToby Isaac $ beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2859d4d07f1eSToby Isaac 2860bb7acecfSBarry Smith + dm - global `DM` 2861d4d07f1eSToby Isaac . l - local vector 2862d4d07f1eSToby Isaac . mode - mode 2863d4d07f1eSToby Isaac . g - global vector 2864d4d07f1eSToby Isaac - ctx - optional user-defined function context 2865d4d07f1eSToby Isaac 2866d4d07f1eSToby Isaac Calling sequence for endhook: 2867d4d07f1eSToby Isaac $ endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx) 2868d4d07f1eSToby Isaac 2869bb7acecfSBarry Smith + global - global `DM` 2870d4d07f1eSToby Isaac . l - local vector 2871d4d07f1eSToby Isaac . mode - mode 2872d4d07f1eSToby Isaac . g - global vector 2873d4d07f1eSToby Isaac - ctx - optional user-defined function context 2874d4d07f1eSToby Isaac 2875d4d07f1eSToby Isaac Level: advanced 2876d4d07f1eSToby Isaac 2877bb7acecfSBarry Smith .seealso: `DMLocalToGlobal()`, `DMRefineHookAdd()`, `DMGlobalToLocalHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 2878d4d07f1eSToby Isaac @*/ 2879d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx) 2880d4d07f1eSToby Isaac { 2881d4d07f1eSToby Isaac DMLocalToGlobalHookLink link,*p; 2882d4d07f1eSToby Isaac 2883d4d07f1eSToby Isaac PetscFunctionBegin; 2884d4d07f1eSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 2885d4d07f1eSToby Isaac for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */ 28869566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 2887d4d07f1eSToby Isaac link->beginhook = beginhook; 2888d4d07f1eSToby Isaac link->endhook = endhook; 2889d4d07f1eSToby Isaac link->ctx = ctx; 2890d4d07f1eSToby Isaac link->next = NULL; 2891d4d07f1eSToby Isaac *p = link; 2892d4d07f1eSToby Isaac PetscFunctionReturn(0); 2893d4d07f1eSToby Isaac } 2894d4d07f1eSToby Isaac 28954c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx) 28964c274da1SToby Isaac { 28974c274da1SToby Isaac Mat cMat; 28984c274da1SToby Isaac Vec cVec; 28994c274da1SToby Isaac PetscSection section, cSec; 29004c274da1SToby Isaac PetscInt pStart, pEnd, p, dof; 29014c274da1SToby Isaac 29024c274da1SToby Isaac PetscFunctionBegin; 29034c274da1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 29049566063dSJacob Faibussowitsch PetscCall(DMGetDefaultConstraints(dm,&cSec,&cMat,NULL)); 29054c274da1SToby Isaac if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) { 29065db9a05bSToby Isaac PetscInt nRows; 29075db9a05bSToby Isaac 29089566063dSJacob Faibussowitsch PetscCall(MatGetSize(cMat,&nRows,NULL)); 29095db9a05bSToby Isaac if (nRows <= 0) PetscFunctionReturn(0); 29109566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm,§ion)); 29119566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(cMat,NULL,&cVec)); 29129566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(cSec,&pStart,&pEnd)); 29134c274da1SToby Isaac for (p = pStart; p < pEnd; p++) { 29149566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(cSec,p,&dof)); 29154c274da1SToby Isaac if (dof) { 29164c274da1SToby Isaac PetscInt d; 29174c274da1SToby Isaac PetscScalar *vals; 29189566063dSJacob Faibussowitsch PetscCall(VecGetValuesSection(l,section,p,&vals)); 29199566063dSJacob Faibussowitsch PetscCall(VecSetValuesSection(cVec,cSec,p,vals,mode)); 29204c274da1SToby Isaac /* for this to be the true transpose, we have to zero the values that 29214c274da1SToby Isaac * we just extracted */ 29224c274da1SToby Isaac for (d = 0; d < dof; d++) { 29234c274da1SToby Isaac vals[d] = 0.; 29244c274da1SToby Isaac } 29254c274da1SToby Isaac } 29264c274da1SToby Isaac } 29279566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd(cMat,cVec,l,l)); 29289566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cVec)); 29294c274da1SToby Isaac } 29304c274da1SToby Isaac PetscFunctionReturn(0); 29314c274da1SToby Isaac } 293201729b5cSPatrick Sanan /*@ 293301729b5cSPatrick Sanan DMLocalToGlobal - updates global vectors from local vectors 293401729b5cSPatrick Sanan 2935d083f849SBarry Smith Neighbor-wise Collective on dm 293601729b5cSPatrick Sanan 293701729b5cSPatrick Sanan Input Parameters: 2938bb7acecfSBarry Smith + dm - the `DM` object 293901729b5cSPatrick Sanan . l - the local vector 2940bb7acecfSBarry 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. 294101729b5cSPatrick Sanan - g - the global vector 294201729b5cSPatrick Sanan 294301729b5cSPatrick Sanan Notes: 294401729b5cSPatrick Sanan The communication involved in this update can be overlapped with computation by using 2945bb7acecfSBarry Smith `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()`. 294601729b5cSPatrick Sanan 2947bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 2948bb7acecfSBarry Smith 2949bb7acecfSBarry 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. 2950bb7acecfSBarry Smith 2951bb7acecfSBarry Smith Use `DMLocalToGlobalHookAdd()` to add additional operations that are performed on the data during the update process 295201729b5cSPatrick Sanan 295301729b5cSPatrick Sanan Level: beginner 295401729b5cSPatrick Sanan 2955bb7acecfSBarry Smith .seealso: `DMLocalToGlobalBegin()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()`, `DMLocalToGlobalHookAdd()`, `DMGlobaToLocallHookAdd()` 295601729b5cSPatrick Sanan 295701729b5cSPatrick Sanan @*/ 295801729b5cSPatrick Sanan PetscErrorCode DMLocalToGlobal(DM dm,Vec l,InsertMode mode,Vec g) 295901729b5cSPatrick Sanan { 296001729b5cSPatrick Sanan PetscFunctionBegin; 29619566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm,l,mode,g)); 29629566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm,l,mode,g)); 296301729b5cSPatrick Sanan PetscFunctionReturn(0); 296401729b5cSPatrick Sanan } 29654c274da1SToby Isaac 296647c6ae99SBarry Smith /*@ 296701729b5cSPatrick Sanan DMLocalToGlobalBegin - begins updating global vectors from local vectors 29689a42bb27SBarry Smith 2969d083f849SBarry Smith Neighbor-wise Collective on dm 29709a42bb27SBarry Smith 29719a42bb27SBarry Smith Input Parameters: 2972bb7acecfSBarry Smith + dm - the `DM` object 2973f6813fd5SJed Brown . l - the local vector 2974bb7acecfSBarry 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. 29751eb28f2eSBarry Smith - g - the global vector 29769a42bb27SBarry Smith 297795452b02SPatrick Sanan Notes: 2978bb7acecfSBarry Smith In the `ADD_VALUES` case you normally would zero the receiving vector before beginning this operation. 2979bb7acecfSBarry Smith 2980bb7acecfSBarry 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. 2981bb7acecfSBarry Smith 2982bb7acecfSBarry Smith Use `DMLocalToGlobalEnd()` to complete the communication process. 2983bb7acecfSBarry Smith 2984bb7acecfSBarry Smith `DMLocalToGlobal()` is a short form of `DMLocalToGlobalBegin()` and `DMLocalToGlobalEnd()` 2985bb7acecfSBarry Smith 2986bb7acecfSBarry Smith `DMLocalToGlobalHookAdd()` may be used to provide additional operations that are performed during the update process. 29879a42bb27SBarry Smith 298801729b5cSPatrick Sanan Level: intermediate 29899a42bb27SBarry Smith 2990bb7acecfSBarry Smith .seealso: `DMLocalToGlobal()`, `DMLocalToGlobalEnd()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocal()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalBegin()` 29919a42bb27SBarry Smith 29929a42bb27SBarry Smith @*/ 29937087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g) 29949a42bb27SBarry Smith { 29957128ae9fSMatthew G Knepley PetscSF sf; 299684330215SMatthew G. Knepley PetscSection s, gs; 2997d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 2998ca3d3a14SMatthew G. Knepley Vec tmpl; 2999ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3000ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3001fa88e482SJed Brown PetscBool isInsert, transform, l_inplace = PETSC_FALSE, g_inplace = PETSC_FALSE; 3002d0295fc0SJunchao Zhang PetscMemType lmtype=PETSC_MEMTYPE_HOST,gmtype=PETSC_MEMTYPE_HOST; 30039a42bb27SBarry Smith 30049a42bb27SBarry Smith PetscFunctionBegin; 3005171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3006d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 30071baa6e33SBarry Smith if (link->beginhook) PetscCall((*link->beginhook)(dm,l,mode,g,link->ctx)); 3008d4d07f1eSToby Isaac } 30099566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL)); 30109566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 30119566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 30127128ae9fSMatthew G Knepley switch (mode) { 30137128ae9fSMatthew G Knepley case INSERT_VALUES: 30147128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 3015304ab55fSMatthew G. Knepley case INSERT_BC_VALUES: 301684330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 30177128ae9fSMatthew G Knepley case ADD_VALUES: 30187128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 3019304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 302084330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 30217128ae9fSMatthew G Knepley default: 302263a3b9bcSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 30237128ae9fSMatthew G Knepley } 3024ca3d3a14SMatthew G. Knepley if ((sf && !isInsert) || (s && isInsert)) { 30259566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3026ca3d3a14SMatthew G. Knepley if (transform) { 30279566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 30289566063dSJacob Faibussowitsch PetscCall(VecCopy(l, tmpl)); 30299566063dSJacob Faibussowitsch PetscCall(DMPlexLocalToGlobalBasis(dm, tmpl)); 30309566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3031fa88e482SJed Brown } else if (isInsert) { 30329566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(l, &lArray)); 3033fa88e482SJed Brown } else { 30349566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, &lmtype)); 3035fa88e482SJed Brown l_inplace = PETSC_TRUE; 3036ca3d3a14SMatthew G. Knepley } 3037fa88e482SJed Brown if (s && isInsert) { 30389566063dSJacob Faibussowitsch PetscCall(VecGetArray(g, &gArray)); 3039fa88e482SJed Brown } else { 30409566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, &gmtype)); 3041fa88e482SJed Brown g_inplace = PETSC_TRUE; 3042fa88e482SJed Brown } 3043ca3d3a14SMatthew G. Knepley if (sf && !isInsert) { 30449566063dSJacob Faibussowitsch PetscCall(PetscSFReduceWithMemTypeBegin(sf, MPIU_SCALAR, lmtype, lArray, gmtype, gArray, MPIU_SUM)); 304584330215SMatthew G. Knepley } else if (s && isInsert) { 304684330215SMatthew G. Knepley PetscInt gStart, pStart, pEnd, p; 304784330215SMatthew G. Knepley 30489566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 30499566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 30509566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(g, &gStart, NULL)); 305184330215SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3052b3b16f48SMatthew G. Knepley PetscInt dof, gdof, cdof, gcdof, off, goff, d, e; 305384330215SMatthew G. Knepley 30549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 30559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(gs, p, &gdof)); 30569566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 30579566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(gs, p, &gcdof)); 30589566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(s, p, &off)); 30599566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(gs, p, &goff)); 3060b3b16f48SMatthew G. Knepley /* Ignore off-process data and points with no global data */ 306103442857SMatthew G. Knepley if (!gdof || goff < 0) continue; 30627a8be351SBarry 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); 3063b3b16f48SMatthew G. Knepley /* If no constraints are enforced in the global vector */ 3064b3b16f48SMatthew G. Knepley if (!gcdof) { 306584330215SMatthew G. Knepley for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d]; 3066b3b16f48SMatthew G. Knepley /* If constraints are enforced in the global vector */ 3067b3b16f48SMatthew G. Knepley } else if (cdof == gcdof) { 306884330215SMatthew G. Knepley const PetscInt *cdofs; 306984330215SMatthew G. Knepley PetscInt cind = 0; 307084330215SMatthew G. Knepley 30719566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintIndices(s, p, &cdofs)); 3072b3b16f48SMatthew G. Knepley for (d = 0, e = 0; d < dof; ++d) { 307384330215SMatthew G. Knepley if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;} 3074b3b16f48SMatthew G. Knepley gArray[goff-gStart+e++] = lArray[off+d]; 307584330215SMatthew G. Knepley } 30767a8be351SBarry 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); 307784330215SMatthew G. Knepley } 3078ca3d3a14SMatthew G. Knepley } 3079fa88e482SJed Brown if (g_inplace) { 30809566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 3081fa88e482SJed Brown } else { 30829566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(g, &gArray)); 3083fa88e482SJed Brown } 3084ca3d3a14SMatthew G. Knepley if (transform) { 30859566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 30869566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3087fa88e482SJed Brown } else if (l_inplace) { 30889566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3089ca3d3a14SMatthew G. Knepley } else { 30909566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(l, &lArray)); 3091ca3d3a14SMatthew G. Knepley } 30927128ae9fSMatthew G Knepley } else { 30939566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g)); 30947128ae9fSMatthew G Knepley } 30959a42bb27SBarry Smith PetscFunctionReturn(0); 30969a42bb27SBarry Smith } 30979a42bb27SBarry Smith 30989a42bb27SBarry Smith /*@ 30999a42bb27SBarry Smith DMLocalToGlobalEnd - updates global vectors from local vectors 310047c6ae99SBarry Smith 3101d083f849SBarry Smith Neighbor-wise Collective on dm 310247c6ae99SBarry Smith 310347c6ae99SBarry Smith Input Parameters: 3104bb7acecfSBarry Smith + dm - the `DM` object 3105f6813fd5SJed Brown . l - the local vector 3106bb7acecfSBarry Smith . mode - `INSERT_VALUES` or `ADD_VALUES` 3107f6813fd5SJed Brown - g - the global vector 310847c6ae99SBarry Smith 310901729b5cSPatrick Sanan Level: intermediate 311047c6ae99SBarry Smith 3111bb7acecfSBarry Smith Note: 3112bb7acecfSBarry Smith See `DMLocalToGlobalBegin()` for full details 3113bb7acecfSBarry Smith 3114bb7acecfSBarry Smith .seealso: `DMLocalToGlobalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMGlobalToLocalEnd()`, `DMGlobalToLocalEnd()` 311547c6ae99SBarry Smith 311647c6ae99SBarry Smith @*/ 31177087cfbeSBarry Smith PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g) 311847c6ae99SBarry Smith { 31197128ae9fSMatthew G Knepley PetscSF sf; 312084330215SMatthew G. Knepley PetscSection s; 3121d4d07f1eSToby Isaac DMLocalToGlobalHookLink link; 3122ca3d3a14SMatthew G. Knepley PetscBool isInsert, transform; 312347c6ae99SBarry Smith 312447c6ae99SBarry Smith PetscFunctionBegin; 3125171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 31269566063dSJacob Faibussowitsch PetscCall(DMGetSectionSF(dm, &sf)); 31279566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 31287128ae9fSMatthew G Knepley switch (mode) { 31297128ae9fSMatthew G Knepley case INSERT_VALUES: 31307128ae9fSMatthew G Knepley case INSERT_ALL_VALUES: 313184330215SMatthew G. Knepley isInsert = PETSC_TRUE; break; 31327128ae9fSMatthew G Knepley case ADD_VALUES: 31337128ae9fSMatthew G Knepley case ADD_ALL_VALUES: 313484330215SMatthew G. Knepley isInsert = PETSC_FALSE; break; 31357128ae9fSMatthew G Knepley default: 313663a3b9bcSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %d", mode); 31377128ae9fSMatthew G Knepley } 313884330215SMatthew G. Knepley if (sf && !isInsert) { 3139ae5cfb4aSMatthew G. Knepley const PetscScalar *lArray; 3140ae5cfb4aSMatthew G. Knepley PetscScalar *gArray; 3141ca3d3a14SMatthew G. Knepley Vec tmpl; 314284330215SMatthew G. Knepley 31439566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 3144ca3d3a14SMatthew G. Knepley if (transform) { 31459566063dSJacob Faibussowitsch PetscCall(DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 31469566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(tmpl, &lArray)); 3147ca3d3a14SMatthew G. Knepley } else { 31489566063dSJacob Faibussowitsch PetscCall(VecGetArrayReadAndMemType(l, &lArray, NULL)); 3149ca3d3a14SMatthew G. Knepley } 31509566063dSJacob Faibussowitsch PetscCall(VecGetArrayAndMemType(g, &gArray, NULL)); 31519566063dSJacob Faibussowitsch PetscCall(PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM)); 3152ca3d3a14SMatthew G. Knepley if (transform) { 31539566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(tmpl, &lArray)); 31549566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl)); 3155ca3d3a14SMatthew G. Knepley } else { 31569566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayReadAndMemType(l, &lArray)); 3157ca3d3a14SMatthew G. Knepley } 31589566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayAndMemType(g, &gArray)); 315984330215SMatthew G. Knepley } else if (s && isInsert) { 31607128ae9fSMatthew G Knepley } else { 31619566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g)); 31627128ae9fSMatthew G Knepley } 3163d4d07f1eSToby Isaac for (link=dm->ltoghook; link; link=link->next) { 31649566063dSJacob Faibussowitsch if (link->endhook) PetscCall((*link->endhook)(dm,g,mode,l,link->ctx)); 3165d4d07f1eSToby Isaac } 316647c6ae99SBarry Smith PetscFunctionReturn(0); 316747c6ae99SBarry Smith } 316847c6ae99SBarry Smith 3169f089877aSRichard Tran Mills /*@ 3170bb7acecfSBarry Smith DMLocalToLocalBegin - Begins the process of mapping values from a local vector (that include ghost points 3171bc0a1609SRichard Tran Mills that contain irrelevant values) to another local vector where the ghost 3172bb7acecfSBarry Smith points in the second are set correctly from values on other MPI ranks. Must be followed by `DMLocalToLocalEnd()`. 3173f089877aSRichard Tran Mills 3174d083f849SBarry Smith Neighbor-wise Collective on dm 3175f089877aSRichard Tran Mills 3176f089877aSRichard Tran Mills Input Parameters: 3177bb7acecfSBarry Smith + dm - the `DM` object 3178bc0a1609SRichard Tran Mills . g - the original local vector 3179bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3180f089877aSRichard Tran Mills 3181bc0a1609SRichard Tran Mills Output Parameter: 3182bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3183f089877aSRichard Tran Mills 3184f089877aSRichard Tran Mills Level: intermediate 3185f089877aSRichard Tran Mills 3186bb7acecfSBarry Smith .seealso: `DMLocalToLocalEnd(), `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMLocalToLocalEnd()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3187f089877aSRichard Tran Mills 3188f089877aSRichard Tran Mills @*/ 3189f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l) 3190f089877aSRichard Tran Mills { 3191f089877aSRichard Tran Mills PetscFunctionBegin; 3192f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 31939566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l)); 3194f089877aSRichard Tran Mills PetscFunctionReturn(0); 3195f089877aSRichard Tran Mills } 3196f089877aSRichard Tran Mills 3197f089877aSRichard Tran Mills /*@ 3198bb7acecfSBarry Smith DMLocalToLocalEnd - Maps from a local vector to another local vector where the ghost 3199bb7acecfSBarry Smith points in the second are set correctly. Must be preceded by `DMLocalToLocalBegin()`. 3200f089877aSRichard Tran Mills 3201d083f849SBarry Smith Neighbor-wise Collective on dm 3202f089877aSRichard Tran Mills 3203f089877aSRichard Tran Mills Input Parameters: 3204bb7acecfSBarry Smith + da - the `DM` object 3205bc0a1609SRichard Tran Mills . g - the original local vector 3206bb7acecfSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 3207f089877aSRichard Tran Mills 3208bc0a1609SRichard Tran Mills Output Parameter: 3209bc0a1609SRichard Tran Mills . l - the local vector with correct ghost values 3210f089877aSRichard Tran Mills 3211f089877aSRichard Tran Mills Level: intermediate 3212f089877aSRichard Tran Mills 3213bb7acecfSBarry Smith .seealso: `DMLocalToLocalBegin()`, `DMCoarsen()`, `DMDestroy()`, `DMView()`, `DMCreateLocalVector()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMLocalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 3214f089877aSRichard Tran Mills 3215f089877aSRichard Tran Mills @*/ 3216f089877aSRichard Tran Mills PetscErrorCode DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l) 3217f089877aSRichard Tran Mills { 3218f089877aSRichard Tran Mills PetscFunctionBegin; 3219f089877aSRichard Tran Mills PetscValidHeaderSpecific(dm,DM_CLASSID,1); 32209566063dSJacob Faibussowitsch PetscCall((*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l)); 3221f089877aSRichard Tran Mills PetscFunctionReturn(0); 3222f089877aSRichard Tran Mills } 3223f089877aSRichard Tran Mills 322447c6ae99SBarry Smith /*@ 3225bb7acecfSBarry Smith DMCoarsen - Coarsens a `DM` object using a standard, non-adaptive coarsening of the underlying mesh 322647c6ae99SBarry Smith 3227d083f849SBarry Smith Collective on dm 322847c6ae99SBarry Smith 3229d8d19677SJose E. Roman Input Parameters: 3230bb7acecfSBarry Smith + dm - the `DM` object 3231bb7acecfSBarry Smith - comm - the communicator to contain the new `DM` object (or MPI_COMM_NULL) 323247c6ae99SBarry Smith 323347c6ae99SBarry Smith Output Parameter: 3234bb7acecfSBarry Smith . dmc - the coarsened `DM` 323547c6ae99SBarry Smith 323647c6ae99SBarry Smith Level: developer 323747c6ae99SBarry Smith 3238bb7acecfSBarry Smith .seealso: `DM`, `DMRefine()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 323947c6ae99SBarry Smith 324047c6ae99SBarry Smith @*/ 32417087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc) 324247c6ae99SBarry Smith { 3243b17ce1afSJed Brown DMCoarsenHookLink link; 324447c6ae99SBarry Smith 324547c6ae99SBarry Smith PetscFunctionBegin; 3246171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 32479566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Coarsen,dm,0,0,0)); 3248*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,coarsen , comm, dmc); 3249b9d85ea2SLisandro Dalcin if (*dmc) { 3250a3574896SRichard Tran Mills (*dmc)->bind_below = dm->bind_below; /* Propagate this from parent DM; otherwise -dm_bind_below will be useless for multigrid cases. */ 32519566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm,*dmc)); 325243842a1eSJed Brown (*dmc)->ops->creatematrix = dm->ops->creatematrix; 32539566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc)); 3254644e2e5bSBarry Smith (*dmc)->ctx = dm->ctx; 32550598a293SJed Brown (*dmc)->levelup = dm->levelup; 3256656b349aSBarry Smith (*dmc)->leveldown = dm->leveldown + 1; 32579566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*dmc,dm->mattype)); 3258b17ce1afSJed Brown for (link=dm->coarsenhook; link; link=link->next) { 32599566063dSJacob Faibussowitsch if (link->coarsenhook) PetscCall((*link->coarsenhook)(dm,*dmc,link->ctx)); 3260b17ce1afSJed Brown } 3261b9d85ea2SLisandro Dalcin } 32629566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Coarsen,dm,0,0,0)); 32637a8be351SBarry Smith PetscCheck(*dmc,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced"); 3264b17ce1afSJed Brown PetscFunctionReturn(0); 3265b17ce1afSJed Brown } 3266b17ce1afSJed Brown 3267bb9467b5SJed Brown /*@C 3268b17ce1afSJed Brown DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid 3269b17ce1afSJed Brown 3270bb7acecfSBarry Smith Logically Collective on fine 3271b17ce1afSJed Brown 32724165533cSJose E. Roman Input Parameters: 3273bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3274b17ce1afSJed Brown . coarsenhook - function to run when setting up a coarser level 3275bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels (called once per `SNESSolve()`) 32760298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3277b17ce1afSJed Brown 3278b17ce1afSJed Brown Calling sequence of coarsenhook: 3279b17ce1afSJed Brown $ coarsenhook(DM fine,DM coarse,void *ctx); 3280b17ce1afSJed Brown 3281bb7acecfSBarry Smith + fine - fine level `DM` 3282bb7acecfSBarry Smith . coarse - coarse level `DM` to restrict problem to 3283b17ce1afSJed Brown - ctx - optional user-defined function context 3284b17ce1afSJed Brown 3285b17ce1afSJed Brown Calling sequence for restricthook: 3286c833c3b5SJed Brown $ restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx) 3287bb7acecfSBarry Smith $ 3288bb7acecfSBarry Smith + fine - fine level `DM` 3289bb7acecfSBarry Smith . mrestrict - matrix restricting a fine-level solution to the coarse grid, usually the transpose of the interpolation 3290c833c3b5SJed Brown . rscale - scaling vector for restriction 3291c833c3b5SJed Brown . inject - matrix restricting by injection 3292b17ce1afSJed Brown . coarse - coarse level DM to update 3293b17ce1afSJed Brown - ctx - optional user-defined function context 3294b17ce1afSJed Brown 3295b17ce1afSJed Brown Level: advanced 3296b17ce1afSJed Brown 3297b17ce1afSJed Brown Notes: 3298bb7acecfSBarry 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`. 3299b17ce1afSJed Brown 3300b17ce1afSJed Brown If this function is called multiple times, the hooks will be run in the order they are added. 3301b17ce1afSJed Brown 3302b17ce1afSJed Brown In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3303bb7acecfSBarry Smith extract the finest level information from its context (instead of from the `SNES`). 3304b17ce1afSJed Brown 3305bb7acecfSBarry Smith The hooks are automatically called by `DMRestrict()` 3306bb7acecfSBarry Smith 3307bb7acecfSBarry Smith Fortran Note: 3308bb7acecfSBarry Smith This function is not available from Fortran. 3309bb9467b5SJed Brown 3310db781477SPatrick Sanan .seealso: `DMCoarsenHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3311b17ce1afSJed Brown @*/ 3312b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3313b17ce1afSJed Brown { 3314b17ce1afSJed Brown DMCoarsenHookLink link,*p; 3315b17ce1afSJed Brown 3316b17ce1afSJed Brown PetscFunctionBegin; 3317b17ce1afSJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 33181e3d8eccSJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 33191e3d8eccSJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 33201e3d8eccSJed Brown } 33219566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 3322b17ce1afSJed Brown link->coarsenhook = coarsenhook; 3323b17ce1afSJed Brown link->restricthook = restricthook; 3324b17ce1afSJed Brown link->ctx = ctx; 33250298fd71SBarry Smith link->next = NULL; 3326b17ce1afSJed Brown *p = link; 3327b17ce1afSJed Brown PetscFunctionReturn(0); 3328b17ce1afSJed Brown } 3329b17ce1afSJed Brown 3330dc822a44SJed Brown /*@C 3331bb7acecfSBarry Smith DMCoarsenHookRemove - remove a callback set with `DMCoarsenHookAdd()` 3332dc822a44SJed Brown 3333bb7acecfSBarry Smith Logically Collective on fine 3334dc822a44SJed Brown 33354165533cSJose E. Roman Input Parameters: 3336bb7acecfSBarry Smith + fine - `DM` on which to run a hook when restricting to a coarser level 3337dc822a44SJed Brown . coarsenhook - function to run when setting up a coarser level 3338bb7acecfSBarry Smith . restricthook - function to run to update data on coarser levels 3339dc822a44SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3340dc822a44SJed Brown 3341dc822a44SJed Brown Level: advanced 3342dc822a44SJed Brown 3343bb7acecfSBarry Smith Note: 3344dc822a44SJed Brown This function does nothing if the hook is not in the list. 3345dc822a44SJed Brown 3346bb7acecfSBarry Smith Fortran Note: 3347bb7acecfSBarry Smith This function is not available from Fortran. 3348dc822a44SJed Brown 3349db781477SPatrick Sanan .seealso: `DMCoarsenHookAdd()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3350dc822a44SJed Brown @*/ 3351dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx) 3352dc822a44SJed Brown { 3353dc822a44SJed Brown DMCoarsenHookLink link,*p; 3354dc822a44SJed Brown 3355dc822a44SJed Brown PetscFunctionBegin; 3356dc822a44SJed Brown PetscValidHeaderSpecific(fine,DM_CLASSID,1); 3357dc822a44SJed Brown for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3358dc822a44SJed Brown if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3359dc822a44SJed Brown link = *p; 3360dc822a44SJed Brown *p = link->next; 33619566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3362dc822a44SJed Brown break; 3363dc822a44SJed Brown } 3364dc822a44SJed Brown } 3365dc822a44SJed Brown PetscFunctionReturn(0); 3366dc822a44SJed Brown } 3367dc822a44SJed Brown 3368b17ce1afSJed Brown /*@ 3369bb7acecfSBarry Smith DMRestrict - restricts user-defined problem data to a coarser `DM` by running hooks registered by `DMCoarsenHookAdd()` 3370b17ce1afSJed Brown 3371b17ce1afSJed Brown Collective if any hooks are 3372b17ce1afSJed Brown 33734165533cSJose E. Roman Input Parameters: 3374bb7acecfSBarry Smith + fine - finer `DM` from which the data is obtained 3375bb7acecfSBarry Smith . restrct - restriction matrix, apply using `MatRestrict()`, usually the transpose of the interpolation 3376e91eccc2SStefano Zampini . rscale - scaling vector for restriction 3377bb7acecfSBarry Smith . inject - injection matrix, also use `MatRestrict()` 3378e91eccc2SStefano Zampini - coarse - coarser DM to update 3379b17ce1afSJed Brown 3380b17ce1afSJed Brown Level: developer 3381b17ce1afSJed Brown 3382bb7acecfSBarry Smith Developer Note: 3383bb7acecfSBarry Smith Though this routine is called `DMRestrict()` the hooks are added with `DMCoarsenHookAdd()`, a consistent terminology would be better 3384bb7acecfSBarry Smith 3385bb7acecfSBarry Smith .seealso: `DMCoarsenHookAdd()`, `MatRestrict()`, `DMInterpolate()`, `DMRefineHookAdd()` 3386b17ce1afSJed Brown @*/ 3387b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse) 3388b17ce1afSJed Brown { 3389b17ce1afSJed Brown DMCoarsenHookLink link; 3390b17ce1afSJed Brown 3391b17ce1afSJed Brown PetscFunctionBegin; 3392b17ce1afSJed Brown for (link=fine->coarsenhook; link; link=link->next) { 33931baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx)); 3394b17ce1afSJed Brown } 339547c6ae99SBarry Smith PetscFunctionReturn(0); 339647c6ae99SBarry Smith } 339747c6ae99SBarry Smith 3398bb9467b5SJed Brown /*@C 3399be081cd6SPeter Brune DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid 34005dbd56e3SPeter Brune 3401d083f849SBarry Smith Logically Collective on global 34025dbd56e3SPeter Brune 34034165533cSJose E. Roman Input Parameters: 3404bb7acecfSBarry Smith + global - global `DM` 3405bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 34065dbd56e3SPeter Brune . restricthook - function to run to update data on block solve (at the beginning of the block solve) 34070298fd71SBarry Smith - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 34085dbd56e3SPeter Brune 3409ec4806b8SPeter Brune Calling sequence for ddhook: 3410ec4806b8SPeter Brune $ ddhook(DM global,DM block,void *ctx) 3411ec4806b8SPeter Brune 3412bb7acecfSBarry Smith + global - global `DM` 3413bb7acecfSBarry Smith . block - block `DM` 3414ec4806b8SPeter Brune - ctx - optional user-defined function context 3415ec4806b8SPeter Brune 34165dbd56e3SPeter Brune Calling sequence for restricthook: 3417ec4806b8SPeter Brune $ restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx) 34185dbd56e3SPeter Brune 3419bb7acecfSBarry Smith + global - global `DM` 34205dbd56e3SPeter Brune . out - scatter to the outer (with ghost and overlap points) block vector 34215dbd56e3SPeter Brune . in - scatter to block vector values only owned locally 3422bb7acecfSBarry Smith . block - block `DM` 34235dbd56e3SPeter Brune - ctx - optional user-defined function context 34245dbd56e3SPeter Brune 34255dbd56e3SPeter Brune Level: advanced 34265dbd56e3SPeter Brune 34275dbd56e3SPeter Brune Notes: 3428bb7acecfSBarry Smith This function is only needed if auxiliary data needs to be set up on subdomain `DM`s. 34295dbd56e3SPeter Brune 34305dbd56e3SPeter Brune If this function is called multiple times, the hooks will be run in the order they are added. 34315dbd56e3SPeter Brune 34325dbd56e3SPeter Brune In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to 3433bb7acecfSBarry Smith extract the global information from its context (instead of from the `SNES`). 34345dbd56e3SPeter Brune 3435bb7acecfSBarry Smith Fortran Note: 3436bb7acecfSBarry Smith This function is not available from Fortran. 3437bb9467b5SJed Brown 3438bb7acecfSBarry Smith .seealso: `DMSubDomainHookRemove()`, `DMRefineHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 34395dbd56e3SPeter Brune @*/ 3440be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 34415dbd56e3SPeter Brune { 3442be081cd6SPeter Brune DMSubDomainHookLink link,*p; 34435dbd56e3SPeter Brune 34445dbd56e3SPeter Brune PetscFunctionBegin; 34455dbd56e3SPeter Brune PetscValidHeaderSpecific(global,DM_CLASSID,1); 3446b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */ 3447b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0); 3448b3a6b972SJed Brown } 34499566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 34505dbd56e3SPeter Brune link->restricthook = restricthook; 3451be081cd6SPeter Brune link->ddhook = ddhook; 34525dbd56e3SPeter Brune link->ctx = ctx; 34530298fd71SBarry Smith link->next = NULL; 34545dbd56e3SPeter Brune *p = link; 34555dbd56e3SPeter Brune PetscFunctionReturn(0); 34565dbd56e3SPeter Brune } 34575dbd56e3SPeter Brune 3458b3a6b972SJed Brown /*@C 3459b3a6b972SJed Brown DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid 3460b3a6b972SJed Brown 3461bb7acecfSBarry Smith Logically Collective on global 3462b3a6b972SJed Brown 34634165533cSJose E. Roman Input Parameters: 3464bb7acecfSBarry Smith + global - global `DM` 3465bb7acecfSBarry Smith . ddhook - function to run to pass data to the decomposition `DM` upon its creation 3466b3a6b972SJed Brown . restricthook - function to run to update data on block solve (at the beginning of the block solve) 3467b3a6b972SJed Brown - ctx - [optional] user-defined context for provide data for the hooks (may be NULL) 3468b3a6b972SJed Brown 3469b3a6b972SJed Brown Level: advanced 3470b3a6b972SJed Brown 3471bb7acecfSBarry Smith Fortran Note: 3472bb7acecfSBarry Smith This function is not available from Fortran. 3473b3a6b972SJed Brown 3474db781477SPatrick Sanan .seealso: `DMSubDomainHookAdd()`, `SNESFASGetInterpolation()`, `SNESFASGetInjection()`, `PetscObjectCompose()`, `PetscContainerCreate()` 3475b3a6b972SJed Brown @*/ 3476b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx) 3477b3a6b972SJed Brown { 3478b3a6b972SJed Brown DMSubDomainHookLink link,*p; 3479b3a6b972SJed Brown 3480b3a6b972SJed Brown PetscFunctionBegin; 3481b3a6b972SJed Brown PetscValidHeaderSpecific(global,DM_CLASSID,1); 3482b3a6b972SJed Brown for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */ 3483b3a6b972SJed Brown if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) { 3484b3a6b972SJed Brown link = *p; 3485b3a6b972SJed Brown *p = link->next; 34869566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 3487b3a6b972SJed Brown break; 3488b3a6b972SJed Brown } 3489b3a6b972SJed Brown } 3490b3a6b972SJed Brown PetscFunctionReturn(0); 3491b3a6b972SJed Brown } 3492b3a6b972SJed Brown 34935dbd56e3SPeter Brune /*@ 3494bb7acecfSBarry Smith DMSubDomainRestrict - restricts user-defined problem data to a block `DM` by running hooks registered by `DMSubDomainHookAdd()` 34955dbd56e3SPeter Brune 34965dbd56e3SPeter Brune Collective if any hooks are 34975dbd56e3SPeter Brune 34984165533cSJose E. Roman Input Parameters: 3499bb7acecfSBarry Smith + fine - finer `DM` to use as a base 3500be081cd6SPeter Brune . oscatter - scatter from domain global vector filling subdomain global vector with overlap 3501be081cd6SPeter Brune . gscatter - scatter from domain global vector filling subdomain local vector with ghosts 3502bb7acecfSBarry Smith - coarse - coarser `DM` to update 35035dbd56e3SPeter Brune 35045dbd56e3SPeter Brune Level: developer 35055dbd56e3SPeter Brune 3506db781477SPatrick Sanan .seealso: `DMCoarsenHookAdd()`, `MatRestrict()` 35075dbd56e3SPeter Brune @*/ 3508be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm) 35095dbd56e3SPeter Brune { 3510be081cd6SPeter Brune DMSubDomainHookLink link; 35115dbd56e3SPeter Brune 35125dbd56e3SPeter Brune PetscFunctionBegin; 3513be081cd6SPeter Brune for (link=global->subdomainhook; link; link=link->next) { 35141baa6e33SBarry Smith if (link->restricthook) PetscCall((*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx)); 35155dbd56e3SPeter Brune } 35165dbd56e3SPeter Brune PetscFunctionReturn(0); 35175dbd56e3SPeter Brune } 35185dbd56e3SPeter Brune 35195fe1f584SPeter Brune /*@ 3520bb7acecfSBarry Smith DMGetCoarsenLevel - Gets the number of coarsenings that have generated this `DM`. 35215fe1f584SPeter Brune 35225fe1f584SPeter Brune Not Collective 35235fe1f584SPeter Brune 35245fe1f584SPeter Brune Input Parameter: 3525bb7acecfSBarry Smith . dm - the `DM` object 35265fe1f584SPeter Brune 35275fe1f584SPeter Brune Output Parameter: 35286a7d9d85SPeter Brune . level - number of coarsenings 35295fe1f584SPeter Brune 35305fe1f584SPeter Brune Level: developer 35315fe1f584SPeter Brune 3532bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMSetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35335fe1f584SPeter Brune 35345fe1f584SPeter Brune @*/ 35355fe1f584SPeter Brune PetscErrorCode DMGetCoarsenLevel(DM dm,PetscInt *level) 35365fe1f584SPeter Brune { 35375fe1f584SPeter Brune PetscFunctionBegin; 35385fe1f584SPeter Brune PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3539b9d85ea2SLisandro Dalcin PetscValidIntPointer(level,2); 35405fe1f584SPeter Brune *level = dm->leveldown; 35415fe1f584SPeter Brune PetscFunctionReturn(0); 35425fe1f584SPeter Brune } 35435fe1f584SPeter Brune 35449a64c4a8SMatthew G. Knepley /*@ 3545bb7acecfSBarry Smith DMSetCoarsenLevel - Sets the number of coarsenings that have generated this `DM`. 35469a64c4a8SMatthew G. Knepley 3547bb7acecfSBarry Smith Collective on dm 35489a64c4a8SMatthew G. Knepley 35499a64c4a8SMatthew G. Knepley Input Parameters: 3550bb7acecfSBarry Smith + dm - the `DM` object 35519a64c4a8SMatthew G. Knepley - level - number of coarsenings 35529a64c4a8SMatthew G. Knepley 35539a64c4a8SMatthew G. Knepley Level: developer 35549a64c4a8SMatthew G. Knepley 3555bb7acecfSBarry Smith Note: 3556bb7acecfSBarry Smith This is rarely used directly, the information is automatically set when a `DM` is created with `DMCoarsen()` 3557bb7acecfSBarry Smith 3558bb7acecfSBarry Smith .seealso: `DMSetCoarsenLevel()`, `DMCoarsen()`, `DMGetCoarsenLevel()`, `DMGetRefineLevel()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 35599a64c4a8SMatthew G. Knepley @*/ 35609a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level) 35619a64c4a8SMatthew G. Knepley { 35629a64c4a8SMatthew G. Knepley PetscFunctionBegin; 35639a64c4a8SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 35649a64c4a8SMatthew G. Knepley dm->leveldown = level; 35659a64c4a8SMatthew G. Knepley PetscFunctionReturn(0); 35669a64c4a8SMatthew G. Knepley } 35679a64c4a8SMatthew G. Knepley 356847c6ae99SBarry Smith /*@C 3569bb7acecfSBarry Smith DMRefineHierarchy - Refines a `DM` object, all levels at once 357047c6ae99SBarry Smith 3571d083f849SBarry Smith Collective on dm 357247c6ae99SBarry Smith 3573d8d19677SJose E. Roman Input Parameters: 3574bb7acecfSBarry Smith + dm - the `DM` object 357547c6ae99SBarry Smith - nlevels - the number of levels of refinement 357647c6ae99SBarry Smith 357747c6ae99SBarry Smith Output Parameter: 3578bb7acecfSBarry Smith . dmf - the refined `DM` hierarchy 357947c6ae99SBarry Smith 358047c6ae99SBarry Smith Level: developer 358147c6ae99SBarry Smith 3582bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMCoarsenHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 358347c6ae99SBarry Smith 358447c6ae99SBarry Smith @*/ 35857087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[]) 358647c6ae99SBarry Smith { 358747c6ae99SBarry Smith PetscFunctionBegin; 3588171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 35897a8be351SBarry Smith PetscCheck(nlevels >= 0,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 359047c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 3591b9d85ea2SLisandro Dalcin PetscValidPointer(dmf,3); 359247c6ae99SBarry Smith if (dm->ops->refinehierarchy) { 3593*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,refinehierarchy ,nlevels,dmf); 359447c6ae99SBarry Smith } else if (dm->ops->refine) { 359547c6ae99SBarry Smith PetscInt i; 359647c6ae99SBarry Smith 35979566063dSJacob Faibussowitsch PetscCall(DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0])); 359847c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 35999566063dSJacob Faibussowitsch PetscCall(DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i])); 360047c6ae99SBarry Smith } 3601ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet"); 360247c6ae99SBarry Smith PetscFunctionReturn(0); 360347c6ae99SBarry Smith } 360447c6ae99SBarry Smith 360547c6ae99SBarry Smith /*@C 3606bb7acecfSBarry Smith DMCoarsenHierarchy - Coarsens a `DM` object, all levels at once 360747c6ae99SBarry Smith 3608d083f849SBarry Smith Collective on dm 360947c6ae99SBarry Smith 3610d8d19677SJose E. Roman Input Parameters: 3611bb7acecfSBarry Smith + dm - the `DM` object 361247c6ae99SBarry Smith - nlevels - the number of levels of coarsening 361347c6ae99SBarry Smith 361447c6ae99SBarry Smith Output Parameter: 3615bb7acecfSBarry Smith . dmc - the coarsened `DM` hierarchy 361647c6ae99SBarry Smith 361747c6ae99SBarry Smith Level: developer 361847c6ae99SBarry Smith 3619bb7acecfSBarry Smith .seealso: `DMCoarsen()`, `DMRefineHierarchy()`, `DMDestroy()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()` 362047c6ae99SBarry Smith 362147c6ae99SBarry Smith @*/ 36227087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[]) 362347c6ae99SBarry Smith { 362447c6ae99SBarry Smith PetscFunctionBegin; 3625171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 36267a8be351SBarry Smith PetscCheck(nlevels >= 0,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 362747c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 362847c6ae99SBarry Smith PetscValidPointer(dmc,3); 362947c6ae99SBarry Smith if (dm->ops->coarsenhierarchy) { 3630*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,coarsenhierarchy , nlevels, dmc); 363147c6ae99SBarry Smith } else if (dm->ops->coarsen) { 363247c6ae99SBarry Smith PetscInt i; 363347c6ae99SBarry Smith 36349566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0])); 363547c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 36369566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i])); 363747c6ae99SBarry Smith } 3638ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet"); 363947c6ae99SBarry Smith PetscFunctionReturn(0); 364047c6ae99SBarry Smith } 364147c6ae99SBarry Smith 36421a266240SBarry Smith /*@C 3643bb7acecfSBarry Smith DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the `DM` is destroyed 36441a266240SBarry Smith 3645bb7acecfSBarry Smith Logically Collective if the function is collective 36461a266240SBarry Smith 36471a266240SBarry Smith Input Parameters: 3648bb7acecfSBarry Smith + dm - the `DM` object 36491a266240SBarry Smith - destroy - the destroy function 36501a266240SBarry Smith 36511a266240SBarry Smith Level: intermediate 36521a266240SBarry Smith 3653bb7acecfSBarry Smith .seealso: `DMSetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 36541a266240SBarry Smith 3655f07f9ceaSJed Brown @*/ 36561a266240SBarry Smith PetscErrorCode DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**)) 36571a266240SBarry Smith { 36581a266240SBarry Smith PetscFunctionBegin; 3659171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 36601a266240SBarry Smith dm->ctxdestroy = destroy; 36611a266240SBarry Smith PetscFunctionReturn(0); 36621a266240SBarry Smith } 36631a266240SBarry Smith 3664b07ff414SBarry Smith /*@ 3665bb7acecfSBarry Smith DMSetApplicationContext - Set a user context into a `DM` object 366647c6ae99SBarry Smith 366747c6ae99SBarry Smith Not Collective 366847c6ae99SBarry Smith 366947c6ae99SBarry Smith Input Parameters: 3670bb7acecfSBarry Smith + dm - the `DM` object 367147c6ae99SBarry Smith - ctx - the user context 367247c6ae99SBarry Smith 367347c6ae99SBarry Smith Level: intermediate 367447c6ae99SBarry Smith 3675bb7acecfSBarry Smith Note: 3676bb7acecfSBarry Smith A user context is a way to pass problem specific information that is accessable whenever the `DM` is available 3677bb7acecfSBarry Smith 3678bb7acecfSBarry Smith .seealso: `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 367947c6ae99SBarry Smith 368047c6ae99SBarry Smith @*/ 36811b2093e4SBarry Smith PetscErrorCode DMSetApplicationContext(DM dm,void *ctx) 368247c6ae99SBarry Smith { 368347c6ae99SBarry Smith PetscFunctionBegin; 3684171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 368547c6ae99SBarry Smith dm->ctx = ctx; 368647c6ae99SBarry Smith PetscFunctionReturn(0); 368747c6ae99SBarry Smith } 368847c6ae99SBarry Smith 368947c6ae99SBarry Smith /*@ 3690bb7acecfSBarry Smith DMGetApplicationContext - Gets a user context from a `DM` object 369147c6ae99SBarry Smith 369247c6ae99SBarry Smith Not Collective 369347c6ae99SBarry Smith 369447c6ae99SBarry Smith Input Parameter: 3695bb7acecfSBarry Smith . dm - the `DM` object 369647c6ae99SBarry Smith 369747c6ae99SBarry Smith Output Parameter: 369847c6ae99SBarry Smith . ctx - the user context 369947c6ae99SBarry Smith 370047c6ae99SBarry Smith Level: intermediate 370147c6ae99SBarry Smith 3702bb7acecfSBarry Smith Note: 3703bb7acecfSBarry Smith A user context is a way to pass problem specific information that is accessable whenever the `DM` is available 3704bb7acecfSBarry Smith 3705bb7acecfSBarry Smith .seealso: `DMGetApplicationContext()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 370647c6ae99SBarry Smith 370747c6ae99SBarry Smith @*/ 37081b2093e4SBarry Smith PetscErrorCode DMGetApplicationContext(DM dm,void *ctx) 370947c6ae99SBarry Smith { 371047c6ae99SBarry Smith PetscFunctionBegin; 3711171400e9SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,1); 37121b2093e4SBarry Smith *(void**)ctx = dm->ctx; 371347c6ae99SBarry Smith PetscFunctionReturn(0); 371447c6ae99SBarry Smith } 371547c6ae99SBarry Smith 371608da532bSDmitry Karpeev /*@C 3717bb7acecfSBarry Smith DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for `SNESVI`. 371808da532bSDmitry Karpeev 3719d083f849SBarry Smith Logically Collective on dm 372008da532bSDmitry Karpeev 3721d8d19677SJose E. Roman Input Parameters: 372208da532bSDmitry Karpeev + dm - the DM object 37230298fd71SBarry Smith - f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set) 372408da532bSDmitry Karpeev 372508da532bSDmitry Karpeev Level: intermediate 372608da532bSDmitry Karpeev 3727bb7acecfSBarry Smith .seealso: `DMComputeVariableBounds()`, `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()`, 3728db781477SPatrick Sanan `DMSetJacobian()` 372908da532bSDmitry Karpeev 373008da532bSDmitry Karpeev @*/ 373108da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec)) 373208da532bSDmitry Karpeev { 373308da532bSDmitry Karpeev PetscFunctionBegin; 37345a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 373508da532bSDmitry Karpeev dm->ops->computevariablebounds = f; 373608da532bSDmitry Karpeev PetscFunctionReturn(0); 373708da532bSDmitry Karpeev } 373808da532bSDmitry Karpeev 373908da532bSDmitry Karpeev /*@ 3740bb7acecfSBarry Smith DMHasVariableBounds - does the `DM` object have a variable bounds function? 374108da532bSDmitry Karpeev 374208da532bSDmitry Karpeev Not Collective 374308da532bSDmitry Karpeev 374408da532bSDmitry Karpeev Input Parameter: 3745bb7acecfSBarry Smith . dm - the `DM` object to destroy 374608da532bSDmitry Karpeev 374708da532bSDmitry Karpeev Output Parameter: 3748bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the variable bounds function exists 374908da532bSDmitry Karpeev 375008da532bSDmitry Karpeev Level: developer 375108da532bSDmitry Karpeev 3752bb7acecfSBarry Smith .seealso: `DMComputeVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 375308da532bSDmitry Karpeev 375408da532bSDmitry Karpeev @*/ 375508da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg) 375608da532bSDmitry Karpeev { 375708da532bSDmitry Karpeev PetscFunctionBegin; 37585a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3759534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 376008da532bSDmitry Karpeev *flg = (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE; 376108da532bSDmitry Karpeev PetscFunctionReturn(0); 376208da532bSDmitry Karpeev } 376308da532bSDmitry Karpeev 376408da532bSDmitry Karpeev /*@C 3765bb7acecfSBarry Smith DMComputeVariableBounds - compute variable bounds used by `SNESVI`. 376608da532bSDmitry Karpeev 3767d083f849SBarry Smith Logically Collective on dm 376808da532bSDmitry Karpeev 3769f899ff85SJose E. Roman Input Parameter: 3770bb7acecfSBarry Smith . dm - the `DM` object 377108da532bSDmitry Karpeev 377208da532bSDmitry Karpeev Output parameters: 377308da532bSDmitry Karpeev + xl - lower bound 377408da532bSDmitry Karpeev - xu - upper bound 377508da532bSDmitry Karpeev 3776907376e6SBarry Smith Level: advanced 3777907376e6SBarry Smith 377895452b02SPatrick Sanan Notes: 377995452b02SPatrick Sanan This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds() 378008da532bSDmitry Karpeev 3781bb7acecfSBarry Smith .seealso: `DMHasVariableBounds()`, `DMView()`, `DMCreateGlobalVector()`, `DMCreateInterpolation()`, `DMCreateColoring()`, `DMCreateMatrix()`, `DMCreateMassMatrix()`, `DMGetApplicationContext()` 378208da532bSDmitry Karpeev 378308da532bSDmitry Karpeev @*/ 378408da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu) 378508da532bSDmitry Karpeev { 378608da532bSDmitry Karpeev PetscFunctionBegin; 37875a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 378808da532bSDmitry Karpeev PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 37895a84ad33SLisandro Dalcin PetscValidHeaderSpecific(xu,VEC_CLASSID,3); 3790*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,computevariablebounds , xl,xu); 379108da532bSDmitry Karpeev PetscFunctionReturn(0); 379208da532bSDmitry Karpeev } 379308da532bSDmitry Karpeev 3794b0ae01b7SPeter Brune /*@ 3795bb7acecfSBarry Smith DMHasColoring - does the `DM` object have a method of providing a coloring? 3796b0ae01b7SPeter Brune 3797b0ae01b7SPeter Brune Not Collective 3798b0ae01b7SPeter Brune 3799b0ae01b7SPeter Brune Input Parameter: 3800b0ae01b7SPeter Brune . dm - the DM object 3801b0ae01b7SPeter Brune 3802b0ae01b7SPeter Brune Output Parameter: 3803bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateColoring()`. 3804b0ae01b7SPeter Brune 3805b0ae01b7SPeter Brune Level: developer 3806b0ae01b7SPeter Brune 3807bb7acecfSBarry Smith .seealso: `DMCreateColoring()` 3808b0ae01b7SPeter Brune 3809b0ae01b7SPeter Brune @*/ 3810b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg) 3811b0ae01b7SPeter Brune { 3812b0ae01b7SPeter Brune PetscFunctionBegin; 38135a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3814534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 3815b0ae01b7SPeter Brune *flg = (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE; 3816b0ae01b7SPeter Brune PetscFunctionReturn(0); 3817b0ae01b7SPeter Brune } 3818b0ae01b7SPeter Brune 38193ad4599aSBarry Smith /*@ 3820bb7acecfSBarry Smith DMHasCreateRestriction - does the `DM` object have a method of providing a restriction? 38213ad4599aSBarry Smith 38223ad4599aSBarry Smith Not Collective 38233ad4599aSBarry Smith 38243ad4599aSBarry Smith Input Parameter: 3825bb7acecfSBarry Smith . dm - the `DM` object 38263ad4599aSBarry Smith 38273ad4599aSBarry Smith Output Parameter: 3828bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateRestriction()`. 38293ad4599aSBarry Smith 38303ad4599aSBarry Smith Level: developer 38313ad4599aSBarry Smith 3832bb7acecfSBarry Smith .seealso: `DMCreateRestriction()`, `DMHasCreateInterpolation()`, `DMHasCreateInjection()` 38333ad4599aSBarry Smith 38343ad4599aSBarry Smith @*/ 38353ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg) 38363ad4599aSBarry Smith { 38373ad4599aSBarry Smith PetscFunctionBegin; 38385a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3839534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 38403ad4599aSBarry Smith *flg = (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE; 38413ad4599aSBarry Smith PetscFunctionReturn(0); 38423ad4599aSBarry Smith } 38433ad4599aSBarry Smith 3844a7058e45SLawrence Mitchell /*@ 3845bb7acecfSBarry Smith DMHasCreateInjection - does the `DM` object have a method of providing an injection? 3846a7058e45SLawrence Mitchell 3847a7058e45SLawrence Mitchell Not Collective 3848a7058e45SLawrence Mitchell 3849a7058e45SLawrence Mitchell Input Parameter: 3850bb7acecfSBarry Smith . dm - the `DM` object 3851a7058e45SLawrence Mitchell 3852a7058e45SLawrence Mitchell Output Parameter: 3853bb7acecfSBarry Smith . flg - `PETSC_TRUE` if the `DM` has facilities for `DMCreateInjection()`. 3854a7058e45SLawrence Mitchell 3855a7058e45SLawrence Mitchell Level: developer 3856a7058e45SLawrence Mitchell 3857bb7acecfSBarry Smith .seealso: `DMCreateInjection()`, `DMHasCreateRestriction()`, `DMHasCreateInterpolation()` 3858a7058e45SLawrence Mitchell 3859a7058e45SLawrence Mitchell @*/ 3860a7058e45SLawrence Mitchell PetscErrorCode DMHasCreateInjection(DM dm,PetscBool *flg) 3861a7058e45SLawrence Mitchell { 3862a7058e45SLawrence Mitchell PetscFunctionBegin; 38635a84ad33SLisandro Dalcin PetscValidHeaderSpecific(dm,DM_CLASSID,1); 3864534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 3865*dbbe0bcdSBarry Smith if (dm->ops->hascreateinjection) PetscUseTypeMethod(dm,hascreateinjection ,flg); 3866*dbbe0bcdSBarry Smith else { 38675a84ad33SLisandro Dalcin *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE; 38685a84ad33SLisandro Dalcin } 3869a7058e45SLawrence Mitchell PetscFunctionReturn(0); 3870a7058e45SLawrence Mitchell } 3871a7058e45SLawrence Mitchell 38720298fd71SBarry Smith PetscFunctionList DMList = NULL; 3873264ace61SBarry Smith PetscBool DMRegisterAllCalled = PETSC_FALSE; 3874264ace61SBarry Smith 3875264ace61SBarry Smith /*@C 3876bb7acecfSBarry Smith DMSetType - Builds a `DM`, for a particular `DM` implementation. 3877264ace61SBarry Smith 3878d083f849SBarry Smith Collective on dm 3879264ace61SBarry Smith 3880264ace61SBarry Smith Input Parameters: 3881bb7acecfSBarry Smith + dm - The `DM` object 3882bb7acecfSBarry Smith - method - The name of the `DMType`, for example `DMDA`, `DMPLEX` 3883264ace61SBarry Smith 3884264ace61SBarry Smith Options Database Key: 3885bb7acecfSBarry Smith . -dm_type <type> - Sets the `DM` type; use -help for a list of available types 3886264ace61SBarry Smith 3887264ace61SBarry Smith Level: intermediate 3888264ace61SBarry Smith 3889bb7acecfSBarry Smith Note: 3890bb7acecfSBarry Smith Of the `DM` is constructed by directly calling a function to construct a particular `DM`, for example, `DMDACreate2d()` or `DMPLEXCreateBoxMesh()` 3891bb7acecfSBarry Smith 3892bb7acecfSBarry Smith .seealso: `DMType`, `DMDA`, `DMPLEX`, `DMGetType()`, `DMCreate()`, `DMDACreate2d()` 3893264ace61SBarry Smith @*/ 389419fd82e9SBarry Smith PetscErrorCode DMSetType(DM dm, DMType method) 3895264ace61SBarry Smith { 3896264ace61SBarry Smith PetscErrorCode (*r)(DM); 3897264ace61SBarry Smith PetscBool match; 3898264ace61SBarry Smith 3899264ace61SBarry Smith PetscFunctionBegin; 3900264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 39019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) dm, method, &match)); 3902264ace61SBarry Smith if (match) PetscFunctionReturn(0); 3903264ace61SBarry Smith 39049566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 39059566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(DMList,method,&r)); 39067a8be351SBarry Smith PetscCheck(r,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method); 3907264ace61SBarry Smith 3908*dbbe0bcdSBarry Smith PetscTryTypeMethod(dm,destroy); 39099566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops,sizeof(*dm->ops))); 39109566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)dm,method)); 39119566063dSJacob Faibussowitsch PetscCall((*r)(dm)); 3912264ace61SBarry Smith PetscFunctionReturn(0); 3913264ace61SBarry Smith } 3914264ace61SBarry Smith 3915264ace61SBarry Smith /*@C 3916bb7acecfSBarry Smith DMGetType - Gets the `DM` type name (as a string) from the `DM`. 3917264ace61SBarry Smith 3918264ace61SBarry Smith Not Collective 3919264ace61SBarry Smith 3920264ace61SBarry Smith Input Parameter: 3921bb7acecfSBarry Smith . dm - The `DM` 3922264ace61SBarry Smith 3923264ace61SBarry Smith Output Parameter: 3924bb7acecfSBarry Smith . type - The `DMType` name 3925264ace61SBarry Smith 3926264ace61SBarry Smith Level: intermediate 3927264ace61SBarry Smith 3928bb7acecfSBarry Smith .seealso: `DMType`, `DMDA`, `DMPLEX`, `DMSetType()`, `DMCreate()` 3929264ace61SBarry Smith @*/ 393019fd82e9SBarry Smith PetscErrorCode DMGetType(DM dm, DMType *type) 3931264ace61SBarry Smith { 3932264ace61SBarry Smith PetscFunctionBegin; 3933264ace61SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID,1); 3934c959eef4SJed Brown PetscValidPointer(type,2); 39359566063dSJacob Faibussowitsch PetscCall(DMRegisterAll()); 3936264ace61SBarry Smith *type = ((PetscObject)dm)->type_name; 3937264ace61SBarry Smith PetscFunctionReturn(0); 3938264ace61SBarry Smith } 3939264ace61SBarry Smith 394067a56275SMatthew G Knepley /*@C 3941bb7acecfSBarry Smith DMConvert - Converts a `DM` to another `DM`, either of the same or different type. 394267a56275SMatthew G Knepley 3943d083f849SBarry Smith Collective on dm 394467a56275SMatthew G Knepley 394567a56275SMatthew G Knepley Input Parameters: 3946bb7acecfSBarry Smith + dm - the `DM` 3947bb7acecfSBarry Smith - newtype - new `DM` type (use "same" for the same type) 394867a56275SMatthew G Knepley 394967a56275SMatthew G Knepley Output Parameter: 3950bb7acecfSBarry Smith . M - pointer to new `DM` 395167a56275SMatthew G Knepley 395267a56275SMatthew G Knepley Notes: 3953bb7acecfSBarry Smith Cannot be used to convert a sequential `DM` to a parallel or a parallel to sequential, 3954bb7acecfSBarry Smith the MPI communicator of the generated `DM` is always the same as the communicator 3955bb7acecfSBarry Smith of the input `DM`. 395667a56275SMatthew G Knepley 395767a56275SMatthew G Knepley Level: intermediate 395867a56275SMatthew G Knepley 3959bb7acecfSBarry Smith .seealso: `DM`, `DMSetType()`, `DMCreate()`, `DMClone()` 396067a56275SMatthew G Knepley @*/ 396119fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M) 396267a56275SMatthew G Knepley { 396367a56275SMatthew G Knepley DM B; 396467a56275SMatthew G Knepley char convname[256]; 3965c067b6caSMatthew G. Knepley PetscBool sametype/*, issame */; 396667a56275SMatthew G Knepley 396767a56275SMatthew G Knepley PetscFunctionBegin; 396867a56275SMatthew G Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 396967a56275SMatthew G Knepley PetscValidType(dm,1); 397067a56275SMatthew G Knepley PetscValidPointer(M,3); 39719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype)); 39729566063dSJacob Faibussowitsch /* PetscCall(PetscStrcmp(newtype, "same", &issame)); */ 3973c067b6caSMatthew G. Knepley if (sametype) { 3974c067b6caSMatthew G. Knepley *M = dm; 39759566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) dm)); 3976c067b6caSMatthew G. Knepley PetscFunctionReturn(0); 3977c067b6caSMatthew G. Knepley } else { 39780298fd71SBarry Smith PetscErrorCode (*conv)(DM, DMType, DM*) = NULL; 397967a56275SMatthew G Knepley 398067a56275SMatthew G Knepley /* 398167a56275SMatthew G Knepley Order of precedence: 398267a56275SMatthew G Knepley 1) See if a specialized converter is known to the current DM. 398367a56275SMatthew G Knepley 2) See if a specialized converter is known to the desired DM class. 398467a56275SMatthew G Knepley 3) See if a good general converter is registered for the desired class 398567a56275SMatthew G Knepley 4) See if a good general converter is known for the current matrix. 398667a56275SMatthew G Knepley 5) Use a really basic converter. 398767a56275SMatthew G Knepley */ 398867a56275SMatthew G Knepley 398967a56275SMatthew G Knepley /* 1) See if a specialized converter is known to the current DM and the desired class */ 39909566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname,"DMConvert_",sizeof(convname))); 39919566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname))); 39929566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 39939566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 39949566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 39959566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)dm,convname,&conv)); 399667a56275SMatthew G Knepley if (conv) goto foundconv; 399767a56275SMatthew G Knepley 399867a56275SMatthew G Knepley /* 2) See if a specialized converter is known to the desired DM class. */ 39999566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &B)); 40009566063dSJacob Faibussowitsch PetscCall(DMSetType(B, newtype)); 40019566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(convname,"DMConvert_",sizeof(convname))); 40029566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname))); 40039566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 40049566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 40059566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 40069566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 400767a56275SMatthew G Knepley if (conv) { 40089566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 400967a56275SMatthew G Knepley goto foundconv; 401067a56275SMatthew G Knepley } 401167a56275SMatthew G Knepley 401267a56275SMatthew G Knepley #if 0 401367a56275SMatthew G Knepley /* 3) See if a good general converter is registered for the desired class */ 401467a56275SMatthew G Knepley conv = B->ops->convertfrom; 40159566063dSJacob Faibussowitsch PetscCall(DMDestroy(&B)); 401667a56275SMatthew G Knepley if (conv) goto foundconv; 401767a56275SMatthew G Knepley 401867a56275SMatthew G Knepley /* 4) See if a good general converter is known for the current matrix */ 401967a56275SMatthew G Knepley if (dm->ops->convert) { 402067a56275SMatthew G Knepley conv = dm->ops->convert; 402167a56275SMatthew G Knepley } 402267a56275SMatthew G Knepley if (conv) goto foundconv; 402367a56275SMatthew G Knepley #endif 402467a56275SMatthew G Knepley 402567a56275SMatthew G Knepley /* 5) Use a really basic converter. */ 402698921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype); 402767a56275SMatthew G Knepley 402867a56275SMatthew G Knepley foundconv: 40299566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Convert,dm,0,0,0)); 40309566063dSJacob Faibussowitsch PetscCall((*conv)(dm,newtype,M)); 403112fa691eSMatthew G. Knepley /* Things that are independent of DM type: We should consult DMClone() here */ 403290b157c4SStefano Zampini { 40334fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 40346858538eSMatthew G. Knepley 40354fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 40364fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*M, maxCell, Lstart, L)); 4037c8a6034eSMark (*M)->prealloc_only = dm->prealloc_only; 40389566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->vectype)); 40399566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype,(char**)&(*M)->vectype)); 40409566063dSJacob Faibussowitsch PetscCall(PetscFree((*M)->mattype)); 40419566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype,(char**)&(*M)->mattype)); 404212fa691eSMatthew G. Knepley } 40439566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Convert,dm,0,0,0)); 404467a56275SMatthew G Knepley } 40459566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject) *M)); 404667a56275SMatthew G Knepley PetscFunctionReturn(0); 404767a56275SMatthew G Knepley } 4048264ace61SBarry Smith 4049264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/ 4050264ace61SBarry Smith 4051264ace61SBarry Smith /*@C 4052bb7acecfSBarry Smith DMRegister - Adds a new `DM` type implementation 40531c84c290SBarry Smith 40541c84c290SBarry Smith Not Collective 40551c84c290SBarry Smith 40561c84c290SBarry Smith Input Parameters: 40571c84c290SBarry Smith + name - The name of a new user-defined creation routine 40581c84c290SBarry Smith - create_func - The creation routine itself 40591c84c290SBarry Smith 40601c84c290SBarry Smith Notes: 4061bb7acecfSBarry Smith DMRegister() may be called multiple times to add several user-defined `DM`s 40621c84c290SBarry Smith 40631c84c290SBarry Smith Sample usage: 40641c84c290SBarry Smith .vb 4065bdf89e91SBarry Smith DMRegister("my_da", MyDMCreate); 40661c84c290SBarry Smith .ve 40671c84c290SBarry Smith 40681c84c290SBarry Smith Then, your DM type can be chosen with the procedural interface via 40691c84c290SBarry Smith .vb 40701c84c290SBarry Smith DMCreate(MPI_Comm, DM *); 40711c84c290SBarry Smith DMSetType(DM,"my_da"); 40721c84c290SBarry Smith .ve 40731c84c290SBarry Smith or at runtime via the option 40741c84c290SBarry Smith .vb 40751c84c290SBarry Smith -da_type my_da 40761c84c290SBarry Smith .ve 4077264ace61SBarry Smith 4078264ace61SBarry Smith Level: advanced 40791c84c290SBarry Smith 4080bb7acecfSBarry Smith .seealso: `DM`, `DMType`, `DMSetType()`, `DMRegisterAll()`, `DMRegisterDestroy()` 40811c84c290SBarry Smith 4082264ace61SBarry Smith @*/ 4083bdf89e91SBarry Smith PetscErrorCode DMRegister(const char sname[],PetscErrorCode (*function)(DM)) 4084264ace61SBarry Smith { 4085264ace61SBarry Smith PetscFunctionBegin; 40869566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 40879566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&DMList,sname,function)); 4088264ace61SBarry Smith PetscFunctionReturn(0); 4089264ace61SBarry Smith } 4090264ace61SBarry Smith 4091b859378eSBarry Smith /*@C 4092bb7acecfSBarry Smith DMLoad - Loads a DM that has been stored in binary with `DMView()`. 4093b859378eSBarry Smith 4094d083f849SBarry Smith Collective on viewer 4095b859378eSBarry Smith 4096b859378eSBarry Smith Input Parameters: 4097bb7acecfSBarry Smith + newdm - the newly loaded `DM`, this needs to have been created with `DMCreate()` or 4098bb7acecfSBarry Smith some related function before a call to `DMLoad()`. 4099bb7acecfSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or 4100bb7acecfSBarry Smith `PETSCVIEWERHDF5` file viewer, obtained from `PetscViewerHDF5Open()` 4101b859378eSBarry Smith 4102b859378eSBarry Smith Level: intermediate 4103b859378eSBarry Smith 4104b859378eSBarry Smith Notes: 410555849f57SBarry Smith The type is determined by the data in the file, any type set into the DM before this call is ignored. 4106b859378eSBarry Smith 4107bb7acecfSBarry Smith Using `PETSCVIEWERHDF5` type with `PETSC_VIEWER_HDF5_PETSC` format, one can save multiple `DMPLEX` 4108bb7acecfSBarry Smith meshes in a single HDF5 file. This in turn requires one to name the `DMPLEX` object with `PetscObjectSetName()` 4109bb7acecfSBarry Smith before saving it with `DMView()` and before loading it with `DMLoad()` for identification of the mesh object. 4110cd7e8a5eSksagiyam 4111b859378eSBarry Smith Notes for advanced users: 4112b859378eSBarry Smith Most users should not need to know the details of the binary storage 4113bb7acecfSBarry Smith format, since `DMLoad()` and `DMView()` completely hide these details. 4114b859378eSBarry Smith But for anyone who's interested, the standard binary matrix storage 4115b859378eSBarry Smith format is 4116b859378eSBarry Smith .vb 4117b859378eSBarry Smith has not yet been determined 4118b859378eSBarry Smith .ve 4119b859378eSBarry Smith 4120db781477SPatrick Sanan .seealso: `PetscViewerBinaryOpen()`, `DMView()`, `MatLoad()`, `VecLoad()` 4121b859378eSBarry Smith @*/ 4122b859378eSBarry Smith PetscErrorCode DMLoad(DM newdm, PetscViewer viewer) 4123b859378eSBarry Smith { 41249331c7a4SMatthew G. Knepley PetscBool isbinary, ishdf5; 4125b859378eSBarry Smith 4126b859378eSBarry Smith PetscFunctionBegin; 4127b859378eSBarry Smith PetscValidHeaderSpecific(newdm,DM_CLASSID,1); 4128b859378eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 41299566063dSJacob Faibussowitsch PetscCall(PetscViewerCheckReadable(viewer)); 41309566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 41319566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5)); 41329566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DM_Load,viewer,0,0,0)); 41339331c7a4SMatthew G. Knepley if (isbinary) { 41349331c7a4SMatthew G. Knepley PetscInt classid; 41359331c7a4SMatthew G. Knepley char type[256]; 4136b859378eSBarry Smith 41379566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT)); 41387a8be351SBarry Smith PetscCheck(classid == DM_FILE_CLASSID,PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid); 41399566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR)); 41409566063dSJacob Faibussowitsch PetscCall(DMSetType(newdm, type)); 4141*dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm,load,viewer); 41429331c7a4SMatthew G. Knepley } else if (ishdf5) { 4143*dbbe0bcdSBarry Smith PetscTryTypeMethod(newdm,load,viewer); 41449331c7a4SMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()"); 41459566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DM_Load,viewer,0,0,0)); 4146b859378eSBarry Smith PetscFunctionReturn(0); 4147b859378eSBarry Smith } 4148b859378eSBarry Smith 41497da65231SMatthew G Knepley /******************************** FEM Support **********************************/ 41507da65231SMatthew G Knepley 4151a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) 4152a6dfd86eSKarl Rupp { 41531d47ebbbSSatish Balay PetscInt f; 41541b30c384SMatthew G Knepley 41557da65231SMatthew G Knepley PetscFunctionBegin; 415663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41571d47ebbbSSatish Balay for (f = 0; f < len; ++f) { 41589566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " | %g |\n", (double)PetscRealPart(x[f]))); 41597da65231SMatthew G Knepley } 41607da65231SMatthew G Knepley PetscFunctionReturn(0); 41617da65231SMatthew G Knepley } 41627da65231SMatthew G Knepley 4163a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) 4164a6dfd86eSKarl Rupp { 41651b30c384SMatthew G Knepley PetscInt f, g; 41667da65231SMatthew G Knepley 41677da65231SMatthew G Knepley PetscFunctionBegin; 416863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "Cell %" PetscInt_FMT " Element %s\n", c, name)); 41691d47ebbbSSatish Balay for (f = 0; f < rows; ++f) { 41709566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |")); 41711d47ebbbSSatish Balay for (g = 0; g < cols; ++g) { 417263a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " % 9.5g", (double)PetscRealPart(A[f*cols+g]))); 41737da65231SMatthew G Knepley } 41749566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, " |\n")); 41757da65231SMatthew G Knepley } 41767da65231SMatthew G Knepley PetscFunctionReturn(0); 41777da65231SMatthew G Knepley } 4178e7c4fc90SDmitry Karpeev 41796113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X) 4180e759306cSMatthew G. Knepley { 41810c5b8624SToby Isaac PetscInt localSize, bs; 41820c5b8624SToby Isaac PetscMPIInt size; 41830c5b8624SToby Isaac Vec x, xglob; 41840c5b8624SToby Isaac const PetscScalar *xarray; 4185e759306cSMatthew G. Knepley 4186e759306cSMatthew G. Knepley PetscFunctionBegin; 41879566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size)); 41889566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &x)); 41899566063dSJacob Faibussowitsch PetscCall(VecCopy(X, x)); 41909566063dSJacob Faibussowitsch PetscCall(VecChop(x, tol)); 41919566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name)); 41920c5b8624SToby Isaac if (size > 1) { 41939566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(x,&localSize)); 41949566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xarray)); 41959566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(x,&bs)); 41969566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob)); 41970c5b8624SToby Isaac } else { 41980c5b8624SToby Isaac xglob = x; 41990c5b8624SToby Isaac } 42009566063dSJacob Faibussowitsch PetscCall(VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)))); 42010c5b8624SToby Isaac if (size > 1) { 42029566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xglob)); 42039566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xarray)); 42040c5b8624SToby Isaac } 42059566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 4206e759306cSMatthew G. Knepley PetscFunctionReturn(0); 4207e759306cSMatthew G. Knepley } 4208e759306cSMatthew G. Knepley 420988ed4aceSMatthew G Knepley /*@ 4210bb7acecfSBarry Smith DMGetSection - Get the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMGetLocalSection()`. Deprecated in v3.12 4211061576a5SJed Brown 4212061576a5SJed Brown Input Parameter: 4213bb7acecfSBarry Smith . dm - The `DM` 4214061576a5SJed Brown 4215061576a5SJed Brown Output Parameter: 4216bb7acecfSBarry Smith . section - The `PetscSection` 4217061576a5SJed Brown 4218061576a5SJed Brown Options Database Keys: 4219bb7acecfSBarry Smith . -dm_petscsection_view - View the `PetscSection` created by the `DM` 4220061576a5SJed Brown 4221061576a5SJed Brown Level: advanced 4222061576a5SJed Brown 4223061576a5SJed Brown Notes: 4224bb7acecfSBarry Smith Use `DMGetLocalSection()` in new code. 4225061576a5SJed Brown 4226bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 4227061576a5SJed Brown 4228db781477SPatrick Sanan .seealso: `DMGetLocalSection()`, `DMSetLocalSection()`, `DMGetGlobalSection()` 4229061576a5SJed Brown @*/ 4230061576a5SJed Brown PetscErrorCode DMGetSection(DM dm, PetscSection *section) 4231061576a5SJed Brown { 4232061576a5SJed Brown PetscFunctionBegin; 42339566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm,section)); 4234061576a5SJed Brown PetscFunctionReturn(0); 4235061576a5SJed Brown } 4236061576a5SJed Brown 4237061576a5SJed Brown /*@ 4238bb7acecfSBarry Smith DMGetLocalSection - Get the `PetscSection` encoding the local data layout for the `DM`. 423988ed4aceSMatthew G Knepley 424088ed4aceSMatthew G Knepley Input Parameter: 4241bb7acecfSBarry Smith . dm - The `DM` 424288ed4aceSMatthew G Knepley 424388ed4aceSMatthew G Knepley Output Parameter: 4244bb7acecfSBarry Smith . section - The `PetscSection` 424588ed4aceSMatthew G Knepley 4246e5893cccSMatthew G. Knepley Options Database Keys: 4247bb7acecfSBarry Smith . -dm_petscsection_view - View the section created by the `DM` 4248e5893cccSMatthew G. Knepley 424988ed4aceSMatthew G Knepley Level: intermediate 425088ed4aceSMatthew G Knepley 4251bb7acecfSBarry Smith Note: 4252bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 425388ed4aceSMatthew G Knepley 4254db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetGlobalSection()` 425588ed4aceSMatthew G Knepley @*/ 4256061576a5SJed Brown PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section) 42570adebc6cSBarry Smith { 425888ed4aceSMatthew G Knepley PetscFunctionBegin; 425988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 426088ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 42611bb6d2a8SBarry Smith if (!dm->localSection && dm->ops->createlocalsection) { 4262e5e52638SMatthew G. Knepley PetscInt d; 4263e5e52638SMatthew G. Knepley 426445480ffeSMatthew G. Knepley if (dm->setfromoptionscalled) { 426545480ffeSMatthew G. Knepley PetscObject obj = (PetscObject) dm; 426645480ffeSMatthew G. Knepley PetscViewer viewer; 426745480ffeSMatthew G. Knepley PetscViewerFormat format; 426845480ffeSMatthew G. Knepley PetscBool flg; 426945480ffeSMatthew G. Knepley 42709566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm(obj), obj->options, obj->prefix, "-dm_petscds_view", &viewer, &format, &flg)); 42719566063dSJacob Faibussowitsch if (flg) PetscCall(PetscViewerPushFormat(viewer, format)); 427245480ffeSMatthew G. Knepley for (d = 0; d < dm->Nds; ++d) { 42739566063dSJacob Faibussowitsch PetscCall(PetscDSSetFromOptions(dm->probs[d].ds)); 42749566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDSView(dm->probs[d].ds, viewer)); 427545480ffeSMatthew G. Knepley } 427645480ffeSMatthew G. Knepley if (flg) { 42779566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 42789566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 42799566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 428045480ffeSMatthew G. Knepley } 428145480ffeSMatthew G. Knepley } 4282*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,createlocalsection); 42839566063dSJacob Faibussowitsch if (dm->localSection) PetscCall(PetscObjectViewFromOptions((PetscObject) dm->localSection, NULL, "-dm_petscsection_view")); 42842f0f8703SMatthew G. Knepley } 42851bb6d2a8SBarry Smith *section = dm->localSection; 428688ed4aceSMatthew G Knepley PetscFunctionReturn(0); 428788ed4aceSMatthew G Knepley } 428888ed4aceSMatthew G Knepley 428988ed4aceSMatthew G Knepley /*@ 4290bb7acecfSBarry Smith DMSetSection - Set the `PetscSection` encoding the local data layout for the `DM`. This is equivalent to `DMSetLocalSection()`. Deprecated in v3.12 4291061576a5SJed Brown 4292061576a5SJed Brown Input Parameters: 4293bb7acecfSBarry Smith + dm - The `DM` 4294bb7acecfSBarry Smith - section - The `PetscSection` 4295061576a5SJed Brown 4296061576a5SJed Brown Level: advanced 4297061576a5SJed Brown 4298061576a5SJed Brown Notes: 4299bb7acecfSBarry Smith Use `DMSetLocalSection()` in new code. 4300061576a5SJed Brown 4301bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4302061576a5SJed Brown 4303db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetLocalSection()`, `DMSetGlobalSection()` 4304061576a5SJed Brown @*/ 4305061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section) 4306061576a5SJed Brown { 4307061576a5SJed Brown PetscFunctionBegin; 43089566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm,section)); 4309061576a5SJed Brown PetscFunctionReturn(0); 4310061576a5SJed Brown } 4311061576a5SJed Brown 4312061576a5SJed Brown /*@ 4313bb7acecfSBarry Smith DMSetLocalSection - Set the `PetscSection` encoding the local data layout for the `DM`. 431488ed4aceSMatthew G Knepley 431588ed4aceSMatthew G Knepley Input Parameters: 4316bb7acecfSBarry Smith + dm - The `DM` 4317bb7acecfSBarry Smith - section - The `PetscSection` 431888ed4aceSMatthew G Knepley 431988ed4aceSMatthew G Knepley Level: intermediate 432088ed4aceSMatthew G Knepley 4321bb7acecfSBarry Smith Note: 4322bb7acecfSBarry Smith Any existing Section will be destroyed 432388ed4aceSMatthew G Knepley 4324bb7acecfSBarry Smith .seealso: `PetscSection`, `DMGetLocalSection()`, `DMSetGlobalSection()` 432588ed4aceSMatthew G Knepley @*/ 4326061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section) 43270adebc6cSBarry Smith { 4328c473ab19SMatthew G. Knepley PetscInt numFields = 0; 4329af122d2aSMatthew G Knepley PetscInt f; 433088ed4aceSMatthew G Knepley 433188ed4aceSMatthew G Knepley PetscFunctionBegin; 433288ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4333b9d85ea2SLisandro Dalcin if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 43349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 43359566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->localSection)); 43361bb6d2a8SBarry Smith dm->localSection = section; 43379566063dSJacob Faibussowitsch if (section) PetscCall(PetscSectionGetNumFields(dm->localSection, &numFields)); 4338af122d2aSMatthew G Knepley if (numFields) { 43399566063dSJacob Faibussowitsch PetscCall(DMSetNumFields(dm, numFields)); 4340af122d2aSMatthew G Knepley for (f = 0; f < numFields; ++f) { 43410f21e855SMatthew G. Knepley PetscObject disc; 4342af122d2aSMatthew G Knepley const char *name; 4343af122d2aSMatthew G Knepley 43449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetFieldName(dm->localSection, f, &name)); 43459566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, &disc)); 43469566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName(disc, name)); 4347af122d2aSMatthew G Knepley } 4348af122d2aSMatthew G Knepley } 4349e87a4003SBarry Smith /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */ 43509566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 435188ed4aceSMatthew G Knepley PetscFunctionReturn(0); 435288ed4aceSMatthew G Knepley } 435388ed4aceSMatthew G Knepley 43549435951eSToby Isaac /*@ 4355bb7acecfSBarry Smith DMGetDefaultConstraints - Get the `PetscSection` and `Mat` that specify the local constraint interpolation. See `DMSetDefaultConstraints()` for a description of the purpose of constraint interpolation. 43569435951eSToby Isaac 4357e228b242SToby Isaac not collective 4358e228b242SToby Isaac 43599435951eSToby Isaac Input Parameter: 4360bb7acecfSBarry Smith . dm - The `DM` 43619435951eSToby Isaac 4362d8d19677SJose E. Roman Output Parameters: 4363bb7acecfSBarry 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. 4364bb7acecfSBarry 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. 436579769bd5SJed Brown - bias - Vector containing bias to be added to constrained dofs 43669435951eSToby Isaac 43679435951eSToby Isaac Level: advanced 43689435951eSToby Isaac 4369bb7acecfSBarry Smith Note: 4370bb7acecfSBarry Smith This gets borrowed references, so the user should not destroy the `PetscSection`, `Mat`, or `Vec`. 43719435951eSToby Isaac 4372db781477SPatrick Sanan .seealso: `DMSetDefaultConstraints()` 43739435951eSToby Isaac @*/ 437479769bd5SJed Brown PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat, Vec *bias) 43759435951eSToby Isaac { 43769435951eSToby Isaac PetscFunctionBegin; 43779435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4378*dbbe0bcdSBarry Smith if (!dm->defaultConstraint.section && !dm->defaultConstraint.mat && dm->ops->createdefaultconstraints) PetscUseTypeMethod(dm,createdefaultconstraints); 43793b8ba7d1SJed Brown if (section) *section = dm->defaultConstraint.section; 43803b8ba7d1SJed Brown if (mat) *mat = dm->defaultConstraint.mat; 438179769bd5SJed Brown if (bias) *bias = dm->defaultConstraint.bias; 43829435951eSToby Isaac PetscFunctionReturn(0); 43839435951eSToby Isaac } 43849435951eSToby Isaac 43859435951eSToby Isaac /*@ 4386bb7acecfSBarry Smith DMSetDefaultConstraints - Set the `PetscSection` and `Mat` that specify the local constraint interpolation. 43879435951eSToby Isaac 4388bb7acecfSBarry 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()`. 43899435951eSToby Isaac 4390bb7acecfSBarry 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. 43919435951eSToby Isaac 4392e228b242SToby Isaac collective on dm 4393e228b242SToby Isaac 43949435951eSToby Isaac Input Parameters: 4395bb7acecfSBarry Smith + dm - The `DM` 4396bb7acecfSBarry 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). 4397bb7acecfSBarry 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). 4398bb7acecfSBarry 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). 43999435951eSToby Isaac 44009435951eSToby Isaac Level: advanced 44019435951eSToby Isaac 4402bb7acecfSBarry Smith Note: 4403bb7acecfSBarry Smith This increments the references of the `PetscSection`, `Mat`, and `Vec`, so they user can destroy them. 44049435951eSToby Isaac 4405db781477SPatrick Sanan .seealso: `DMGetDefaultConstraints()` 44069435951eSToby Isaac @*/ 440779769bd5SJed Brown PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat, Vec bias) 44089435951eSToby Isaac { 4409e228b242SToby Isaac PetscMPIInt result; 44109435951eSToby Isaac 44119435951eSToby Isaac PetscFunctionBegin; 44129435951eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4413e228b242SToby Isaac if (section) { 4414e228b242SToby Isaac PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 44159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result)); 44167a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT,PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator"); 4417e228b242SToby Isaac } 4418e228b242SToby Isaac if (mat) { 4419e228b242SToby Isaac PetscValidHeaderSpecific(mat,MAT_CLASSID,3); 44209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result)); 44217a8be351SBarry Smith PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT,PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator"); 4422e228b242SToby Isaac } 442379769bd5SJed Brown if (bias) { 442479769bd5SJed Brown PetscValidHeaderSpecific(bias,VEC_CLASSID,4); 44259566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)bias),&result)); 442679769bd5SJed Brown PetscCheck(result == MPI_CONGRUENT || result == MPI_IDENT,PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint bias must have local communicator"); 442779769bd5SJed Brown } 44289566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 44299566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->defaultConstraint.section)); 44303b8ba7d1SJed Brown dm->defaultConstraint.section = section; 44319566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)mat)); 44329566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dm->defaultConstraint.mat)); 44333b8ba7d1SJed Brown dm->defaultConstraint.mat = mat; 44349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)bias)); 44359566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dm->defaultConstraint.bias)); 443679769bd5SJed Brown dm->defaultConstraint.bias = bias; 44379435951eSToby Isaac PetscFunctionReturn(0); 44389435951eSToby Isaac } 44399435951eSToby Isaac 4440497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 4441507e4973SMatthew G. Knepley /* 4442bb7acecfSBarry Smith DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections. Generates and error if they are not consistent. 4443507e4973SMatthew G. Knepley 4444507e4973SMatthew G. Knepley Input Parameters: 4445bb7acecfSBarry Smith + dm - The `DM` 4446bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4447bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 4448507e4973SMatthew G. Knepley 4449507e4973SMatthew G. Knepley Level: intermediate 4450507e4973SMatthew G. Knepley 4451db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMSetSectionSF()` 4452507e4973SMatthew G. Knepley */ 4453f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection) 4454507e4973SMatthew G. Knepley { 4455507e4973SMatthew G. Knepley MPI_Comm comm; 4456507e4973SMatthew G. Knepley PetscLayout layout; 4457507e4973SMatthew G. Knepley const PetscInt *ranges; 4458507e4973SMatthew G. Knepley PetscInt pStart, pEnd, p, nroots; 4459507e4973SMatthew G. Knepley PetscMPIInt size, rank; 4460507e4973SMatthew G. Knepley PetscBool valid = PETSC_TRUE, gvalid; 4461507e4973SMatthew G. Knepley 4462507e4973SMatthew G. Knepley PetscFunctionBegin; 44639566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm,&comm)); 4464507e4973SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 44659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 44669566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 44679566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(globalSection, &pStart, &pEnd)); 44689566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(globalSection, &nroots)); 44699566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &layout)); 44709566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(layout, 1)); 44719566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(layout, nroots)); 44729566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(layout)); 44739566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRanges(layout, &ranges)); 4474507e4973SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4475f741bcd2SMatthew G. Knepley PetscInt dof, cdof, off, gdof, gcdof, goff, gsize, d; 4476507e4973SMatthew G. Knepley 44779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(localSection, p, &dof)); 44789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(localSection, p, &off)); 44799566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(localSection, p, &cdof)); 44809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(globalSection, p, &gdof)); 44819566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(globalSection, p, &gcdof)); 44829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(globalSection, p, &goff)); 4483507e4973SMatthew G. Knepley if (!gdof) continue; /* Censored point */ 448463a3b9bcSJacob Faibussowitsch if ((gdof < 0 ? -(gdof+1) : gdof) != dof) {PetscCall(PetscSynchronizedPrintf(comm, "[%d]Global dof %" PetscInt_FMT " for point %" PetscInt_FMT " not equal to local dof %" PetscInt_FMT "\n", rank, gdof, p, dof)); valid = PETSC_FALSE;} 448563a3b9bcSJacob Faibussowitsch if (gcdof && (gcdof != cdof)) {PetscCall(PetscSynchronizedPrintf(comm, "[%d]Global constraints %" PetscInt_FMT " for point %" PetscInt_FMT " not equal to local constraints %" PetscInt_FMT "\n", rank, gcdof, p, cdof)); valid = PETSC_FALSE;} 4486507e4973SMatthew G. Knepley if (gdof < 0) { 4487507e4973SMatthew G. Knepley gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof; 4488507e4973SMatthew G. Knepley for (d = 0; d < gsize; ++d) { 4489507e4973SMatthew G. Knepley PetscInt offset = -(goff+1) + d, r; 4490507e4973SMatthew G. Knepley 44919566063dSJacob Faibussowitsch PetscCall(PetscFindInt(offset,size+1,ranges,&r)); 4492507e4973SMatthew G. Knepley if (r < 0) r = -(r+2); 449363a3b9bcSJacob Faibussowitsch if ((r < 0) || (r >= size)) {PetscCall(PetscSynchronizedPrintf(comm, "[%d]Point %" PetscInt_FMT " mapped to invalid process %" PetscInt_FMT " (%" PetscInt_FMT ", %" PetscInt_FMT ")\n", rank, p, r, gdof, goff)); valid = PETSC_FALSE;break;} 4494507e4973SMatthew G. Knepley } 4495507e4973SMatthew G. Knepley } 4496507e4973SMatthew G. Knepley } 44979566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&layout)); 44989566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 44991c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm)); 4500507e4973SMatthew G. Knepley if (!gvalid) { 45019566063dSJacob Faibussowitsch PetscCall(DMView(dm, NULL)); 4502507e4973SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections"); 4503507e4973SMatthew G. Knepley } 4504507e4973SMatthew G. Knepley PetscFunctionReturn(0); 4505507e4973SMatthew G. Knepley } 4506f741bcd2SMatthew G. Knepley #endif 4507507e4973SMatthew G. Knepley 450888ed4aceSMatthew G Knepley /*@ 4509bb7acecfSBarry Smith DMGetGlobalSection - Get the `PetscSection` encoding the global data layout for the `DM`. 451088ed4aceSMatthew G Knepley 4511d083f849SBarry Smith Collective on dm 45128b1ab98fSJed Brown 451388ed4aceSMatthew G Knepley Input Parameter: 4514bb7acecfSBarry Smith . dm - The `DM` 451588ed4aceSMatthew G Knepley 451688ed4aceSMatthew G Knepley Output Parameter: 4517bb7acecfSBarry Smith . section - The `PetscSection` 451888ed4aceSMatthew G Knepley 451988ed4aceSMatthew G Knepley Level: intermediate 452088ed4aceSMatthew G Knepley 4521bb7acecfSBarry Smith Note: 4522bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSection`. 452388ed4aceSMatthew G Knepley 4524db781477SPatrick Sanan .seealso: `DMSetLocalSection()`, `DMGetLocalSection()` 452588ed4aceSMatthew G Knepley @*/ 4526e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section) 45270adebc6cSBarry Smith { 452888ed4aceSMatthew G Knepley PetscFunctionBegin; 452988ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 453088ed4aceSMatthew G Knepley PetscValidPointer(section, 2); 45311bb6d2a8SBarry Smith if (!dm->globalSection) { 4532fd59a867SMatthew G. Knepley PetscSection s; 4533fd59a867SMatthew G. Knepley 45349566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 45357a8be351SBarry Smith PetscCheck(s,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection"); 45367a8be351SBarry Smith PetscCheck(dm->sf,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection"); 45379566063dSJacob Faibussowitsch PetscCall(PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->globalSection)); 45389566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&dm->map)); 45399566063dSJacob Faibussowitsch PetscCall(PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->globalSection, &dm->map)); 45409566063dSJacob Faibussowitsch PetscCall(PetscSectionViewFromOptions(dm->globalSection, NULL, "-global_section_view")); 454188ed4aceSMatthew G Knepley } 45421bb6d2a8SBarry Smith *section = dm->globalSection; 454388ed4aceSMatthew G Knepley PetscFunctionReturn(0); 454488ed4aceSMatthew G Knepley } 454588ed4aceSMatthew G Knepley 4546b21d0597SMatthew G Knepley /*@ 4547bb7acecfSBarry Smith DMSetGlobalSection - Set the `PetscSection` encoding the global data layout for the `DM`. 4548b21d0597SMatthew G Knepley 4549b21d0597SMatthew G Knepley Input Parameters: 4550bb7acecfSBarry Smith + dm - The `DM` 45515080bbdbSMatthew G Knepley - section - The PetscSection, or NULL 4552b21d0597SMatthew G Knepley 4553b21d0597SMatthew G Knepley Level: intermediate 4554b21d0597SMatthew G Knepley 4555bb7acecfSBarry Smith Note: 4556bb7acecfSBarry Smith Any existing `PetscSection` will be destroyed 4557b21d0597SMatthew G Knepley 4558db781477SPatrick Sanan .seealso: `DMGetGlobalSection()`, `DMSetLocalSection()` 4559b21d0597SMatthew G Knepley @*/ 4560e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section) 45610adebc6cSBarry Smith { 4562b21d0597SMatthew G Knepley PetscFunctionBegin; 4563b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 45645080bbdbSMatthew G Knepley if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2); 45659566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)section)); 45669566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&dm->globalSection)); 45671bb6d2a8SBarry Smith dm->globalSection = section; 4568497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG) 45699566063dSJacob Faibussowitsch if (section) PetscCall(DMDefaultSectionCheckConsistency_Internal(dm, dm->localSection, section)); 4570507e4973SMatthew G. Knepley #endif 4571b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4572b21d0597SMatthew G Knepley } 4573b21d0597SMatthew G Knepley 457488ed4aceSMatthew G Knepley /*@ 4575bb7acecfSBarry Smith DMGetSectionSF - Get the `PetscSF` encoding the parallel dof overlap for the `DM`. If it has not been set, 4576bb7acecfSBarry Smith it is created from the default `PetscSection` layouts in the `DM`. 457788ed4aceSMatthew G Knepley 457888ed4aceSMatthew G Knepley Input Parameter: 4579bb7acecfSBarry Smith . dm - The `DM` 458088ed4aceSMatthew G Knepley 458188ed4aceSMatthew G Knepley Output Parameter: 4582bb7acecfSBarry Smith . sf - The `PetscSF` 458388ed4aceSMatthew G Knepley 458488ed4aceSMatthew G Knepley Level: intermediate 458588ed4aceSMatthew G Knepley 4586bb7acecfSBarry Smith Note: 4587bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 458888ed4aceSMatthew G Knepley 4589db781477SPatrick Sanan .seealso: `DMSetSectionSF()`, `DMCreateSectionSF()` 459088ed4aceSMatthew G Knepley @*/ 45911bb6d2a8SBarry Smith PetscErrorCode DMGetSectionSF(DM dm, PetscSF *sf) 45920adebc6cSBarry Smith { 459388ed4aceSMatthew G Knepley PetscInt nroots; 459488ed4aceSMatthew G Knepley 459588ed4aceSMatthew G Knepley PetscFunctionBegin; 459688ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 459788ed4aceSMatthew G Knepley PetscValidPointer(sf, 2); 45981bb6d2a8SBarry Smith if (!dm->sectionSF) { 45999566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->sectionSF)); 460033907cc2SStefano Zampini } 46019566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(dm->sectionSF, &nroots, NULL, NULL, NULL)); 460288ed4aceSMatthew G Knepley if (nroots < 0) { 460388ed4aceSMatthew G Knepley PetscSection section, gSection; 460488ed4aceSMatthew G Knepley 46059566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 460631ea6d37SMatthew G Knepley if (section) { 46079566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gSection)); 46089566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSF(dm, section, gSection)); 460931ea6d37SMatthew G Knepley } else { 46100298fd71SBarry Smith *sf = NULL; 461131ea6d37SMatthew G Knepley PetscFunctionReturn(0); 461231ea6d37SMatthew G Knepley } 461388ed4aceSMatthew G Knepley } 46141bb6d2a8SBarry Smith *sf = dm->sectionSF; 461588ed4aceSMatthew G Knepley PetscFunctionReturn(0); 461688ed4aceSMatthew G Knepley } 461788ed4aceSMatthew G Knepley 461888ed4aceSMatthew G Knepley /*@ 4619bb7acecfSBarry Smith DMSetSectionSF - Set the `PetscSF` encoding the parallel dof overlap for the `DM` 462088ed4aceSMatthew G Knepley 462188ed4aceSMatthew G Knepley Input Parameters: 4622bb7acecfSBarry Smith + dm - The `DM` 4623bb7acecfSBarry Smith - sf - The `PetscSF` 462488ed4aceSMatthew G Knepley 462588ed4aceSMatthew G Knepley Level: intermediate 462688ed4aceSMatthew G Knepley 4627bb7acecfSBarry Smith Note: 4628bb7acecfSBarry Smith Any previous `PetscSF` is destroyed 462988ed4aceSMatthew G Knepley 4630db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMCreateSectionSF()` 463188ed4aceSMatthew G Knepley @*/ 46321bb6d2a8SBarry Smith PetscErrorCode DMSetSectionSF(DM dm, PetscSF sf) 46330adebc6cSBarry Smith { 463488ed4aceSMatthew G Knepley PetscFunctionBegin; 463588ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4636b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 46379566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) sf)); 46389566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sectionSF)); 46391bb6d2a8SBarry Smith dm->sectionSF = sf; 464088ed4aceSMatthew G Knepley PetscFunctionReturn(0); 464188ed4aceSMatthew G Knepley } 464288ed4aceSMatthew G Knepley 464388ed4aceSMatthew G Knepley /*@C 4644bb7acecfSBarry Smith DMCreateSectionSF - Create the `PetscSF` encoding the parallel dof overlap for the `DM` based upon the `PetscSection`s 464588ed4aceSMatthew G Knepley describing the data layout. 464688ed4aceSMatthew G Knepley 464788ed4aceSMatthew G Knepley Input Parameters: 4648bb7acecfSBarry Smith + dm - The `DM` 4649bb7acecfSBarry Smith . localSection - `PetscSection` describing the local data layout 4650bb7acecfSBarry Smith - globalSection - `PetscSection` describing the global data layout 465188ed4aceSMatthew G Knepley 46521bb6d2a8SBarry Smith Level: developer 46531bb6d2a8SBarry Smith 4654bb7acecfSBarry Smith Note: 4655bb7acecfSBarry Smith One usually uses `DMGetSectionSF()` to obtain the `PetscSF` 4656bb7acecfSBarry Smith 4657bb7acecfSBarry Smith Developer Note: 4658bb7acecfSBarry Smith Since this routine has for arguments the two sections from the `DM` and puts the resulting `PetscSF` 4659bb7acecfSBarry Smith directly into the `DM`, perhaps this function should not take the local and global sections as 4660bb7acecfSBarry Smith input and should just obtain them from the `DM`? 46611bb6d2a8SBarry Smith 4662db781477SPatrick Sanan .seealso: `DMGetSectionSF()`, `DMSetSectionSF()`, `DMGetLocalSection()`, `DMGetGlobalSection()` 466388ed4aceSMatthew G Knepley @*/ 46641bb6d2a8SBarry Smith PetscErrorCode DMCreateSectionSF(DM dm, PetscSection localSection, PetscSection globalSection) 466588ed4aceSMatthew G Knepley { 466688ed4aceSMatthew G Knepley PetscFunctionBegin; 466788ed4aceSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46689566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraphSection(dm->sectionSF, localSection, globalSection)); 466988ed4aceSMatthew G Knepley PetscFunctionReturn(0); 467088ed4aceSMatthew G Knepley } 4671af122d2aSMatthew G Knepley 4672b21d0597SMatthew G Knepley /*@ 4673bb7acecfSBarry Smith DMGetPointSF - Get the `PetscSF` encoding the parallel section point overlap for the `DM`. 4674bb7acecfSBarry Smith 4675bb7acecfSBarry Smith Not collective but the resulting `PetscSF` is collective 4676b21d0597SMatthew G Knepley 4677b21d0597SMatthew G Knepley Input Parameter: 4678bb7acecfSBarry Smith . dm - The `DM` 4679b21d0597SMatthew G Knepley 4680b21d0597SMatthew G Knepley Output Parameter: 4681bb7acecfSBarry Smith . sf - The `PetscSF` 4682b21d0597SMatthew G Knepley 4683b21d0597SMatthew G Knepley Level: intermediate 4684b21d0597SMatthew G Knepley 4685bb7acecfSBarry Smith Note: 4686bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 4687b21d0597SMatthew G Knepley 4688db781477SPatrick Sanan .seealso: `DMSetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4689b21d0597SMatthew G Knepley @*/ 46900adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) 46910adebc6cSBarry Smith { 4692b21d0597SMatthew G Knepley PetscFunctionBegin; 4693b21d0597SMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4694b21d0597SMatthew G Knepley PetscValidPointer(sf, 2); 4695b21d0597SMatthew G Knepley *sf = dm->sf; 4696b21d0597SMatthew G Knepley PetscFunctionReturn(0); 4697b21d0597SMatthew G Knepley } 4698b21d0597SMatthew G Knepley 4699057b4bcdSMatthew G Knepley /*@ 4700bb7acecfSBarry Smith DMSetPointSF - Set the `PetscSF` encoding the parallel section point overlap for the `DM`. 4701bb7acecfSBarry Smith 4702bb7acecfSBarry Smith Collective on dm 4703057b4bcdSMatthew G Knepley 4704057b4bcdSMatthew G Knepley Input Parameters: 4705bb7acecfSBarry Smith + dm - The `DM` 4706bb7acecfSBarry Smith - sf - The` PetscSF` 4707057b4bcdSMatthew G Knepley 4708057b4bcdSMatthew G Knepley Level: intermediate 4709057b4bcdSMatthew G Knepley 4710db781477SPatrick Sanan .seealso: `DMGetPointSF()`, `DMGetSectionSF()`, `DMSetSectionSF()`, `DMCreateSectionSF()` 4711057b4bcdSMatthew G Knepley @*/ 47120adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) 47130adebc6cSBarry Smith { 4714057b4bcdSMatthew G Knepley PetscFunctionBegin; 4715057b4bcdSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4716b9d85ea2SLisandro Dalcin if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47179566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) sf)); 47189566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sf)); 4719057b4bcdSMatthew G Knepley dm->sf = sf; 4720057b4bcdSMatthew G Knepley PetscFunctionReturn(0); 4721057b4bcdSMatthew G Knepley } 4722057b4bcdSMatthew G Knepley 47234f37162bSMatthew G. Knepley /*@ 4724bb7acecfSBarry Smith DMGetNaturalSF - Get the `PetscSF` encoding the map back to the original mesh ordering 47254f37162bSMatthew G. Knepley 47264f37162bSMatthew G. Knepley Input Parameter: 4727bb7acecfSBarry Smith . dm - The `DM` 47284f37162bSMatthew G. Knepley 47294f37162bSMatthew G. Knepley Output Parameter: 4730bb7acecfSBarry Smith . sf - The `PetscSF` 47314f37162bSMatthew G. Knepley 47324f37162bSMatthew G. Knepley Level: intermediate 47334f37162bSMatthew G. Knepley 4734bb7acecfSBarry Smith Note: 4735bb7acecfSBarry Smith This gets a borrowed reference, so the user should not destroy this `PetscSF`. 47364f37162bSMatthew G. Knepley 4737db781477SPatrick Sanan .seealso: `DMSetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47384f37162bSMatthew G. Knepley @*/ 47394f37162bSMatthew G. Knepley PetscErrorCode DMGetNaturalSF(DM dm, PetscSF *sf) 47404f37162bSMatthew G. Knepley { 47414f37162bSMatthew G. Knepley PetscFunctionBegin; 47424f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47434f37162bSMatthew G. Knepley PetscValidPointer(sf, 2); 47444f37162bSMatthew G. Knepley *sf = dm->sfNatural; 47454f37162bSMatthew G. Knepley PetscFunctionReturn(0); 47464f37162bSMatthew G. Knepley } 47474f37162bSMatthew G. Knepley 47484f37162bSMatthew G. Knepley /*@ 47494f37162bSMatthew G. Knepley DMSetNaturalSF - Set the PetscSF encoding the map back to the original mesh ordering 47504f37162bSMatthew G. Knepley 47514f37162bSMatthew G. Knepley Input Parameters: 47524f37162bSMatthew G. Knepley + dm - The DM 47534f37162bSMatthew G. Knepley - sf - The PetscSF 47544f37162bSMatthew G. Knepley 47554f37162bSMatthew G. Knepley Level: intermediate 47564f37162bSMatthew G. Knepley 4757db781477SPatrick Sanan .seealso: `DMGetNaturalSF()`, `DMSetUseNatural()`, `DMGetUseNatural()`, `DMPlexCreateGlobalToNaturalSF()`, `DMPlexDistribute()` 47584f37162bSMatthew G. Knepley @*/ 47594f37162bSMatthew G. Knepley PetscErrorCode DMSetNaturalSF(DM dm, PetscSF sf) 47604f37162bSMatthew G. Knepley { 47614f37162bSMatthew G. Knepley PetscFunctionBegin; 47624f37162bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47634f37162bSMatthew G. Knepley if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 47649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) sf)); 47659566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&dm->sfNatural)); 47664f37162bSMatthew G. Knepley dm->sfNatural = sf; 47674f37162bSMatthew G. Knepley PetscFunctionReturn(0); 47684f37162bSMatthew G. Knepley } 47694f37162bSMatthew G. Knepley 477034aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc) 477134aa8a36SMatthew G. Knepley { 477234aa8a36SMatthew G. Knepley PetscClassId id; 477334aa8a36SMatthew G. Knepley 477434aa8a36SMatthew G. Knepley PetscFunctionBegin; 47759566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 477634aa8a36SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 47779566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 477834aa8a36SMatthew G. Knepley } else if (id == PETSCFV_CLASSID) { 47799566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE)); 478017c1d62eSMatthew G. Knepley } else { 47819566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE)); 478234aa8a36SMatthew G. Knepley } 478334aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 478434aa8a36SMatthew G. Knepley } 478534aa8a36SMatthew G. Knepley 478644a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew) 478744a7f3ddSMatthew G. Knepley { 478844a7f3ddSMatthew G. Knepley RegionField *tmpr; 478944a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf, f; 479044a7f3ddSMatthew G. Knepley 479144a7f3ddSMatthew G. Knepley PetscFunctionBegin; 479244a7f3ddSMatthew G. Knepley if (Nf >= NfNew) PetscFunctionReturn(0); 47939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NfNew, &tmpr)); 479444a7f3ddSMatthew G. Knepley for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f]; 4795e0b68406SMatthew Knepley for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL; tmpr[f].avoidTensor = PETSC_FALSE;} 47969566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 479744a7f3ddSMatthew G. Knepley dm->Nf = NfNew; 479844a7f3ddSMatthew G. Knepley dm->fields = tmpr; 479944a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 480044a7f3ddSMatthew G. Knepley } 480144a7f3ddSMatthew G. Knepley 480244a7f3ddSMatthew G. Knepley /*@ 480344a7f3ddSMatthew G. Knepley DMClearFields - Remove all fields from the DM 480444a7f3ddSMatthew G. Knepley 4805d083f849SBarry Smith Logically collective on dm 480644a7f3ddSMatthew G. Knepley 480744a7f3ddSMatthew G. Knepley Input Parameter: 480844a7f3ddSMatthew G. Knepley . dm - The DM 480944a7f3ddSMatthew G. Knepley 481044a7f3ddSMatthew G. Knepley Level: intermediate 481144a7f3ddSMatthew G. Knepley 4812db781477SPatrick Sanan .seealso: `DMGetNumFields()`, `DMSetNumFields()`, `DMSetField()` 481344a7f3ddSMatthew G. Knepley @*/ 481444a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm) 481544a7f3ddSMatthew G. Knepley { 481644a7f3ddSMatthew G. Knepley PetscInt f; 481744a7f3ddSMatthew G. Knepley 481844a7f3ddSMatthew G. Knepley PetscFunctionBegin; 481944a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 482044a7f3ddSMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 48219566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 48229566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 482344a7f3ddSMatthew G. Knepley } 48249566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->fields)); 482544a7f3ddSMatthew G. Knepley dm->fields = NULL; 482644a7f3ddSMatthew G. Knepley dm->Nf = 0; 482744a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 482844a7f3ddSMatthew G. Knepley } 482944a7f3ddSMatthew G. Knepley 4830689b5837SMatthew G. Knepley /*@ 4831689b5837SMatthew G. Knepley DMGetNumFields - Get the number of fields in the DM 4832689b5837SMatthew G. Knepley 4833689b5837SMatthew G. Knepley Not collective 4834689b5837SMatthew G. Knepley 4835689b5837SMatthew G. Knepley Input Parameter: 4836689b5837SMatthew G. Knepley . dm - The DM 4837689b5837SMatthew G. Knepley 4838689b5837SMatthew G. Knepley Output Parameter: 4839689b5837SMatthew G. Knepley . Nf - The number of fields 4840689b5837SMatthew G. Knepley 4841689b5837SMatthew G. Knepley Level: intermediate 4842689b5837SMatthew G. Knepley 4843db781477SPatrick Sanan .seealso: `DMSetNumFields()`, `DMSetField()` 4844689b5837SMatthew G. Knepley @*/ 48450f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields) 48460f21e855SMatthew G. Knepley { 48470f21e855SMatthew G. Knepley PetscFunctionBegin; 48480f21e855SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4849534a8f05SLisandro Dalcin PetscValidIntPointer(numFields, 2); 485044a7f3ddSMatthew G. Knepley *numFields = dm->Nf; 4851af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4852af122d2aSMatthew G Knepley } 4853af122d2aSMatthew G Knepley 4854689b5837SMatthew G. Knepley /*@ 4855689b5837SMatthew G. Knepley DMSetNumFields - Set the number of fields in the DM 4856689b5837SMatthew G. Knepley 4857d083f849SBarry Smith Logically collective on dm 4858689b5837SMatthew G. Knepley 4859689b5837SMatthew G. Knepley Input Parameters: 4860689b5837SMatthew G. Knepley + dm - The DM 4861689b5837SMatthew G. Knepley - Nf - The number of fields 4862689b5837SMatthew G. Knepley 4863689b5837SMatthew G. Knepley Level: intermediate 4864689b5837SMatthew G. Knepley 4865db781477SPatrick Sanan .seealso: `DMGetNumFields()`, `DMSetField()` 4866689b5837SMatthew G. Knepley @*/ 4867af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields) 4868af122d2aSMatthew G Knepley { 48690f21e855SMatthew G. Knepley PetscInt Nf, f; 4870af122d2aSMatthew G Knepley 4871af122d2aSMatthew G Knepley PetscFunctionBegin; 4872af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48739566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 48740f21e855SMatthew G. Knepley for (f = Nf; f < numFields; ++f) { 48750f21e855SMatthew G. Knepley PetscContainer obj; 48760f21e855SMatthew G. Knepley 48779566063dSJacob Faibussowitsch PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj)); 48789566063dSJacob Faibussowitsch PetscCall(DMAddField(dm, NULL, (PetscObject) obj)); 48799566063dSJacob Faibussowitsch PetscCall(PetscContainerDestroy(&obj)); 4880af122d2aSMatthew G Knepley } 4881af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4882af122d2aSMatthew G Knepley } 4883af122d2aSMatthew G Knepley 4884c1929be8SMatthew G. Knepley /*@ 4885bb7acecfSBarry Smith DMGetField - Return the `DMLabel` and discretization object for a given `DM` field 4886c1929be8SMatthew G. Knepley 4887c1929be8SMatthew G. Knepley Not collective 4888c1929be8SMatthew G. Knepley 4889c1929be8SMatthew G. Knepley Input Parameters: 4890bb7acecfSBarry Smith + dm - The `DM` 4891c1929be8SMatthew G. Knepley - f - The field number 4892c1929be8SMatthew G. Knepley 489344a7f3ddSMatthew G. Knepley Output Parameters: 4894bb7acecfSBarry Smith + label - The label indicating the support of the field, or NULL for the entire mesh (pass in NULL if not needed) 4895bb7acecfSBarry Smith - disc - The discretization object (pass in NULL if not needed) 4896c1929be8SMatthew G. Knepley 489744a7f3ddSMatthew G. Knepley Level: intermediate 4898c1929be8SMatthew G. Knepley 4899db781477SPatrick Sanan .seealso: `DMAddField()`, `DMSetField()` 4900c1929be8SMatthew G. Knepley @*/ 4901bb7acecfSBarry Smith PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *disc) 4902af122d2aSMatthew G Knepley { 4903af122d2aSMatthew G Knepley PetscFunctionBegin; 4904af122d2aSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4905bb7acecfSBarry Smith PetscValidPointer(disc, 4); 49067a8be351SBarry 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); 490744a7f3ddSMatthew G. Knepley if (label) *label = dm->fields[f].label; 4908bb7acecfSBarry Smith if (disc) *disc = dm->fields[f].disc; 4909decb47aaSMatthew G. Knepley PetscFunctionReturn(0); 4910decb47aaSMatthew G. Knepley } 4911decb47aaSMatthew G. Knepley 4912083401c6SMatthew G. Knepley /* Does not clear the DS */ 4913bb7acecfSBarry Smith PetscErrorCode DMSetField_Internal(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4914083401c6SMatthew G. Knepley { 4915083401c6SMatthew G. Knepley PetscFunctionBegin; 49169566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, f+1)); 49179566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->fields[f].label)); 49189566063dSJacob Faibussowitsch PetscCall(PetscObjectDestroy(&dm->fields[f].disc)); 4919083401c6SMatthew G. Knepley dm->fields[f].label = label; 4920bb7acecfSBarry Smith dm->fields[f].disc = disc; 49219566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label)); 4922bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject) disc)); 4923083401c6SMatthew G. Knepley PetscFunctionReturn(0); 4924083401c6SMatthew G. Knepley } 4925083401c6SMatthew G. Knepley 4926c1929be8SMatthew G. Knepley /*@ 4927bb7acecfSBarry Smith DMSetField - Set the discretization object for a given `DM` field. Usually one would call `DMAddField()` which automatically handles 4928bb7acecfSBarry Smith the field numbering. 4929c1929be8SMatthew G. Knepley 4930d083f849SBarry Smith Logically collective on dm 4931c1929be8SMatthew G. Knepley 4932c1929be8SMatthew G. Knepley Input Parameters: 4933bb7acecfSBarry Smith + dm - The `DM` 4934c1929be8SMatthew G. Knepley . f - The field number 493544a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4936bb7acecfSBarry Smith - disc - The discretization object 4937c1929be8SMatthew G. Knepley 493844a7f3ddSMatthew G. Knepley Level: intermediate 4939c1929be8SMatthew G. Knepley 4940db781477SPatrick Sanan .seealso: `DMAddField()`, `DMGetField()` 4941c1929be8SMatthew G. Knepley @*/ 4942bb7acecfSBarry Smith PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject disc) 4943decb47aaSMatthew G. Knepley { 4944decb47aaSMatthew G. Knepley PetscFunctionBegin; 4945decb47aaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4946e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3); 4947bb7acecfSBarry Smith PetscValidHeader(disc, 4); 49487a8be351SBarry Smith PetscCheck(f >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f); 4949bb7acecfSBarry Smith PetscCall(DMSetField_Internal(dm, f, label, disc)); 4950bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, f, disc)); 49519566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 495244a7f3ddSMatthew G. Knepley PetscFunctionReturn(0); 495344a7f3ddSMatthew G. Knepley } 495444a7f3ddSMatthew G. Knepley 495544a7f3ddSMatthew G. Knepley /*@ 4956bb7acecfSBarry 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) 4957bb7acecfSBarry Smith and a discretization object that defines the function space associated with those points. 495844a7f3ddSMatthew G. Knepley 4959d083f849SBarry Smith Logically collective on dm 496044a7f3ddSMatthew G. Knepley 496144a7f3ddSMatthew G. Knepley Input Parameters: 4962bb7acecfSBarry Smith + dm - The `DM` 496344a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh 4964bb7acecfSBarry Smith - disc - The discretization object 496544a7f3ddSMatthew G. Knepley 496644a7f3ddSMatthew G. Knepley Level: intermediate 496744a7f3ddSMatthew G. Knepley 4968bb7acecfSBarry Smith Notes: 4969bb7acecfSBarry Smith The label already exists or will be added to the `DM` with `DMSetLabel()`. 4970bb7acecfSBarry Smith 4971bb7acecfSBarry Smith For example, a piecewise continous pressure field can be defined by coefficients at the cell centers of a mesh and piecewise constant functions 4972bb7acecfSBarry 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 4973bb7acecfSBarry Smith geometry entities, a `DMLabel` indicating a subset of those geometric entities, and a discretization object, such as a `PetscFE`. 4974bb7acecfSBarry Smith 4975bb7acecfSBarry Smith .seealso: `DMSetLabel()`, `DMSetField()`, `DMGetField()`, `PetscFE` 497644a7f3ddSMatthew G. Knepley @*/ 4977bb7acecfSBarry Smith PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject disc) 497844a7f3ddSMatthew G. Knepley { 497944a7f3ddSMatthew G. Knepley PetscInt Nf = dm->Nf; 498044a7f3ddSMatthew G. Knepley 498144a7f3ddSMatthew G. Knepley PetscFunctionBegin; 498244a7f3ddSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4983064a246eSJacob Faibussowitsch if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 4984bb7acecfSBarry Smith PetscValidHeader(disc, 3); 49859566063dSJacob Faibussowitsch PetscCall(DMFieldEnlarge_Static(dm, Nf+1)); 498644a7f3ddSMatthew G. Knepley dm->fields[Nf].label = label; 4987bb7acecfSBarry Smith dm->fields[Nf].disc = disc; 49889566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label)); 4989bb7acecfSBarry Smith PetscCall(PetscObjectReference((PetscObject) disc)); 4990bb7acecfSBarry Smith PetscCall(DMSetDefaultAdjacency_Private(dm, Nf, disc)); 49919566063dSJacob Faibussowitsch PetscCall(DMClearDS(dm)); 4992af122d2aSMatthew G Knepley PetscFunctionReturn(0); 4993af122d2aSMatthew G Knepley } 49946636e97aSMatthew G Knepley 4995e5e52638SMatthew G. Knepley /*@ 4996e0b68406SMatthew Knepley DMSetFieldAvoidTensor - Set flag to avoid defining the field on tensor cells 4997e0b68406SMatthew Knepley 4998e0b68406SMatthew Knepley Logically collective on dm 4999e0b68406SMatthew Knepley 5000e0b68406SMatthew Knepley Input Parameters: 5001bb7acecfSBarry Smith + dm - The `DM` 5002e0b68406SMatthew Knepley . f - The field index 5003bb7acecfSBarry Smith - avoidTensor - `PETSC_TRUE` to skip defining the field on tensor cells 5004e0b68406SMatthew Knepley 5005e0b68406SMatthew Knepley Level: intermediate 5006e0b68406SMatthew Knepley 5007db781477SPatrick Sanan .seealso: `DMGetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5008e0b68406SMatthew Knepley @*/ 5009e0b68406SMatthew Knepley PetscErrorCode DMSetFieldAvoidTensor(DM dm, PetscInt f, PetscBool avoidTensor) 5010e0b68406SMatthew Knepley { 5011e0b68406SMatthew Knepley PetscFunctionBegin; 501263a3b9bcSJacob 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); 5013e0b68406SMatthew Knepley dm->fields[f].avoidTensor = avoidTensor; 5014e0b68406SMatthew Knepley PetscFunctionReturn(0); 5015e0b68406SMatthew Knepley } 5016e0b68406SMatthew Knepley 5017e0b68406SMatthew Knepley /*@ 5018e0b68406SMatthew Knepley DMGetFieldAvoidTensor - Get flag to avoid defining the field on tensor cells 5019e0b68406SMatthew Knepley 5020bb7acecfSBarry Smith Not collective 5021e0b68406SMatthew Knepley 5022e0b68406SMatthew Knepley Input Parameters: 5023bb7acecfSBarry Smith + dm - The `DM` 5024e0b68406SMatthew Knepley - f - The field index 5025e0b68406SMatthew Knepley 5026e0b68406SMatthew Knepley Output Parameter: 5027e0b68406SMatthew Knepley . avoidTensor - The flag to avoid defining the field on tensor cells 5028e0b68406SMatthew Knepley 5029e0b68406SMatthew Knepley Level: intermediate 5030e0b68406SMatthew Knepley 5031bb7acecfSBarry Smith .seealso: `DMAddField()`, `DMSetField()`, `DMGetField()`, `DMSetFieldAvoidTensor()`, `DMSetField()`, `DMGetField()` 5032e0b68406SMatthew Knepley @*/ 5033e0b68406SMatthew Knepley PetscErrorCode DMGetFieldAvoidTensor(DM dm, PetscInt f, PetscBool *avoidTensor) 5034e0b68406SMatthew Knepley { 5035e0b68406SMatthew Knepley PetscFunctionBegin; 503663a3b9bcSJacob 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); 5037e0b68406SMatthew Knepley *avoidTensor = dm->fields[f].avoidTensor; 5038e0b68406SMatthew Knepley PetscFunctionReturn(0); 5039e0b68406SMatthew Knepley } 5040e0b68406SMatthew Knepley 5041e0b68406SMatthew Knepley /*@ 5042bb7acecfSBarry Smith DMCopyFields - Copy the discretizations for the `DM` into another `DM` 5043e5e52638SMatthew G. Knepley 5044d083f849SBarry Smith Collective on dm 5045e5e52638SMatthew G. Knepley 5046e5e52638SMatthew G. Knepley Input Parameter: 5047bb7acecfSBarry Smith . dm - The `DM` 5048e5e52638SMatthew G. Knepley 5049e5e52638SMatthew G. Knepley Output Parameter: 5050bb7acecfSBarry Smith . newdm - The `DM` 5051e5e52638SMatthew G. Knepley 5052e5e52638SMatthew G. Knepley Level: advanced 5053e5e52638SMatthew G. Knepley 5054db781477SPatrick Sanan .seealso: `DMGetField()`, `DMSetField()`, `DMAddField()`, `DMCopyDS()`, `DMGetDS()`, `DMGetCellDS()` 5055e5e52638SMatthew G. Knepley @*/ 5056e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm) 5057e5e52638SMatthew G. Knepley { 5058e5e52638SMatthew G. Knepley PetscInt Nf, f; 5059e5e52638SMatthew G. Knepley 5060e5e52638SMatthew G. Knepley PetscFunctionBegin; 5061e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 50629566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 50639566063dSJacob Faibussowitsch PetscCall(DMClearFields(newdm)); 5064e5e52638SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5065e5e52638SMatthew G. Knepley DMLabel label; 5066e5e52638SMatthew G. Knepley PetscObject field; 506734aa8a36SMatthew G. Knepley PetscBool useCone, useClosure; 5068e5e52638SMatthew G. Knepley 50699566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, &label, &field)); 50709566063dSJacob Faibussowitsch PetscCall(DMSetField(newdm, f, label, field)); 50719566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, f, &useCone, &useClosure)); 50729566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(newdm, f, useCone, useClosure)); 507334aa8a36SMatthew G. Knepley } 507434aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 507534aa8a36SMatthew G. Knepley } 507634aa8a36SMatthew G. Knepley 507734aa8a36SMatthew G. Knepley /*@ 507834aa8a36SMatthew G. Knepley DMGetAdjacency - Returns the flags for determining variable influence 507934aa8a36SMatthew G. Knepley 508034aa8a36SMatthew G. Knepley Not collective 508134aa8a36SMatthew G. Knepley 508234aa8a36SMatthew G. Knepley Input Parameters: 508334aa8a36SMatthew G. Knepley + dm - The DM object 508434aa8a36SMatthew G. Knepley - f - The field number, or PETSC_DEFAULT for the default adjacency 508534aa8a36SMatthew G. Knepley 5086d8d19677SJose E. Roman Output Parameters: 508734aa8a36SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 508834aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 508934aa8a36SMatthew G. Knepley 509034aa8a36SMatthew G. Knepley Notes: 509134aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 509234aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 509334aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5094979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 509534aa8a36SMatthew G. Knepley 509634aa8a36SMatthew G. Knepley Level: developer 509734aa8a36SMatthew G. Knepley 5098db781477SPatrick Sanan .seealso: `DMSetAdjacency()`, `DMGetField()`, `DMSetField()` 509934aa8a36SMatthew G. Knepley @*/ 510034aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure) 510134aa8a36SMatthew G. Knepley { 510234aa8a36SMatthew G. Knepley PetscFunctionBegin; 510334aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5104534a8f05SLisandro Dalcin if (useCone) PetscValidBoolPointer(useCone, 3); 5105534a8f05SLisandro Dalcin if (useClosure) PetscValidBoolPointer(useClosure, 4); 510634aa8a36SMatthew G. Knepley if (f < 0) { 510734aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->adjacency[0]; 510834aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->adjacency[1]; 510934aa8a36SMatthew G. Knepley } else { 511034aa8a36SMatthew G. Knepley PetscInt Nf; 511134aa8a36SMatthew G. Knepley 51129566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51137a8be351SBarry Smith PetscCheck(f < Nf,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 511434aa8a36SMatthew G. Knepley if (useCone) *useCone = dm->fields[f].adjacency[0]; 511534aa8a36SMatthew G. Knepley if (useClosure) *useClosure = dm->fields[f].adjacency[1]; 511634aa8a36SMatthew G. Knepley } 511734aa8a36SMatthew G. Knepley PetscFunctionReturn(0); 511834aa8a36SMatthew G. Knepley } 511934aa8a36SMatthew G. Knepley 512034aa8a36SMatthew G. Knepley /*@ 512134aa8a36SMatthew G. Knepley DMSetAdjacency - Set the flags for determining variable influence 512234aa8a36SMatthew G. Knepley 512334aa8a36SMatthew G. Knepley Not collective 512434aa8a36SMatthew G. Knepley 512534aa8a36SMatthew G. Knepley Input Parameters: 512634aa8a36SMatthew G. Knepley + dm - The DM object 512734aa8a36SMatthew G. Knepley . f - The field number 512834aa8a36SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 512934aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 513034aa8a36SMatthew G. Knepley 513134aa8a36SMatthew G. Knepley Notes: 513234aa8a36SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 513334aa8a36SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 513434aa8a36SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5135979e053dSMatthew G. Knepley Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another. 513634aa8a36SMatthew G. Knepley 513734aa8a36SMatthew G. Knepley Level: developer 513834aa8a36SMatthew G. Knepley 5139db781477SPatrick Sanan .seealso: `DMGetAdjacency()`, `DMGetField()`, `DMSetField()` 514034aa8a36SMatthew G. Knepley @*/ 514134aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure) 514234aa8a36SMatthew G. Knepley { 514334aa8a36SMatthew G. Knepley PetscFunctionBegin; 514434aa8a36SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 514534aa8a36SMatthew G. Knepley if (f < 0) { 514634aa8a36SMatthew G. Knepley dm->adjacency[0] = useCone; 514734aa8a36SMatthew G. Knepley dm->adjacency[1] = useClosure; 514834aa8a36SMatthew G. Knepley } else { 514934aa8a36SMatthew G. Knepley PetscInt Nf; 515034aa8a36SMatthew G. Knepley 51519566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 51527a8be351SBarry Smith PetscCheck(f < Nf,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf); 515334aa8a36SMatthew G. Knepley dm->fields[f].adjacency[0] = useCone; 515434aa8a36SMatthew G. Knepley dm->fields[f].adjacency[1] = useClosure; 5155e5e52638SMatthew G. Knepley } 5156e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5157e5e52638SMatthew G. Knepley } 5158e5e52638SMatthew G. Knepley 5159b0441da4SMatthew G. Knepley /*@ 5160b0441da4SMatthew G. Knepley DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined 5161b0441da4SMatthew G. Knepley 5162b0441da4SMatthew G. Knepley Not collective 5163b0441da4SMatthew G. Knepley 5164f899ff85SJose E. Roman Input Parameter: 5165b0441da4SMatthew G. Knepley . dm - The DM object 5166b0441da4SMatthew G. Knepley 5167d8d19677SJose E. Roman Output Parameters: 5168b0441da4SMatthew G. Knepley + useCone - Flag for variable influence starting with the cone operation 5169b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5170b0441da4SMatthew G. Knepley 5171b0441da4SMatthew G. Knepley Notes: 5172b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5173b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5174b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5175b0441da4SMatthew G. Knepley 5176b0441da4SMatthew G. Knepley Level: developer 5177b0441da4SMatthew G. Knepley 5178db781477SPatrick Sanan .seealso: `DMSetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5179b0441da4SMatthew G. Knepley @*/ 5180b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure) 5181b0441da4SMatthew G. Knepley { 5182b0441da4SMatthew G. Knepley PetscInt Nf; 5183b0441da4SMatthew G. Knepley 5184b0441da4SMatthew G. Knepley PetscFunctionBegin; 5185b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5186064a246eSJacob Faibussowitsch if (useCone) PetscValidBoolPointer(useCone, 2); 5187064a246eSJacob Faibussowitsch if (useClosure) PetscValidBoolPointer(useClosure, 3); 51889566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5189b0441da4SMatthew G. Knepley if (!Nf) { 51909566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5191b0441da4SMatthew G. Knepley } else { 51929566063dSJacob Faibussowitsch PetscCall(DMGetAdjacency(dm, 0, useCone, useClosure)); 5193b0441da4SMatthew G. Knepley } 5194b0441da4SMatthew G. Knepley PetscFunctionReturn(0); 5195b0441da4SMatthew G. Knepley } 5196b0441da4SMatthew G. Knepley 5197b0441da4SMatthew G. Knepley /*@ 5198b0441da4SMatthew G. Knepley DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined 5199b0441da4SMatthew G. Knepley 5200b0441da4SMatthew G. Knepley Not collective 5201b0441da4SMatthew G. Knepley 5202b0441da4SMatthew G. Knepley Input Parameters: 5203b0441da4SMatthew G. Knepley + dm - The DM object 5204b0441da4SMatthew G. Knepley . useCone - Flag for variable influence starting with the cone operation 5205b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure 5206b0441da4SMatthew G. Knepley 5207b0441da4SMatthew G. Knepley Notes: 5208b0441da4SMatthew G. Knepley $ FEM: Two points p and q are adjacent if q \in closure(star(p)), useCone = PETSC_FALSE, useClosure = PETSC_TRUE 5209b0441da4SMatthew G. Knepley $ FVM: Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE, useClosure = PETSC_FALSE 5210b0441da4SMatthew G. Knepley $ FVM++: Two points p and q are adjacent if q \in star(closure(p)), useCone = PETSC_TRUE, useClosure = PETSC_TRUE 5211b0441da4SMatthew G. Knepley 5212b0441da4SMatthew G. Knepley Level: developer 5213b0441da4SMatthew G. Knepley 5214db781477SPatrick Sanan .seealso: `DMGetBasicAdjacency()`, `DMGetField()`, `DMSetField()` 5215b0441da4SMatthew G. Knepley @*/ 5216b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure) 5217b0441da4SMatthew G. Knepley { 5218b0441da4SMatthew G. Knepley PetscInt Nf; 5219b0441da4SMatthew G. Knepley 5220b0441da4SMatthew G. Knepley PetscFunctionBegin; 5221b0441da4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 52229566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 5223b0441da4SMatthew G. Knepley if (!Nf) { 52249566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure)); 5225b0441da4SMatthew G. Knepley } else { 52269566063dSJacob Faibussowitsch PetscCall(DMSetAdjacency(dm, 0, useCone, useClosure)); 5227e5e52638SMatthew G. Knepley } 5228e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5229e5e52638SMatthew G. Knepley } 5230e5e52638SMatthew G. Knepley 5231799db056SMatthew G. Knepley PetscErrorCode DMCompleteBCLabels_Internal(DM dm) 5232783e2ec8SMatthew G. Knepley { 5233799db056SMatthew G. Knepley DM plex; 5234799db056SMatthew G. Knepley DMLabel *labels, *glabels; 5235799db056SMatthew G. Knepley const char **names; 5236799db056SMatthew G. Knepley char *sendNames, *recvNames; 5237799db056SMatthew G. Knepley PetscInt Nds, s, maxLabels = 0, maxLen = 0, gmaxLen, Nl = 0, gNl, l, gl, m; 5238799db056SMatthew G. Knepley size_t len; 5239799db056SMatthew G. Knepley MPI_Comm comm; 5240799db056SMatthew G. Knepley PetscMPIInt rank, size, p, *counts, *displs; 5241783e2ec8SMatthew G. Knepley 5242783e2ec8SMatthew G. Knepley PetscFunctionBegin; 5243799db056SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject) dm, &comm)); 5244799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 5245799db056SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5246799db056SMatthew G. Knepley PetscCall(DMGetNumDS(dm, &Nds)); 5247799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5248799db056SMatthew G. Knepley PetscDS dsBC; 5249799db056SMatthew G. Knepley PetscInt numBd; 5250799db056SMatthew G. Knepley 5251799db056SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC)); 5252799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5253799db056SMatthew G. Knepley maxLabels += numBd; 5254799db056SMatthew G. Knepley } 5255799db056SMatthew G. Knepley PetscCall(PetscCalloc1(maxLabels, &labels)); 5256799db056SMatthew G. Knepley /* Get list of labels to be completed */ 5257799db056SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5258799db056SMatthew G. Knepley PetscDS dsBC; 5259799db056SMatthew G. Knepley PetscInt numBd, bd; 5260799db056SMatthew G. Knepley 5261799db056SMatthew G. Knepley PetscCall(DMGetRegionNumDS(dm, s, NULL, NULL, &dsBC)); 5262799db056SMatthew G. Knepley PetscCall(PetscDSGetNumBoundary(dsBC, &numBd)); 5263799db056SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5264799db056SMatthew G. Knepley DMLabel label; 5265799db056SMatthew G. Knepley PetscInt field; 5266799db056SMatthew G. Knepley PetscObject obj; 5267799db056SMatthew G. Knepley PetscClassId id; 5268799db056SMatthew G. Knepley 5269799db056SMatthew G. Knepley PetscCall(PetscDSGetBoundary(dsBC, bd, NULL, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 52709566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, field, NULL, &obj)); 52719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(obj, &id)); 5272799db056SMatthew G. Knepley if (!(id == PETSCFE_CLASSID) || !label) continue; 5273799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) if (labels[l] == label) break; 5274799db056SMatthew G. Knepley if (l == Nl) labels[Nl++] = label; 5275783e2ec8SMatthew G. Knepley } 5276799db056SMatthew G. Knepley } 5277799db056SMatthew G. Knepley /* Get label names */ 5278799db056SMatthew G. Knepley PetscCall(PetscMalloc1(Nl, &names)); 5279799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscObjectGetName((PetscObject) labels[l], &names[l])); 5280799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) {PetscCall(PetscStrlen(names[l], &len)); maxLen = PetscMax(maxLen, (PetscInt) len+2);} 5281799db056SMatthew G. Knepley PetscCall(PetscFree(labels)); 5282799db056SMatthew G. Knepley PetscCallMPI(MPI_Allreduce(&maxLen, &gmaxLen, 1, MPIU_INT, MPI_MAX, comm)); 5283799db056SMatthew G. Knepley PetscCall(PetscCalloc1(Nl * gmaxLen, &sendNames)); 5284799db056SMatthew G. Knepley for (l = 0; l < Nl; ++l) PetscCall(PetscStrcpy(&sendNames[gmaxLen*l], names[l])); 5285799db056SMatthew G. Knepley PetscCall(PetscFree(names)); 5286799db056SMatthew G. Knepley /* Put all names on all processes */ 5287799db056SMatthew G. Knepley PetscCall(PetscCalloc2(size, &counts, size+1, &displs)); 5288799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgather(&Nl, 1, MPI_INT, counts, 1, MPI_INT, comm)); 5289799db056SMatthew G. Knepley for (p = 0; p < size; ++p) displs[p+1] = displs[p] + counts[p]; 5290799db056SMatthew G. Knepley gNl = displs[size]; 5291799db056SMatthew G. Knepley for (p = 0; p < size; ++p) {counts[p] *= gmaxLen; displs[p] *= gmaxLen;} 5292799db056SMatthew G. Knepley PetscCall(PetscCalloc2(gNl * gmaxLen, &recvNames, gNl, &glabels)); 5293799db056SMatthew G. Knepley PetscCallMPI(MPI_Allgatherv(sendNames, counts[rank], MPI_CHAR, recvNames, counts, displs, MPI_CHAR, comm)); 5294799db056SMatthew G. Knepley PetscCall(PetscFree2(counts, displs)); 5295799db056SMatthew G. Knepley PetscCall(PetscFree(sendNames)); 5296799db056SMatthew G. Knepley for (l = 0, gl = 0; l < gNl; ++l) { 5297799db056SMatthew G. Knepley PetscCall(DMGetLabel(dm, &recvNames[l*gmaxLen], &glabels[gl])); 5298799db056SMatthew G. Knepley PetscCheck(glabels[gl], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Label %s missing on rank %d", &recvNames[l*gmaxLen], rank); 5299799db056SMatthew G. Knepley for (m = 0; m < gl; ++m) if (glabels[m] == glabels[gl]) continue; 53009566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 5301799db056SMatthew G. Knepley PetscCall(DMPlexLabelComplete(plex, glabels[gl])); 53029566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5303799db056SMatthew G. Knepley ++gl; 5304783e2ec8SMatthew G. Knepley } 5305799db056SMatthew G. Knepley PetscCall(PetscFree2(recvNames, glabels)); 5306783e2ec8SMatthew G. Knepley PetscFunctionReturn(0); 5307783e2ec8SMatthew G. Knepley } 5308783e2ec8SMatthew G. Knepley 5309e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew) 5310e5e52638SMatthew G. Knepley { 5311e5e52638SMatthew G. Knepley DMSpace *tmpd; 5312e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5313e5e52638SMatthew G. Knepley 5314e5e52638SMatthew G. Knepley PetscFunctionBegin; 5315e5e52638SMatthew G. Knepley if (Nds >= NdsNew) PetscFunctionReturn(0); 53169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(NdsNew, &tmpd)); 5317e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s]; 5318b3cf3223SMatthew G. Knepley for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;} 53199566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5320e5e52638SMatthew G. Knepley dm->Nds = NdsNew; 5321e5e52638SMatthew G. Knepley dm->probs = tmpd; 5322e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5323e5e52638SMatthew G. Knepley } 5324e5e52638SMatthew G. Knepley 5325e5e52638SMatthew G. Knepley /*@ 5326e5e52638SMatthew G. Knepley DMGetNumDS - Get the number of discrete systems in the DM 5327e5e52638SMatthew G. Knepley 5328e5e52638SMatthew G. Knepley Not collective 5329e5e52638SMatthew G. Knepley 5330e5e52638SMatthew G. Knepley Input Parameter: 5331e5e52638SMatthew G. Knepley . dm - The DM 5332e5e52638SMatthew G. Knepley 5333e5e52638SMatthew G. Knepley Output Parameter: 5334e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects 5335e5e52638SMatthew G. Knepley 5336e5e52638SMatthew G. Knepley Level: intermediate 5337e5e52638SMatthew G. Knepley 5338db781477SPatrick Sanan .seealso: `DMGetDS()`, `DMGetCellDS()` 5339e5e52638SMatthew G. Knepley @*/ 5340e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds) 5341e5e52638SMatthew G. Knepley { 5342e5e52638SMatthew G. Knepley PetscFunctionBegin; 5343e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5344534a8f05SLisandro Dalcin PetscValidIntPointer(Nds, 2); 5345e5e52638SMatthew G. Knepley *Nds = dm->Nds; 5346e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5347e5e52638SMatthew G. Knepley } 5348e5e52638SMatthew G. Knepley 5349e5e52638SMatthew G. Knepley /*@ 5350e5e52638SMatthew G. Knepley DMClearDS - Remove all discrete systems from the DM 5351e5e52638SMatthew G. Knepley 5352d083f849SBarry Smith Logically collective on dm 5353e5e52638SMatthew G. Knepley 5354e5e52638SMatthew G. Knepley Input Parameter: 5355e5e52638SMatthew G. Knepley . dm - The DM 5356e5e52638SMatthew G. Knepley 5357e5e52638SMatthew G. Knepley Level: intermediate 5358e5e52638SMatthew G. Knepley 5359db781477SPatrick Sanan .seealso: `DMGetNumDS()`, `DMGetDS()`, `DMSetField()` 5360e5e52638SMatthew G. Knepley @*/ 5361e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm) 5362e5e52638SMatthew G. Knepley { 5363e5e52638SMatthew G. Knepley PetscInt s; 5364e5e52638SMatthew G. Knepley 5365e5e52638SMatthew G. Knepley PetscFunctionBegin; 5366e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5367e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 53689566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 53699566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[s].label)); 53709566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[s].fields)); 5371e5e52638SMatthew G. Knepley } 53729566063dSJacob Faibussowitsch PetscCall(PetscFree(dm->probs)); 5373e5e52638SMatthew G. Knepley dm->probs = NULL; 5374e5e52638SMatthew G. Knepley dm->Nds = 0; 5375e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5376e5e52638SMatthew G. Knepley } 5377e5e52638SMatthew G. Knepley 5378e5e52638SMatthew G. Knepley /*@ 5379e5e52638SMatthew G. Knepley DMGetDS - Get the default PetscDS 5380e5e52638SMatthew G. Knepley 5381e5e52638SMatthew G. Knepley Not collective 5382e5e52638SMatthew G. Knepley 5383e5e52638SMatthew G. Knepley Input Parameter: 5384e5e52638SMatthew G. Knepley . dm - The DM 5385e5e52638SMatthew G. Knepley 5386e5e52638SMatthew G. Knepley Output Parameter: 5387e5e52638SMatthew G. Knepley . prob - The default PetscDS 5388e5e52638SMatthew G. Knepley 5389e5e52638SMatthew G. Knepley Level: intermediate 5390e5e52638SMatthew G. Knepley 5391db781477SPatrick Sanan .seealso: `DMGetCellDS()`, `DMGetRegionDS()` 5392e5e52638SMatthew G. Knepley @*/ 5393e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob) 5394e5e52638SMatthew G. Knepley { 5395e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5396e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5397e5e52638SMatthew G. Knepley PetscValidPointer(prob, 2); 5398b0143b4dSMatthew G. Knepley if (dm->Nds <= 0) { 5399b0143b4dSMatthew G. Knepley PetscDS ds; 5400b0143b4dSMatthew G. Knepley 54019566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 54029566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, NULL, NULL, ds)); 54039566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 5404b0143b4dSMatthew G. Knepley } 5405b0143b4dSMatthew G. Knepley *prob = dm->probs[0].ds; 5406e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5407e5e52638SMatthew G. Knepley } 5408e5e52638SMatthew G. Knepley 5409e5e52638SMatthew G. Knepley /*@ 5410e5e52638SMatthew G. Knepley DMGetCellDS - Get the PetscDS defined on a given cell 5411e5e52638SMatthew G. Knepley 5412e5e52638SMatthew G. Knepley Not collective 5413e5e52638SMatthew G. Knepley 5414e5e52638SMatthew G. Knepley Input Parameters: 5415e5e52638SMatthew G. Knepley + dm - The DM 5416e5e52638SMatthew G. Knepley - point - Cell for the DS 5417e5e52638SMatthew G. Knepley 5418e5e52638SMatthew G. Knepley Output Parameter: 5419e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell 5420e5e52638SMatthew G. Knepley 5421e5e52638SMatthew G. Knepley Level: developer 5422e5e52638SMatthew G. Knepley 5423db781477SPatrick Sanan .seealso: `DMGetDS()`, `DMSetRegionDS()` 5424e5e52638SMatthew G. Knepley @*/ 5425e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob) 5426e5e52638SMatthew G. Knepley { 5427e5e52638SMatthew G. Knepley PetscDS probDef = NULL; 5428e5e52638SMatthew G. Knepley PetscInt s; 5429e5e52638SMatthew G. Knepley 5430e5e52638SMatthew G. Knepley PetscFunctionBeginHot; 5431e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5432e5e52638SMatthew G. Knepley PetscValidPointer(prob, 3); 543363a3b9bcSJacob Faibussowitsch PetscCheck(point >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Mesh point cannot be negative: %" PetscInt_FMT, point); 5434e5e52638SMatthew G. Knepley *prob = NULL; 5435e5e52638SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5436e5e52638SMatthew G. Knepley PetscInt val; 5437e5e52638SMatthew G. Knepley 5438e5e52638SMatthew G. Knepley if (!dm->probs[s].label) {probDef = dm->probs[s].ds;} 5439e5e52638SMatthew G. Knepley else { 54409566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(dm->probs[s].label, point, &val)); 5441e5e52638SMatthew G. Knepley if (val >= 0) {*prob = dm->probs[s].ds; break;} 5442e5e52638SMatthew G. Knepley } 5443e5e52638SMatthew G. Knepley } 5444e5e52638SMatthew G. Knepley if (!*prob) *prob = probDef; 5445e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5446e5e52638SMatthew G. Knepley } 5447e5e52638SMatthew G. Knepley 5448e5e52638SMatthew G. Knepley /*@ 5449e5e52638SMatthew G. Knepley DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel 5450e5e52638SMatthew G. Knepley 5451e5e52638SMatthew G. Knepley Not collective 5452e5e52638SMatthew G. Knepley 5453e5e52638SMatthew G. Knepley Input Parameters: 5454e5e52638SMatthew G. Knepley + dm - The DM 5455e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh 5456e5e52638SMatthew G. Knepley 5457b3cf3223SMatthew G. Knepley Output Parameters: 5458b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5459b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL 5460e5e52638SMatthew G. Knepley 5461154ca461SJed Brown Note: 5462154ca461SJed Brown If a non-NULL label is given, but there is no PetscDS on that specific label, 5463154ca461SJed Brown the PetscDS for the full domain (if present) is returned. Returns with 5464154ca461SJed Brown fields=NULL and prob=NULL if there is no PetscDS for the full domain. 5465e5e52638SMatthew G. Knepley 5466e5e52638SMatthew G. Knepley Level: advanced 5467e5e52638SMatthew G. Knepley 5468db781477SPatrick Sanan .seealso: `DMGetRegionNumDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5469e5e52638SMatthew G. Knepley @*/ 5470b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds) 5471e5e52638SMatthew G. Knepley { 5472e5e52638SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5473e5e52638SMatthew G. Knepley 5474e5e52638SMatthew G. Knepley PetscFunctionBegin; 5475e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5476e5e52638SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5477b3cf3223SMatthew G. Knepley if (fields) {PetscValidPointer(fields, 3); *fields = NULL;} 5478b3cf3223SMatthew G. Knepley if (ds) {PetscValidPointer(ds, 4); *ds = NULL;} 5479e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5480154ca461SJed Brown if (dm->probs[s].label == label || !dm->probs[s].label) { 5481b3cf3223SMatthew G. Knepley if (fields) *fields = dm->probs[s].fields; 5482b3cf3223SMatthew G. Knepley if (ds) *ds = dm->probs[s].ds; 5483154ca461SJed Brown if (dm->probs[s].label) PetscFunctionReturn(0); 5484b3cf3223SMatthew G. Knepley } 5485e5e52638SMatthew G. Knepley } 54862df9ee95SMatthew G. Knepley PetscFunctionReturn(0); 5487e5e52638SMatthew G. Knepley } 5488e5e52638SMatthew G. Knepley 5489e5e52638SMatthew G. Knepley /*@ 5490bb7acecfSBarry Smith DMSetRegionDS - Set the `PetscDS` for a given mesh region, defined by a `DMLabel` 5491083401c6SMatthew G. Knepley 5492083401c6SMatthew G. Knepley Collective on dm 5493083401c6SMatthew G. Knepley 5494083401c6SMatthew G. Knepley Input Parameters: 5495bb7acecfSBarry Smith + dm - The `DM` 5496bb7acecfSBarry Smith . label - The `DMLabel` defining the mesh region, or NULL for the entire mesh 5497bb7acecfSBarry Smith . fields - The IS containing the `DM` field numbers for the fields in this `PetscDS`, or NULL for all fields 5498bb7acecfSBarry Smith - prob - The `PetscDS` defined on the given region 5499083401c6SMatthew G. Knepley 5500bb7acecfSBarry Smith Note: 5501bb7acecfSBarry 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, 5502083401c6SMatthew G. Knepley the fields argument is ignored. 5503083401c6SMatthew G. Knepley 5504083401c6SMatthew G. Knepley Level: advanced 5505083401c6SMatthew G. Knepley 5506db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionNumDS()`, `DMGetDS()`, `DMGetCellDS()` 5507083401c6SMatthew G. Knepley @*/ 5508083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds) 5509083401c6SMatthew G. Knepley { 5510083401c6SMatthew G. Knepley PetscInt Nds = dm->Nds, s; 5511083401c6SMatthew G. Knepley 5512083401c6SMatthew G. Knepley PetscFunctionBegin; 5513083401c6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5514083401c6SMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 5515064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 4); 5516083401c6SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 5517083401c6SMatthew G. Knepley if (dm->probs[s].label == label) { 55189566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[s].ds)); 5519083401c6SMatthew G. Knepley dm->probs[s].ds = ds; 5520083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5521083401c6SMatthew G. Knepley } 5522083401c6SMatthew G. Knepley } 55239566063dSJacob Faibussowitsch PetscCall(DMDSEnlarge_Static(dm, Nds+1)); 55249566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label)); 55259566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) fields)); 55269566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) ds)); 5527083401c6SMatthew G. Knepley if (!label) { 5528083401c6SMatthew G. Knepley /* Put the NULL label at the front, so it is returned as the default */ 5529083401c6SMatthew G. Knepley for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s]; 5530083401c6SMatthew G. Knepley Nds = 0; 5531083401c6SMatthew G. Knepley } 5532083401c6SMatthew G. Knepley dm->probs[Nds].label = label; 5533083401c6SMatthew G. Knepley dm->probs[Nds].fields = fields; 5534083401c6SMatthew G. Knepley dm->probs[Nds].ds = ds; 5535083401c6SMatthew G. Knepley PetscFunctionReturn(0); 5536083401c6SMatthew G. Knepley } 5537083401c6SMatthew G. Knepley 5538083401c6SMatthew G. Knepley /*@ 5539e5e52638SMatthew G. Knepley DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number 5540e5e52638SMatthew G. Knepley 5541e5e52638SMatthew G. Knepley Not collective 5542e5e52638SMatthew G. Knepley 5543e5e52638SMatthew G. Knepley Input Parameters: 5544e5e52638SMatthew G. Knepley + dm - The DM 5545e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds) 5546e5e52638SMatthew G. Knepley 5547e5e52638SMatthew G. Knepley Output Parameters: 5548b3cf3223SMatthew G. Knepley + label - The region label, or NULL 5549b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL 5550083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL 5551e5e52638SMatthew G. Knepley 5552e5e52638SMatthew G. Knepley Level: advanced 5553e5e52638SMatthew G. Knepley 5554db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5555e5e52638SMatthew G. Knepley @*/ 5556b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds) 5557e5e52638SMatthew G. Knepley { 5558e5e52638SMatthew G. Knepley PetscInt Nds; 5559e5e52638SMatthew G. Knepley 5560e5e52638SMatthew G. Knepley PetscFunctionBegin; 5561e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55629566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 556363a3b9bcSJacob 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); 5564e5e52638SMatthew G. Knepley if (label) { 5565e5e52638SMatthew G. Knepley PetscValidPointer(label, 3); 5566e5e52638SMatthew G. Knepley *label = dm->probs[num].label; 5567e5e52638SMatthew G. Knepley } 5568b3cf3223SMatthew G. Knepley if (fields) { 5569b3cf3223SMatthew G. Knepley PetscValidPointer(fields, 4); 5570b3cf3223SMatthew G. Knepley *fields = dm->probs[num].fields; 5571b3cf3223SMatthew G. Knepley } 5572e5e52638SMatthew G. Knepley if (ds) { 5573b3cf3223SMatthew G. Knepley PetscValidPointer(ds, 5); 5574e5e52638SMatthew G. Knepley *ds = dm->probs[num].ds; 5575e5e52638SMatthew G. Knepley } 5576e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5577e5e52638SMatthew G. Knepley } 5578e5e52638SMatthew G. Knepley 5579e5e52638SMatthew G. Knepley /*@ 5580083401c6SMatthew G. Knepley DMSetRegionNumDS - Set the PetscDS for a given mesh region, defined by the region number 5581e5e52638SMatthew G. Knepley 5582083401c6SMatthew G. Knepley Not collective 5583e5e52638SMatthew G. Knepley 5584e5e52638SMatthew G. Knepley Input Parameters: 5585e5e52638SMatthew G. Knepley + dm - The DM 5586083401c6SMatthew G. Knepley . num - The region number, in [0, Nds) 5587083401c6SMatthew G. Knepley . label - The region label, or NULL 5588083401c6SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL to prevent setting 5589083401c6SMatthew G. Knepley - ds - The PetscDS defined on the given region, or NULL to prevent setting 5590e5e52638SMatthew G. Knepley 5591e5e52638SMatthew G. Knepley Level: advanced 5592e5e52638SMatthew G. Knepley 5593db781477SPatrick Sanan .seealso: `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 5594e5e52638SMatthew G. Knepley @*/ 5595083401c6SMatthew G. Knepley PetscErrorCode DMSetRegionNumDS(DM dm, PetscInt num, DMLabel label, IS fields, PetscDS ds) 5596e5e52638SMatthew G. Knepley { 5597083401c6SMatthew G. Knepley PetscInt Nds; 5598e5e52638SMatthew G. Knepley 5599e5e52638SMatthew G. Knepley PetscFunctionBegin; 5600e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5601083401c6SMatthew G. Knepley if (label) {PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);} 56029566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 560363a3b9bcSJacob 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); 56049566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label)); 56059566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dm->probs[num].label)); 5606083401c6SMatthew G. Knepley dm->probs[num].label = label; 5607083401c6SMatthew G. Knepley if (fields) { 5608083401c6SMatthew G. Knepley PetscValidHeaderSpecific(fields, IS_CLASSID, 4); 56099566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) fields)); 56109566063dSJacob Faibussowitsch PetscCall(ISDestroy(&dm->probs[num].fields)); 5611083401c6SMatthew G. Knepley dm->probs[num].fields = fields; 5612e5e52638SMatthew G. Knepley } 5613083401c6SMatthew G. Knepley if (ds) { 5614083401c6SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 5); 56159566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) ds)); 56169566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dm->probs[num].ds)); 5617083401c6SMatthew G. Knepley dm->probs[num].ds = ds; 5618083401c6SMatthew G. Knepley } 5619e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5620e5e52638SMatthew G. Knepley } 5621e5e52638SMatthew G. Knepley 5622e5e52638SMatthew G. Knepley /*@ 56231d3af9e0SMatthew G. Knepley DMFindRegionNum - Find the region number for a given PetscDS, or -1 if it is not found. 56241d3af9e0SMatthew G. Knepley 56251d3af9e0SMatthew G. Knepley Not collective 56261d3af9e0SMatthew G. Knepley 56271d3af9e0SMatthew G. Knepley Input Parameters: 56281d3af9e0SMatthew G. Knepley + dm - The DM 56291d3af9e0SMatthew G. Knepley - ds - The PetscDS defined on the given region 56301d3af9e0SMatthew G. Knepley 56311d3af9e0SMatthew G. Knepley Output Parameter: 56321d3af9e0SMatthew G. Knepley . num - The region number, in [0, Nds), or -1 if not found 56331d3af9e0SMatthew G. Knepley 56341d3af9e0SMatthew G. Knepley Level: advanced 56351d3af9e0SMatthew G. Knepley 5636db781477SPatrick Sanan .seealso: `DMGetRegionNumDS()`, `DMGetRegionDS()`, `DMSetRegionDS()`, `DMGetDS()`, `DMGetCellDS()` 56371d3af9e0SMatthew G. Knepley @*/ 56381d3af9e0SMatthew G. Knepley PetscErrorCode DMFindRegionNum(DM dm, PetscDS ds, PetscInt *num) 56391d3af9e0SMatthew G. Knepley { 56401d3af9e0SMatthew G. Knepley PetscInt Nds, n; 56411d3af9e0SMatthew G. Knepley 56421d3af9e0SMatthew G. Knepley PetscFunctionBegin; 56431d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56441d3af9e0SMatthew G. Knepley PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 2); 5645dadcf809SJacob Faibussowitsch PetscValidIntPointer(num, 3); 56469566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 56471d3af9e0SMatthew G. Knepley for (n = 0; n < Nds; ++n) if (ds == dm->probs[n].ds) break; 56481d3af9e0SMatthew G. Knepley if (n >= Nds) *num = -1; 56491d3af9e0SMatthew G. Knepley else *num = n; 56501d3af9e0SMatthew G. Knepley PetscFunctionReturn(0); 56511d3af9e0SMatthew G. Knepley } 56521d3af9e0SMatthew G. Knepley 56532df84da0SMatthew G. Knepley /*@C 5654bb7acecfSBarry Smith DMCreateFEDefault - Create a `PetscFE` based on the celltype for the mesh 56552df84da0SMatthew G. Knepley 56562df84da0SMatthew G. Knepley Not collective 56572df84da0SMatthew G. Knepley 5658f1a722f8SMatthew G. Knepley Input Parameters: 5659bb7acecfSBarry Smith + dm - The `DM` 56602df84da0SMatthew G. Knepley . Nc - The number of components for the field 5661bb7acecfSBarry Smith . prefix - The options prefix for the output `PetscFE`, or NULL 5662bb7acecfSBarry Smith - qorder - The quadrature order or `PETSC_DETERMINE` to use `PetscSpace` polynomial degree 56632df84da0SMatthew G. Knepley 56642df84da0SMatthew G. Knepley Output Parameter: 5665bb7acecfSBarry Smith . fem - The `PetscFE` 56662df84da0SMatthew G. Knepley 5667bb7acecfSBarry Smith Note: 5668bb7acecfSBarry Smith This is a convenience method that just calls `PetscFECreateByCell()` underneath. 56692df84da0SMatthew G. Knepley 56702df84da0SMatthew G. Knepley Level: intermediate 56712df84da0SMatthew G. Knepley 5672db781477SPatrick Sanan .seealso: `PetscFECreateByCell()`, `DMAddField()`, `DMCreateDS()`, `DMGetCellDS()`, `DMGetRegionDS()` 56732df84da0SMatthew G. Knepley @*/ 56742df84da0SMatthew G. Knepley PetscErrorCode DMCreateFEDefault(DM dm, PetscInt Nc, const char prefix[], PetscInt qorder, PetscFE *fem) 56752df84da0SMatthew G. Knepley { 56762df84da0SMatthew G. Knepley DMPolytopeType ct; 56772df84da0SMatthew G. Knepley PetscInt dim, cStart; 56782df84da0SMatthew G. Knepley 56792df84da0SMatthew G. Knepley PetscFunctionBegin; 56802df84da0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56812df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 2); 56822df84da0SMatthew G. Knepley if (prefix) PetscValidCharPointer(prefix, 3); 56832df84da0SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, qorder, 4); 56842df84da0SMatthew G. Knepley PetscValidPointer(fem, 5); 56859566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 56869566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 56879566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 56889566063dSJacob Faibussowitsch PetscCall(PetscFECreateByCell(PETSC_COMM_SELF, dim, Nc, ct, prefix, qorder, fem)); 56892df84da0SMatthew G. Knepley PetscFunctionReturn(0); 56902df84da0SMatthew G. Knepley } 56912df84da0SMatthew G. Knepley 56921d3af9e0SMatthew G. Knepley /*@ 5693bb7acecfSBarry Smith DMCreateDS - Create the discrete systems for the `DM` based upon the fields added to the `DM` 5694e5e52638SMatthew G. Knepley 5695d083f849SBarry Smith Collective on dm 5696e5e52638SMatthew G. Knepley 5697e5e52638SMatthew G. Knepley Input Parameter: 5698bb7acecfSBarry Smith . dm - The `DM` 5699e5e52638SMatthew G. Knepley 570045480ffeSMatthew G. Knepley Options Database Keys: 5701bb7acecfSBarry Smith . -dm_petscds_view - View all the `PetscDS` objects in this `DM` 570245480ffeSMatthew G. Knepley 5703bb7acecfSBarry Smith Note: 5704bb7acecfSBarry Smith If the label has a `PetscDS` defined, it will be replaced. Otherwise, it will be added to the `DM`. 5705e5e52638SMatthew G. Knepley 5706e5e52638SMatthew G. Knepley Level: intermediate 5707e5e52638SMatthew G. Knepley 5708db781477SPatrick Sanan .seealso: `DMSetField`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 5709e5e52638SMatthew G. Knepley @*/ 5710e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm) 5711e5e52638SMatthew G. Knepley { 5712e5e52638SMatthew G. Knepley MPI_Comm comm; 5713083401c6SMatthew G. Knepley PetscDS dsDef; 5714083401c6SMatthew G. Knepley DMLabel *labelSet; 5715f9244615SMatthew G. Knepley PetscInt dE, Nf = dm->Nf, f, s, Nl, l, Ndef, k; 5716f9244615SMatthew G. Knepley PetscBool doSetup = PETSC_TRUE, flg; 5717e5e52638SMatthew G. Knepley 5718e5e52638SMatthew G. Knepley PetscFunctionBegin; 5719e5e52638SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5720e5e52638SMatthew G. Knepley if (!dm->fields) PetscFunctionReturn(0); 57219566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject) dm, &comm)); 57229566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dm, &dE)); 5723083401c6SMatthew G. Knepley /* Determine how many regions we have */ 57249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Nf, &labelSet)); 5725083401c6SMatthew G. Knepley Nl = 0; 5726083401c6SMatthew G. Knepley Ndef = 0; 5727083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5728083401c6SMatthew G. Knepley DMLabel label = dm->fields[f].label; 5729083401c6SMatthew G. Knepley PetscInt l; 5730083401c6SMatthew G. Knepley 5731f918ec44SMatthew G. Knepley #ifdef PETSC_HAVE_LIBCEED 5732f918ec44SMatthew G. Knepley /* Move CEED context to discretizations */ 5733f918ec44SMatthew G. Knepley { 5734f918ec44SMatthew G. Knepley PetscClassId id; 5735f918ec44SMatthew G. Knepley 57369566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(dm->fields[f].disc, &id)); 5737f918ec44SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 5738f918ec44SMatthew G. Knepley Ceed ceed; 5739f918ec44SMatthew G. Knepley 57409566063dSJacob Faibussowitsch PetscCall(DMGetCeed(dm, &ceed)); 57419566063dSJacob Faibussowitsch PetscCall(PetscFESetCeed((PetscFE) dm->fields[f].disc, ceed)); 5742f918ec44SMatthew G. Knepley } 5743f918ec44SMatthew G. Knepley } 5744f918ec44SMatthew G. Knepley #endif 5745083401c6SMatthew G. Knepley if (!label) {++Ndef; continue;} 5746083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) if (label == labelSet[l]) break; 5747083401c6SMatthew G. Knepley if (l < Nl) continue; 5748083401c6SMatthew G. Knepley labelSet[Nl++] = label; 5749083401c6SMatthew G. Knepley } 5750083401c6SMatthew G. Knepley /* Create default DS if there are no labels to intersect with */ 57519566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef)); 5752083401c6SMatthew G. Knepley if (!dsDef && Ndef && !Nl) { 5753b3cf3223SMatthew G. Knepley IS fields; 5754b3cf3223SMatthew G. Knepley PetscInt *fld, nf; 5755b3cf3223SMatthew G. Knepley 5756b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf; 57577a8be351SBarry Smith PetscCheck(nf,comm, PETSC_ERR_PLIB, "All fields have labels, but we are trying to create a default DS"); 57589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 5759b3cf3223SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f; 57609566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 57619566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_")); 57629566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 57639566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 576488f0c812SMatthew G. Knepley 57659566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 57669566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, NULL, fields, dsDef)); 57679566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 57689566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 57692df9ee95SMatthew G. Knepley } 57709566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(dm, NULL, NULL, &dsDef)); 57719566063dSJacob Faibussowitsch if (dsDef) PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 5772083401c6SMatthew G. Knepley /* Intersect labels with default fields */ 5773083401c6SMatthew G. Knepley if (Ndef && Nl) { 57740122748bSMatthew G. Knepley DM plex; 5775083401c6SMatthew G. Knepley DMLabel cellLabel; 5776083401c6SMatthew G. Knepley IS fieldIS, allcellIS, defcellIS = NULL; 5777083401c6SMatthew G. Knepley PetscInt *fields; 5778083401c6SMatthew G. Knepley const PetscInt *cells; 5779083401c6SMatthew G. Knepley PetscInt depth, nf = 0, n, c; 57800122748bSMatthew G. Knepley 57819566063dSJacob Faibussowitsch PetscCall(DMConvert(dm, DMPLEX, &plex)); 57829566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(plex, &depth)); 57839566063dSJacob Faibussowitsch PetscCall(DMGetStratumIS(plex, "dim", depth, &allcellIS)); 57849566063dSJacob Faibussowitsch if (!allcellIS) PetscCall(DMGetStratumIS(plex, "depth", depth, &allcellIS)); 57855fedec97SMatthew G. Knepley /* TODO This looks like it only works for one label */ 5786083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5787083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5788083401c6SMatthew G. Knepley IS pointIS; 5789083401c6SMatthew G. Knepley 57909566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 57919566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, 1, &pointIS)); 57929566063dSJacob Faibussowitsch PetscCall(ISDifference(allcellIS, pointIS, &defcellIS)); 57939566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointIS)); 5794083401c6SMatthew G. Knepley } 57959566063dSJacob Faibussowitsch PetscCall(ISDestroy(&allcellIS)); 5796083401c6SMatthew G. Knepley 57979566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "defaultCells", &cellLabel)); 57989566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(defcellIS, &n)); 57999566063dSJacob Faibussowitsch PetscCall(ISGetIndices(defcellIS, &cells)); 58009566063dSJacob Faibussowitsch for (c = 0; c < n; ++c) PetscCall(DMLabelSetValue(cellLabel, cells[c], 1)); 58019566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(defcellIS, &cells)); 58029566063dSJacob Faibussowitsch PetscCall(ISDestroy(&defcellIS)); 58039566063dSJacob Faibussowitsch PetscCall(DMPlexLabelComplete(plex, cellLabel)); 5804083401c6SMatthew G. Knepley 58059566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(Ndef, &fields)); 5806083401c6SMatthew G. Knepley for (f = 0; f < Nf; ++f) if (!dm->fields[f].label) fields[nf++] = f; 58079566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fieldIS)); 58089566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject) fieldIS, "dm_fields_")); 58099566063dSJacob Faibussowitsch PetscCall(ISSetType(fieldIS, ISGENERAL)); 58109566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fieldIS, nf, fields, PETSC_OWN_POINTER)); 5811083401c6SMatthew G. Knepley 58129566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &dsDef)); 58139566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, cellLabel, fieldIS, dsDef)); 58149566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsDef, dE)); 58159566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&cellLabel)); 58169566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsDef)); 58179566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fieldIS)); 58189566063dSJacob Faibussowitsch PetscCall(DMDestroy(&plex)); 5819083401c6SMatthew G. Knepley } 5820083401c6SMatthew G. Knepley /* Create label DSes 5821083401c6SMatthew G. Knepley - WE ONLY SUPPORT IDENTICAL OR DISJOINT LABELS 5822083401c6SMatthew G. Knepley */ 5823083401c6SMatthew G. Knepley /* TODO Should check that labels are disjoint */ 5824083401c6SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 5825083401c6SMatthew G. Knepley DMLabel label = labelSet[l]; 5826083401c6SMatthew G. Knepley PetscDS ds; 5827083401c6SMatthew G. Knepley IS fields; 5828083401c6SMatthew G. Knepley PetscInt *fld, nf; 5829083401c6SMatthew G. Knepley 58309566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PETSC_COMM_SELF, &ds)); 5831083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) ++nf; 58329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nf, &fld)); 5833083401c6SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) if (label == dm->fields[f].label || !dm->fields[f].label) fld[nf++] = f; 58349566063dSJacob Faibussowitsch PetscCall(ISCreate(PETSC_COMM_SELF, &fields)); 58359566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_")); 58369566063dSJacob Faibussowitsch PetscCall(ISSetType(fields, ISGENERAL)); 58379566063dSJacob Faibussowitsch PetscCall(ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER)); 58389566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, label, fields, ds)); 58399566063dSJacob Faibussowitsch PetscCall(ISDestroy(&fields)); 58409566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(ds, dE)); 5841083401c6SMatthew G. Knepley { 5842083401c6SMatthew G. Knepley DMPolytopeType ct; 5843083401c6SMatthew G. Knepley PetscInt lStart, lEnd; 58445fedec97SMatthew G. Knepley PetscBool isCohesiveLocal = PETSC_FALSE, isCohesive; 58450122748bSMatthew G. Knepley 58469566063dSJacob Faibussowitsch PetscCall(DMLabelGetBounds(label, &lStart, &lEnd)); 5847665f567fSMatthew G. Knepley if (lStart >= 0) { 58489566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, lStart, &ct)); 5849412e9a14SMatthew G. Knepley switch (ct) { 5850412e9a14SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 5851412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 5852412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 5853412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 58545fedec97SMatthew G. Knepley isCohesiveLocal = PETSC_TRUE;break; 5855083401c6SMatthew G. Knepley default: break; 5856412e9a14SMatthew G. Knepley } 5857665f567fSMatthew G. Knepley } 58589566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&isCohesiveLocal, &isCohesive, 1, MPIU_BOOL, MPI_LOR, comm)); 58595fedec97SMatthew G. Knepley for (f = 0, nf = 0; f < Nf; ++f) { 58605fedec97SMatthew G. Knepley if (label == dm->fields[f].label || !dm->fields[f].label) { 58615fedec97SMatthew G. Knepley if (label == dm->fields[f].label) { 58629566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, nf, NULL)); 58639566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(ds, nf, isCohesive)); 58645fedec97SMatthew G. Knepley } 58655fedec97SMatthew G. Knepley ++nf; 58665fedec97SMatthew G. Knepley } 58675fedec97SMatthew G. Knepley } 5868e5e52638SMatthew G. Knepley } 58699566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&ds)); 5870e5e52638SMatthew G. Knepley } 58719566063dSJacob Faibussowitsch PetscCall(PetscFree(labelSet)); 5872e5e52638SMatthew G. Knepley /* Set fields in DSes */ 5873083401c6SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 5874083401c6SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 5875083401c6SMatthew G. Knepley IS fields = dm->probs[s].fields; 5876083401c6SMatthew G. Knepley const PetscInt *fld; 58775fedec97SMatthew G. Knepley PetscInt nf, dsnf; 58785fedec97SMatthew G. Knepley PetscBool isCohesive; 5879e5e52638SMatthew G. Knepley 58809566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsnf)); 58819566063dSJacob Faibussowitsch PetscCall(PetscDSIsCohesive(ds, &isCohesive)); 58829566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(fields, &nf)); 58839566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fields, &fld)); 5884083401c6SMatthew G. Knepley for (f = 0; f < nf; ++f) { 5885083401c6SMatthew G. Knepley PetscObject disc = dm->fields[fld[f]].disc; 58865fedec97SMatthew G. Knepley PetscBool isCohesiveField; 5887e5e52638SMatthew G. Knepley PetscClassId id; 5888e5e52638SMatthew G. Knepley 58895fedec97SMatthew G. Knepley /* Handle DS with no fields */ 58909566063dSJacob Faibussowitsch if (dsnf) PetscCall(PetscDSGetCohesive(ds, f, &isCohesiveField)); 58915fedec97SMatthew G. Knepley /* If this is a cohesive cell, then regular fields need the lower dimensional discretization */ 58929566063dSJacob Faibussowitsch if (isCohesive && !isCohesiveField) PetscCall(PetscFEGetHeightSubspace((PetscFE) disc, 1, (PetscFE *) &disc)); 58939566063dSJacob Faibussowitsch PetscCall(PetscDSSetDiscretization(ds, f, disc)); 5894083401c6SMatthew G. Knepley /* We allow people to have placeholder fields and construct the Section by hand */ 58959566063dSJacob Faibussowitsch PetscCall(PetscObjectGetClassId(disc, &id)); 5896e5e52638SMatthew G. Knepley if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE; 5897e5e52638SMatthew G. Knepley } 58989566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fields, &fld)); 5899e5e52638SMatthew G. Knepley } 5900f9244615SMatthew G. Knepley /* Allow k-jet tabulation */ 59019566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) dm)->prefix, "-dm_ds_jet_degree", &k, &flg)); 5902f9244615SMatthew G. Knepley if (flg) { 59033b4aee56SMatthew G. Knepley for (s = 0; s < dm->Nds; ++s) { 59043b4aee56SMatthew G. Knepley PetscDS ds = dm->probs[s].ds; 59053b4aee56SMatthew G. Knepley PetscInt Nf, f; 59063b4aee56SMatthew G. Knepley 59079566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 59089566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSSetJetDegree(ds, f, k)); 59093b4aee56SMatthew G. Knepley } 5910f9244615SMatthew G. Knepley } 5911e5e52638SMatthew G. Knepley /* Setup DSes */ 5912e5e52638SMatthew G. Knepley if (doSetup) { 59139566063dSJacob Faibussowitsch for (s = 0; s < dm->Nds; ++s) PetscCall(PetscDSSetUp(dm->probs[s].ds)); 5914e5e52638SMatthew G. Knepley } 5915e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 5916e5e52638SMatthew G. Knepley } 5917e5e52638SMatthew G. Knepley 5918e5e52638SMatthew G. Knepley /*@ 5919bb7acecfSBarry Smith DMComputeExactSolution - Compute the exact solution for a given `DM`, using the `PetscDS` information. 59207f96f943SMatthew G. Knepley 5921bb7acecfSBarry Smith Collective on `DM` 5922f2cacb80SMatthew G. Knepley 59237f96f943SMatthew G. Knepley Input Parameters: 5924bb7acecfSBarry Smith + dm - The `DM` 59257f96f943SMatthew G. Knepley - time - The time 59267f96f943SMatthew G. Knepley 59277f96f943SMatthew G. Knepley Output Parameters: 5928f2cacb80SMatthew G. Knepley + u - The vector will be filled with exact solution values, or NULL 5929f2cacb80SMatthew G. Knepley - u_t - The vector will be filled with the time derivative of exact solution values, or NULL 59307f96f943SMatthew G. Knepley 5931bb7acecfSBarry Smith Note: 5932bb7acecfSBarry Smith The user must call `PetscDSSetExactSolution()` before using this routine 59337f96f943SMatthew G. Knepley 59347f96f943SMatthew G. Knepley Level: developer 59357f96f943SMatthew G. Knepley 5936db781477SPatrick Sanan .seealso: `PetscDSSetExactSolution()` 59377f96f943SMatthew G. Knepley @*/ 5938f2cacb80SMatthew G. Knepley PetscErrorCode DMComputeExactSolution(DM dm, PetscReal time, Vec u, Vec u_t) 59397f96f943SMatthew G. Knepley { 59407f96f943SMatthew G. Knepley PetscErrorCode (**exacts)(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 59417f96f943SMatthew G. Knepley void **ectxs; 59427f96f943SMatthew G. Knepley PetscInt Nf, Nds, s; 59437f96f943SMatthew G. Knepley 59447f96f943SMatthew G. Knepley PetscFunctionBegin; 5945f2cacb80SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5946f2cacb80SMatthew G. Knepley if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 3); 5947f2cacb80SMatthew G. Knepley if (u_t) PetscValidHeaderSpecific(u_t, VEC_CLASSID, 4); 59489566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 59499566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exacts, Nf, &ectxs)); 59509566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 59517f96f943SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 59527f96f943SMatthew G. Knepley PetscDS ds; 59537f96f943SMatthew G. Knepley DMLabel label; 59547f96f943SMatthew G. Knepley IS fieldIS; 59557f96f943SMatthew G. Knepley const PetscInt *fields, id = 1; 59567f96f943SMatthew G. Knepley PetscInt dsNf, f; 59577f96f943SMatthew G. Knepley 59589566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds)); 59599566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 59609566063dSJacob Faibussowitsch PetscCall(ISGetIndices(fieldIS, &fields)); 59619566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 59629566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 5963f2cacb80SMatthew G. Knepley if (u) { 59647f96f943SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 59657f96f943SMatthew G. Knepley const PetscInt field = fields[f]; 59669566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exacts[field], &ectxs[field])); 59677f96f943SMatthew G. Knepley } 59689566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 59697f96f943SMatthew G. Knepley if (label) { 59709566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u)); 59717f96f943SMatthew G. Knepley } else { 59729566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u)); 59737f96f943SMatthew G. Knepley } 59747f96f943SMatthew G. Knepley } 5975f2cacb80SMatthew G. Knepley if (u_t) { 59769566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(exacts, Nf)); 59779566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(ectxs, Nf)); 5978f2cacb80SMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 5979f2cacb80SMatthew G. Knepley const PetscInt field = fields[f]; 59809566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, field, &exacts[field], &ectxs[field])); 5981f2cacb80SMatthew G. Knepley } 59829566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(fieldIS, &fields)); 5983f2cacb80SMatthew G. Knepley if (label) { 59849566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabel(dm, time, label, 1, &id, 0, NULL, exacts, ectxs, INSERT_ALL_VALUES, u_t)); 5985f2cacb80SMatthew G. Knepley } else { 59869566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, time, exacts, ectxs, INSERT_ALL_VALUES, u_t)); 5987f2cacb80SMatthew G. Knepley } 5988f2cacb80SMatthew G. Knepley } 5989f2cacb80SMatthew G. Knepley } 5990f2cacb80SMatthew G. Knepley if (u) { 59919566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) u, "Exact Solution")); 59929566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject) u, "exact_")); 5993f2cacb80SMatthew G. Knepley } 5994f2cacb80SMatthew G. Knepley if (u_t) { 59959566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) u, "Exact Solution Time Derivative")); 59969566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject) u_t, "exact_t_")); 5997f2cacb80SMatthew G. Knepley } 59989566063dSJacob Faibussowitsch PetscCall(PetscFree2(exacts, ectxs)); 59997f96f943SMatthew G. Knepley PetscFunctionReturn(0); 60007f96f943SMatthew G. Knepley } 60017f96f943SMatthew G. Knepley 600245480ffeSMatthew G. Knepley PetscErrorCode DMTransferDS_Internal(DM dm, DMLabel label, IS fields, PetscDS ds) 600345480ffeSMatthew G. Knepley { 600445480ffeSMatthew G. Knepley PetscDS dsNew; 600545480ffeSMatthew G. Knepley DSBoundary b; 60066a02485aSMatthew G. Knepley PetscInt cdim, Nf, f, d; 60075fedec97SMatthew G. Knepley PetscBool isCohesive; 600845480ffeSMatthew G. Knepley void *ctx; 600945480ffeSMatthew G. Knepley 601045480ffeSMatthew G. Knepley PetscFunctionBegin; 60119566063dSJacob Faibussowitsch PetscCall(PetscDSCreate(PetscObjectComm((PetscObject) ds), &dsNew)); 60129566063dSJacob Faibussowitsch PetscCall(PetscDSCopyConstants(ds, dsNew)); 60139566063dSJacob Faibussowitsch PetscCall(PetscDSCopyExactSolutions(ds, dsNew)); 60149566063dSJacob Faibussowitsch PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew)); 60159566063dSJacob Faibussowitsch PetscCall(PetscDSCopyEquations(ds, dsNew)); 60169566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &Nf)); 601745480ffeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 60189566063dSJacob Faibussowitsch PetscCall(PetscDSGetContext(ds, f, &ctx)); 60199566063dSJacob Faibussowitsch PetscCall(PetscDSSetContext(dsNew, f, ctx)); 60209566063dSJacob Faibussowitsch PetscCall(PetscDSGetCohesive(ds, f, &isCohesive)); 60219566063dSJacob Faibussowitsch PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive)); 60226a02485aSMatthew G. Knepley PetscCall(PetscDSGetJetDegree(ds, f, &d)); 60236a02485aSMatthew G. Knepley PetscCall(PetscDSSetJetDegree(dsNew, f, d)); 602445480ffeSMatthew G. Knepley } 602545480ffeSMatthew G. Knepley if (Nf) { 60269566063dSJacob Faibussowitsch PetscCall(PetscDSGetCoordinateDimension(ds, &cdim)); 60279566063dSJacob Faibussowitsch PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim)); 602845480ffeSMatthew G. Knepley } 60299566063dSJacob Faibussowitsch PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew)); 603045480ffeSMatthew G. Knepley for (b = dsNew->boundary; b; b = b->next) { 60319566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, b->lname, &b->label)); 603245480ffeSMatthew G. Knepley /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */ 60337a8be351SBarry Smith //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name); 603445480ffeSMatthew G. Knepley } 603545480ffeSMatthew G. Knepley 60369566063dSJacob Faibussowitsch PetscCall(DMSetRegionDS(dm, label, fields, dsNew)); 60379566063dSJacob Faibussowitsch PetscCall(PetscDSDestroy(&dsNew)); 603845480ffeSMatthew G. Knepley PetscFunctionReturn(0); 603945480ffeSMatthew G. Knepley } 604045480ffeSMatthew G. Knepley 60417f96f943SMatthew G. Knepley /*@ 6042bb7acecfSBarry Smith DMCopyDS - Copy the discrete systems for the `DM` into another `DM` 6043e5e52638SMatthew G. Knepley 6044d083f849SBarry Smith Collective on dm 6045e5e52638SMatthew G. Knepley 6046e5e52638SMatthew G. Knepley Input Parameter: 6047bb7acecfSBarry Smith . dm - The `DM` 6048e5e52638SMatthew G. Knepley 6049e5e52638SMatthew G. Knepley Output Parameter: 6050bb7acecfSBarry Smith . newdm - The `DM` 6051e5e52638SMatthew G. Knepley 6052e5e52638SMatthew G. Knepley Level: advanced 6053e5e52638SMatthew G. Knepley 6054db781477SPatrick Sanan .seealso: `DMCopyFields()`, `DMAddField()`, `DMGetDS()`, `DMGetCellDS()`, `DMGetRegionDS()`, `DMSetRegionDS()` 6055e5e52638SMatthew G. Knepley @*/ 6056e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm) 6057e5e52638SMatthew G. Knepley { 6058e5e52638SMatthew G. Knepley PetscInt Nds, s; 6059e5e52638SMatthew G. Knepley 6060e5e52638SMatthew G. Knepley PetscFunctionBegin; 6061e5e52638SMatthew G. Knepley if (dm == newdm) PetscFunctionReturn(0); 60629566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 60639566063dSJacob Faibussowitsch PetscCall(DMClearDS(newdm)); 6064e5e52638SMatthew G. Knepley for (s = 0; s < Nds; ++s) { 6065e5e52638SMatthew G. Knepley DMLabel label; 6066b3cf3223SMatthew G. Knepley IS fields; 606745480ffeSMatthew G. Knepley PetscDS ds, newds; 6068783e2ec8SMatthew G. Knepley PetscInt Nbd, bd; 6069e5e52638SMatthew G. Knepley 60709566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fields, &ds)); 6071b8025e53SMatthew G. Knepley /* TODO: We need to change all keys from labels in the old DM to labels in the new DM */ 60729566063dSJacob Faibussowitsch PetscCall(DMTransferDS_Internal(newdm, label, fields, ds)); 607345480ffeSMatthew G. Knepley /* Commplete new labels in the new DS */ 60749566063dSJacob Faibussowitsch PetscCall(DMGetRegionDS(newdm, label, NULL, &newds)); 60759566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumBoundary(newds, &Nbd)); 6076783e2ec8SMatthew G. Knepley for (bd = 0; bd < Nbd; ++bd) { 6077b8025e53SMatthew G. Knepley PetscWeakForm wf; 607845480ffeSMatthew G. Knepley DMLabel label; 6079783e2ec8SMatthew G. Knepley PetscInt field; 6080783e2ec8SMatthew G. Knepley 60819566063dSJacob Faibussowitsch PetscCall(PetscDSGetBoundary(newds, bd, &wf, NULL, NULL, &label, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL)); 60829566063dSJacob Faibussowitsch PetscCall(PetscWeakFormReplaceLabel(wf, label)); 6083783e2ec8SMatthew G. Knepley } 6084e5e52638SMatthew G. Knepley } 6085799db056SMatthew G. Knepley PetscCall(DMCompleteBCLabels_Internal(newdm)); 6086e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6087e5e52638SMatthew G. Knepley } 6088e5e52638SMatthew G. Knepley 6089e5e52638SMatthew G. Knepley /*@ 6090bb7acecfSBarry Smith DMCopyDisc - Copy the fields and discrete systems for the `DM` into another `DM` 6091e5e52638SMatthew G. Knepley 6092d083f849SBarry Smith Collective on dm 6093e5e52638SMatthew G. Knepley 6094e5e52638SMatthew G. Knepley Input Parameter: 6095bb7acecfSBarry Smith . dm - The `DM` 6096e5e52638SMatthew G. Knepley 6097e5e52638SMatthew G. Knepley Output Parameter: 6098bb7acecfSBarry Smith . newdm - The `DM` 6099e5e52638SMatthew G. Knepley 6100e5e52638SMatthew G. Knepley Level: advanced 6101e5e52638SMatthew G. Knepley 6102bb7acecfSBarry Smith Developer Note: 6103bb7acecfSBarry Smith Really ugly name, nothing in PETSc is called a `Disc` plus it is an ugly abbreviation 6104bb7acecfSBarry Smith 6105db781477SPatrick Sanan .seealso: `DMCopyFields()`, `DMCopyDS()` 6106e5e52638SMatthew G. Knepley @*/ 6107e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm) 6108e5e52638SMatthew G. Knepley { 6109e5e52638SMatthew G. Knepley PetscFunctionBegin; 61109566063dSJacob Faibussowitsch PetscCall(DMCopyFields(dm, newdm)); 61119566063dSJacob Faibussowitsch PetscCall(DMCopyDS(dm, newdm)); 6112e5e52638SMatthew G. Knepley PetscFunctionReturn(0); 6113e5e52638SMatthew G. Knepley } 6114e5e52638SMatthew G. Knepley 6115c73cfb54SMatthew G. Knepley /*@ 6116bb7acecfSBarry Smith DMGetDimension - Return the topological dimension of the `DM` 6117c73cfb54SMatthew G. Knepley 6118c73cfb54SMatthew G. Knepley Not collective 6119c73cfb54SMatthew G. Knepley 6120c73cfb54SMatthew G. Knepley Input Parameter: 6121bb7acecfSBarry Smith . dm - The `DM` 6122c73cfb54SMatthew G. Knepley 6123c73cfb54SMatthew G. Knepley Output Parameter: 6124c73cfb54SMatthew G. Knepley . dim - The topological dimension 6125c73cfb54SMatthew G. Knepley 6126c73cfb54SMatthew G. Knepley Level: beginner 6127c73cfb54SMatthew G. Knepley 6128db781477SPatrick Sanan .seealso: `DMSetDimension()`, `DMCreate()` 6129c73cfb54SMatthew G. Knepley @*/ 6130c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim) 6131c73cfb54SMatthew G. Knepley { 6132c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6133c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6134534a8f05SLisandro Dalcin PetscValidIntPointer(dim, 2); 6135c73cfb54SMatthew G. Knepley *dim = dm->dim; 6136c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6137c73cfb54SMatthew G. Knepley } 6138c73cfb54SMatthew G. Knepley 6139c73cfb54SMatthew G. Knepley /*@ 6140bb7acecfSBarry Smith DMSetDimension - Set the topological dimension of the `DM` 6141c73cfb54SMatthew G. Knepley 6142c73cfb54SMatthew G. Knepley Collective on dm 6143c73cfb54SMatthew G. Knepley 6144c73cfb54SMatthew G. Knepley Input Parameters: 6145bb7acecfSBarry Smith + dm - The `DM` 6146c73cfb54SMatthew G. Knepley - dim - The topological dimension 6147c73cfb54SMatthew G. Knepley 6148c73cfb54SMatthew G. Knepley Level: beginner 6149c73cfb54SMatthew G. Knepley 6150db781477SPatrick Sanan .seealso: `DMGetDimension()`, `DMCreate()` 6151c73cfb54SMatthew G. Knepley @*/ 6152c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim) 6153c73cfb54SMatthew G. Knepley { 6154e5e52638SMatthew G. Knepley PetscDS ds; 615545480ffeSMatthew G. Knepley PetscInt Nds, n; 6156f17e8794SMatthew G. Knepley 6157c73cfb54SMatthew G. Knepley PetscFunctionBegin; 6158c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6159c73cfb54SMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, dim, 2); 6160c73cfb54SMatthew G. Knepley dm->dim = dim; 6161d17bd122SMatthew G. Knepley if (dm->dim >= 0) { 61629566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 616345480ffeSMatthew G. Knepley for (n = 0; n < Nds; ++n) { 61649566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, n, NULL, NULL, &ds)); 61659566063dSJacob Faibussowitsch if (ds->dimEmbed < 0) PetscCall(PetscDSSetCoordinateDimension(ds, dim)); 616645480ffeSMatthew G. Knepley } 6167d17bd122SMatthew G. Knepley } 6168c73cfb54SMatthew G. Knepley PetscFunctionReturn(0); 6169c73cfb54SMatthew G. Knepley } 6170c73cfb54SMatthew G. Knepley 6171793f3fe5SMatthew G. Knepley /*@ 6172793f3fe5SMatthew G. Knepley DMGetDimPoints - Get the half-open interval for all points of a given dimension 6173793f3fe5SMatthew G. Knepley 6174d083f849SBarry Smith Collective on dm 6175793f3fe5SMatthew G. Knepley 6176793f3fe5SMatthew G. Knepley Input Parameters: 6177bb7acecfSBarry Smith + dm - the `DM` 6178793f3fe5SMatthew G. Knepley - dim - the dimension 6179793f3fe5SMatthew G. Knepley 6180793f3fe5SMatthew G. Knepley Output Parameters: 6181793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension 6182aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension 6183793f3fe5SMatthew G. Knepley 6184793f3fe5SMatthew G. Knepley Note: 6185793f3fe5SMatthew G. Knepley The points are vertices in the Hasse diagram encoding the topology. This is explained in 6186a8d69d7bSBarry Smith https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme, 6187793f3fe5SMatthew G. Knepley then the interval is empty. 6188793f3fe5SMatthew G. Knepley 6189793f3fe5SMatthew G. Knepley Level: intermediate 6190793f3fe5SMatthew G. Knepley 6191db781477SPatrick Sanan .seealso: `DMPLEX`, `DMPlexGetDepthStratum()`, `DMPlexGetHeightStratum()` 6192793f3fe5SMatthew G. Knepley @*/ 6193793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd) 6194793f3fe5SMatthew G. Knepley { 6195793f3fe5SMatthew G. Knepley PetscInt d; 6196793f3fe5SMatthew G. Knepley 6197793f3fe5SMatthew G. Knepley PetscFunctionBegin; 6198793f3fe5SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 61999566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &d)); 62007a8be351SBarry Smith PetscCheck((dim >= 0) && (dim <= d),PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %" PetscInt_FMT, dim); 6201*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm,getdimpoints , dim, pStart, pEnd); 6202793f3fe5SMatthew G. Knepley PetscFunctionReturn(0); 6203793f3fe5SMatthew G. Knepley } 6204793f3fe5SMatthew G. Knepley 62056636e97aSMatthew G Knepley /*@ 6206bb7acecfSBarry Smith DMGetOutputDM - Retrieve the `DM` associated with the layout for output 6207f4d763aaSMatthew G. Knepley 62088f700142SStefano Zampini Collective on dm 62098f700142SStefano Zampini 6210f4d763aaSMatthew G. Knepley Input Parameter: 6211bb7acecfSBarry Smith . dm - The original `DM` 6212f4d763aaSMatthew G. Knepley 6213f4d763aaSMatthew G. Knepley Output Parameter: 6214bb7acecfSBarry Smith . odm - The `DM` which provides the layout for output 6215f4d763aaSMatthew G. Knepley 6216f4d763aaSMatthew G. Knepley Level: intermediate 6217f4d763aaSMatthew G. Knepley 6218bb7acecfSBarry Smith Note: 6219bb7acecfSBarry Smith In some situations the vector obtained with `DMCreateGlobalVector()` excludes points for degrees of freedom that are associated with fixed (Dirichelet) boundary 6220bb7acecfSBarry 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 6221bb7acecfSBarry Smith locations for those dof so that they can be output to a file or other viewer along with the unconstrained dof. 6222bb7acecfSBarry Smith 6223bb7acecfSBarry Smith .seealso: `VecView()`, `DMGetGlobalSection()`, `DMCreateGlobalVector()`, `PetscSectionHasConstraints()`, `DMSetGlobalSection()` 6224f4d763aaSMatthew G. Knepley @*/ 622514f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm) 622614f150ffSMatthew G. Knepley { 6227c26acbdeSMatthew G. Knepley PetscSection section; 62282d4e4a49SMatthew G. Knepley PetscBool hasConstraints, ghasConstraints; 622914f150ffSMatthew G. Knepley 623014f150ffSMatthew G. Knepley PetscFunctionBegin; 623114f150ffSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 623214f150ffSMatthew G. Knepley PetscValidPointer(odm,2); 62339566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, §ion)); 62349566063dSJacob Faibussowitsch PetscCall(PetscSectionHasConstraints(section, &hasConstraints)); 62359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm))); 62362d4e4a49SMatthew G. Knepley if (!ghasConstraints) { 6237c26acbdeSMatthew G. Knepley *odm = dm; 6238c26acbdeSMatthew G. Knepley PetscFunctionReturn(0); 6239c26acbdeSMatthew G. Knepley } 624014f150ffSMatthew G. Knepley if (!dm->dmBC) { 6241c26acbdeSMatthew G. Knepley PetscSection newSection, gsection; 624214f150ffSMatthew G. Knepley PetscSF sf; 624314f150ffSMatthew G. Knepley 62449566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &dm->dmBC)); 62459566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, dm->dmBC)); 62469566063dSJacob Faibussowitsch PetscCall(PetscSectionClone(section, &newSection)); 62479566063dSJacob Faibussowitsch PetscCall(DMSetLocalSection(dm->dmBC, newSection)); 62489566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&newSection)); 62499566063dSJacob Faibussowitsch PetscCall(DMGetPointSF(dm->dmBC, &sf)); 62509566063dSJacob Faibussowitsch PetscCall(PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection)); 62519566063dSJacob Faibussowitsch PetscCall(DMSetGlobalSection(dm->dmBC, gsection)); 62529566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&gsection)); 625314f150ffSMatthew G. Knepley } 625414f150ffSMatthew G. Knepley *odm = dm->dmBC; 625514f150ffSMatthew G. Knepley PetscFunctionReturn(0); 625614f150ffSMatthew G. Knepley } 6257f4d763aaSMatthew G. Knepley 6258f4d763aaSMatthew G. Knepley /*@ 6259cdb7a50dSMatthew G. Knepley DMGetOutputSequenceNumber - Retrieve the sequence number/value for output 6260f4d763aaSMatthew G. Knepley 6261f4d763aaSMatthew G. Knepley Input Parameter: 6262bb7acecfSBarry Smith . dm - The original `DM` 6263f4d763aaSMatthew G. Knepley 6264cdb7a50dSMatthew G. Knepley Output Parameters: 6265cdb7a50dSMatthew G. Knepley + num - The output sequence number 6266cdb7a50dSMatthew G. Knepley - val - The output sequence value 6267f4d763aaSMatthew G. Knepley 6268f4d763aaSMatthew G. Knepley Level: intermediate 6269f4d763aaSMatthew G. Knepley 6270bb7acecfSBarry Smith Note: 6271bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6272bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6273bb7acecfSBarry Smith 6274bb7acecfSBarry Smith Developer Note: 6275bb7acecfSBarry Smith The `DM` serves as a convenient place to store the current iteration value. The iteration is not 6276bb7acecfSBarry Smith not directly related to the `DM`. 6277f4d763aaSMatthew G. Knepley 6278db781477SPatrick Sanan .seealso: `VecView()` 6279f4d763aaSMatthew G. Knepley @*/ 6280cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val) 6281f4d763aaSMatthew G. Knepley { 6282f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6283f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6284534a8f05SLisandro Dalcin if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;} 6285534a8f05SLisandro Dalcin if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;} 6286f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 6287f4d763aaSMatthew G. Knepley } 6288f4d763aaSMatthew G. Knepley 6289f4d763aaSMatthew G. Knepley /*@ 6290cdb7a50dSMatthew G. Knepley DMSetOutputSequenceNumber - Set the sequence number/value for output 6291f4d763aaSMatthew G. Knepley 6292f4d763aaSMatthew G. Knepley Input Parameters: 6293bb7acecfSBarry Smith + dm - The original `DM` 6294cdb7a50dSMatthew G. Knepley . num - The output sequence number 6295cdb7a50dSMatthew G. Knepley - val - The output sequence value 6296f4d763aaSMatthew G. Knepley 6297f4d763aaSMatthew G. Knepley Level: intermediate 6298f4d763aaSMatthew G. Knepley 6299bb7acecfSBarry Smith Note: 6300bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6301bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6302f4d763aaSMatthew G. Knepley 6303db781477SPatrick Sanan .seealso: `VecView()` 6304f4d763aaSMatthew G. Knepley @*/ 6305cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val) 6306f4d763aaSMatthew G. Knepley { 6307f4d763aaSMatthew G. Knepley PetscFunctionBegin; 6308f4d763aaSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6309f4d763aaSMatthew G. Knepley dm->outputSequenceNum = num; 6310cdb7a50dSMatthew G. Knepley dm->outputSequenceVal = val; 6311cdb7a50dSMatthew G. Knepley PetscFunctionReturn(0); 6312cdb7a50dSMatthew G. Knepley } 6313cdb7a50dSMatthew G. Knepley 6314cdb7a50dSMatthew G. Knepley /*@C 6315bb7acecfSBarry Smith DMOutputSequenceLoad - Retrieve the sequence value from a `PetscViewer` 6316cdb7a50dSMatthew G. Knepley 6317cdb7a50dSMatthew G. Knepley Input Parameters: 6318bb7acecfSBarry Smith + dm - The original `DM` 6319cdb7a50dSMatthew G. Knepley . name - The sequence name 6320cdb7a50dSMatthew G. Knepley - num - The output sequence number 6321cdb7a50dSMatthew G. Knepley 6322cdb7a50dSMatthew G. Knepley Output Parameter: 6323cdb7a50dSMatthew G. Knepley . val - The output sequence value 6324cdb7a50dSMatthew G. Knepley 6325cdb7a50dSMatthew G. Knepley Level: intermediate 6326cdb7a50dSMatthew G. Knepley 6327bb7acecfSBarry Smith Note: 6328bb7acecfSBarry Smith This is intended for output that should appear in sequence, for instance 6329bb7acecfSBarry Smith a set of timesteps in an `PETSCVIEWERHDF5` file, or a set of realizations of a stochastic system. 6330bb7acecfSBarry Smith 6331bb7acecfSBarry Smith Developer Note: 6332bb7acecfSBarry Smith It is unclear at the user API level why a `DM` is needed as input 6333cdb7a50dSMatthew G. Knepley 6334db781477SPatrick Sanan .seealso: `DMGetOutputSequenceNumber()`, `DMSetOutputSequenceNumber()`, `VecView()` 6335cdb7a50dSMatthew G. Knepley @*/ 6336cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val) 6337cdb7a50dSMatthew G. Knepley { 6338cdb7a50dSMatthew G. Knepley PetscBool ishdf5; 6339cdb7a50dSMatthew G. Knepley 6340cdb7a50dSMatthew G. Knepley PetscFunctionBegin; 6341cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 6342cdb7a50dSMatthew G. Knepley PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 6343064a246eSJacob Faibussowitsch PetscValidRealPointer(val,5); 63449566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5)); 6345cdb7a50dSMatthew G. Knepley if (ishdf5) { 6346cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6347cdb7a50dSMatthew G. Knepley PetscScalar value; 6348cdb7a50dSMatthew G. Knepley 63499566063dSJacob Faibussowitsch PetscCall(DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer)); 63504aeb217fSMatthew G. Knepley *val = PetscRealPart(value); 6351cdb7a50dSMatthew G. Knepley #endif 6352cdb7a50dSMatthew G. Knepley } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()"); 6353f4d763aaSMatthew G. Knepley PetscFunctionReturn(0); 6354f4d763aaSMatthew G. Knepley } 63558e4ac7eaSMatthew G. Knepley 63568e4ac7eaSMatthew G. Knepley /*@ 6357bb7acecfSBarry Smith DMGetUseNatural - Get the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 63588e4ac7eaSMatthew G. Knepley 63598e4ac7eaSMatthew G. Knepley Not collective 63608e4ac7eaSMatthew G. Knepley 63618e4ac7eaSMatthew G. Knepley Input Parameter: 6362bb7acecfSBarry Smith . dm - The `DM` 63638e4ac7eaSMatthew G. Knepley 63648e4ac7eaSMatthew G. Knepley Output Parameter: 6365bb7acecfSBarry Smith . useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 63668e4ac7eaSMatthew G. Knepley 63678e4ac7eaSMatthew G. Knepley Level: beginner 63688e4ac7eaSMatthew G. Knepley 6369db781477SPatrick Sanan .seealso: `DMSetUseNatural()`, `DMCreate()` 63708e4ac7eaSMatthew G. Knepley @*/ 63718e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural) 63728e4ac7eaSMatthew G. Knepley { 63738e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 63748e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6375534a8f05SLisandro Dalcin PetscValidBoolPointer(useNatural, 2); 63768e4ac7eaSMatthew G. Knepley *useNatural = dm->useNatural; 63778e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 63788e4ac7eaSMatthew G. Knepley } 63798e4ac7eaSMatthew G. Knepley 63808e4ac7eaSMatthew G. Knepley /*@ 6381bb7acecfSBarry Smith DMSetUseNatural - Set the flag for creating a mapping to the natural order when a `DM` is (re)distributed in parallel 63828e4ac7eaSMatthew G. Knepley 63838e4ac7eaSMatthew G. Knepley Collective on dm 63848e4ac7eaSMatthew G. Knepley 63858e4ac7eaSMatthew G. Knepley Input Parameters: 6386bb7acecfSBarry Smith + dm - The `DM` 6387bb7acecfSBarry Smith - useNatural - `PETSC_TRUE` to build the mapping to a natural order during distribution 63888e4ac7eaSMatthew G. Knepley 6389bb7acecfSBarry Smith Note: 6390bb7acecfSBarry Smith This also causes the map to be build after `DMCreateSubDM()` and `DMCreateSuperDM()` 63915d3b26e6SMatthew G. Knepley 63928e4ac7eaSMatthew G. Knepley Level: beginner 63938e4ac7eaSMatthew G. Knepley 6394db781477SPatrick Sanan .seealso: `DMGetUseNatural()`, `DMCreate()`, `DMPlexDistribute()`, `DMCreateSubDM()`, `DMCreateSuperDM()` 63958e4ac7eaSMatthew G. Knepley @*/ 63968e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural) 63978e4ac7eaSMatthew G. Knepley { 63988e4ac7eaSMatthew G. Knepley PetscFunctionBegin; 63998e4ac7eaSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 64008833efb5SBlaise Bourdin PetscValidLogicalCollectiveBool(dm, useNatural, 2); 64018e4ac7eaSMatthew G. Knepley dm->useNatural = useNatural; 64028e4ac7eaSMatthew G. Knepley PetscFunctionReturn(0); 64038e4ac7eaSMatthew G. Knepley } 6404c58f1c22SToby Isaac 6405c58f1c22SToby Isaac /*@C 6406bb7acecfSBarry Smith DMCreateLabel - Create a label of the given name if it does not already exist in the `DM` 6407c58f1c22SToby Isaac 6408c58f1c22SToby Isaac Not Collective 6409c58f1c22SToby Isaac 6410c58f1c22SToby Isaac Input Parameters: 6411bb7acecfSBarry Smith + dm - The `DM` object 6412c58f1c22SToby Isaac - name - The label name 6413c58f1c22SToby Isaac 6414c58f1c22SToby Isaac Level: intermediate 6415c58f1c22SToby Isaac 6416db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6417c58f1c22SToby Isaac @*/ 6418c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[]) 6419c58f1c22SToby Isaac { 64205d80c0bfSVaclav Hapla PetscBool flg; 64215d80c0bfSVaclav Hapla DMLabel label; 6422c58f1c22SToby Isaac 6423c58f1c22SToby Isaac PetscFunctionBegin; 6424c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6425c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 64269566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 6427c58f1c22SToby Isaac if (!flg) { 64289566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 64299566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 64309566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 6431c58f1c22SToby Isaac } 6432c58f1c22SToby Isaac PetscFunctionReturn(0); 6433c58f1c22SToby Isaac } 6434c58f1c22SToby Isaac 6435c58f1c22SToby Isaac /*@C 6436bb7acecfSBarry 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. 64370fdc7489SMatthew Knepley 64380fdc7489SMatthew Knepley Not Collective 64390fdc7489SMatthew Knepley 64400fdc7489SMatthew Knepley Input Parameters: 6441bb7acecfSBarry Smith + dm - The `DM` object 64420fdc7489SMatthew Knepley . l - The index for the label 64430fdc7489SMatthew Knepley - name - The label name 64440fdc7489SMatthew Knepley 64450fdc7489SMatthew Knepley Level: intermediate 64460fdc7489SMatthew Knepley 6447db781477SPatrick Sanan .seealso: `DMCreateLabel()`, `DMLabelCreate()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 64480fdc7489SMatthew Knepley @*/ 64490fdc7489SMatthew Knepley PetscErrorCode DMCreateLabelAtIndex(DM dm, PetscInt l, const char name[]) 64500fdc7489SMatthew Knepley { 64510fdc7489SMatthew Knepley DMLabelLink orig, prev = NULL; 64520fdc7489SMatthew Knepley DMLabel label; 64530fdc7489SMatthew Knepley PetscInt Nl, m; 64540fdc7489SMatthew Knepley PetscBool flg, match; 64550fdc7489SMatthew Knepley const char *lname; 64560fdc7489SMatthew Knepley 64570fdc7489SMatthew Knepley PetscFunctionBegin; 64580fdc7489SMatthew Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6459064a246eSJacob Faibussowitsch PetscValidCharPointer(name, 3); 64609566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, name, &flg)); 64610fdc7489SMatthew Knepley if (!flg) { 64629566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, &label)); 64639566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dm, label)); 64649566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 64650fdc7489SMatthew Knepley } 64669566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 646763a3b9bcSJacob Faibussowitsch PetscCheck(l < Nl,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label index %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", l, Nl); 64680fdc7489SMatthew Knepley for (m = 0, orig = dm->labels; m < Nl; ++m, prev = orig, orig = orig->next) { 64699566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) orig->label, &lname)); 64709566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &match)); 64710fdc7489SMatthew Knepley if (match) break; 64720fdc7489SMatthew Knepley } 64730fdc7489SMatthew Knepley if (m == l) PetscFunctionReturn(0); 64740fdc7489SMatthew Knepley if (!m) dm->labels = orig->next; 64750fdc7489SMatthew Knepley else prev->next = orig->next; 64760fdc7489SMatthew Knepley if (!l) { 64770fdc7489SMatthew Knepley orig->next = dm->labels; 64780fdc7489SMatthew Knepley dm->labels = orig; 64790fdc7489SMatthew Knepley } else { 64800fdc7489SMatthew Knepley for (m = 0, prev = dm->labels; m < l-1; ++m, prev = prev->next); 64810fdc7489SMatthew Knepley orig->next = prev->next; 64820fdc7489SMatthew Knepley prev->next = orig; 64830fdc7489SMatthew Knepley } 64840fdc7489SMatthew Knepley PetscFunctionReturn(0); 64850fdc7489SMatthew Knepley } 64860fdc7489SMatthew Knepley 64870fdc7489SMatthew Knepley /*@C 6488bb7acecfSBarry Smith DMGetLabelValue - Get the value in a `DMLabel` for the given point, with -1 as the default 6489c58f1c22SToby Isaac 6490c58f1c22SToby Isaac Not Collective 6491c58f1c22SToby Isaac 6492c58f1c22SToby Isaac Input Parameters: 6493bb7acecfSBarry Smith + dm - The `DM` object 6494c58f1c22SToby Isaac . name - The label name 6495c58f1c22SToby Isaac - point - The mesh point 6496c58f1c22SToby Isaac 6497c58f1c22SToby Isaac Output Parameter: 6498c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label 6499c58f1c22SToby Isaac 6500c58f1c22SToby Isaac Level: beginner 6501c58f1c22SToby Isaac 6502db781477SPatrick Sanan .seealso: `DMLabelGetValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6503c58f1c22SToby Isaac @*/ 6504c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value) 6505c58f1c22SToby Isaac { 6506c58f1c22SToby Isaac DMLabel label; 6507c58f1c22SToby Isaac 6508c58f1c22SToby Isaac PetscFunctionBegin; 6509c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6510c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 65119566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 65127a8be351SBarry Smith PetscCheck(label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name); 65139566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, point, value)); 6514c58f1c22SToby Isaac PetscFunctionReturn(0); 6515c58f1c22SToby Isaac } 6516c58f1c22SToby Isaac 6517c58f1c22SToby Isaac /*@C 6518bb7acecfSBarry Smith DMSetLabelValue - Add a point to a `DMLabel` with given value 6519c58f1c22SToby Isaac 6520c58f1c22SToby Isaac Not Collective 6521c58f1c22SToby Isaac 6522c58f1c22SToby Isaac Input Parameters: 6523bb7acecfSBarry Smith + dm - The `DM` object 6524c58f1c22SToby Isaac . name - The label name 6525c58f1c22SToby Isaac . point - The mesh point 6526c58f1c22SToby Isaac - value - The label value for this point 6527c58f1c22SToby Isaac 6528c58f1c22SToby Isaac Output Parameter: 6529c58f1c22SToby Isaac 6530c58f1c22SToby Isaac Level: beginner 6531c58f1c22SToby Isaac 6532db781477SPatrick Sanan .seealso: `DMLabelSetValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6533c58f1c22SToby Isaac @*/ 6534c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6535c58f1c22SToby Isaac { 6536c58f1c22SToby Isaac DMLabel label; 6537c58f1c22SToby Isaac 6538c58f1c22SToby Isaac PetscFunctionBegin; 6539c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6540c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 65419566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6542c58f1c22SToby Isaac if (!label) { 65439566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 65449566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6545c58f1c22SToby Isaac } 65469566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, point, value)); 6547c58f1c22SToby Isaac PetscFunctionReturn(0); 6548c58f1c22SToby Isaac } 6549c58f1c22SToby Isaac 6550c58f1c22SToby Isaac /*@C 6551bb7acecfSBarry Smith DMClearLabelValue - Remove a point from a `DMLabel` with given value 6552c58f1c22SToby Isaac 6553c58f1c22SToby Isaac Not Collective 6554c58f1c22SToby Isaac 6555c58f1c22SToby Isaac Input Parameters: 6556bb7acecfSBarry Smith + dm - The `DM` object 6557c58f1c22SToby Isaac . name - The label name 6558c58f1c22SToby Isaac . point - The mesh point 6559c58f1c22SToby Isaac - value - The label value for this point 6560c58f1c22SToby Isaac 6561c58f1c22SToby Isaac Level: beginner 6562c58f1c22SToby Isaac 6563db781477SPatrick Sanan .seealso: `DMLabelClearValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6564c58f1c22SToby Isaac @*/ 6565c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value) 6566c58f1c22SToby Isaac { 6567c58f1c22SToby Isaac DMLabel label; 6568c58f1c22SToby Isaac 6569c58f1c22SToby Isaac PetscFunctionBegin; 6570c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6571c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 65729566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6573c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 65749566063dSJacob Faibussowitsch PetscCall(DMLabelClearValue(label, point, value)); 6575c58f1c22SToby Isaac PetscFunctionReturn(0); 6576c58f1c22SToby Isaac } 6577c58f1c22SToby Isaac 6578c58f1c22SToby Isaac /*@C 6579bb7acecfSBarry Smith DMGetLabelSize - Get the value of `DMLabelGetNumValues()` of a `DMLabel` in the `DM` 6580c58f1c22SToby Isaac 6581c58f1c22SToby Isaac Not Collective 6582c58f1c22SToby Isaac 6583c58f1c22SToby Isaac Input Parameters: 6584bb7acecfSBarry Smith + dm - The `DM` object 6585c58f1c22SToby Isaac - name - The label name 6586c58f1c22SToby Isaac 6587c58f1c22SToby Isaac Output Parameter: 6588c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist 6589c58f1c22SToby Isaac 6590c58f1c22SToby Isaac Level: beginner 6591c58f1c22SToby Isaac 6592bb7acecfSBarry Smith Developer Note: 6593bb7acecfSBarry Smith This should be renamed to something like `DMGetLabelNumValues()` or removed. 6594bb7acecfSBarry Smith 6595bb7acecfSBarry Smith .seealso: `DMLabelGetNumValues()`, `DMSetLabelValue()`, `DMGetLabel()` 6596c58f1c22SToby Isaac @*/ 6597c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size) 6598c58f1c22SToby Isaac { 6599c58f1c22SToby Isaac DMLabel label; 6600c58f1c22SToby Isaac 6601c58f1c22SToby Isaac PetscFunctionBegin; 6602c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6603c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6604534a8f05SLisandro Dalcin PetscValidIntPointer(size, 3); 66059566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6606c58f1c22SToby Isaac *size = 0; 6607c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 66089566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, size)); 6609c58f1c22SToby Isaac PetscFunctionReturn(0); 6610c58f1c22SToby Isaac } 6611c58f1c22SToby Isaac 6612c58f1c22SToby Isaac /*@C 6613bb7acecfSBarry Smith DMGetLabelIdIS - Get the `DMLabelGetValueIS()` from a `DMLabel` in the `DM` 6614c58f1c22SToby Isaac 6615c58f1c22SToby Isaac Not Collective 6616c58f1c22SToby Isaac 6617c58f1c22SToby Isaac Input Parameters: 6618bb7acecfSBarry Smith + mesh - The `DM` object 6619c58f1c22SToby Isaac - name - The label name 6620c58f1c22SToby Isaac 6621c58f1c22SToby Isaac Output Parameter: 6622c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist 6623c58f1c22SToby Isaac 6624c58f1c22SToby Isaac Level: beginner 6625c58f1c22SToby Isaac 6626db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMGetLabelSize()` 6627c58f1c22SToby Isaac @*/ 6628c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids) 6629c58f1c22SToby Isaac { 6630c58f1c22SToby Isaac DMLabel label; 6631c58f1c22SToby Isaac 6632c58f1c22SToby Isaac PetscFunctionBegin; 6633c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6634c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6635c58f1c22SToby Isaac PetscValidPointer(ids, 3); 66369566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6637c58f1c22SToby Isaac *ids = NULL; 6638dab2e251SBlaise Bourdin if (label) { 66399566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, ids)); 6640dab2e251SBlaise Bourdin } else { 6641dab2e251SBlaise Bourdin /* returning an empty IS */ 66429566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids)); 6643dab2e251SBlaise Bourdin } 6644c58f1c22SToby Isaac PetscFunctionReturn(0); 6645c58f1c22SToby Isaac } 6646c58f1c22SToby Isaac 6647c58f1c22SToby Isaac /*@C 6648c58f1c22SToby Isaac DMGetStratumSize - Get the number of points in a label stratum 6649c58f1c22SToby Isaac 6650c58f1c22SToby Isaac Not Collective 6651c58f1c22SToby Isaac 6652c58f1c22SToby Isaac Input Parameters: 6653bb7acecfSBarry Smith + dm - The `DM` object 6654c58f1c22SToby Isaac . name - The label name 6655c58f1c22SToby Isaac - value - The stratum value 6656c58f1c22SToby Isaac 6657c58f1c22SToby Isaac Output Parameter: 6658bb7acecfSBarry Smith . size - The number of points, also called the stratum size 6659c58f1c22SToby Isaac 6660c58f1c22SToby Isaac Level: beginner 6661c58f1c22SToby Isaac 6662db781477SPatrick Sanan .seealso: `DMLabelGetStratumSize()`, `DMGetLabelSize()`, `DMGetLabelIds()` 6663c58f1c22SToby Isaac @*/ 6664c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size) 6665c58f1c22SToby Isaac { 6666c58f1c22SToby Isaac DMLabel label; 6667c58f1c22SToby Isaac 6668c58f1c22SToby Isaac PetscFunctionBegin; 6669c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6670c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6671534a8f05SLisandro Dalcin PetscValidIntPointer(size, 4); 66729566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6673c58f1c22SToby Isaac *size = 0; 6674c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 66759566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, value, size)); 6676c58f1c22SToby Isaac PetscFunctionReturn(0); 6677c58f1c22SToby Isaac } 6678c58f1c22SToby Isaac 6679c58f1c22SToby Isaac /*@C 6680c58f1c22SToby Isaac DMGetStratumIS - Get the points in a label stratum 6681c58f1c22SToby Isaac 6682c58f1c22SToby Isaac Not Collective 6683c58f1c22SToby Isaac 6684c58f1c22SToby Isaac Input Parameters: 6685bb7acecfSBarry Smith + dm - The `DM` object 6686c58f1c22SToby Isaac . name - The label name 6687c58f1c22SToby Isaac - value - The stratum value 6688c58f1c22SToby Isaac 6689c58f1c22SToby Isaac Output Parameter: 6690c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value 6691c58f1c22SToby Isaac 6692c58f1c22SToby Isaac Level: beginner 6693c58f1c22SToby Isaac 6694db781477SPatrick Sanan .seealso: `DMLabelGetStratumIS()`, `DMGetStratumSize()` 6695c58f1c22SToby Isaac @*/ 6696c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points) 6697c58f1c22SToby Isaac { 6698c58f1c22SToby Isaac DMLabel label; 6699c58f1c22SToby Isaac 6700c58f1c22SToby Isaac PetscFunctionBegin; 6701c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6702c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6703c58f1c22SToby Isaac PetscValidPointer(points, 4); 67049566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6705c58f1c22SToby Isaac *points = NULL; 6706c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 67079566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, value, points)); 6708c58f1c22SToby Isaac PetscFunctionReturn(0); 6709c58f1c22SToby Isaac } 6710c58f1c22SToby Isaac 67114de306b1SToby Isaac /*@C 67129044fa66SMatthew G. Knepley DMSetStratumIS - Set the points in a label stratum 67134de306b1SToby Isaac 67144de306b1SToby Isaac Not Collective 67154de306b1SToby Isaac 67164de306b1SToby Isaac Input Parameters: 6717bb7acecfSBarry Smith + dm - The `DM` object 67184de306b1SToby Isaac . name - The label name 67194de306b1SToby Isaac . value - The stratum value 67204de306b1SToby Isaac - points - The stratum points 67214de306b1SToby Isaac 67224de306b1SToby Isaac Level: beginner 67234de306b1SToby Isaac 6724bb7acecfSBarry Smith .seealso: `DMLabel`, `DMClearLabelStratum()`, `DMLabelClearStratum()`, `DMLabelSetStratumIS()`, `DMGetStratumSize()` 67254de306b1SToby Isaac @*/ 67264de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points) 67274de306b1SToby Isaac { 67284de306b1SToby Isaac DMLabel label; 67294de306b1SToby Isaac 67304de306b1SToby Isaac PetscFunctionBegin; 67314de306b1SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 67324de306b1SToby Isaac PetscValidCharPointer(name, 2); 67334de306b1SToby Isaac PetscValidPointer(points, 4); 67349566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 67354de306b1SToby Isaac if (!label) PetscFunctionReturn(0); 67369566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, points)); 67374de306b1SToby Isaac PetscFunctionReturn(0); 67384de306b1SToby Isaac } 67394de306b1SToby Isaac 6740c58f1c22SToby Isaac /*@C 6741bb7acecfSBarry Smith DMClearLabelStratum - Remove all points from a stratum from a `DMLabel` 6742c58f1c22SToby Isaac 6743c58f1c22SToby Isaac Not Collective 6744c58f1c22SToby Isaac 6745c58f1c22SToby Isaac Input Parameters: 6746bb7acecfSBarry Smith + dm - The `DM` object 6747c58f1c22SToby Isaac . name - The label name 6748c58f1c22SToby Isaac - value - The label value for this point 6749c58f1c22SToby Isaac 6750c58f1c22SToby Isaac Output Parameter: 6751c58f1c22SToby Isaac 6752c58f1c22SToby Isaac Level: beginner 6753c58f1c22SToby Isaac 6754bb7acecfSBarry Smith .seealso: `DMLabel`, `DMLabelClearStratum()`, `DMSetLabelValue()`, `DMGetStratumIS()`, `DMClearLabelValue()` 6755c58f1c22SToby Isaac @*/ 6756c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value) 6757c58f1c22SToby Isaac { 6758c58f1c22SToby Isaac DMLabel label; 6759c58f1c22SToby Isaac 6760c58f1c22SToby Isaac PetscFunctionBegin; 6761c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6762c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 67639566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, &label)); 6764c58f1c22SToby Isaac if (!label) PetscFunctionReturn(0); 67659566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 6766c58f1c22SToby Isaac PetscFunctionReturn(0); 6767c58f1c22SToby Isaac } 6768c58f1c22SToby Isaac 6769c58f1c22SToby Isaac /*@ 6770bb7acecfSBarry Smith DMGetNumLabels - Return the number of labels defined by on the `DM` 6771c58f1c22SToby Isaac 6772c58f1c22SToby Isaac Not Collective 6773c58f1c22SToby Isaac 6774c58f1c22SToby Isaac Input Parameter: 6775bb7acecfSBarry Smith . dm - The `DM` object 6776c58f1c22SToby Isaac 6777c58f1c22SToby Isaac Output Parameter: 6778c58f1c22SToby Isaac . numLabels - the number of Labels 6779c58f1c22SToby Isaac 6780c58f1c22SToby Isaac Level: intermediate 6781c58f1c22SToby Isaac 6782bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabelByNum()`, `DMGetLabelName()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6783c58f1c22SToby Isaac @*/ 6784c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels) 6785c58f1c22SToby Isaac { 67865d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6787c58f1c22SToby Isaac PetscInt n = 0; 6788c58f1c22SToby Isaac 6789c58f1c22SToby Isaac PetscFunctionBegin; 6790c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6791534a8f05SLisandro Dalcin PetscValidIntPointer(numLabels, 2); 6792c58f1c22SToby Isaac while (next) {++n; next = next->next;} 6793c58f1c22SToby Isaac *numLabels = n; 6794c58f1c22SToby Isaac PetscFunctionReturn(0); 6795c58f1c22SToby Isaac } 6796c58f1c22SToby Isaac 6797c58f1c22SToby Isaac /*@C 6798c58f1c22SToby Isaac DMGetLabelName - Return the name of nth label 6799c58f1c22SToby Isaac 6800c58f1c22SToby Isaac Not Collective 6801c58f1c22SToby Isaac 6802c58f1c22SToby Isaac Input Parameters: 6803bb7acecfSBarry Smith + dm - The `DM` object 6804c58f1c22SToby Isaac - n - the label number 6805c58f1c22SToby Isaac 6806c58f1c22SToby Isaac Output Parameter: 6807c58f1c22SToby Isaac . name - the label name 6808c58f1c22SToby Isaac 6809c58f1c22SToby Isaac Level: intermediate 6810c58f1c22SToby Isaac 6811bb7acecfSBarry Smith Developer Note: 6812bb7acecfSBarry Smith Some of the functions that appropriate on labels using their number have the suffix ByNum, others do not. 6813bb7acecfSBarry Smith 6814bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabelByNum()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6815c58f1c22SToby Isaac @*/ 6816c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name) 6817c58f1c22SToby Isaac { 68185d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6819c58f1c22SToby Isaac PetscInt l = 0; 6820c58f1c22SToby Isaac 6821c58f1c22SToby Isaac PetscFunctionBegin; 6822c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6823c58f1c22SToby Isaac PetscValidPointer(name, 3); 6824c58f1c22SToby Isaac while (next) { 6825c58f1c22SToby Isaac if (l == n) { 68269566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) next->label, name)); 6827c58f1c22SToby Isaac PetscFunctionReturn(0); 6828c58f1c22SToby Isaac } 6829c58f1c22SToby Isaac ++l; 6830c58f1c22SToby Isaac next = next->next; 6831c58f1c22SToby Isaac } 683263a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 6833c58f1c22SToby Isaac } 6834c58f1c22SToby Isaac 6835c58f1c22SToby Isaac /*@C 6836bb7acecfSBarry Smith DMHasLabel - Determine whether the `DM` has a label of a given name 6837c58f1c22SToby Isaac 6838c58f1c22SToby Isaac Not Collective 6839c58f1c22SToby Isaac 6840c58f1c22SToby Isaac Input Parameters: 6841bb7acecfSBarry Smith + dm - The `DM` object 6842c58f1c22SToby Isaac - name - The label name 6843c58f1c22SToby Isaac 6844c58f1c22SToby Isaac Output Parameter: 6845bb7acecfSBarry Smith . hasLabel - `PETSC_TRUE` if the label is present 6846c58f1c22SToby Isaac 6847c58f1c22SToby Isaac Level: intermediate 6848c58f1c22SToby Isaac 6849bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetLabel()`, `DMGetLabelByNum()`, `DMCreateLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6850c58f1c22SToby Isaac @*/ 6851c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel) 6852c58f1c22SToby Isaac { 68535d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6854d67d17b1SMatthew G. Knepley const char *lname; 6855c58f1c22SToby Isaac 6856c58f1c22SToby Isaac PetscFunctionBegin; 6857c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6858c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6859534a8f05SLisandro Dalcin PetscValidBoolPointer(hasLabel, 3); 6860c58f1c22SToby Isaac *hasLabel = PETSC_FALSE; 6861c58f1c22SToby Isaac while (next) { 68629566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) next->label, &lname)); 68639566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, hasLabel)); 6864c58f1c22SToby Isaac if (*hasLabel) break; 6865c58f1c22SToby Isaac next = next->next; 6866c58f1c22SToby Isaac } 6867c58f1c22SToby Isaac PetscFunctionReturn(0); 6868c58f1c22SToby Isaac } 6869c58f1c22SToby Isaac 6870c58f1c22SToby Isaac /*@C 6871bb7acecfSBarry Smith DMGetLabel - Return the label of a given name, or NULL, from a `DM` 6872c58f1c22SToby Isaac 6873c58f1c22SToby Isaac Not Collective 6874c58f1c22SToby Isaac 6875c58f1c22SToby Isaac Input Parameters: 6876bb7acecfSBarry Smith + dm - The `DM` object 6877c58f1c22SToby Isaac - name - The label name 6878c58f1c22SToby Isaac 6879c58f1c22SToby Isaac Output Parameter: 6880bb7acecfSBarry Smith . label - The `DMLabel`, or NULL if the label is absent 6881c58f1c22SToby Isaac 6882bb7acecfSBarry Smith Default labels in a `DMPLEX`: 6883bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 6884bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 6885bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 6886bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 6887bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 6888bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 68896d7c9049SMatthew G. Knepley 6890c58f1c22SToby Isaac Level: intermediate 6891c58f1c22SToby Isaac 6892bb7acecfSBarry Smith .seealso: `DMLabel`, `DMHasLabel()`, `DMGetLabelByNum()`, `DMAddLabel()`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 6893c58f1c22SToby Isaac @*/ 6894c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label) 6895c58f1c22SToby Isaac { 68965d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6897c58f1c22SToby Isaac PetscBool hasLabel; 6898d67d17b1SMatthew G. Knepley const char *lname; 6899c58f1c22SToby Isaac 6900c58f1c22SToby Isaac PetscFunctionBegin; 6901c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6902c58f1c22SToby Isaac PetscValidCharPointer(name, 2); 6903c58f1c22SToby Isaac PetscValidPointer(label, 3); 6904c58f1c22SToby Isaac *label = NULL; 6905c58f1c22SToby Isaac while (next) { 69069566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) next->label, &lname)); 69079566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 6908c58f1c22SToby Isaac if (hasLabel) { 6909c58f1c22SToby Isaac *label = next->label; 6910c58f1c22SToby Isaac break; 6911c58f1c22SToby Isaac } 6912c58f1c22SToby Isaac next = next->next; 6913c58f1c22SToby Isaac } 6914c58f1c22SToby Isaac PetscFunctionReturn(0); 6915c58f1c22SToby Isaac } 6916c58f1c22SToby Isaac 6917c58f1c22SToby Isaac /*@C 6918bb7acecfSBarry Smith DMGetLabelByNum - Return the nth label on a `DM` 6919c58f1c22SToby Isaac 6920c58f1c22SToby Isaac Not Collective 6921c58f1c22SToby Isaac 6922c58f1c22SToby Isaac Input Parameters: 6923bb7acecfSBarry Smith + dm - The `DM` object 6924c58f1c22SToby Isaac - n - the label number 6925c58f1c22SToby Isaac 6926c58f1c22SToby Isaac Output Parameter: 6927c58f1c22SToby Isaac . label - the label 6928c58f1c22SToby Isaac 6929c58f1c22SToby Isaac Level: intermediate 6930c58f1c22SToby Isaac 6931bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6932c58f1c22SToby Isaac @*/ 6933c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label) 6934c58f1c22SToby Isaac { 69355d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 6936c58f1c22SToby Isaac PetscInt l = 0; 6937c58f1c22SToby Isaac 6938c58f1c22SToby Isaac PetscFunctionBegin; 6939c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6940c58f1c22SToby Isaac PetscValidPointer(label, 3); 6941c58f1c22SToby Isaac while (next) { 6942c58f1c22SToby Isaac if (l == n) { 6943c58f1c22SToby Isaac *label = next->label; 6944c58f1c22SToby Isaac PetscFunctionReturn(0); 6945c58f1c22SToby Isaac } 6946c58f1c22SToby Isaac ++l; 6947c58f1c22SToby Isaac next = next->next; 6948c58f1c22SToby Isaac } 694963a3b9bcSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %" PetscInt_FMT " does not exist in this DM", n); 6950c58f1c22SToby Isaac } 6951c58f1c22SToby Isaac 6952c58f1c22SToby Isaac /*@C 6953bb7acecfSBarry Smith DMAddLabel - Add the label to this `DM` 6954c58f1c22SToby Isaac 6955c58f1c22SToby Isaac Not Collective 6956c58f1c22SToby Isaac 6957c58f1c22SToby Isaac Input Parameters: 6958bb7acecfSBarry Smith + dm - The `DM` object 6959bb7acecfSBarry Smith - label - The `DMLabel` 6960c58f1c22SToby Isaac 6961c58f1c22SToby Isaac Level: developer 6962c58f1c22SToby Isaac 6963bb7acecfSBarry Smith .seealso: `DMLabel`, `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 6964c58f1c22SToby Isaac @*/ 6965c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label) 6966c58f1c22SToby Isaac { 69675d80c0bfSVaclav Hapla DMLabelLink l, *p, tmpLabel; 6968c58f1c22SToby Isaac PetscBool hasLabel; 6969d67d17b1SMatthew G. Knepley const char *lname; 69705d80c0bfSVaclav Hapla PetscBool flg; 6971c58f1c22SToby Isaac 6972c58f1c22SToby Isaac PetscFunctionBegin; 6973c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &lname)); 69759566063dSJacob Faibussowitsch PetscCall(DMHasLabel(dm, lname, &hasLabel)); 69767a8be351SBarry Smith PetscCheck(!hasLabel,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname); 69779566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(1, &tmpLabel)); 6978c58f1c22SToby Isaac tmpLabel->label = label; 6979c58f1c22SToby Isaac tmpLabel->output = PETSC_TRUE; 69805d80c0bfSVaclav Hapla for (p=&dm->labels; (l=*p); p=&l->next) {} 69815d80c0bfSVaclav Hapla *p = tmpLabel; 69829566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 69839566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 69845d80c0bfSVaclav Hapla if (flg) dm->depthLabel = label; 69859566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 6986ba2698f1SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 6987c58f1c22SToby Isaac PetscFunctionReturn(0); 6988c58f1c22SToby Isaac } 6989c58f1c22SToby Isaac 6990c58f1c22SToby Isaac /*@C 69914a7ee7d0SMatthew G. Knepley DMSetLabel - Replaces the label of a given name, or ignores it if the name is not present 69924a7ee7d0SMatthew G. Knepley 69934a7ee7d0SMatthew G. Knepley Not Collective 69944a7ee7d0SMatthew G. Knepley 69954a7ee7d0SMatthew G. Knepley Input Parameters: 6996bb7acecfSBarry Smith + dm - The `DM` object 6997bb7acecfSBarry Smith - label - The `DMLabel`, having the same name, to substitute 69984a7ee7d0SMatthew G. Knepley 6999bb7acecfSBarry Smith Default labels in a `DMPLEX`: 7000bb7acecfSBarry Smith + "depth" - Holds the depth (co-dimension) of each mesh point 7001bb7acecfSBarry Smith . "celltype" - Holds the topological type of each cell 7002bb7acecfSBarry Smith . "ghost" - If the DM is distributed with overlap, this marks the cells and faces in the overlap 7003bb7acecfSBarry Smith . "Cell Sets" - Mirrors the cell sets defined by GMsh and ExodusII 7004bb7acecfSBarry Smith . "Face Sets" - Mirrors the face sets defined by GMsh and ExodusII 7005bb7acecfSBarry Smith - "Vertex Sets" - Mirrors the vertex sets defined by GMsh 70064a7ee7d0SMatthew G. Knepley 70074a7ee7d0SMatthew G. Knepley Level: intermediate 70084a7ee7d0SMatthew G. Knepley 7009bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMPlexGetDepthLabel()`, `DMPlexGetCellType()` 70104a7ee7d0SMatthew G. Knepley @*/ 70114a7ee7d0SMatthew G. Knepley PetscErrorCode DMSetLabel(DM dm, DMLabel label) 70124a7ee7d0SMatthew G. Knepley { 70134a7ee7d0SMatthew G. Knepley DMLabelLink next = dm->labels; 70144a7ee7d0SMatthew G. Knepley PetscBool hasLabel, flg; 70154a7ee7d0SMatthew G. Knepley const char *name, *lname; 70164a7ee7d0SMatthew G. Knepley 70174a7ee7d0SMatthew G. Knepley PetscFunctionBegin; 70184a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70194a7ee7d0SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 70209566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &name)); 70214a7ee7d0SMatthew G. Knepley while (next) { 70229566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) next->label, &lname)); 70239566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 70244a7ee7d0SMatthew G. Knepley if (hasLabel) { 70259566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label)); 70269566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "depth", &flg)); 70274a7ee7d0SMatthew G. Knepley if (flg) dm->depthLabel = label; 70289566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lname, "celltype", &flg)); 70294a7ee7d0SMatthew G. Knepley if (flg) dm->celltypeLabel = label; 70309566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&next->label)); 70314a7ee7d0SMatthew G. Knepley next->label = label; 70324a7ee7d0SMatthew G. Knepley break; 70334a7ee7d0SMatthew G. Knepley } 70344a7ee7d0SMatthew G. Knepley next = next->next; 70354a7ee7d0SMatthew G. Knepley } 70364a7ee7d0SMatthew G. Knepley PetscFunctionReturn(0); 70374a7ee7d0SMatthew G. Knepley } 70384a7ee7d0SMatthew G. Knepley 70394a7ee7d0SMatthew G. Knepley /*@C 7040bb7acecfSBarry Smith DMRemoveLabel - Remove the label given by name from this `DM` 7041c58f1c22SToby Isaac 7042c58f1c22SToby Isaac Not Collective 7043c58f1c22SToby Isaac 7044c58f1c22SToby Isaac Input Parameters: 7045bb7acecfSBarry Smith + dm - The `DM` object 7046c58f1c22SToby Isaac - name - The label name 7047c58f1c22SToby Isaac 7048c58f1c22SToby Isaac Output Parameter: 7049bb7acecfSBarry Smith . label - The `DMLabel`, or NULL if the label is absent. Pass in NULL to call `DMLabelDestroy()` on the label, otherwise the 7050bb7acecfSBarry Smith caller is responsible for calling `DMLabelDestroy()`. 7051c58f1c22SToby Isaac 7052c58f1c22SToby Isaac Level: developer 7053c58f1c22SToby Isaac 7054bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabelBySelf()` 7055c58f1c22SToby Isaac @*/ 7056c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label) 7057c58f1c22SToby Isaac { 705895d578d6SVaclav Hapla DMLabelLink link, *pnext; 7059c58f1c22SToby Isaac PetscBool hasLabel; 7060d67d17b1SMatthew G. Knepley const char *lname; 7061c58f1c22SToby Isaac 7062c58f1c22SToby Isaac PetscFunctionBegin; 7063c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7064e5472504SVaclav Hapla PetscValidCharPointer(name, 2); 7065e5472504SVaclav Hapla if (label) { 7066e5472504SVaclav Hapla PetscValidPointer(label, 3); 7067c58f1c22SToby Isaac *label = NULL; 7068e5472504SVaclav Hapla } 70695d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 70709566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) link->label, &lname)); 70719566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &hasLabel)); 7072c58f1c22SToby Isaac if (hasLabel) { 707395d578d6SVaclav Hapla *pnext = link->next; /* Remove from list */ 70749566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &hasLabel)); 707595d578d6SVaclav Hapla if (hasLabel) dm->depthLabel = NULL; 70769566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &hasLabel)); 7077ba2698f1SMatthew G. Knepley if (hasLabel) dm->celltypeLabel = NULL; 707895d578d6SVaclav Hapla if (label) *label = link->label; 70799566063dSJacob Faibussowitsch else PetscCall(DMLabelDestroy(&link->label)); 70809566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7081c58f1c22SToby Isaac break; 7082c58f1c22SToby Isaac } 7083c58f1c22SToby Isaac } 7084c58f1c22SToby Isaac PetscFunctionReturn(0); 7085c58f1c22SToby Isaac } 7086c58f1c22SToby Isaac 7087306894acSVaclav Hapla /*@ 7088bb7acecfSBarry Smith DMRemoveLabelBySelf - Remove the label from this `DM` 7089306894acSVaclav Hapla 7090306894acSVaclav Hapla Not Collective 7091306894acSVaclav Hapla 7092306894acSVaclav Hapla Input Parameters: 7093bb7acecfSBarry Smith + dm - The `DM` object 7094bb7acecfSBarry Smith . label - The `DMLabel` to be removed from the `DM` 7095306894acSVaclav Hapla - failNotFound - Should it fail if the label is not found in the DM? 7096306894acSVaclav Hapla 7097306894acSVaclav Hapla Level: developer 7098306894acSVaclav Hapla 7099bb7acecfSBarry Smith Note: 7100306894acSVaclav Hapla Only exactly the same instance is removed if found, name match is ignored. 7101bb7acecfSBarry Smith If the `DM` has an exclusive reference to the label, the label gets destroyed and 7102306894acSVaclav Hapla *label nullified. 7103306894acSVaclav Hapla 7104bb7acecfSBarry Smith .seealso: `DMLabel`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabel()` `DMGetLabelValue()`, `DMSetLabelValue()`, `DMLabelDestroy()`, `DMRemoveLabel()` 7105306894acSVaclav Hapla @*/ 7106306894acSVaclav Hapla PetscErrorCode DMRemoveLabelBySelf(DM dm, DMLabel *label, PetscBool failNotFound) 7107306894acSVaclav Hapla { 710843e45a93SVaclav Hapla DMLabelLink link, *pnext; 7109306894acSVaclav Hapla PetscBool hasLabel = PETSC_FALSE; 7110306894acSVaclav Hapla 7111306894acSVaclav Hapla PetscFunctionBegin; 7112306894acSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7113306894acSVaclav Hapla PetscValidPointer(label, 2); 7114f39a9ae0SVaclav Hapla if (!*label && !failNotFound) PetscFunctionReturn(0); 7115306894acSVaclav Hapla PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 2); 7116306894acSVaclav Hapla PetscValidLogicalCollectiveBool(dm,failNotFound,3); 71175d80c0bfSVaclav Hapla for (pnext=&dm->labels; (link=*pnext); pnext=&link->next) { 711843e45a93SVaclav Hapla if (*label == link->label) { 7119306894acSVaclav Hapla hasLabel = PETSC_TRUE; 712043e45a93SVaclav Hapla *pnext = link->next; /* Remove from list */ 7121306894acSVaclav Hapla if (*label == dm->depthLabel) dm->depthLabel = NULL; 7122ba2698f1SMatthew G. Knepley if (*label == dm->celltypeLabel) dm->celltypeLabel = NULL; 712343e45a93SVaclav Hapla if (((PetscObject) link->label)->refct < 2) *label = NULL; /* nullify if exclusive reference */ 71249566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&link->label)); 71259566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 7126306894acSVaclav Hapla break; 7127306894acSVaclav Hapla } 7128306894acSVaclav Hapla } 71297a8be351SBarry Smith PetscCheck(hasLabel || !failNotFound,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Given label not found in DM"); 7130306894acSVaclav Hapla PetscFunctionReturn(0); 7131306894acSVaclav Hapla } 7132306894acSVaclav Hapla 7133c58f1c22SToby Isaac /*@C 7134c58f1c22SToby Isaac DMGetLabelOutput - Get the output flag for a given label 7135c58f1c22SToby Isaac 7136c58f1c22SToby Isaac Not Collective 7137c58f1c22SToby Isaac 7138c58f1c22SToby Isaac Input Parameters: 7139bb7acecfSBarry Smith + dm - The `DM` object 7140c58f1c22SToby Isaac - name - The label name 7141c58f1c22SToby Isaac 7142c58f1c22SToby Isaac Output Parameter: 7143c58f1c22SToby Isaac . output - The flag for output 7144c58f1c22SToby Isaac 7145c58f1c22SToby Isaac Level: developer 7146c58f1c22SToby Isaac 7147bb7acecfSBarry Smith .seealso: `DMLabel`, `DMSetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7148c58f1c22SToby Isaac @*/ 7149c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output) 7150c58f1c22SToby Isaac { 71515d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7152d67d17b1SMatthew G. Knepley const char *lname; 7153c58f1c22SToby Isaac 7154c58f1c22SToby Isaac PetscFunctionBegin; 7155c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7156dadcf809SJacob Faibussowitsch PetscValidCharPointer(name, 2); 7157dadcf809SJacob Faibussowitsch PetscValidBoolPointer(output, 3); 7158c58f1c22SToby Isaac while (next) { 7159c58f1c22SToby Isaac PetscBool flg; 7160c58f1c22SToby Isaac 71619566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) next->label, &lname)); 71629566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 7163c58f1c22SToby Isaac if (flg) {*output = next->output; PetscFunctionReturn(0);} 7164c58f1c22SToby Isaac next = next->next; 7165c58f1c22SToby Isaac } 716698921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7167c58f1c22SToby Isaac } 7168c58f1c22SToby Isaac 7169c58f1c22SToby Isaac /*@C 7170bb7acecfSBarry Smith DMSetLabelOutput - Set if a given label should be saved to a `PetscViewer` in calls to `DMView()` 7171c58f1c22SToby Isaac 7172c58f1c22SToby Isaac Not Collective 7173c58f1c22SToby Isaac 7174c58f1c22SToby Isaac Input Parameters: 7175bb7acecfSBarry Smith + dm - The `DM` object 7176c58f1c22SToby Isaac . name - The label name 7177bb7acecfSBarry Smith - output - `PETSC_TRUE` to save the label to the viewer 7178c58f1c22SToby Isaac 7179c58f1c22SToby Isaac Level: developer 7180c58f1c22SToby Isaac 7181bb7acecfSBarry Smith .seealso: `DMLabel`, `DMGetOutputFlag()`, `DMGetLabelOutput()`, `DMCreateLabel()`, `DMHasLabel()`, `DMGetLabelValue()`, `DMSetLabelValue()`, `DMGetStratumIS()` 7182c58f1c22SToby Isaac @*/ 7183c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output) 7184c58f1c22SToby Isaac { 71855d80c0bfSVaclav Hapla DMLabelLink next = dm->labels; 7186d67d17b1SMatthew G. Knepley const char *lname; 7187c58f1c22SToby Isaac 7188c58f1c22SToby Isaac PetscFunctionBegin; 7189c58f1c22SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7190534a8f05SLisandro Dalcin PetscValidCharPointer(name, 2); 7191c58f1c22SToby Isaac while (next) { 7192c58f1c22SToby Isaac PetscBool flg; 7193c58f1c22SToby Isaac 71949566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) next->label, &lname)); 71959566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, lname, &flg)); 7196c58f1c22SToby Isaac if (flg) {next->output = output; PetscFunctionReturn(0);} 7197c58f1c22SToby Isaac next = next->next; 7198c58f1c22SToby Isaac } 719998921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name); 7200c58f1c22SToby Isaac } 7201c58f1c22SToby Isaac 7202c58f1c22SToby Isaac /*@ 7203bb7acecfSBarry Smith DMCopyLabels - Copy labels from one `DM` mesh to another `DM` with a superset of the points 7204c58f1c22SToby Isaac 7205d083f849SBarry Smith Collective on dmA 7206c58f1c22SToby Isaac 7207d8d19677SJose E. Roman Input Parameters: 7208bb7acecfSBarry Smith + dmA - The `DM` object with initial labels 7209bb7acecfSBarry Smith . dmB - The `DM` object to which labels are copied 7210bb7acecfSBarry Smith . mode - Copy labels by pointers (`PETSC_OWN_POINTER`) or duplicate them (`PETSC_COPY_VALUES`) 7211bb7acecfSBarry Smith . all - Copy all labels including "depth", "dim", and "celltype" (`PETSC_TRUE`) which are otherwise ignored (`PETSC_FALSE`) 7212bb7acecfSBarry Smith - emode - How to behave when a `DMLabel` in the source and destination `DM`s with the same name is encountered (see `DMCopyLabelsMode`) 7213c58f1c22SToby Isaac 7214c58f1c22SToby Isaac Level: intermediate 7215c58f1c22SToby Isaac 7216bb7acecfSBarry Smith Note: 72172cbb9b06SVaclav Hapla This is typically used when interpolating or otherwise adding to a mesh, or testing. 7218c58f1c22SToby Isaac 7219bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode` 7220c58f1c22SToby Isaac @*/ 72212cbb9b06SVaclav Hapla PetscErrorCode DMCopyLabels(DM dmA, DM dmB, PetscCopyMode mode, PetscBool all, DMCopyLabelsMode emode) 7222c58f1c22SToby Isaac { 72232cbb9b06SVaclav Hapla DMLabel label, labelNew, labelOld; 7224c58f1c22SToby Isaac const char *name; 7225c58f1c22SToby Isaac PetscBool flg; 72265d80c0bfSVaclav Hapla DMLabelLink link; 7227c58f1c22SToby Isaac 72285d80c0bfSVaclav Hapla PetscFunctionBegin; 72295d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 72305d80c0bfSVaclav Hapla PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 72315d80c0bfSVaclav Hapla PetscValidLogicalCollectiveEnum(dmA, mode,3); 72325d80c0bfSVaclav Hapla PetscValidLogicalCollectiveBool(dmA, all, 4); 72337a8be351SBarry Smith PetscCheck(mode != PETSC_USE_POINTER,PetscObjectComm((PetscObject)dmA), PETSC_ERR_SUP, "PETSC_USE_POINTER not supported for objects"); 72345d80c0bfSVaclav Hapla if (dmA == dmB) PetscFunctionReturn(0); 72355d80c0bfSVaclav Hapla for (link=dmA->labels; link; link=link->next) { 72365d80c0bfSVaclav Hapla label=link->label; 72379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 72385d80c0bfSVaclav Hapla if (!all) { 72399566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "depth", &flg)); 7240c58f1c22SToby Isaac if (flg) continue; 72419566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "dim", &flg)); 72427d5acc75SStefano Zampini if (flg) continue; 72439566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, "celltype", &flg)); 7244ba2698f1SMatthew G. Knepley if (flg) continue; 72455d80c0bfSVaclav Hapla } 72469566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmB, name, &labelOld)); 72472cbb9b06SVaclav Hapla if (labelOld) { 72482cbb9b06SVaclav Hapla switch (emode) { 72492cbb9b06SVaclav Hapla case DM_COPY_LABELS_KEEP: 72502cbb9b06SVaclav Hapla continue; 72512cbb9b06SVaclav Hapla case DM_COPY_LABELS_REPLACE: 72529566063dSJacob Faibussowitsch PetscCall(DMRemoveLabelBySelf(dmB, &labelOld, PETSC_TRUE)); 72532cbb9b06SVaclav Hapla break; 72542cbb9b06SVaclav Hapla case DM_COPY_LABELS_FAIL: 725598921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in destination DM", name); 72562cbb9b06SVaclav Hapla default: 72577a8be351SBarry Smith SETERRQ(PetscObjectComm((PetscObject)dmA), PETSC_ERR_ARG_OUTOFRANGE, "Unhandled DMCopyLabelsMode %d", (int)emode); 72582cbb9b06SVaclav Hapla } 72592cbb9b06SVaclav Hapla } 72605d80c0bfSVaclav Hapla if (mode==PETSC_COPY_VALUES) { 72619566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, &labelNew)); 72625d80c0bfSVaclav Hapla } else { 72635d80c0bfSVaclav Hapla labelNew = label; 72645d80c0bfSVaclav Hapla } 72659566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmB, labelNew)); 72669566063dSJacob Faibussowitsch if (mode==PETSC_COPY_VALUES) PetscCall(DMLabelDestroy(&labelNew)); 7267c58f1c22SToby Isaac } 7268c58f1c22SToby Isaac PetscFunctionReturn(0); 7269c58f1c22SToby Isaac } 7270461a15a0SLisandro Dalcin 7271609dae6eSVaclav Hapla /*@C 7272bb7acecfSBarry Smith DMCompareLabels - Compare labels of two `DMPLEX` meshes 7273609dae6eSVaclav Hapla 72745efe38ccSVaclav Hapla Collective 7275609dae6eSVaclav Hapla 7276609dae6eSVaclav Hapla Input Parameters: 7277bb7acecfSBarry Smith + dm0 - First `DM` object 7278bb7acecfSBarry Smith - dm1 - Second `DM` object 7279609dae6eSVaclav Hapla 7280609dae6eSVaclav Hapla Output Parameters 72815efe38ccSVaclav Hapla + equal - (Optional) Flag whether labels of dm0 and dm1 are the same 7282609dae6eSVaclav Hapla - message - (Optional) Message describing the difference, or NULL if there is no difference 7283609dae6eSVaclav Hapla 7284609dae6eSVaclav Hapla Level: intermediate 7285609dae6eSVaclav Hapla 7286609dae6eSVaclav Hapla Notes: 7287bb7acecfSBarry Smith The output flag equal will be the same on all processes. 7288bb7acecfSBarry Smith 7289bb7acecfSBarry Smith If equal is passed as NULL and difference is found, an error is thrown on all processes. 7290bb7acecfSBarry Smith 7291bb7acecfSBarry Smith Make sure to pass equal is NULL on all processes or none of them. 7292609dae6eSVaclav Hapla 72935efe38ccSVaclav Hapla The output message is set independently on each rank. 7294bb7acecfSBarry Smith 7295bb7acecfSBarry Smith message must be freed with `PetscFree()` 7296bb7acecfSBarry Smith 7297bb7acecfSBarry Smith If message is passed as NULL and a difference is found, the difference description is printed to stderr in synchronized manner. 7298bb7acecfSBarry Smith 7299bb7acecfSBarry Smith Make sure to pass message as NULL on all processes or no processes. 7300609dae6eSVaclav Hapla 7301609dae6eSVaclav Hapla Labels are matched by name. If the number of labels and their names are equal, 7302bb7acecfSBarry Smith `DMLabelCompare()` is used to compare each pair of labels with the same name. 7303609dae6eSVaclav Hapla 7304bb7acecfSBarry Smith Fortran Note: 7305bb7acecfSBarry Smith This function is not available from Fortran. 7306609dae6eSVaclav Hapla 7307bb7acecfSBarry Smith .seealso: `DMLabel`, `DMAddLabel()`, `DMCopyLabelsMode`, `DMLabelCompare()` 7308609dae6eSVaclav Hapla @*/ 73095efe38ccSVaclav Hapla PetscErrorCode DMCompareLabels(DM dm0, DM dm1, PetscBool *equal, char **message) 7310609dae6eSVaclav Hapla { 73115efe38ccSVaclav Hapla PetscInt n, i; 7312609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 73135efe38ccSVaclav Hapla PetscBool eq; 7314609dae6eSVaclav Hapla MPI_Comm comm; 73155efe38ccSVaclav Hapla PetscMPIInt rank; 7316609dae6eSVaclav Hapla 7317609dae6eSVaclav Hapla PetscFunctionBegin; 7318609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm0,DM_CLASSID,1); 7319609dae6eSVaclav Hapla PetscValidHeaderSpecific(dm1,DM_CLASSID,2); 7320609dae6eSVaclav Hapla PetscCheckSameComm(dm0,1,dm1,2); 73215efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal,3); 7322609dae6eSVaclav Hapla if (message) PetscValidPointer(message, 4); 73239566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm0, &comm)); 73249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 73255efe38ccSVaclav Hapla { 73265efe38ccSVaclav Hapla PetscInt n1; 73275efe38ccSVaclav Hapla 73289566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm0, &n)); 73299566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm1, &n1)); 73305efe38ccSVaclav Hapla eq = (PetscBool) (n == n1); 73315efe38ccSVaclav Hapla if (!eq) { 733263a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Number of labels in dm0 = %" PetscInt_FMT " != %" PetscInt_FMT " = Number of labels in dm1", n, n1)); 7333609dae6eSVaclav Hapla } 73349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 73355efe38ccSVaclav Hapla if (!eq) goto finish; 73365efe38ccSVaclav Hapla } 73375efe38ccSVaclav Hapla for (i=0; i<n; i++) { 7338609dae6eSVaclav Hapla DMLabel l0, l1; 7339609dae6eSVaclav Hapla const char *name; 7340609dae6eSVaclav Hapla char *msgInner; 7341609dae6eSVaclav Hapla 7342609dae6eSVaclav Hapla /* Ignore label order */ 73439566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm0, i, &l0)); 73449566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name)); 73459566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm1, name, &l1)); 7346609dae6eSVaclav Hapla if (!l1) { 734763a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Label \"%s\" (#%" PetscInt_FMT " in dm0) not found in dm1", name, i)); 73485efe38ccSVaclav Hapla eq = PETSC_FALSE; 73495efe38ccSVaclav Hapla break; 7350609dae6eSVaclav Hapla } 73519566063dSJacob Faibussowitsch PetscCall(DMLabelCompare(comm, l0, l1, &eq, &msgInner)); 73529566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(msg, msgInner, sizeof(msg))); 73539566063dSJacob Faibussowitsch PetscCall(PetscFree(msgInner)); 73545efe38ccSVaclav Hapla if (!eq) break; 7355609dae6eSVaclav Hapla } 73569566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 7357609dae6eSVaclav Hapla finish: 73585efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 7359609dae6eSVaclav Hapla if (message) { 7360609dae6eSVaclav Hapla *message = NULL; 7361609dae6eSVaclav Hapla if (msg[0]) { 73629566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(msg, message)); 7363609dae6eSVaclav Hapla } 73645efe38ccSVaclav Hapla } else { 73655efe38ccSVaclav Hapla if (msg[0]) { 73669566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 7367609dae6eSVaclav Hapla } 73689566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 73695efe38ccSVaclav Hapla } 73705efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 73715efe38ccSVaclav Hapla if (equal) *equal = eq; 73727a8be351SBarry Smith else PetscCheck(eq,comm, PETSC_ERR_ARG_INCOMP, "DMLabels are not the same in dm0 and dm1"); 7373609dae6eSVaclav Hapla PetscFunctionReturn(0); 7374609dae6eSVaclav Hapla } 7375609dae6eSVaclav Hapla 7376461a15a0SLisandro Dalcin PetscErrorCode DMSetLabelValue_Fast(DM dm, DMLabel *label, const char name[], PetscInt point, PetscInt value) 7377461a15a0SLisandro Dalcin { 7378461a15a0SLisandro Dalcin PetscFunctionBegin; 7379461a15a0SLisandro Dalcin PetscValidPointer(label,2); 7380461a15a0SLisandro Dalcin if (!*label) { 73819566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, name)); 73829566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, name, label)); 7383461a15a0SLisandro Dalcin } 73849566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(*label, point, value)); 7385461a15a0SLisandro Dalcin PetscFunctionReturn(0); 7386461a15a0SLisandro Dalcin } 7387461a15a0SLisandro Dalcin 73880fdc7489SMatthew Knepley /* 73890fdc7489SMatthew Knepley Many mesh programs, such as Triangle and TetGen, allow only a single label for each mesh point. Therefore, we would 73900fdc7489SMatthew Knepley like to encode all label IDs using a single, universal label. We can do this by assigning an integer to every 73910fdc7489SMatthew Knepley (label, id) pair in the DM. 73920fdc7489SMatthew Knepley 73930fdc7489SMatthew Knepley However, a mesh point can have multiple labels, so we must separate all these values. We will assign a bit range to 73940fdc7489SMatthew Knepley each label. 73950fdc7489SMatthew Knepley */ 73960fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreate(DM dm, DMUniversalLabel *universal) 73970fdc7489SMatthew Knepley { 73980fdc7489SMatthew Knepley DMUniversalLabel ul; 73990fdc7489SMatthew Knepley PetscBool *active; 74000fdc7489SMatthew Knepley PetscInt pStart, pEnd, p, Nl, l, m; 74010fdc7489SMatthew Knepley 74020fdc7489SMatthew Knepley PetscFunctionBegin; 74039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &ul)); 74049566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "universal", &ul->label)); 74059566063dSJacob Faibussowitsch PetscCall(DMGetNumLabels(dm, &Nl)); 74069566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nl, &active)); 74070fdc7489SMatthew Knepley ul->Nl = 0; 74080fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 74090fdc7489SMatthew Knepley PetscBool isdepth, iscelltype; 74100fdc7489SMatthew Knepley const char *name; 74110fdc7489SMatthew Knepley 74129566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 74139566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "depth", 6, &isdepth)); 74149566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(name, "celltype", 9, &iscelltype)); 74150fdc7489SMatthew Knepley active[l] = !(isdepth || iscelltype) ? PETSC_TRUE : PETSC_FALSE; 74160fdc7489SMatthew Knepley if (active[l]) ++ul->Nl; 74170fdc7489SMatthew Knepley } 74189566063dSJacob 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)); 74190fdc7489SMatthew Knepley ul->Nv = 0; 74200fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 74210fdc7489SMatthew Knepley DMLabel label; 74220fdc7489SMatthew Knepley PetscInt nv; 74230fdc7489SMatthew Knepley const char *name; 74240fdc7489SMatthew Knepley 74250fdc7489SMatthew Knepley if (!active[l]) continue; 74269566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, l, &name)); 74279566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 74289566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 74299566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &ul->names[m])); 74300fdc7489SMatthew Knepley ul->indices[m] = l; 74310fdc7489SMatthew Knepley ul->Nv += nv; 74320fdc7489SMatthew Knepley ul->offsets[m+1] = nv; 74330fdc7489SMatthew Knepley ul->bits[m+1] = PetscCeilReal(PetscLog2Real(nv+1)); 74340fdc7489SMatthew Knepley ++m; 74350fdc7489SMatthew Knepley } 74360fdc7489SMatthew Knepley for (l = 1; l <= ul->Nl; ++l) { 74370fdc7489SMatthew Knepley ul->offsets[l] = ul->offsets[l-1] + ul->offsets[l]; 74380fdc7489SMatthew Knepley ul->bits[l] = ul->bits[l-1] + ul->bits[l]; 74390fdc7489SMatthew Knepley } 74400fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 74410fdc7489SMatthew Knepley PetscInt b; 74420fdc7489SMatthew Knepley 74430fdc7489SMatthew Knepley ul->masks[l] = 0; 74440fdc7489SMatthew Knepley for (b = ul->bits[l]; b < ul->bits[l+1]; ++b) ul->masks[l] |= 1 << b; 74450fdc7489SMatthew Knepley } 74469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ul->Nv, &ul->values)); 74470fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 74480fdc7489SMatthew Knepley DMLabel label; 74490fdc7489SMatthew Knepley IS valueIS; 74500fdc7489SMatthew Knepley const PetscInt *varr; 74510fdc7489SMatthew Knepley PetscInt nv, v; 74520fdc7489SMatthew Knepley 74530fdc7489SMatthew Knepley if (!active[l]) continue; 74549566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 74559566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nv)); 74569566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &valueIS)); 74579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &varr)); 74580fdc7489SMatthew Knepley for (v = 0; v < nv; ++v) { 74590fdc7489SMatthew Knepley ul->values[ul->offsets[m]+v] = varr[v]; 74600fdc7489SMatthew Knepley } 74619566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(valueIS, &varr)); 74629566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valueIS)); 74639566063dSJacob Faibussowitsch PetscCall(PetscSortInt(nv, &ul->values[ul->offsets[m]])); 74640fdc7489SMatthew Knepley ++m; 74650fdc7489SMatthew Knepley } 74669566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 74670fdc7489SMatthew Knepley for (p = pStart; p < pEnd; ++p) { 74680fdc7489SMatthew Knepley PetscInt uval = 0; 74690fdc7489SMatthew Knepley PetscBool marked = PETSC_FALSE; 74700fdc7489SMatthew Knepley 74710fdc7489SMatthew Knepley for (l = 0, m = 0; l < Nl; ++l) { 74720fdc7489SMatthew Knepley DMLabel label; 74730649b39aSStefano Zampini PetscInt val, defval, loc, nv; 74740fdc7489SMatthew Knepley 74750fdc7489SMatthew Knepley if (!active[l]) continue; 74769566063dSJacob Faibussowitsch PetscCall(DMGetLabelByNum(dm, l, &label)); 74779566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &val)); 74789566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(label, &defval)); 74790fdc7489SMatthew Knepley if (val == defval) {++m; continue;} 74800649b39aSStefano Zampini nv = ul->offsets[m+1]-ul->offsets[m]; 74810fdc7489SMatthew Knepley marked = PETSC_TRUE; 74829566063dSJacob Faibussowitsch PetscCall(PetscFindInt(val, nv, &ul->values[ul->offsets[m]], &loc)); 748363a3b9bcSJacob Faibussowitsch PetscCheck(loc >= 0,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label value %" PetscInt_FMT " not found in compression array", val); 74840fdc7489SMatthew Knepley uval += (loc+1) << ul->bits[m]; 74850fdc7489SMatthew Knepley ++m; 74860fdc7489SMatthew Knepley } 74879566063dSJacob Faibussowitsch if (marked) PetscCall(DMLabelSetValue(ul->label, p, uval)); 74880fdc7489SMatthew Knepley } 74899566063dSJacob Faibussowitsch PetscCall(PetscFree(active)); 74900fdc7489SMatthew Knepley *universal = ul; 74910fdc7489SMatthew Knepley PetscFunctionReturn(0); 74920fdc7489SMatthew Knepley } 74930fdc7489SMatthew Knepley 74940fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelDestroy(DMUniversalLabel *universal) 74950fdc7489SMatthew Knepley { 74960fdc7489SMatthew Knepley PetscInt l; 74970fdc7489SMatthew Knepley 74980fdc7489SMatthew Knepley PetscFunctionBegin; 74999566063dSJacob Faibussowitsch for (l = 0; l < (*universal)->Nl; ++l) PetscCall(PetscFree((*universal)->names[l])); 75009566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&(*universal)->label)); 75019566063dSJacob Faibussowitsch PetscCall(PetscFree5((*universal)->names, (*universal)->indices, (*universal)->offsets, (*universal)->bits, (*universal)->masks)); 75029566063dSJacob Faibussowitsch PetscCall(PetscFree((*universal)->values)); 75039566063dSJacob Faibussowitsch PetscCall(PetscFree(*universal)); 75040fdc7489SMatthew Knepley *universal = NULL; 75050fdc7489SMatthew Knepley PetscFunctionReturn(0); 75060fdc7489SMatthew Knepley } 75070fdc7489SMatthew Knepley 75080fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelGetLabel(DMUniversalLabel ul, DMLabel *ulabel) 75090fdc7489SMatthew Knepley { 75100fdc7489SMatthew Knepley PetscFunctionBegin; 75110fdc7489SMatthew Knepley PetscValidPointer(ulabel, 2); 75120fdc7489SMatthew Knepley *ulabel = ul->label; 75130fdc7489SMatthew Knepley PetscFunctionReturn(0); 75140fdc7489SMatthew Knepley } 75150fdc7489SMatthew Knepley 75160fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelCreateLabels(DMUniversalLabel ul, PetscBool preserveOrder, DM dm) 75170fdc7489SMatthew Knepley { 75180fdc7489SMatthew Knepley PetscInt Nl = ul->Nl, l; 75190fdc7489SMatthew Knepley 75200fdc7489SMatthew Knepley PetscFunctionBegin; 7521064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 3); 75220fdc7489SMatthew Knepley for (l = 0; l < Nl; ++l) { 75239566063dSJacob Faibussowitsch if (preserveOrder) PetscCall(DMCreateLabelAtIndex(dm, ul->indices[l], ul->names[l])); 75249566063dSJacob Faibussowitsch else PetscCall(DMCreateLabel(dm, ul->names[l])); 75250fdc7489SMatthew Knepley } 75260fdc7489SMatthew Knepley if (preserveOrder) { 75270fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 75280fdc7489SMatthew Knepley const char *name; 75290fdc7489SMatthew Knepley PetscBool match; 75300fdc7489SMatthew Knepley 75319566063dSJacob Faibussowitsch PetscCall(DMGetLabelName(dm, ul->indices[l], &name)); 75329566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, ul->names[l], &match)); 753363a3b9bcSJacob 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]); 75340fdc7489SMatthew Knepley } 75350fdc7489SMatthew Knepley } 75360fdc7489SMatthew Knepley PetscFunctionReturn(0); 75370fdc7489SMatthew Knepley } 75380fdc7489SMatthew Knepley 75390fdc7489SMatthew Knepley PetscErrorCode DMUniversalLabelSetLabelValue(DMUniversalLabel ul, DM dm, PetscBool useIndex, PetscInt p, PetscInt value) 75400fdc7489SMatthew Knepley { 75410fdc7489SMatthew Knepley PetscInt l; 75420fdc7489SMatthew Knepley 75430fdc7489SMatthew Knepley PetscFunctionBegin; 75440fdc7489SMatthew Knepley for (l = 0; l < ul->Nl; ++l) { 75450fdc7489SMatthew Knepley DMLabel label; 75460fdc7489SMatthew Knepley PetscInt lval = (value & ul->masks[l]) >> ul->bits[l]; 75470fdc7489SMatthew Knepley 75480fdc7489SMatthew Knepley if (lval) { 75499566063dSJacob Faibussowitsch if (useIndex) PetscCall(DMGetLabelByNum(dm, ul->indices[l], &label)); 75509566063dSJacob Faibussowitsch else PetscCall(DMGetLabel(dm, ul->names[l], &label)); 75519566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, p, ul->values[ul->offsets[l]+lval-1])); 75520fdc7489SMatthew Knepley } 75530fdc7489SMatthew Knepley } 75540fdc7489SMatthew Knepley PetscFunctionReturn(0); 75550fdc7489SMatthew Knepley } 7556a8fb8f29SToby Isaac 7557a8fb8f29SToby Isaac /*@ 7558bb7acecfSBarry Smith DMGetCoarseDM - Get the coarse `DM`from which this `DM` was obtained by refinement 7559bb7acecfSBarry Smith 7560bb7acecfSBarry Smith Not collective 7561a8fb8f29SToby Isaac 7562a8fb8f29SToby Isaac Input Parameter: 7563bb7acecfSBarry Smith . dm - The `DM` object 7564a8fb8f29SToby Isaac 7565a8fb8f29SToby Isaac Output Parameter: 7566bb7acecfSBarry Smith . cdm - The coarse `DM` 7567a8fb8f29SToby Isaac 7568a8fb8f29SToby Isaac Level: intermediate 7569a8fb8f29SToby Isaac 7570bb7acecfSBarry Smith .seealso: `DMSetCoarseDM()`, `DMCoarsen()` 7571a8fb8f29SToby Isaac @*/ 7572a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm) 7573a8fb8f29SToby Isaac { 7574a8fb8f29SToby Isaac PetscFunctionBegin; 7575a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7576a8fb8f29SToby Isaac PetscValidPointer(cdm, 2); 7577a8fb8f29SToby Isaac *cdm = dm->coarseMesh; 7578a8fb8f29SToby Isaac PetscFunctionReturn(0); 7579a8fb8f29SToby Isaac } 7580a8fb8f29SToby Isaac 7581a8fb8f29SToby Isaac /*@ 7582bb7acecfSBarry Smith DMSetCoarseDM - Set the coarse `DM` from which this `DM` was obtained by refinement 7583a8fb8f29SToby Isaac 7584a8fb8f29SToby Isaac Input Parameters: 7585bb7acecfSBarry Smith + dm - The `DM` object 7586bb7acecfSBarry Smith - cdm - The coarse `DM` 7587a8fb8f29SToby Isaac 7588a8fb8f29SToby Isaac Level: intermediate 7589a8fb8f29SToby Isaac 7590bb7acecfSBarry Smith Note: 7591bb7acecfSBarry Smith Normally this is set automatically by `DMRefine()` 7592bb7acecfSBarry Smith 7593bb7acecfSBarry Smith .seealso: `DMGetCoarseDM()`, `DMCoarsen()`, `DMSetRefine()`, `DMSetFineDM()` 7594a8fb8f29SToby Isaac @*/ 7595a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm) 7596a8fb8f29SToby Isaac { 7597a8fb8f29SToby Isaac PetscFunctionBegin; 7598a8fb8f29SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7599a8fb8f29SToby Isaac if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 76009566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cdm)); 76019566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->coarseMesh)); 7602a8fb8f29SToby Isaac dm->coarseMesh = cdm; 7603a8fb8f29SToby Isaac PetscFunctionReturn(0); 7604a8fb8f29SToby Isaac } 7605a8fb8f29SToby Isaac 760688bdff64SToby Isaac /*@ 7607bb7acecfSBarry Smith DMGetFineDM - Get the fine mesh from which this `DM` was obtained by coarsening 760888bdff64SToby Isaac 760988bdff64SToby Isaac Input Parameter: 7610bb7acecfSBarry Smith . dm - The `DM` object 761188bdff64SToby Isaac 761288bdff64SToby Isaac Output Parameter: 7613bb7acecfSBarry Smith . fdm - The fine `DM` 761488bdff64SToby Isaac 761588bdff64SToby Isaac Level: intermediate 761688bdff64SToby Isaac 7617bb7acecfSBarry Smith .seealso: `DMSetFineDM()`, `DMCoarsen()`, `DMRefine()` 761888bdff64SToby Isaac @*/ 761988bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm) 762088bdff64SToby Isaac { 762188bdff64SToby Isaac PetscFunctionBegin; 762288bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 762388bdff64SToby Isaac PetscValidPointer(fdm, 2); 762488bdff64SToby Isaac *fdm = dm->fineMesh; 762588bdff64SToby Isaac PetscFunctionReturn(0); 762688bdff64SToby Isaac } 762788bdff64SToby Isaac 762888bdff64SToby Isaac /*@ 7629bb7acecfSBarry Smith DMSetFineDM - Set the fine mesh from which this was obtained by coarsening 763088bdff64SToby Isaac 763188bdff64SToby Isaac Input Parameters: 7632bb7acecfSBarry Smith + dm - The `DM` object 7633bb7acecfSBarry Smith - fdm - The fine `DM` 763488bdff64SToby Isaac 7635bb7acecfSBarry Smith Level: developer 763688bdff64SToby Isaac 7637bb7acecfSBarry Smith Note: 7638bb7acecfSBarry Smith Normally this is set automatically by `DMCoarsen()` 7639bb7acecfSBarry Smith 7640bb7acecfSBarry Smith .seealso: `DMGetFineDM()`, `DMCoarsen()`, `DMRefine()` 764188bdff64SToby Isaac @*/ 764288bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm) 764388bdff64SToby Isaac { 764488bdff64SToby Isaac PetscFunctionBegin; 764588bdff64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 764688bdff64SToby Isaac if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2); 76479566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fdm)); 76489566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm->fineMesh)); 764988bdff64SToby Isaac dm->fineMesh = fdm; 765088bdff64SToby Isaac PetscFunctionReturn(0); 765188bdff64SToby Isaac } 765288bdff64SToby Isaac 7653a6ba4734SToby Isaac /*@C 7654bb7acecfSBarry Smith DMAddBoundary - Add a boundary condition to a model represented by a `DM` 7655a6ba4734SToby Isaac 7656783e2ec8SMatthew G. Knepley Collective on dm 7657783e2ec8SMatthew G. Knepley 7658a6ba4734SToby Isaac Input Parameters: 7659bb7acecfSBarry Smith + dm - The `DM`, with a `PetscDS` that matches the problem being constrained 7660bb7acecfSBarry Smith . type - The type of condition, e.g. `DM_BC_ESSENTIAL_ANALYTIC`, `DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann) 7661a6ba4734SToby Isaac . name - The BC name 766245480ffeSMatthew G. Knepley . label - The label defining constrained points 7663bb7acecfSBarry Smith . Nv - The number of `DMLabel` values for constrained points 766445480ffeSMatthew G. Knepley . values - An array of values for constrained points 7665a6ba4734SToby Isaac . field - The field to constrain 766645480ffeSMatthew G. Knepley . Nc - The number of constrained field components (0 will constrain all fields) 7667a6ba4734SToby Isaac . comps - An array of constrained component numbers 7668a6ba4734SToby Isaac . bcFunc - A pointwise function giving boundary values 766956cf3b9cSMatthew G. Knepley . bcFunc_t - A pointwise function giving the time deriative of the boundary values, or NULL 7670a6ba4734SToby Isaac - ctx - An optional user context for bcFunc 7671a6ba4734SToby Isaac 767245480ffeSMatthew G. Knepley Output Parameter: 767345480ffeSMatthew G. Knepley . bd - (Optional) Boundary number 767445480ffeSMatthew G. Knepley 7675a6ba4734SToby Isaac Options Database Keys: 7676a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids 7677a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components 7678a6ba4734SToby Isaac 7679bb7acecfSBarry Smith Notes: 7680bb7acecfSBarry 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: 768156cf3b9cSMatthew G. Knepley 768256cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[]) 768356cf3b9cSMatthew G. Knepley 7684bb7acecfSBarry Smith If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is: 768556cf3b9cSMatthew G. Knepley 768656cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux, 768756cf3b9cSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 768856cf3b9cSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 768956cf3b9cSMatthew G. Knepley $ PetscReal time, const PetscReal x[], PetscScalar bcval[]) 769056cf3b9cSMatthew G. Knepley 769156cf3b9cSMatthew G. Knepley + dim - the spatial dimension 769256cf3b9cSMatthew G. Knepley . Nf - the number of fields 769356cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field 769456cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field 769556cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point 769656cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point 769756cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point 769856cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field 769956cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field 770056cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point 770156cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point 770256cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point 770356cf3b9cSMatthew G. Knepley . t - current time 770456cf3b9cSMatthew G. Knepley . x - coordinates of the current point 770556cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters 770656cf3b9cSMatthew G. Knepley . constants - constant parameters 770756cf3b9cSMatthew G. Knepley - bcval - output values at the current point 770856cf3b9cSMatthew G. Knepley 7709ed808b8fSJed Brown Level: intermediate 7710a6ba4734SToby Isaac 7711db781477SPatrick Sanan .seealso: `DSGetBoundary()`, `PetscDSAddBoundary()` 7712a6ba4734SToby Isaac @*/ 771345480ffeSMatthew G. Knepley 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) 7714a6ba4734SToby Isaac { 7715e5e52638SMatthew G. Knepley PetscDS ds; 7716a6ba4734SToby Isaac 7717a6ba4734SToby Isaac PetscFunctionBegin; 7718a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7719783e2ec8SMatthew G. Knepley PetscValidLogicalCollectiveEnum(dm, type, 2); 772045480ffeSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 772145480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nv, 5); 772245480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, field, 7); 772345480ffeSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, Nc, 8); 772401a5d20dSJed Brown PetscCheck(!dm->localSection,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot add boundary to DM after creating local section"); 77259566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7726799db056SMatthew G. Knepley /* Complete label */ 7727799db056SMatthew G. Knepley if (label) { 7728799db056SMatthew G. Knepley PetscObject obj; 7729799db056SMatthew G. Knepley PetscClassId id; 7730799db056SMatthew G. Knepley 7731799db056SMatthew G. Knepley PetscCall(DMGetField(dm, field, NULL, &obj)); 7732799db056SMatthew G. Knepley PetscCall(PetscObjectGetClassId(obj, &id)); 7733799db056SMatthew G. Knepley if (id == PETSCFE_CLASSID) { 7734799db056SMatthew G. Knepley DM plex; 7735799db056SMatthew G. Knepley 7736799db056SMatthew G. Knepley PetscCall(DMConvert(dm, DMPLEX, &plex)); 7737799db056SMatthew G. Knepley if (plex) PetscCall(DMPlexLabelComplete(plex, label)); 7738799db056SMatthew G. Knepley PetscCall(DMDestroy(&plex)); 7739799db056SMatthew G. Knepley } 7740799db056SMatthew G. Knepley } 77419566063dSJacob Faibussowitsch PetscCall(PetscDSAddBoundary(ds, type, name, label, Nv, values, field, Nc, comps, bcFunc, bcFunc_t, ctx, bd)); 7742a6ba4734SToby Isaac PetscFunctionReturn(0); 7743a6ba4734SToby Isaac } 7744a6ba4734SToby Isaac 774545480ffeSMatthew G. Knepley /* TODO Remove this since now the structures are the same */ 7746e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm) 7747e6f8dbb6SToby Isaac { 7748e5e52638SMatthew G. Knepley PetscDS ds; 7749dff059c6SToby Isaac DMBoundary *lastnext; 7750e6f8dbb6SToby Isaac DSBoundary dsbound; 7751e6f8dbb6SToby Isaac 7752e6f8dbb6SToby Isaac PetscFunctionBegin; 77539566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &ds)); 7754e5e52638SMatthew G. Knepley dsbound = ds->boundary; 775547a1f5adSToby Isaac if (dm->boundary) { 775647a1f5adSToby Isaac DMBoundary next = dm->boundary; 775747a1f5adSToby Isaac 775847a1f5adSToby Isaac /* quick check to see if the PetscDS has changed */ 775947a1f5adSToby Isaac if (next->dsboundary == dsbound) PetscFunctionReturn(0); 776047a1f5adSToby Isaac /* the PetscDS has changed: tear down and rebuild */ 776147a1f5adSToby Isaac while (next) { 776247a1f5adSToby Isaac DMBoundary b = next; 776347a1f5adSToby Isaac 776447a1f5adSToby Isaac next = b->next; 77659566063dSJacob Faibussowitsch PetscCall(PetscFree(b)); 7766a6ba4734SToby Isaac } 776747a1f5adSToby Isaac dm->boundary = NULL; 7768a6ba4734SToby Isaac } 776947a1f5adSToby Isaac 7770dff059c6SToby Isaac lastnext = &(dm->boundary); 7771e6f8dbb6SToby Isaac while (dsbound) { 7772e6f8dbb6SToby Isaac DMBoundary dmbound; 7773e6f8dbb6SToby Isaac 77749566063dSJacob Faibussowitsch PetscCall(PetscNew(&dmbound)); 7775e6f8dbb6SToby Isaac dmbound->dsboundary = dsbound; 777645480ffeSMatthew G. Knepley dmbound->label = dsbound->label; 777747a1f5adSToby Isaac /* push on the back instead of the front so that it is in the same order as in the PetscDS */ 7778dff059c6SToby Isaac *lastnext = dmbound; 7779dff059c6SToby Isaac lastnext = &(dmbound->next); 7780dff059c6SToby Isaac dsbound = dsbound->next; 7781a6ba4734SToby Isaac } 7782a6ba4734SToby Isaac PetscFunctionReturn(0); 7783a6ba4734SToby Isaac } 7784a6ba4734SToby Isaac 7785bb7acecfSBarry Smith /* TODO: missing manual page */ 7786a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd) 7787a6ba4734SToby Isaac { 7788b95f2879SToby Isaac DMBoundary b; 7789a6ba4734SToby Isaac 7790a6ba4734SToby Isaac PetscFunctionBegin; 7791a6ba4734SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7792534a8f05SLisandro Dalcin PetscValidBoolPointer(isBd, 3); 7793a6ba4734SToby Isaac *isBd = PETSC_FALSE; 77949566063dSJacob Faibussowitsch PetscCall(DMPopulateBoundary(dm)); 7795b95f2879SToby Isaac b = dm->boundary; 7796a6ba4734SToby Isaac while (b && !(*isBd)) { 7797e6f8dbb6SToby Isaac DMLabel label = b->label; 7798e6f8dbb6SToby Isaac DSBoundary dsb = b->dsboundary; 7799a6ba4734SToby Isaac PetscInt i; 7800a6ba4734SToby Isaac 780145480ffeSMatthew G. Knepley if (label) { 78029566063dSJacob Faibussowitsch for (i = 0; i < dsb->Nv && !(*isBd); ++i) PetscCall(DMLabelStratumHasPoint(label, dsb->values[i], point, isBd)); 7803a6ba4734SToby Isaac } 7804a6ba4734SToby Isaac b = b->next; 7805a6ba4734SToby Isaac } 7806a6ba4734SToby Isaac PetscFunctionReturn(0); 7807a6ba4734SToby Isaac } 78084d6f44ffSToby Isaac 78094d6f44ffSToby Isaac /*@C 7810bb7acecfSBarry Smith DMProjectFunction - This projects the given function into the function space provided by a `DM`, putting the coefficients in a global vector. 7811a6e0b375SMatthew G. Knepley 7812bb7acecfSBarry Smith Collective on dm 78134d6f44ffSToby Isaac 78144d6f44ffSToby Isaac Input Parameters: 7815bb7acecfSBarry Smith + dm - The `DM` 78160709b2feSToby Isaac . time - The time 78174d6f44ffSToby Isaac . funcs - The coordinate functions to evaluate, one per field 78184d6f44ffSToby Isaac . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 78194d6f44ffSToby Isaac - mode - The insertion mode for values 78204d6f44ffSToby Isaac 78214d6f44ffSToby Isaac Output Parameter: 78224d6f44ffSToby Isaac . X - vector 78234d6f44ffSToby Isaac 78244d6f44ffSToby Isaac Calling sequence of func: 782577b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 78264d6f44ffSToby Isaac 78274d6f44ffSToby Isaac + dim - The spatial dimension 78288ec8862eSJed Brown . time - The time at which to sample 78294d6f44ffSToby Isaac . x - The coordinates 783077b739a6SMatthew Knepley . Nc - The number of components 78314d6f44ffSToby Isaac . u - The output field values 78324d6f44ffSToby Isaac - ctx - optional user-defined function context 78334d6f44ffSToby Isaac 78344d6f44ffSToby Isaac Level: developer 78354d6f44ffSToby Isaac 7836bb7acecfSBarry Smith Developer Notes: 7837bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7838bb7acecfSBarry Smith 7839bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7840bb7acecfSBarry Smith 7841db781477SPatrick Sanan .seealso: `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 78424d6f44ffSToby Isaac @*/ 78430709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 78444d6f44ffSToby Isaac { 78454d6f44ffSToby Isaac Vec localX; 78464d6f44ffSToby Isaac 78474d6f44ffSToby Isaac PetscFunctionBegin; 78484d6f44ffSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 78499566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 78509566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX)); 78519566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 78529566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 78539566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 78544d6f44ffSToby Isaac PetscFunctionReturn(0); 78554d6f44ffSToby Isaac } 78564d6f44ffSToby Isaac 7857a6e0b375SMatthew G. Knepley /*@C 7858bb7acecfSBarry Smith DMProjectFunctionLocal - This projects the given function into the function space provided by a `DM`, putting the coefficients in a local vector. 7859a6e0b375SMatthew G. Knepley 7860a6e0b375SMatthew G. Knepley Not collective 7861a6e0b375SMatthew G. Knepley 7862a6e0b375SMatthew G. Knepley Input Parameters: 7863bb7acecfSBarry Smith + dm - The `DM` 7864a6e0b375SMatthew G. Knepley . time - The time 7865a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 7866a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 7867a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 7868a6e0b375SMatthew G. Knepley 7869a6e0b375SMatthew G. Knepley Output Parameter: 7870a6e0b375SMatthew G. Knepley . localX - vector 7871a6e0b375SMatthew G. Knepley 7872a6e0b375SMatthew G. Knepley Calling sequence of func: 787377b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 7874a6e0b375SMatthew G. Knepley 7875a6e0b375SMatthew G. Knepley + dim - The spatial dimension 7876a6e0b375SMatthew G. Knepley . x - The coordinates 787777b739a6SMatthew Knepley . Nc - The number of components 7878a6e0b375SMatthew G. Knepley . u - The output field values 7879a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 7880a6e0b375SMatthew G. Knepley 7881a6e0b375SMatthew G. Knepley Level: developer 7882a6e0b375SMatthew G. Knepley 7883bb7acecfSBarry Smith Developer Notes: 7884bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7885bb7acecfSBarry Smith 7886bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7887bb7acecfSBarry Smith 7888db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 7889a6e0b375SMatthew G. Knepley @*/ 78900709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 78914d6f44ffSToby Isaac { 78924d6f44ffSToby Isaac PetscFunctionBegin; 78934d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7894064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 78959566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX)); 78964d6f44ffSToby Isaac PetscFunctionReturn(0); 78974d6f44ffSToby Isaac } 78984d6f44ffSToby Isaac 7899a6e0b375SMatthew G. Knepley /*@C 7900bb7acecfSBarry 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. 7901a6e0b375SMatthew G. Knepley 7902bb7acecfSBarry Smith Collective on dm 7903a6e0b375SMatthew G. Knepley 7904a6e0b375SMatthew G. Knepley Input Parameters: 7905bb7acecfSBarry Smith + dm - The `DM` 7906a6e0b375SMatthew G. Knepley . time - The time 7907bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 7908a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 7909bb7acecfSBarry Smith . ctxs - Optional array of contexts to pass to each coordinate function. ctxs may be null. 7910a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 7911a6e0b375SMatthew G. Knepley 7912a6e0b375SMatthew G. Knepley Output Parameter: 7913a6e0b375SMatthew G. Knepley . X - vector 7914a6e0b375SMatthew G. Knepley 7915a6e0b375SMatthew G. Knepley Calling sequence of func: 791677b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 7917a6e0b375SMatthew G. Knepley 7918a6e0b375SMatthew G. Knepley + dim - The spatial dimension 7919a6e0b375SMatthew G. Knepley . x - The coordinates 792077b739a6SMatthew Knepley . Nc - The number of components 7921a6e0b375SMatthew G. Knepley . u - The output field values 7922a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 7923a6e0b375SMatthew G. Knepley 7924a6e0b375SMatthew G. Knepley Level: developer 7925a6e0b375SMatthew G. Knepley 7926bb7acecfSBarry Smith Developer Notes: 7927bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7928bb7acecfSBarry Smith 7929bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7930bb7acecfSBarry Smith 7931db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabelLocal()`, `DMComputeL2Diff()` 7932a6e0b375SMatthew G. Knepley @*/ 79332c53366bSMatthew G. Knepley PetscErrorCode DMProjectFunctionLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X) 79342c53366bSMatthew G. Knepley { 79352c53366bSMatthew G. Knepley Vec localX; 79362c53366bSMatthew G. Knepley 79372c53366bSMatthew G. Knepley PetscFunctionBegin; 79382c53366bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 79399566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &localX)); 79409566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 79419566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 79429566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 79439566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &localX)); 79442c53366bSMatthew G. Knepley PetscFunctionReturn(0); 79452c53366bSMatthew G. Knepley } 79462c53366bSMatthew G. Knepley 7947a6e0b375SMatthew G. Knepley /*@C 7948bb7acecfSBarry 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. 7949a6e0b375SMatthew G. Knepley 7950a6e0b375SMatthew G. Knepley Not collective 7951a6e0b375SMatthew G. Knepley 7952a6e0b375SMatthew G. Knepley Input Parameters: 7953bb7acecfSBarry Smith + dm - The `DM` 7954a6e0b375SMatthew G. Knepley . time - The time 7955bb7acecfSBarry Smith . label - The `DMLabel` selecting the portion of the mesh for projection 7956a6e0b375SMatthew G. Knepley . funcs - The coordinate functions to evaluate, one per field 7957a6e0b375SMatthew G. Knepley . ctxs - Optional array of contexts to pass to each coordinate function. ctxs itself may be null. 7958a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 7959a6e0b375SMatthew G. Knepley 7960a6e0b375SMatthew G. Knepley Output Parameter: 7961a6e0b375SMatthew G. Knepley . localX - vector 7962a6e0b375SMatthew G. Knepley 7963a6e0b375SMatthew G. Knepley Calling sequence of func: 796477b739a6SMatthew Knepley $ func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx); 7965a6e0b375SMatthew G. Knepley 7966a6e0b375SMatthew G. Knepley + dim - The spatial dimension 7967a6e0b375SMatthew G. Knepley . x - The coordinates 796877b739a6SMatthew Knepley . Nc - The number of components 7969a6e0b375SMatthew G. Knepley . u - The output field values 7970a6e0b375SMatthew G. Knepley - ctx - optional user-defined function context 7971a6e0b375SMatthew G. Knepley 7972a6e0b375SMatthew G. Knepley Level: developer 7973a6e0b375SMatthew G. Knepley 7974bb7acecfSBarry Smith Developer Notes: 7975bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 7976bb7acecfSBarry Smith 7977bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 7978bb7acecfSBarry Smith 7979db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMProjectFunctionLocal()`, `DMProjectFunctionLabel()`, `DMComputeL2Diff()` 7980a6e0b375SMatthew G. Knepley @*/ 79811c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFunctionLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX) 79824d6f44ffSToby Isaac { 79834d6f44ffSToby Isaac PetscFunctionBegin; 79844d6f44ffSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 7985064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,11); 79869566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX)); 79874d6f44ffSToby Isaac PetscFunctionReturn(0); 79884d6f44ffSToby Isaac } 79892716604bSToby Isaac 7990a6e0b375SMatthew G. Knepley /*@C 7991bb7acecfSBarry 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. 7992a6e0b375SMatthew G. Knepley 7993a6e0b375SMatthew G. Knepley Not collective 7994a6e0b375SMatthew G. Knepley 7995a6e0b375SMatthew G. Knepley Input Parameters: 7996bb7acecfSBarry Smith + dm - The `DM` 7997a6e0b375SMatthew G. Knepley . time - The time 7998a6e0b375SMatthew G. Knepley . localU - The input field vector 7999a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8000a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8001a6e0b375SMatthew G. Knepley 8002a6e0b375SMatthew G. Knepley Output Parameter: 8003a6e0b375SMatthew G. Knepley . localX - The output vector 8004a6e0b375SMatthew G. Knepley 8005a6e0b375SMatthew G. Knepley Calling sequence of func: 8006a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8007a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8008a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8009a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8010a6e0b375SMatthew G. Knepley 8011a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8012a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8013a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8014a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8015a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8016a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8017a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8018a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8019a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8020a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8021a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8022a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8023a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8024a6e0b375SMatthew G. Knepley . t - The current time 8025a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8026a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8027a6e0b375SMatthew G. Knepley . constants - The value of each constant 8028a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8029a6e0b375SMatthew G. Knepley 8030bb7acecfSBarry Smith Note: 8031bb7acecfSBarry 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. 8032bb7acecfSBarry 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 8033bb7acecfSBarry 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 8034a6e0b375SMatthew 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. 8035a6e0b375SMatthew G. Knepley 8036a6e0b375SMatthew G. Knepley Level: intermediate 8037a6e0b375SMatthew G. Knepley 8038bb7acecfSBarry Smith Developer Notes: 8039bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8040bb7acecfSBarry Smith 8041bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8042bb7acecfSBarry Smith 8043db781477SPatrick Sanan .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8044a6e0b375SMatthew G. Knepley @*/ 80458c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU, 80468c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 80478c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 80488c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8049191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 80508c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 80518c6c5593SMatthew G. Knepley { 80528c6c5593SMatthew G. Knepley PetscFunctionBegin; 80538c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 80548c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localU,VEC_CLASSID,3); 80558c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(localX,VEC_CLASSID,6); 80569566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX)); 80578c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 80588c6c5593SMatthew G. Knepley } 80598c6c5593SMatthew G. Knepley 8060a6e0b375SMatthew G. Knepley /*@C 8061a6e0b375SMatthew 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. 8062a6e0b375SMatthew G. Knepley 8063a6e0b375SMatthew G. Knepley Not collective 8064a6e0b375SMatthew G. Knepley 8065a6e0b375SMatthew G. Knepley Input Parameters: 8066bb7acecfSBarry Smith + dm - The `DM` 8067a6e0b375SMatthew G. Knepley . time - The time 8068bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8069a6e0b375SMatthew G. Knepley . numIds - The number of label ids to use 8070a6e0b375SMatthew G. Knepley . ids - The label ids to use for marking 8071bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8072a6e0b375SMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8073a6e0b375SMatthew G. Knepley . localU - The input field vector 8074a6e0b375SMatthew G. Knepley . funcs - The functions to evaluate, one per field 8075a6e0b375SMatthew G. Knepley - mode - The insertion mode for values 8076a6e0b375SMatthew G. Knepley 8077a6e0b375SMatthew G. Knepley Output Parameter: 8078a6e0b375SMatthew G. Knepley . localX - The output vector 8079a6e0b375SMatthew G. Knepley 8080a6e0b375SMatthew G. Knepley Calling sequence of func: 8081a6e0b375SMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8082a6e0b375SMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8083a6e0b375SMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8084a6e0b375SMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8085a6e0b375SMatthew G. Knepley 8086a6e0b375SMatthew G. Knepley + dim - The spatial dimension 8087a6e0b375SMatthew G. Knepley . Nf - The number of input fields 8088a6e0b375SMatthew G. Knepley . NfAux - The number of input auxiliary fields 8089a6e0b375SMatthew G. Knepley . uOff - The offset of each field in u[] 8090a6e0b375SMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8091a6e0b375SMatthew G. Knepley . u - The field values at this point in space 8092a6e0b375SMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8093a6e0b375SMatthew G. Knepley . u_x - The field derivatives at this point in space 8094a6e0b375SMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8095a6e0b375SMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8096a6e0b375SMatthew G. Knepley . a - The auxiliary field values at this point in space 8097a6e0b375SMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8098a6e0b375SMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8099a6e0b375SMatthew G. Knepley . t - The current time 8100a6e0b375SMatthew G. Knepley . x - The coordinates of this point 8101a6e0b375SMatthew G. Knepley . numConstants - The number of constants 8102a6e0b375SMatthew G. Knepley . constants - The value of each constant 8103a6e0b375SMatthew G. Knepley - f - The value of the function at this point in space 8104a6e0b375SMatthew G. Knepley 8105bb7acecfSBarry Smith Note: 8106bb7acecfSBarry 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. 8107bb7acecfSBarry 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 8108bb7acecfSBarry 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 8109a6e0b375SMatthew 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. 8110a6e0b375SMatthew G. Knepley 8111a6e0b375SMatthew G. Knepley Level: intermediate 8112a6e0b375SMatthew G. Knepley 8113bb7acecfSBarry Smith Developer Notes: 8114bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8115bb7acecfSBarry Smith 8116bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8117bb7acecfSBarry Smith 8118d29d7c6eSMatthew G. Knepley .seealso: `DMProjectField()`, `DMProjectFieldLabel()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8119a6e0b375SMatthew G. Knepley @*/ 81201c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 81218c6c5593SMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 81228c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 81238c6c5593SMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8124191494d9SMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 81258c6c5593SMatthew G. Knepley InsertMode mode, Vec localX) 81268c6c5593SMatthew G. Knepley { 81278c6c5593SMatthew G. Knepley PetscFunctionBegin; 81288c6c5593SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8129064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU,VEC_CLASSID,8); 8130064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,11); 81319566063dSJacob Faibussowitsch PetscCall((dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 81328c6c5593SMatthew G. Knepley PetscFunctionReturn(0); 81338c6c5593SMatthew G. Knepley } 81348c6c5593SMatthew G. Knepley 81352716604bSToby Isaac /*@C 8136d29d7c6eSMatthew 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. 8137d29d7c6eSMatthew G. Knepley 8138d29d7c6eSMatthew G. Knepley Not collective 8139d29d7c6eSMatthew G. Knepley 8140d29d7c6eSMatthew G. Knepley Input Parameters: 8141bb7acecfSBarry Smith + dm - The `DM` 8142d29d7c6eSMatthew G. Knepley . time - The time 8143bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain to output 8144d29d7c6eSMatthew G. Knepley . numIds - The number of label ids to use 8145d29d7c6eSMatthew G. Knepley . ids - The label ids to use for marking 8146bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8147d29d7c6eSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8148d29d7c6eSMatthew G. Knepley . U - The input field vector 8149d29d7c6eSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8150d29d7c6eSMatthew G. Knepley - mode - The insertion mode for values 8151d29d7c6eSMatthew G. Knepley 8152d29d7c6eSMatthew G. Knepley Output Parameter: 8153d29d7c6eSMatthew G. Knepley . X - The output vector 8154d29d7c6eSMatthew G. Knepley 8155d29d7c6eSMatthew G. Knepley Calling sequence of func: 8156d29d7c6eSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8157d29d7c6eSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8158d29d7c6eSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8159d29d7c6eSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8160d29d7c6eSMatthew G. Knepley 8161d29d7c6eSMatthew G. Knepley + dim - The spatial dimension 8162d29d7c6eSMatthew G. Knepley . Nf - The number of input fields 8163d29d7c6eSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8164d29d7c6eSMatthew G. Knepley . uOff - The offset of each field in u[] 8165d29d7c6eSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8166d29d7c6eSMatthew G. Knepley . u - The field values at this point in space 8167d29d7c6eSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8168d29d7c6eSMatthew G. Knepley . u_x - The field derivatives at this point in space 8169d29d7c6eSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8170d29d7c6eSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8171d29d7c6eSMatthew G. Knepley . a - The auxiliary field values at this point in space 8172d29d7c6eSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8173d29d7c6eSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8174d29d7c6eSMatthew G. Knepley . t - The current time 8175d29d7c6eSMatthew G. Knepley . x - The coordinates of this point 8176d29d7c6eSMatthew G. Knepley . numConstants - The number of constants 8177d29d7c6eSMatthew G. Knepley . constants - The value of each constant 8178d29d7c6eSMatthew G. Knepley - f - The value of the function at this point in space 8179d29d7c6eSMatthew G. Knepley 8180bb7acecfSBarry Smith Note: 8181bb7acecfSBarry 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. 8182bb7acecfSBarry 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 8183bb7acecfSBarry 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 8184d29d7c6eSMatthew 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. 8185d29d7c6eSMatthew G. Knepley 8186d29d7c6eSMatthew G. Knepley Level: intermediate 8187d29d7c6eSMatthew G. Knepley 8188bb7acecfSBarry Smith Developer Notes: 8189bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8190bb7acecfSBarry Smith 8191bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8192bb7acecfSBarry Smith 8193d29d7c6eSMatthew G. Knepley .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8194d29d7c6eSMatthew G. Knepley @*/ 8195d29d7c6eSMatthew G. Knepley PetscErrorCode DMProjectFieldLabel(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec U, 8196d29d7c6eSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 8197d29d7c6eSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8198d29d7c6eSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8199d29d7c6eSMatthew G. Knepley PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 8200d29d7c6eSMatthew G. Knepley InsertMode mode, Vec X) 8201d29d7c6eSMatthew G. Knepley { 8202d29d7c6eSMatthew G. Knepley DM dmIn; 8203d29d7c6eSMatthew G. Knepley Vec localU, localX; 8204d29d7c6eSMatthew G. Knepley 8205d29d7c6eSMatthew G. Knepley PetscFunctionBegin; 8206d29d7c6eSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8207d29d7c6eSMatthew G. Knepley PetscCall(VecGetDM(U, &dmIn)); 8208d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dmIn, &localU)); 8209d29d7c6eSMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &localX)); 8210d29d7c6eSMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dm, U, mode, localU)); 8211d29d7c6eSMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dm, U, mode, localU)); 8212d29d7c6eSMatthew G. Knepley PetscCall(DMProjectFieldLabelLocal(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8213d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, localX, mode, X)); 8214d29d7c6eSMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, localX, mode, X)); 8215d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &localX)); 8216d29d7c6eSMatthew G. Knepley PetscCall(DMRestoreLocalVector(dmIn, &localU)); 8217d29d7c6eSMatthew G. Knepley PetscFunctionReturn(0); 8218d29d7c6eSMatthew G. Knepley } 8219d29d7c6eSMatthew G. Knepley 8220d29d7c6eSMatthew G. Knepley /*@C 8221ece3a9fcSMatthew 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. 8222ece3a9fcSMatthew G. Knepley 8223ece3a9fcSMatthew G. Knepley Not collective 8224ece3a9fcSMatthew G. Knepley 8225ece3a9fcSMatthew G. Knepley Input Parameters: 8226bb7acecfSBarry Smith + dm - The `DM` 8227ece3a9fcSMatthew G. Knepley . time - The time 8228bb7acecfSBarry Smith . label - The `DMLabel` marking the portion of the domain boundary to output 8229ece3a9fcSMatthew G. Knepley . numIds - The number of label ids to use 8230ece3a9fcSMatthew G. Knepley . ids - The label ids to use for marking 8231bb7acecfSBarry Smith . Nc - The number of components to set in the output, or `PETSC_DETERMINE` for all components 8232ece3a9fcSMatthew G. Knepley . comps - The components to set in the output, or NULL for all components 8233ece3a9fcSMatthew G. Knepley . localU - The input field vector 8234ece3a9fcSMatthew G. Knepley . funcs - The functions to evaluate, one per field 8235ece3a9fcSMatthew G. Knepley - mode - The insertion mode for values 8236ece3a9fcSMatthew G. Knepley 8237ece3a9fcSMatthew G. Knepley Output Parameter: 8238ece3a9fcSMatthew G. Knepley . localX - The output vector 8239ece3a9fcSMatthew G. Knepley 8240ece3a9fcSMatthew G. Knepley Calling sequence of func: 8241ece3a9fcSMatthew G. Knepley $ func(PetscInt dim, PetscInt Nf, PetscInt NfAux, 8242ece3a9fcSMatthew G. Knepley $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 8243ece3a9fcSMatthew G. Knepley $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 8244ece3a9fcSMatthew G. Knepley $ PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f[]); 8245ece3a9fcSMatthew G. Knepley 8246ece3a9fcSMatthew G. Knepley + dim - The spatial dimension 8247ece3a9fcSMatthew G. Knepley . Nf - The number of input fields 8248ece3a9fcSMatthew G. Knepley . NfAux - The number of input auxiliary fields 8249ece3a9fcSMatthew G. Knepley . uOff - The offset of each field in u[] 8250ece3a9fcSMatthew G. Knepley . uOff_x - The offset of each field in u_x[] 8251ece3a9fcSMatthew G. Knepley . u - The field values at this point in space 8252ece3a9fcSMatthew G. Knepley . u_t - The field time derivative at this point in space (or NULL) 8253ece3a9fcSMatthew G. Knepley . u_x - The field derivatives at this point in space 8254ece3a9fcSMatthew G. Knepley . aOff - The offset of each auxiliary field in u[] 8255ece3a9fcSMatthew G. Knepley . aOff_x - The offset of each auxiliary field in u_x[] 8256ece3a9fcSMatthew G. Knepley . a - The auxiliary field values at this point in space 8257ece3a9fcSMatthew G. Knepley . a_t - The auxiliary field time derivative at this point in space (or NULL) 8258ece3a9fcSMatthew G. Knepley . a_x - The auxiliary field derivatives at this point in space 8259ece3a9fcSMatthew G. Knepley . t - The current time 8260ece3a9fcSMatthew G. Knepley . x - The coordinates of this point 8261ece3a9fcSMatthew G. Knepley . n - The face normal 8262ece3a9fcSMatthew G. Knepley . numConstants - The number of constants 8263ece3a9fcSMatthew G. Knepley . constants - The value of each constant 8264ece3a9fcSMatthew G. Knepley - f - The value of the function at this point in space 8265ece3a9fcSMatthew G. Knepley 8266ece3a9fcSMatthew G. Knepley Note: 8267bb7acecfSBarry 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. 8268bb7acecfSBarry 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 8269bb7acecfSBarry 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 8270ece3a9fcSMatthew 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. 8271ece3a9fcSMatthew G. Knepley 8272ece3a9fcSMatthew G. Knepley Level: intermediate 8273ece3a9fcSMatthew G. Knepley 8274bb7acecfSBarry Smith Developer Notes: 8275bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8276bb7acecfSBarry Smith 8277bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8278bb7acecfSBarry Smith 8279db781477SPatrick Sanan .seealso: `DMProjectField()`, `DMProjectFieldLabelLocal()`, `DMProjectFunction()`, `DMComputeL2Diff()` 8280ece3a9fcSMatthew G. Knepley @*/ 8281ece3a9fcSMatthew G. Knepley PetscErrorCode DMProjectBdFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU, 8282ece3a9fcSMatthew G. Knepley void (**funcs)(PetscInt, PetscInt, PetscInt, 8283ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8284ece3a9fcSMatthew G. Knepley const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], 8285ece3a9fcSMatthew G. Knepley PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), 8286ece3a9fcSMatthew G. Knepley InsertMode mode, Vec localX) 8287ece3a9fcSMatthew G. Knepley { 8288ece3a9fcSMatthew G. Knepley PetscFunctionBegin; 8289ece3a9fcSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8290064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localU,VEC_CLASSID,8); 8291064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(localX,VEC_CLASSID,11); 82929566063dSJacob Faibussowitsch PetscCall((dm->ops->projectbdfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX)); 8293ece3a9fcSMatthew G. Knepley PetscFunctionReturn(0); 8294ece3a9fcSMatthew G. Knepley } 8295ece3a9fcSMatthew G. Knepley 8296ece3a9fcSMatthew G. Knepley /*@C 82972716604bSToby Isaac DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h. 82982716604bSToby Isaac 8299bb7acecfSBarry Smith Collective on dm 8300bb7acecfSBarry Smith 83012716604bSToby Isaac Input Parameters: 8302bb7acecfSBarry Smith + dm - The `DM` 83030709b2feSToby Isaac . time - The time 83042716604bSToby Isaac . funcs - The functions to evaluate for each field component 83052716604bSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8306574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 83072716604bSToby Isaac 83082716604bSToby Isaac Output Parameter: 83092716604bSToby Isaac . diff - The diff ||u - u_h||_2 83102716604bSToby Isaac 83112716604bSToby Isaac Level: developer 83122716604bSToby Isaac 8313bb7acecfSBarry Smith Developer Notes: 8314bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8315bb7acecfSBarry Smith 8316bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8317bb7acecfSBarry Smith 8318db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 83192716604bSToby Isaac @*/ 83200709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff) 83212716604bSToby Isaac { 83222716604bSToby Isaac PetscFunctionBegin; 83232716604bSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8324b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 83259566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff)); 83262716604bSToby Isaac PetscFunctionReturn(0); 83272716604bSToby Isaac } 8328b698f381SToby Isaac 8329b698f381SToby Isaac /*@C 8330b698f381SToby Isaac DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h. 8331b698f381SToby Isaac 8332d083f849SBarry Smith Collective on dm 8333d083f849SBarry Smith 8334b698f381SToby Isaac Input Parameters: 8335bb7acecfSBarry Smith + dm - The `DM` 8336b698f381SToby Isaac , time - The time 8337b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component 8338b698f381SToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8339574a98acSMatthew G. Knepley . X - The coefficient vector u_h, a global vector 8340b698f381SToby Isaac - n - The vector to project along 8341b698f381SToby Isaac 8342b698f381SToby Isaac Output Parameter: 8343b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2 8344b698f381SToby Isaac 8345b698f381SToby Isaac Level: developer 8346b698f381SToby Isaac 8347bb7acecfSBarry Smith Developer Notes: 8348bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8349bb7acecfSBarry Smith 8350bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8351bb7acecfSBarry Smith 8352bb7acecfSBarry Smith .seealso: `DMProjectFunction()`, `DMComputeL2Diff()`, `DMComputeL2FieldDiff()` 8353b698f381SToby Isaac @*/ 8354b698f381SToby Isaac 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) 8355b698f381SToby Isaac { 8356b698f381SToby Isaac PetscFunctionBegin; 8357b698f381SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 8358b698f381SToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 83599566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff)); 8360b698f381SToby Isaac PetscFunctionReturn(0); 8361b698f381SToby Isaac } 8362b698f381SToby Isaac 83632a16baeaSToby Isaac /*@C 83642a16baeaSToby Isaac DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components. 83652a16baeaSToby Isaac 8366d083f849SBarry Smith Collective on dm 8367d083f849SBarry Smith 83682a16baeaSToby Isaac Input Parameters: 8369bb7acecfSBarry Smith + dm - The `DM` 83702a16baeaSToby Isaac . time - The time 83712a16baeaSToby Isaac . funcs - The functions to evaluate for each field component 83722a16baeaSToby Isaac . ctxs - Optional array of contexts to pass to each function, or NULL. 8373574a98acSMatthew G. Knepley - X - The coefficient vector u_h, a global vector 83742a16baeaSToby Isaac 83752a16baeaSToby Isaac Output Parameter: 83762a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2 83772a16baeaSToby Isaac 83782a16baeaSToby Isaac Level: developer 83792a16baeaSToby Isaac 8380bb7acecfSBarry Smith Developer Notes: 8381bb7acecfSBarry Smith This API is specific to only particular usage of `DM` 8382bb7acecfSBarry Smith 8383bb7acecfSBarry Smith The notes need to provide some information about what has to be provided to the `DM` to be able to perform the computation. 8384bb7acecfSBarry Smith 8385db781477SPatrick Sanan .seealso: `DMProjectFunction()`, `DMComputeL2FieldDiff()`, `DMComputeL2GradientDiff()` 83862a16baeaSToby Isaac @*/ 83871189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[]) 83882a16baeaSToby Isaac { 83892a16baeaSToby Isaac PetscFunctionBegin; 83902a16baeaSToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 83912a16baeaSToby Isaac PetscValidHeaderSpecific(X,VEC_CLASSID,5); 83929566063dSJacob Faibussowitsch PetscCall((dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff)); 83932a16baeaSToby Isaac PetscFunctionReturn(0); 83942a16baeaSToby Isaac } 83952a16baeaSToby Isaac 8396df0b854cSToby Isaac /*@C 8397bb7acecfSBarry Smith DMGetNeighbors - Gets an array containing the MPI ranks of all the processes neighbors 8398502a2867SDave May 8399502a2867SDave May Not Collective 8400502a2867SDave May 8401502a2867SDave May Input Parameter: 8402bb7acecfSBarry Smith . dm - The `DM` 8403502a2867SDave May 84040a19bb7dSprj- Output Parameters: 84050a19bb7dSprj- + nranks - the number of neighbours 84060a19bb7dSprj- - ranks - the neighbors ranks 8407502a2867SDave May 8408bb7acecfSBarry Smith Note: 8409bb7acecfSBarry Smith Do not free the array, it is freed when the `DM` is destroyed. 8410502a2867SDave May 8411502a2867SDave May Level: beginner 8412502a2867SDave May 8413db781477SPatrick Sanan .seealso: `DMDAGetNeighbors()`, `PetscSFGetRootRanks()` 8414502a2867SDave May @*/ 8415502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[]) 8416502a2867SDave May { 8417502a2867SDave May PetscFunctionBegin; 8418502a2867SDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 84199566063dSJacob Faibussowitsch PetscCall((dm->ops->getneighbors)(dm,nranks,ranks)); 8420502a2867SDave May PetscFunctionReturn(0); 8421502a2867SDave May } 8422502a2867SDave May 8423531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */ 8424531c7667SBarry Smith 8425531c7667SBarry Smith /* 8426531c7667SBarry Smith Converts the input vector to a ghosted vector and then calls the standard coloring code. 8427531c7667SBarry Smith This has be a different function because it requires DM which is not defined in the Mat library 8428531c7667SBarry Smith */ 8429531c7667SBarry Smith PetscErrorCode MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx) 8430531c7667SBarry Smith { 8431531c7667SBarry Smith PetscFunctionBegin; 8432531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8433531c7667SBarry Smith Vec x1local; 8434531c7667SBarry Smith DM dm; 84359566063dSJacob Faibussowitsch PetscCall(MatGetDM(J,&dm)); 84367a8be351SBarry Smith PetscCheck(dm,PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM"); 84379566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm,&x1local)); 84389566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local)); 84399566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local)); 8440531c7667SBarry Smith x1 = x1local; 8441531c7667SBarry Smith } 84429566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply_AIJ(J,coloring,x1,sctx)); 8443531c7667SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 8444531c7667SBarry Smith DM dm; 84459566063dSJacob Faibussowitsch PetscCall(MatGetDM(J,&dm)); 84469566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm,&x1)); 8447531c7667SBarry Smith } 8448531c7667SBarry Smith PetscFunctionReturn(0); 8449531c7667SBarry Smith } 8450531c7667SBarry Smith 8451531c7667SBarry Smith /*@ 8452bb7acecfSBarry Smith MatFDColoringUseDM - allows a `MatFDColoring` object to use the `DM` associated with the matrix to compute a `IS_COLORING_LOCAL` coloring 8453531c7667SBarry Smith 8454531c7667SBarry Smith Input Parameter: 8455bb7acecfSBarry Smith . coloring - the `MatFDColoring` object 8456531c7667SBarry Smith 8457bb7acecfSBarry Smith Developer Note: 8458bb7acecfSBarry Smith this routine exists because the PETSc `Mat` library does not know about the `DM` objects 8459531c7667SBarry Smith 84601b266c99SBarry Smith Level: advanced 84611b266c99SBarry Smith 8462db781477SPatrick Sanan .seealso: `MatFDColoring`, `MatFDColoringCreate()`, `ISColoringType` 8463531c7667SBarry Smith @*/ 8464531c7667SBarry Smith PetscErrorCode MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring) 8465531c7667SBarry Smith { 8466531c7667SBarry Smith PetscFunctionBegin; 8467531c7667SBarry Smith coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM; 8468531c7667SBarry Smith PetscFunctionReturn(0); 8469531c7667SBarry Smith } 84708320bc6fSPatrick Sanan 84718320bc6fSPatrick Sanan /*@ 8472bb7acecfSBarry Smith DMGetCompatibility - determine if two `DM`s are compatible 84738320bc6fSPatrick Sanan 84748320bc6fSPatrick Sanan Collective 84758320bc6fSPatrick Sanan 84768320bc6fSPatrick Sanan Input Parameters: 8477bb7acecfSBarry Smith + dm1 - the first `DM` 8478bb7acecfSBarry Smith - dm2 - the second `DM` 84798320bc6fSPatrick Sanan 84808320bc6fSPatrick Sanan Output Parameters: 8481bb7acecfSBarry Smith + compatible - whether or not the two `DM`s are compatible 8482bb7acecfSBarry Smith - set - whether or not the compatible value was actually determined and set 84838320bc6fSPatrick Sanan 84848320bc6fSPatrick Sanan Notes: 8485bb7acecfSBarry Smith Two `DM`s are deemed compatible if they represent the same parallel decomposition 84863d862458SPatrick Sanan of the same topology. This implies that the section (field data) on one 84878320bc6fSPatrick Sanan "makes sense" with respect to the topology and parallel decomposition of the other. 8488bb7acecfSBarry Smith Loosely speaking, compatible `DM`s represent the same domain and parallel 84893d862458SPatrick Sanan decomposition, but hold different data. 84908320bc6fSPatrick Sanan 84918320bc6fSPatrick Sanan Typically, one would confirm compatibility if intending to simultaneously iterate 8492bb7acecfSBarry Smith over a pair of vectors obtained from different `DM`s. 84938320bc6fSPatrick Sanan 8494bb7acecfSBarry Smith For example, two `DMDA` objects are compatible if they have the same local 84958320bc6fSPatrick Sanan and global sizes and the same stencil width. They can have different numbers 84968320bc6fSPatrick Sanan of degrees of freedom per node. Thus, one could use the node numbering from 8497bb7acecfSBarry Smith either `DM` in bounds for a loop over vectors derived from either `DM`. 84988320bc6fSPatrick Sanan 8499bb7acecfSBarry Smith Consider the operation of summing data living on a 2-dof `DMDA` to data living 8500bb7acecfSBarry Smith on a 1-dof `DMDA`, which should be compatible, as in the following snippet. 85018320bc6fSPatrick Sanan .vb 85028320bc6fSPatrick Sanan ... 85039566063dSJacob Faibussowitsch PetscCall(DMGetCompatibility(da1,da2,&compatible,&set)); 85048320bc6fSPatrick Sanan if (set && compatible) { 85059566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1)); 85069566063dSJacob Faibussowitsch PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2)); 85079566063dSJacob Faibussowitsch PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL)); 85088320bc6fSPatrick Sanan for (j=y; j<y+n; ++j) { 85098320bc6fSPatrick Sanan for (i=x; i<x+m, ++i) { 85108320bc6fSPatrick Sanan arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1]; 85118320bc6fSPatrick Sanan } 85128320bc6fSPatrick Sanan } 85139566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1)); 85149566063dSJacob Faibussowitsch PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2)); 85158320bc6fSPatrick Sanan } else { 85168320bc6fSPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible"); 85178320bc6fSPatrick Sanan } 85188320bc6fSPatrick Sanan ... 85198320bc6fSPatrick Sanan .ve 85208320bc6fSPatrick Sanan 8521bb7acecfSBarry Smith Checking compatibility might be expensive for a given implementation of `DM`, 85228320bc6fSPatrick Sanan or might be impossible to unambiguously confirm or deny. For this reason, 85238320bc6fSPatrick Sanan this function may decline to determine compatibility, and hence users should 85248320bc6fSPatrick Sanan always check the "set" output parameter. 85258320bc6fSPatrick Sanan 8526bb7acecfSBarry Smith A `DM` is always compatible with itself. 85278320bc6fSPatrick Sanan 8528bb7acecfSBarry Smith In the current implementation, `DM`s which live on "unequal" communicators 85298320bc6fSPatrick Sanan (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed 85308320bc6fSPatrick Sanan incompatible. 85318320bc6fSPatrick Sanan 85328320bc6fSPatrick Sanan This function is labeled "Collective," as information about all subdomains 8533bb7acecfSBarry Smith is required on each rank. However, in `DM` implementations which store all this 85348320bc6fSPatrick Sanan information locally, this function may be merely "Logically Collective". 85358320bc6fSPatrick Sanan 8536bb7acecfSBarry Smith Developer Note: 8537bb7acecfSBarry Smith Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B 85383d862458SPatrick Sanan iff B is compatible with A. Thus, this function checks the implementations 8539a5bc1bf3SBarry Smith of both dm and dmc (if they are of different types), attempting to determine 8540bb7acecfSBarry Smith compatibility. It is left to `DM` implementers to ensure that symmetry is 85418320bc6fSPatrick Sanan preserved. The simplest way to do this is, when implementing type-specific 85423d862458SPatrick Sanan logic for this function, is to check for existing logic in the implementation 8543bb7acecfSBarry Smith of other `DM` types and let *set = PETSC_FALSE if found. 85448320bc6fSPatrick Sanan 85458320bc6fSPatrick Sanan Level: advanced 85468320bc6fSPatrick Sanan 8547db781477SPatrick Sanan .seealso: `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()` 85488320bc6fSPatrick Sanan @*/ 8549a5bc1bf3SBarry Smith PetscErrorCode DMGetCompatibility(DM dm1,DM dm2,PetscBool *compatible,PetscBool *set) 85508320bc6fSPatrick Sanan { 85518320bc6fSPatrick Sanan PetscMPIInt compareResult; 85528320bc6fSPatrick Sanan DMType type,type2; 85538320bc6fSPatrick Sanan PetscBool sameType; 85548320bc6fSPatrick Sanan 85558320bc6fSPatrick Sanan PetscFunctionBegin; 8556a5bc1bf3SBarry Smith PetscValidHeaderSpecific(dm1,DM_CLASSID,1); 85578320bc6fSPatrick Sanan PetscValidHeaderSpecific(dm2,DM_CLASSID,2); 85588320bc6fSPatrick Sanan 85598320bc6fSPatrick Sanan /* Declare a DM compatible with itself */ 8560a5bc1bf3SBarry Smith if (dm1 == dm2) { 85618320bc6fSPatrick Sanan *set = PETSC_TRUE; 85628320bc6fSPatrick Sanan *compatible = PETSC_TRUE; 85638320bc6fSPatrick Sanan PetscFunctionReturn(0); 85648320bc6fSPatrick Sanan } 85658320bc6fSPatrick Sanan 85668320bc6fSPatrick Sanan /* Declare a DM incompatible with a DM that lives on an "unequal" 85678320bc6fSPatrick Sanan communicator. Note that this does not preclude compatibility with 85688320bc6fSPatrick Sanan DMs living on "congruent" or "similar" communicators, but this must be 85698320bc6fSPatrick Sanan determined by the implementation-specific logic */ 85709566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)dm1),PetscObjectComm((PetscObject)dm2),&compareResult)); 85718320bc6fSPatrick Sanan if (compareResult == MPI_UNEQUAL) { 85728320bc6fSPatrick Sanan *set = PETSC_TRUE; 85738320bc6fSPatrick Sanan *compatible = PETSC_FALSE; 85748320bc6fSPatrick Sanan PetscFunctionReturn(0); 85758320bc6fSPatrick Sanan } 85768320bc6fSPatrick Sanan 85778320bc6fSPatrick Sanan /* Pass to the implementation-specific routine, if one exists. */ 8578a5bc1bf3SBarry Smith if (dm1->ops->getcompatibility) { 8579*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm1,getcompatibility ,dm2,compatible,set); 8580b9d85ea2SLisandro Dalcin if (*set) PetscFunctionReturn(0); 85818320bc6fSPatrick Sanan } 85828320bc6fSPatrick Sanan 8583a5bc1bf3SBarry Smith /* If dm1 and dm2 are of different types, then attempt to check compatibility 85848320bc6fSPatrick Sanan with an implementation of this function from dm2 */ 85859566063dSJacob Faibussowitsch PetscCall(DMGetType(dm1,&type)); 85869566063dSJacob Faibussowitsch PetscCall(DMGetType(dm2,&type2)); 85879566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(type,type2,&sameType)); 85888320bc6fSPatrick Sanan if (!sameType && dm2->ops->getcompatibility) { 8589*dbbe0bcdSBarry Smith PetscUseTypeMethod(dm2,getcompatibility ,dm1,compatible,set); /* Note argument order */ 85908320bc6fSPatrick Sanan } else { 85918320bc6fSPatrick Sanan *set = PETSC_FALSE; 85928320bc6fSPatrick Sanan } 85938320bc6fSPatrick Sanan PetscFunctionReturn(0); 85948320bc6fSPatrick Sanan } 8595c0f0dcc3SMatthew G. Knepley 8596c0f0dcc3SMatthew G. Knepley /*@C 8597bb7acecfSBarry Smith DMMonitorSet - Sets an additional monitor function that is to be used after a solve to monitor discretization performance. 8598c0f0dcc3SMatthew G. Knepley 8599bb7acecfSBarry Smith Logically Collective on dm 8600c0f0dcc3SMatthew G. Knepley 8601c0f0dcc3SMatthew G. Knepley Input Parameters: 8602bb7acecfSBarry Smith + DM - the `DM` 8603c0f0dcc3SMatthew G. Knepley . f - the monitor function 8604c0f0dcc3SMatthew G. Knepley . mctx - [optional] user-defined context for private data for the monitor routine (use NULL if no context is desired) 8605c0f0dcc3SMatthew G. Knepley - monitordestroy - [optional] routine that frees monitor context (may be NULL) 8606c0f0dcc3SMatthew G. Knepley 8607c0f0dcc3SMatthew G. Knepley Options Database Keys: 8608bb7acecfSBarry Smith - -dm_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `DMMonitorSet()`, but 8609c0f0dcc3SMatthew G. Knepley does not cancel those set via the options database. 8610c0f0dcc3SMatthew G. Knepley 8611bb7acecfSBarry Smith Note: 8612c0f0dcc3SMatthew G. Knepley Several different monitoring routines may be set by calling 8613bb7acecfSBarry Smith `DMMonitorSet()` multiple times or with `DMMonitorSetFromOptions()`; all will be called in the 8614c0f0dcc3SMatthew G. Knepley order in which they were set. 8615c0f0dcc3SMatthew G. Knepley 8616bb7acecfSBarry Smith Fortran Note: 8617bb7acecfSBarry Smith Only a single monitor function can be set for each `DM` object 8618bb7acecfSBarry Smith 8619bb7acecfSBarry Smith Developer Note: 8620bb7acecfSBarry Smith This API has a generic name but seems specific to a very particular aspect of the use of `DM` 8621c0f0dcc3SMatthew G. Knepley 8622c0f0dcc3SMatthew G. Knepley Level: intermediate 8623c0f0dcc3SMatthew G. Knepley 8624bb7acecfSBarry Smith .seealso: `DMMonitorCancel()`,`DMMonitorSetFromOptions()`, `DMMonitor()` 8625c0f0dcc3SMatthew G. Knepley @*/ 8626c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSet(DM dm, PetscErrorCode (*f)(DM, void *), void *mctx, PetscErrorCode (*monitordestroy)(void**)) 8627c0f0dcc3SMatthew G. Knepley { 8628c0f0dcc3SMatthew G. Knepley PetscInt m; 8629c0f0dcc3SMatthew G. Knepley 8630c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8631c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8632c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 8633c0f0dcc3SMatthew G. Knepley PetscBool identical; 8634c0f0dcc3SMatthew G. Knepley 86359566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void)) f, mctx, monitordestroy, (PetscErrorCode (*)(void)) dm->monitor[m], dm->monitorcontext[m], dm->monitordestroy[m], &identical)); 8636c0f0dcc3SMatthew G. Knepley if (identical) PetscFunctionReturn(0); 8637c0f0dcc3SMatthew G. Knepley } 86387a8be351SBarry Smith PetscCheck(dm->numbermonitors < MAXDMMONITORS,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 8639c0f0dcc3SMatthew G. Knepley dm->monitor[dm->numbermonitors] = f; 8640c0f0dcc3SMatthew G. Knepley dm->monitordestroy[dm->numbermonitors] = monitordestroy; 8641c0f0dcc3SMatthew G. Knepley dm->monitorcontext[dm->numbermonitors++] = (void *) mctx; 8642c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8643c0f0dcc3SMatthew G. Knepley } 8644c0f0dcc3SMatthew G. Knepley 8645c0f0dcc3SMatthew G. Knepley /*@ 8646bb7acecfSBarry Smith DMMonitorCancel - Clears all the monitor functions for a `DM` object. 8647c0f0dcc3SMatthew G. Knepley 8648bb7acecfSBarry Smith Logically Collective on dm 8649c0f0dcc3SMatthew G. Knepley 8650c0f0dcc3SMatthew G. Knepley Input Parameter: 8651c0f0dcc3SMatthew G. Knepley . dm - the DM 8652c0f0dcc3SMatthew G. Knepley 8653c0f0dcc3SMatthew G. Knepley Options Database Key: 8654c0f0dcc3SMatthew G. Knepley . -dm_monitor_cancel - cancels all monitors that have been hardwired 8655bb7acecfSBarry Smith into a code by calls to `DMonitorSet()`, but does not cancel those 8656c0f0dcc3SMatthew G. Knepley set via the options database 8657c0f0dcc3SMatthew G. Knepley 8658bb7acecfSBarry Smith Note: 8659bb7acecfSBarry Smith There is no way to clear one specific monitor from a `DM` object. 8660c0f0dcc3SMatthew G. Knepley 8661c0f0dcc3SMatthew G. Knepley Level: intermediate 8662c0f0dcc3SMatthew G. Knepley 8663bb7acecfSBarry Smith .seealso: `DMMonitorSet()`, `DMMonitorSetFromOptions()`, `DMMonitor()` 8664c0f0dcc3SMatthew G. Knepley @*/ 8665c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorCancel(DM dm) 8666c0f0dcc3SMatthew G. Knepley { 8667c0f0dcc3SMatthew G. Knepley PetscInt m; 8668c0f0dcc3SMatthew G. Knepley 8669c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8670c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8671c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 86729566063dSJacob Faibussowitsch if (dm->monitordestroy[m]) PetscCall((*dm->monitordestroy[m])(&dm->monitorcontext[m])); 8673c0f0dcc3SMatthew G. Knepley } 8674c0f0dcc3SMatthew G. Knepley dm->numbermonitors = 0; 8675c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8676c0f0dcc3SMatthew G. Knepley } 8677c0f0dcc3SMatthew G. Knepley 8678c0f0dcc3SMatthew G. Knepley /*@C 8679c0f0dcc3SMatthew G. Knepley DMMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 8680c0f0dcc3SMatthew G. Knepley 8681bb7acecfSBarry Smith Collective on dm 8682c0f0dcc3SMatthew G. Knepley 8683c0f0dcc3SMatthew G. Knepley Input Parameters: 8684bb7acecfSBarry Smith + dm - `DM` object you wish to monitor 8685c0f0dcc3SMatthew G. Knepley . name - the monitor type one is seeking 8686c0f0dcc3SMatthew G. Knepley . help - message indicating what monitoring is done 8687c0f0dcc3SMatthew G. Knepley . manual - manual page for the monitor 8688c0f0dcc3SMatthew G. Knepley . monitor - the monitor function 8689bb7acecfSBarry 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 8690c0f0dcc3SMatthew G. Knepley 8691c0f0dcc3SMatthew G. Knepley Output Parameter: 8692c0f0dcc3SMatthew G. Knepley . flg - Flag set if the monitor was created 8693c0f0dcc3SMatthew G. Knepley 8694c0f0dcc3SMatthew G. Knepley Level: developer 8695c0f0dcc3SMatthew G. Knepley 8696db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 8697db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 8698db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 8699db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 8700c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 8701db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 8702bb7acecfSBarry Smith `PetscOptionsFList()`, `PetscOptionsEList()`, `DMMonitor()`, `DMMonitorSet()` 8703c0f0dcc3SMatthew G. Knepley @*/ 8704c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitorSetFromOptions(DM dm, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(DM, void *), PetscErrorCode (*monitorsetup)(DM, PetscViewerAndFormat *), PetscBool *flg) 8705c0f0dcc3SMatthew G. Knepley { 8706c0f0dcc3SMatthew G. Knepley PetscViewer viewer; 8707c0f0dcc3SMatthew G. Knepley PetscViewerFormat format; 8708c0f0dcc3SMatthew G. Knepley 8709c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8710c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 87119566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject) dm), ((PetscObject) dm)->options, ((PetscObject) dm)->prefix, name, &viewer, &format, flg)); 8712c0f0dcc3SMatthew G. Knepley if (*flg) { 8713c0f0dcc3SMatthew G. Knepley PetscViewerAndFormat *vf; 8714c0f0dcc3SMatthew G. Knepley 87159566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 87169566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject) viewer)); 87179566063dSJacob Faibussowitsch if (monitorsetup) PetscCall((*monitorsetup)(dm, vf)); 87189566063dSJacob Faibussowitsch PetscCall(DMMonitorSet(dm,(PetscErrorCode (*)(DM, void *)) monitor, vf, (PetscErrorCode (*)(void **)) PetscViewerAndFormatDestroy)); 8719c0f0dcc3SMatthew G. Knepley } 8720c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8721c0f0dcc3SMatthew G. Knepley } 8722c0f0dcc3SMatthew G. Knepley 8723c0f0dcc3SMatthew G. Knepley /*@ 8724c0f0dcc3SMatthew G. Knepley DMMonitor - runs the user provided monitor routines, if they exist 8725c0f0dcc3SMatthew G. Knepley 8726bb7acecfSBarry Smith Collective on dm 8727c0f0dcc3SMatthew G. Knepley 8728c0f0dcc3SMatthew G. Knepley Input Parameters: 8729bb7acecfSBarry Smith . dm - The `DM` 8730c0f0dcc3SMatthew G. Knepley 8731c0f0dcc3SMatthew G. Knepley Level: developer 8732c0f0dcc3SMatthew G. Knepley 8733bb7acecfSBarry Smith Question: 8734bb7acecfSBarry Smith Note should indicate when during the life of the `DM` the monitor is run. It appears to be related to the discretization process seems rather specialized 8735bb7acecfSBarry Smith since some `DM` have no concept of discretization 8736bb7acecfSBarry Smith 8737bb7acecfSBarry Smith .seealso: `DMMonitorSet()`, `DMMonitorSetFromOptions()` 8738c0f0dcc3SMatthew G. Knepley @*/ 8739c0f0dcc3SMatthew G. Knepley PetscErrorCode DMMonitor(DM dm) 8740c0f0dcc3SMatthew G. Knepley { 8741c0f0dcc3SMatthew G. Knepley PetscInt m; 8742c0f0dcc3SMatthew G. Knepley 8743c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 8744c0f0dcc3SMatthew G. Knepley if (!dm) PetscFunctionReturn(0); 8745c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8746c0f0dcc3SMatthew G. Knepley for (m = 0; m < dm->numbermonitors; ++m) { 87479566063dSJacob Faibussowitsch PetscCall((*dm->monitor[m])(dm, dm->monitorcontext[m])); 8748c0f0dcc3SMatthew G. Knepley } 8749c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 8750c0f0dcc3SMatthew G. Knepley } 87512e4af2aeSMatthew G. Knepley 87522e4af2aeSMatthew G. Knepley /*@ 8753bb7acecfSBarry Smith DMComputeError - Computes the error assuming the user has provided the exact solution functions 87542e4af2aeSMatthew G. Knepley 8755bb7acecfSBarry Smith Collective on dm 87562e4af2aeSMatthew G. Knepley 87572e4af2aeSMatthew G. Knepley Input Parameters: 8758bb7acecfSBarry Smith + dm - The `DM` 87596b867d5aSJose E. Roman - sol - The solution vector 87602e4af2aeSMatthew G. Knepley 87616b867d5aSJose E. Roman Input/Output Parameter: 87626b867d5aSJose E. Roman . errors - An array of length Nf, the number of fields, or NULL for no output; on output 87636b867d5aSJose E. Roman contains the error in each field 87646b867d5aSJose E. Roman 87656b867d5aSJose E. Roman Output Parameter: 87666b867d5aSJose E. Roman . errorVec - A vector to hold the cellwise error (may be NULL) 87672e4af2aeSMatthew G. Knepley 8768bb7acecfSBarry Smith Note: 8769bb7acecfSBarry Smith The exact solutions come from the `PetscDS` object, and the time comes from `DMGetOutputSequenceNumber()`. 87702e4af2aeSMatthew G. Knepley 87712e4af2aeSMatthew G. Knepley Level: developer 87722e4af2aeSMatthew G. Knepley 8773db781477SPatrick Sanan .seealso: `DMMonitorSet()`, `DMGetRegionNumDS()`, `PetscDSGetExactSolution()`, `DMGetOutputSequenceNumber()` 87742e4af2aeSMatthew G. Knepley @*/ 87752e4af2aeSMatthew G. Knepley PetscErrorCode DMComputeError(DM dm, Vec sol, PetscReal errors[], Vec *errorVec) 87762e4af2aeSMatthew G. Knepley { 87772e4af2aeSMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 87782e4af2aeSMatthew G. Knepley void **ctxs; 87792e4af2aeSMatthew G. Knepley PetscReal time; 87802e4af2aeSMatthew G. Knepley PetscInt Nf, f, Nds, s; 87812e4af2aeSMatthew G. Knepley 87822e4af2aeSMatthew G. Knepley PetscFunctionBegin; 87839566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 87849566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(Nf, &exactSol, Nf, &ctxs)); 87859566063dSJacob Faibussowitsch PetscCall(DMGetNumDS(dm, &Nds)); 87862e4af2aeSMatthew G. Knepley for (s = 0; s < Nds; ++s) { 87872e4af2aeSMatthew G. Knepley PetscDS ds; 87882e4af2aeSMatthew G. Knepley DMLabel label; 87892e4af2aeSMatthew G. Knepley IS fieldIS; 87902e4af2aeSMatthew G. Knepley const PetscInt *fields; 87912e4af2aeSMatthew G. Knepley PetscInt dsNf; 87922e4af2aeSMatthew G. Knepley 87939566063dSJacob Faibussowitsch PetscCall(DMGetRegionNumDS(dm, s, &label, &fieldIS, &ds)); 87949566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(ds, &dsNf)); 87959566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISGetIndices(fieldIS, &fields)); 87962e4af2aeSMatthew G. Knepley for (f = 0; f < dsNf; ++f) { 87972e4af2aeSMatthew G. Knepley const PetscInt field = fields[f]; 87989566063dSJacob Faibussowitsch PetscCall(PetscDSGetExactSolution(ds, field, &exactSol[field], &ctxs[field])); 87992e4af2aeSMatthew G. Knepley } 88009566063dSJacob Faibussowitsch if (fieldIS) PetscCall(ISRestoreIndices(fieldIS, &fields)); 88012e4af2aeSMatthew G. Knepley } 88022e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 880363a3b9bcSJacob Faibussowitsch 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); 88042e4af2aeSMatthew G. Knepley } 88059566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, NULL, &time)); 88069566063dSJacob Faibussowitsch if (errors) PetscCall(DMComputeL2FieldDiff(dm, time, exactSol, ctxs, sol, errors)); 88072e4af2aeSMatthew G. Knepley if (errorVec) { 88082e4af2aeSMatthew G. Knepley DM edm; 88092e4af2aeSMatthew G. Knepley DMPolytopeType ct; 88102e4af2aeSMatthew G. Knepley PetscBool simplex; 88112e4af2aeSMatthew G. Knepley PetscInt dim, cStart, Nf; 88122e4af2aeSMatthew G. Knepley 88139566063dSJacob Faibussowitsch PetscCall(DMClone(dm, &edm)); 88149566063dSJacob Faibussowitsch PetscCall(DMGetDimension(edm, &dim)); 88159566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL)); 88169566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(dm, cStart, &ct)); 88172e4af2aeSMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 88189566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 88192e4af2aeSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 88202e4af2aeSMatthew G. Knepley PetscFE fe, efe; 88212e4af2aeSMatthew G. Knepley PetscQuadrature q; 88222e4af2aeSMatthew G. Knepley const char *name; 88232e4af2aeSMatthew G. Knepley 88249566063dSJacob Faibussowitsch PetscCall(DMGetField(dm, f, NULL, (PetscObject *) &fe)); 88259566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nf, simplex, 0, PETSC_DETERMINE, &efe)); 88269566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) fe, &name)); 88279566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) efe, name)); 88289566063dSJacob Faibussowitsch PetscCall(PetscFEGetQuadrature(fe, &q)); 88299566063dSJacob Faibussowitsch PetscCall(PetscFESetQuadrature(efe, q)); 88309566063dSJacob Faibussowitsch PetscCall(DMSetField(edm, f, NULL, (PetscObject) efe)); 88319566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&efe)); 88322e4af2aeSMatthew G. Knepley } 88339566063dSJacob Faibussowitsch PetscCall(DMCreateDS(edm)); 88342e4af2aeSMatthew G. Knepley 88359566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(edm, errorVec)); 88369566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) *errorVec, "Error")); 88379566063dSJacob Faibussowitsch PetscCall(DMPlexComputeL2DiffVec(dm, time, exactSol, ctxs, sol, *errorVec)); 88389566063dSJacob Faibussowitsch PetscCall(DMDestroy(&edm)); 88392e4af2aeSMatthew G. Knepley } 88409566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, ctxs)); 88412e4af2aeSMatthew G. Knepley PetscFunctionReturn(0); 88422e4af2aeSMatthew G. Knepley } 88439a2a23afSMatthew G. Knepley 88449a2a23afSMatthew G. Knepley /*@ 8845bb7acecfSBarry Smith DMGetNumAuxiliaryVec - Get the number of auxiliary vectors associated with this `DM` 88469a2a23afSMatthew G. Knepley 88479a2a23afSMatthew G. Knepley Not collective 88489a2a23afSMatthew G. Knepley 88499a2a23afSMatthew G. Knepley Input Parameter: 8850bb7acecfSBarry Smith . dm - The `DM` 88519a2a23afSMatthew G. Knepley 88529a2a23afSMatthew G. Knepley Output Parameter: 8853a5b23f4aSJose E. Roman . numAux - The number of auxiliary data vectors 88549a2a23afSMatthew G. Knepley 88559a2a23afSMatthew G. Knepley Level: advanced 88569a2a23afSMatthew G. Knepley 8857bb7acecfSBarry Smith .seealso: `DMSetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 88589a2a23afSMatthew G. Knepley @*/ 88599a2a23afSMatthew G. Knepley PetscErrorCode DMGetNumAuxiliaryVec(DM dm, PetscInt *numAux) 88609a2a23afSMatthew G. Knepley { 88619a2a23afSMatthew G. Knepley PetscFunctionBegin; 88629a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 88639566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetSize(dm->auxData, numAux)); 88649a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 88659a2a23afSMatthew G. Knepley } 88669a2a23afSMatthew G. Knepley 88679a2a23afSMatthew G. Knepley /*@ 8868ac17215fSMatthew G. Knepley DMGetAuxiliaryVec - Get the auxiliary vector for region specified by the given label and value, and equation part 88699a2a23afSMatthew G. Knepley 88709a2a23afSMatthew G. Knepley Not collective 88719a2a23afSMatthew G. Knepley 88729a2a23afSMatthew G. Knepley Input Parameters: 8873bb7acecfSBarry Smith + dm - The `DM` 8874bb7acecfSBarry Smith . label - The `DMLabel` 8875ac17215fSMatthew G. Knepley . value - The label value indicating the region 8876ac17215fSMatthew G. Knepley - part - The equation part, or 0 if unused 88779a2a23afSMatthew G. Knepley 88789a2a23afSMatthew G. Knepley Output Parameter: 8879bb7acecfSBarry Smith . aux - The `Vec` holding auxiliary field data 88809a2a23afSMatthew G. Knepley 8881bb7acecfSBarry Smith Note: 8882bb7acecfSBarry Smith If no auxiliary vector is found for this (label, value), (NULL, 0, 0) is checked as well. 888304c51a94SMatthew G. Knepley 88849a2a23afSMatthew G. Knepley Level: advanced 88859a2a23afSMatthew G. Knepley 8886bb7acecfSBarry Smith .seealso: `DMSetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryLabels()` 88879a2a23afSMatthew G. Knepley @*/ 8888ac17215fSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec *aux) 88899a2a23afSMatthew G. Knepley { 8890ac17215fSMatthew G. Knepley PetscHashAuxKey key, wild = {NULL, 0, 0}; 889104c51a94SMatthew G. Knepley PetscBool has; 88929a2a23afSMatthew G. Knepley 88939a2a23afSMatthew G. Knepley PetscFunctionBegin; 88949a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 88959a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 88969a2a23afSMatthew G. Knepley key.label = label; 88979a2a23afSMatthew G. Knepley key.value = value; 8898ac17215fSMatthew G. Knepley key.part = part; 88999566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxHas(dm->auxData, key, &has)); 89009566063dSJacob Faibussowitsch if (has) PetscCall(PetscHMapAuxGet(dm->auxData, key, aux)); 89019566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxGet(dm->auxData, wild, aux)); 89029a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89039a2a23afSMatthew G. Knepley } 89049a2a23afSMatthew G. Knepley 89059a2a23afSMatthew G. Knepley /*@ 8906bb7acecfSBarry Smith DMSetAuxiliaryVec - Set an auxiliary vector for region specified by the given label and value, and equation part 89079a2a23afSMatthew G. Knepley 8908bb7acecfSBarry Smith Not collective because auxilary vectors are not parallel 89099a2a23afSMatthew G. Knepley 89109a2a23afSMatthew G. Knepley Input Parameters: 8911bb7acecfSBarry Smith + dm - The `DM` 8912bb7acecfSBarry Smith . label - The `DMLabel` 89139a2a23afSMatthew G. Knepley . value - The label value indicating the region 8914ac17215fSMatthew G. Knepley . part - The equation part, or 0 if unused 8915bb7acecfSBarry Smith - aux - The `Vec` holding auxiliary field data 89169a2a23afSMatthew G. Knepley 89179a2a23afSMatthew G. Knepley Level: advanced 89189a2a23afSMatthew G. Knepley 8919bb7acecfSBarry Smith .seealso: `DMGetAuxiliaryVec()`, `DMGetAuxiliaryLabels()`, `DMCopyAuxiliaryVec()` 89209a2a23afSMatthew G. Knepley @*/ 8921ac17215fSMatthew G. Knepley PetscErrorCode DMSetAuxiliaryVec(DM dm, DMLabel label, PetscInt value, PetscInt part, Vec aux) 89229a2a23afSMatthew G. Knepley { 89239a2a23afSMatthew G. Knepley Vec old; 89249a2a23afSMatthew G. Knepley PetscHashAuxKey key; 89259a2a23afSMatthew G. Knepley 89269a2a23afSMatthew G. Knepley PetscFunctionBegin; 89279a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89289a2a23afSMatthew G. Knepley if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 89299a2a23afSMatthew G. Knepley key.label = label; 89309a2a23afSMatthew G. Knepley key.value = value; 8931ac17215fSMatthew G. Knepley key.part = part; 89329566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGet(dm->auxData, key, &old)); 89339566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) aux)); 89349566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject) old)); 89359566063dSJacob Faibussowitsch if (!aux) PetscCall(PetscHMapAuxDel(dm->auxData, key)); 89369566063dSJacob Faibussowitsch else PetscCall(PetscHMapAuxSet(dm->auxData, key, aux)); 89379a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89389a2a23afSMatthew G. Knepley } 89399a2a23afSMatthew G. Knepley 89409a2a23afSMatthew G. Knepley /*@C 8941bb7acecfSBarry Smith DMGetAuxiliaryLabels - Get the labels, values, and parts for all auxiliary vectors in this `DM` 89429a2a23afSMatthew G. Knepley 89439a2a23afSMatthew G. Knepley Not collective 89449a2a23afSMatthew G. Knepley 89459a2a23afSMatthew G. Knepley Input Parameter: 8946bb7acecfSBarry Smith . dm - The `DM` 89479a2a23afSMatthew G. Knepley 89489a2a23afSMatthew G. Knepley Output Parameters: 8949bb7acecfSBarry Smith + labels - The `DMLabel`s for each `Vec` 8950bb7acecfSBarry Smith . values - The label values for each `Vec` 8951bb7acecfSBarry Smith - parts - The equation parts for each `Vec` 89529a2a23afSMatthew G. Knepley 8953bb7acecfSBarry Smith Note: 8954bb7acecfSBarry Smith The arrays passed in must be at least as large as `DMGetNumAuxiliaryVec()`. 89559a2a23afSMatthew G. Knepley 89569a2a23afSMatthew G. Knepley Level: advanced 89579a2a23afSMatthew G. Knepley 8958bb7acecfSBarry Smith .seealso: `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMGetNumAuxiliaryVec()`, `DMSetAuxiliaryVec()`, DMCopyAuxiliaryVec()` 89599a2a23afSMatthew G. Knepley @*/ 8960ac17215fSMatthew G. Knepley PetscErrorCode DMGetAuxiliaryLabels(DM dm, DMLabel labels[], PetscInt values[], PetscInt parts[]) 89619a2a23afSMatthew G. Knepley { 89629a2a23afSMatthew G. Knepley PetscHashAuxKey *keys; 89639a2a23afSMatthew G. Knepley PetscInt n, i, off = 0; 89649a2a23afSMatthew G. Knepley 89659a2a23afSMatthew G. Knepley PetscFunctionBegin; 89669a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89679a2a23afSMatthew G. Knepley PetscValidPointer(labels, 2); 8968dadcf809SJacob Faibussowitsch PetscValidIntPointer(values, 3); 8969dadcf809SJacob Faibussowitsch PetscValidIntPointer(parts, 4); 89709566063dSJacob Faibussowitsch PetscCall(DMGetNumAuxiliaryVec(dm, &n)); 89719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &keys)); 89729566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxGetKeys(dm->auxData, &off, keys)); 8973ac17215fSMatthew G. Knepley for (i = 0; i < n; ++i) {labels[i] = keys[i].label; values[i] = keys[i].value; parts[i] = keys[i].part;} 89749566063dSJacob Faibussowitsch PetscCall(PetscFree(keys)); 89759a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 89769a2a23afSMatthew G. Knepley } 89779a2a23afSMatthew G. Knepley 89789a2a23afSMatthew G. Knepley /*@ 8979bb7acecfSBarry Smith DMCopyAuxiliaryVec - Copy the auxiliary vector data on a `DM` to a new `DM` 89809a2a23afSMatthew G. Knepley 89819a2a23afSMatthew G. Knepley Not collective 89829a2a23afSMatthew G. Knepley 89839a2a23afSMatthew G. Knepley Input Parameter: 8984bb7acecfSBarry Smith . dm - The `DM` 89859a2a23afSMatthew G. Knepley 89869a2a23afSMatthew G. Knepley Output Parameter: 8987bb7acecfSBarry Smith . dmNew - The new `DM`, now with the same auxiliary data 89889a2a23afSMatthew G. Knepley 89899a2a23afSMatthew G. Knepley Level: advanced 89909a2a23afSMatthew G. Knepley 8991bb7acecfSBarry Smith Note: 8992bb7acecfSBarry Smith This is a shallow copy of the auxiliary vectors 8993bb7acecfSBarry Smith 8994db781477SPatrick Sanan .seealso: `DMGetNumAuxiliaryVec()`, `DMGetAuxiliaryVec()`, `DMSetAuxiliaryVec()` 89959a2a23afSMatthew G. Knepley @*/ 89969a2a23afSMatthew G. Knepley PetscErrorCode DMCopyAuxiliaryVec(DM dm, DM dmNew) 89979a2a23afSMatthew G. Knepley { 89989a2a23afSMatthew G. Knepley PetscFunctionBegin; 89999a2a23afSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90009566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDestroy(&dmNew->auxData)); 90019566063dSJacob Faibussowitsch PetscCall(PetscHMapAuxDuplicate(dm->auxData, &dmNew->auxData)); 90029a2a23afSMatthew G. Knepley PetscFunctionReturn(0); 90039a2a23afSMatthew G. Knepley } 9004b5a892a1SMatthew G. Knepley 9005b5a892a1SMatthew G. Knepley /*@C 9006bb7acecfSBarry Smith DMPolytopeMatchOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9007b5a892a1SMatthew G. Knepley 9008b5a892a1SMatthew G. Knepley Not collective 9009b5a892a1SMatthew G. Knepley 9010b5a892a1SMatthew G. Knepley Input Parameters: 9011bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9012b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9013b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9014b5a892a1SMatthew G. Knepley 9015b5a892a1SMatthew G. Knepley Output Parameters: 9016bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9017b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9018b5a892a1SMatthew G. Knepley 9019b5a892a1SMatthew G. Knepley Level: advanced 9020b5a892a1SMatthew G. Knepley 9021bb7acecfSBarry Smith Note: 9022bb7acecfSBarry Smith An arrangement is a face order combined with an orientation for each face 9023bb7acecfSBarry Smith 9024bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9025bb7acecfSBarry Smith that labels each arrangement (face ordering plus orientation for each face). 9026bb7acecfSBarry Smith 9027bb7acecfSBarry Smith See `DMPolytopeMatchVertexOrientation()` to find a new vertex orientation that takes the source vertex arrangement to the target vertex arrangement 9028bb7acecfSBarry Smith 9029bb7acecfSBarry Smith .seealso: `DMPolytopeGetOrientation()`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetVertexOrientation()` 9030b5a892a1SMatthew G. Knepley @*/ 9031b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt, PetscBool *found) 9032b5a892a1SMatthew G. Knepley { 9033b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetConeSize(ct); 9034b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct)/2; 9035b5a892a1SMatthew G. Knepley PetscInt o, c; 9036b5a892a1SMatthew G. Knepley 9037b5a892a1SMatthew G. Knepley PetscFunctionBegin; 9038b5a892a1SMatthew G. Knepley if (!nO) {*ornt = 0; *found = PETSC_TRUE; PetscFunctionReturn(0);} 9039b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9040b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 9041b5a892a1SMatthew G. Knepley 9042b5a892a1SMatthew G. Knepley for (c = 0; c < cS; ++c) if (sourceCone[arr[c*2]] != targetCone[c]) break; 9043b5a892a1SMatthew G. Knepley if (c == cS) {*ornt = o; break;} 9044b5a892a1SMatthew G. Knepley } 9045b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 9046b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9047b5a892a1SMatthew G. Knepley } 9048b5a892a1SMatthew G. Knepley 9049b5a892a1SMatthew G. Knepley /*@C 9050bb7acecfSBarry Smith DMPolytopeGetOrientation - Determine an orientation (transformation) that takes the source face arrangement to the target face arrangement 9051b5a892a1SMatthew G. Knepley 9052b5a892a1SMatthew G. Knepley Not collective 9053b5a892a1SMatthew G. Knepley 9054b5a892a1SMatthew G. Knepley Input Parameters: 9055bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9056b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of faces 9057b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of faces 9058b5a892a1SMatthew G. Knepley 9059b5a892a1SMatthew G. Knepley Output Parameters: 9060bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9061b5a892a1SMatthew G. Knepley 9062b5a892a1SMatthew G. Knepley Level: advanced 9063b5a892a1SMatthew G. Knepley 9064bb7acecfSBarry Smith Note: 9065bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchOrientation()` except it will generate an error if no suitable orientation can be found. 9066bb7acecfSBarry Smith 9067bb7acecfSBarry Smith Developer Note: 9068bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchOrientation()` and error if none is found 9069bb7acecfSBarry Smith 9070bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeMatchOrientation()`, `DMPolytopeGetVertexOrientation()`, `DMPolytopeMatchVertexOrientation()` 9071b5a892a1SMatthew G. Knepley @*/ 9072b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9073b5a892a1SMatthew G. Knepley { 9074b5a892a1SMatthew G. Knepley PetscBool found; 9075b5a892a1SMatthew G. Knepley 9076b5a892a1SMatthew G. Knepley PetscFunctionBegin; 90779566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchOrientation(ct, sourceCone, targetCone, ornt, &found)); 90787a8be351SBarry Smith PetscCheck(found,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 9079b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9080b5a892a1SMatthew G. Knepley } 9081b5a892a1SMatthew G. Knepley 9082b5a892a1SMatthew G. Knepley /*@C 9083bb7acecfSBarry Smith DMPolytopeMatchVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9084b5a892a1SMatthew G. Knepley 9085b5a892a1SMatthew G. Knepley Not collective 9086b5a892a1SMatthew G. Knepley 9087b5a892a1SMatthew G. Knepley Input Parameters: 9088bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9089b5a892a1SMatthew G. Knepley . sourceVert - The source arrangement of vertices 9090b5a892a1SMatthew G. Knepley - targetVert - The target arrangement of vertices 9091b5a892a1SMatthew G. Knepley 9092b5a892a1SMatthew G. Knepley Output Parameters: 9093bb7acecfSBarry Smith + ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9094b5a892a1SMatthew G. Knepley - found - Flag indicating that a suitable orientation was found 9095b5a892a1SMatthew G. Knepley 9096b5a892a1SMatthew G. Knepley Level: advanced 9097b5a892a1SMatthew G. Knepley 9098bb7acecfSBarry Smith Note: 9099bb7acecfSBarry Smith An arrangement is a vertex order 9100bb7acecfSBarry Smith 9101bb7acecfSBarry Smith Each orientation (transformation) is labeled with an integer from negative `DMPolytopeTypeGetNumArrangments(ct)`/2 to `DMPolytopeTypeGetNumArrangments(ct)`/2 9102bb7acecfSBarry Smith that labels each arrangement (vertex ordering). 9103bb7acecfSBarry Smith 9104bb7acecfSBarry Smith See `DMPolytopeMatchOrientation()` to find a new face orientation that takes the source face arrangement to the target face arrangement 9105bb7acecfSBarry Smith 9106bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeGetOrientation()`, `DMPolytopeMatchOrientation()`, `DMPolytopeTypeGetNumVertices()`, `DMPolytopeTypeGetVertexArrangment()` 9107b5a892a1SMatthew G. Knepley @*/ 9108b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType ct, const PetscInt sourceVert[], const PetscInt targetVert[], PetscInt *ornt, PetscBool *found) 9109b5a892a1SMatthew G. Knepley { 9110b5a892a1SMatthew G. Knepley const PetscInt cS = DMPolytopeTypeGetNumVertices(ct); 9111b5a892a1SMatthew G. Knepley const PetscInt nO = DMPolytopeTypeGetNumArrangments(ct)/2; 9112b5a892a1SMatthew G. Knepley PetscInt o, c; 9113b5a892a1SMatthew G. Knepley 9114b5a892a1SMatthew G. Knepley PetscFunctionBegin; 9115b5a892a1SMatthew G. Knepley if (!nO) {*ornt = 0; *found = PETSC_TRUE; PetscFunctionReturn(0);} 9116b5a892a1SMatthew G. Knepley for (o = -nO; o < nO; ++o) { 9117b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetVertexArrangment(ct, o); 9118b5a892a1SMatthew G. Knepley 9119b5a892a1SMatthew G. Knepley for (c = 0; c < cS; ++c) if (sourceVert[arr[c]] != targetVert[c]) break; 9120b5a892a1SMatthew G. Knepley if (c == cS) {*ornt = o; break;} 9121b5a892a1SMatthew G. Knepley } 9122b5a892a1SMatthew G. Knepley *found = o == nO ? PETSC_FALSE : PETSC_TRUE; 9123b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9124b5a892a1SMatthew G. Knepley } 9125b5a892a1SMatthew G. Knepley 9126b5a892a1SMatthew G. Knepley /*@C 9127bb7acecfSBarry Smith DMPolytopeGetVertexOrientation - Determine an orientation (transformation) that takes the source vertex arrangement to the target vertex arrangement 9128b5a892a1SMatthew G. Knepley 9129b5a892a1SMatthew G. Knepley Not collective 9130b5a892a1SMatthew G. Knepley 9131b5a892a1SMatthew G. Knepley Input Parameters: 9132bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9133b5a892a1SMatthew G. Knepley . sourceCone - The source arrangement of vertices 9134b5a892a1SMatthew G. Knepley - targetCone - The target arrangement of vertices 9135b5a892a1SMatthew G. Knepley 9136b5a892a1SMatthew G. Knepley Output Parameters: 9137bb7acecfSBarry Smith . ornt - The orientation (transformation) which will take the source arrangement to the target arrangement 9138b5a892a1SMatthew G. Knepley 9139b5a892a1SMatthew G. Knepley Level: advanced 9140b5a892a1SMatthew G. Knepley 9141bb7acecfSBarry Smith Note: 9142bb7acecfSBarry Smith This function is the same as `DMPolytopeMatchVertexOrientation()` except it errors if not orientation is possible. 9143bb7acecfSBarry Smith 9144bb7acecfSBarry Smith Developer Note: 9145bb7acecfSBarry Smith It is unclear why this function needs to exist since one can simply call `DMPolytopeMatchVertexOrientation()` and error if none is found 9146bb7acecfSBarry Smith 9147bb7acecfSBarry Smith .seealso: `DMPolytopeType`, `DMPolytopeMatchVertexOrientation()`, `DMPolytopeGetOrientation()` 9148b5a892a1SMatthew G. Knepley @*/ 9149b5a892a1SMatthew G. Knepley PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType ct, const PetscInt sourceCone[], const PetscInt targetCone[], PetscInt *ornt) 9150b5a892a1SMatthew G. Knepley { 9151b5a892a1SMatthew G. Knepley PetscBool found; 9152b5a892a1SMatthew G. Knepley 9153b5a892a1SMatthew G. Knepley PetscFunctionBegin; 91549566063dSJacob Faibussowitsch PetscCall(DMPolytopeMatchVertexOrientation(ct, sourceCone, targetCone, ornt, &found)); 91557a8be351SBarry Smith PetscCheck(found,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find orientation for %s", DMPolytopeTypes[ct]); 9156b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 9157b5a892a1SMatthew G. Knepley } 9158012bc364SMatthew G. Knepley 9159012bc364SMatthew G. Knepley /*@C 9160012bc364SMatthew G. Knepley DMPolytopeInCellTest - Check whether a point lies inside the reference cell of given type 9161012bc364SMatthew G. Knepley 9162012bc364SMatthew G. Knepley Not collective 9163012bc364SMatthew G. Knepley 9164012bc364SMatthew G. Knepley Input Parameters: 9165bb7acecfSBarry Smith + ct - The `DMPolytopeType` 9166012bc364SMatthew G. Knepley - point - Coordinates of the point 9167012bc364SMatthew G. Knepley 9168012bc364SMatthew G. Knepley Output Parameters: 9169012bc364SMatthew G. Knepley . inside - Flag indicating whether the point is inside the reference cell of given type 9170012bc364SMatthew G. Knepley 9171012bc364SMatthew G. Knepley Level: advanced 9172012bc364SMatthew G. Knepley 9173bb7acecfSBarry Smith .seealso: `DM`, `DMPolytopeType`, `DMLocatePoints()` 9174012bc364SMatthew G. Knepley @*/ 9175012bc364SMatthew G. Knepley PetscErrorCode DMPolytopeInCellTest(DMPolytopeType ct, const PetscReal point[], PetscBool *inside) 9176012bc364SMatthew G. Knepley { 9177012bc364SMatthew G. Knepley PetscReal sum = 0.0; 9178012bc364SMatthew G. Knepley PetscInt d; 9179012bc364SMatthew G. Knepley 9180012bc364SMatthew G. Knepley PetscFunctionBegin; 9181012bc364SMatthew G. Knepley *inside = PETSC_TRUE; 9182012bc364SMatthew G. Knepley switch (ct) { 9183012bc364SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 9184012bc364SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 9185012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) { 9186012bc364SMatthew G. Knepley if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 9187012bc364SMatthew G. Knepley sum += point[d]; 9188012bc364SMatthew G. Knepley } 9189012bc364SMatthew G. Knepley if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;} 9190012bc364SMatthew G. Knepley break; 9191012bc364SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 9192012bc364SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 9193012bc364SMatthew G. Knepley for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) 9194012bc364SMatthew G. Knepley if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;} 9195012bc364SMatthew G. Knepley break; 9196012bc364SMatthew G. Knepley default: 919798921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]); 9198012bc364SMatthew G. Knepley } 9199012bc364SMatthew G. Knepley PetscFunctionReturn(0); 9200012bc364SMatthew G. Knepley } 9201