xref: /petsc/src/dm/interface/dm.c (revision 979e053d25e40e6aa33fa7f6f26fb9e414273f4d)
1af0996ceSBarry Smith #include <petsc/private/dmimpl.h>           /*I      "petscdm.h"          I*/
2c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h>      /*I      "petscdmlabel.h"     I*/
3e6f8dbb6SToby Isaac #include <petsc/private/petscdsimpl.h>      /*I      "petscds.h"     I*/
43e922f36SToby Isaac #include <petscdmplex.h>
5f19dbd58SToby Isaac #include <petscdmfield.h>
60c312b8eSJed Brown #include <petscsf.h>
72764a2aaSMatthew G. Knepley #include <petscds.h>
847c6ae99SBarry Smith 
9732e2eb9SMatthew G Knepley PetscClassId  DM_CLASSID;
10d67d17b1SMatthew G. Knepley PetscClassId  DMLABEL_CLASSID;
111ac00216SMatthew G. Knepley PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction;
1267a56275SMatthew G Knepley 
13e249ee26SToby Isaac const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DMBoundaryType","DM_BOUNDARY_",0};
1440967b3bSMatthew G. Knepley const char *const DMBoundaryConditionTypes[] = {"INVALID","ESSENTIAL","NATURAL","INVALID","INVALID","ESSENTIAL_FIELD","NATURAL_FIELD","INVALID","INVALID","INVALID","NATURAL_RIEMANN","DMBoundaryConditionType","DM_BC_",0};
15bff4a2f0SMatthew G. Knepley 
164a7a4c06SLawrence Mitchell static PetscErrorCode DMHasCreateInjection_Default(DM dm, PetscBool *flg)
174a7a4c06SLawrence Mitchell {
184a7a4c06SLawrence Mitchell   PetscFunctionBegin;
194a7a4c06SLawrence Mitchell   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
204a7a4c06SLawrence Mitchell   PetscValidPointer(flg,2);
214a7a4c06SLawrence Mitchell   *flg = PETSC_FALSE;
224a7a4c06SLawrence Mitchell   PetscFunctionReturn(0);
234a7a4c06SLawrence Mitchell }
244a7a4c06SLawrence Mitchell 
25a4121054SBarry Smith /*@
26de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
27a4121054SBarry Smith 
28a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
29a4121054SBarry Smith    error when you try to use the vector.
30a4121054SBarry Smith 
31a4121054SBarry Smith   Collective on MPI_Comm
32a4121054SBarry Smith 
33a4121054SBarry Smith   Input Parameter:
34a4121054SBarry Smith . comm - The communicator for the DM object
35a4121054SBarry Smith 
36a4121054SBarry Smith   Output Parameter:
37a4121054SBarry Smith . dm - The DM object
38a4121054SBarry Smith 
39a4121054SBarry Smith   Level: beginner
40a4121054SBarry Smith 
418472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK
42a4121054SBarry Smith @*/
437087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
44a4121054SBarry Smith {
45a4121054SBarry Smith   DM             v;
46e5e52638SMatthew G. Knepley   PetscDS        ds;
47a4121054SBarry Smith   PetscErrorCode ierr;
48a4121054SBarry Smith 
49a4121054SBarry Smith   PetscFunctionBegin;
501411c6eeSJed Brown   PetscValidPointer(dm,2);
510298fd71SBarry Smith   *dm = NULL;
52607a6623SBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
53a4121054SBarry Smith 
5473107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
55e7c4fc90SDmitry Karpeev 
5649be4549SMatthew G. Knepley   v->setupcalled              = PETSC_FALSE;
5749be4549SMatthew G. Knepley   v->setfromoptionscalled     = PETSC_FALSE;
580298fd71SBarry Smith   v->ltogmap                  = NULL;
591411c6eeSJed Brown   v->bs                       = 1;
60171400e9SBarry Smith   v->coloringtype             = IS_COLORING_GLOBAL;
6188ed4aceSMatthew G Knepley   ierr                        = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
6288ed4aceSMatthew G Knepley   ierr                        = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
63c58f1c22SToby Isaac   v->labels                   = NULL;
6434aa8a36SMatthew G. Knepley   v->adjacency[0]             = PETSC_FALSE;
6534aa8a36SMatthew G. Knepley   v->adjacency[1]             = PETSC_TRUE;
66c58f1c22SToby Isaac   v->depthLabel               = NULL;
670298fd71SBarry Smith   v->defaultSection           = NULL;
680298fd71SBarry Smith   v->defaultGlobalSection     = NULL;
69fba222abSToby Isaac   v->defaultConstraintSection = NULL;
70fba222abSToby Isaac   v->defaultConstraintMat     = NULL;
71c6b900c6SMatthew G. Knepley   v->L                        = NULL;
72c6b900c6SMatthew G. Knepley   v->maxCell                  = NULL;
735dc8c3f7SMatthew G. Knepley   v->bdtype                   = NULL;
749a9a41abSToby Isaac   v->dimEmbed                 = PETSC_DEFAULT;
7596173672SStefano Zampini   v->dim                      = PETSC_DETERMINE;
76435a35e8SMatthew G Knepley   {
77435a35e8SMatthew G Knepley     PetscInt i;
78435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
790298fd71SBarry Smith       v->nullspaceConstructors[i] = NULL;
80f9d4088aSMatthew G. Knepley       v->nearnullspaceConstructors[i] = NULL;
81435a35e8SMatthew G Knepley     }
82435a35e8SMatthew G Knepley   }
83e5e52638SMatthew G. Knepley   ierr = PetscDSCreate(PetscObjectComm((PetscObject) v), &ds);CHKERRQ(ierr);
84e5e52638SMatthew G. Knepley   ierr = DMSetRegionDS(v, NULL, ds);CHKERRQ(ierr);
85e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
8614f150ffSMatthew G. Knepley   v->dmBC = NULL;
87a8fb8f29SToby Isaac   v->coarseMesh = NULL;
88f4d763aaSMatthew G. Knepley   v->outputSequenceNum = -1;
89cdb7a50dSMatthew G. Knepley   v->outputSequenceVal = 0.0;
90c0dedaeaSBarry Smith   ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr);
91b412c318SBarry Smith   ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr);
92bcc5ffd9SToby Isaac   ierr = PetscNew(&(v->labels));CHKERRQ(ierr);
93c58f1c22SToby Isaac   v->labels->refct = 1;
944a7a4c06SLawrence Mitchell 
954a7a4c06SLawrence Mitchell   v->ops->hascreateinjection = DMHasCreateInjection_Default;
964a7a4c06SLawrence Mitchell 
971411c6eeSJed Brown   *dm = v;
98a4121054SBarry Smith   PetscFunctionReturn(0);
99a4121054SBarry Smith }
100a4121054SBarry Smith 
10138221697SMatthew G. Knepley /*@
10238221697SMatthew G. Knepley   DMClone - Creates a DM object with the same topology as the original.
10338221697SMatthew G. Knepley 
10438221697SMatthew G. Knepley   Collective on MPI_Comm
10538221697SMatthew G. Knepley 
10638221697SMatthew G. Knepley   Input Parameter:
10738221697SMatthew G. Knepley . dm - The original DM object
10838221697SMatthew G. Knepley 
10938221697SMatthew G. Knepley   Output Parameter:
11038221697SMatthew G. Knepley . newdm  - The new DM object
11138221697SMatthew G. Knepley 
11238221697SMatthew G. Knepley   Level: beginner
11338221697SMatthew G. Knepley 
11438221697SMatthew G. Knepley .keywords: DM, topology, create
11538221697SMatthew G. Knepley @*/
11638221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm)
11738221697SMatthew G. Knepley {
11838221697SMatthew G. Knepley   PetscSF        sf;
11938221697SMatthew G. Knepley   Vec            coords;
12038221697SMatthew G. Knepley   void          *ctx;
121a3219837SMatthew G. Knepley   PetscInt       dim, cdim;
12238221697SMatthew G. Knepley   PetscErrorCode ierr;
12338221697SMatthew G. Knepley 
12438221697SMatthew G. Knepley   PetscFunctionBegin;
12538221697SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12638221697SMatthew G. Knepley   PetscValidPointer(newdm,2);
12738221697SMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr);
128c58f1c22SToby Isaac   ierr = PetscFree((*newdm)->labels);CHKERRQ(ierr);
129c58f1c22SToby Isaac   dm->labels->refct++;
130c58f1c22SToby Isaac   (*newdm)->labels = dm->labels;
131c58f1c22SToby Isaac   (*newdm)->depthLabel = dm->depthLabel;
132ddf8437dSMatthew G. Knepley   (*newdm)->leveldown  = dm->leveldown;
133ddf8437dSMatthew G. Knepley   (*newdm)->levelup    = dm->levelup;
1341de53e9aSMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
1351de53e9aSMatthew G. Knepley   ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr);
13638221697SMatthew G. Knepley   if (dm->ops->clone) {
13738221697SMatthew G. Knepley     ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr);
13838221697SMatthew G. Knepley   }
1393f22bcbcSToby Isaac   (*newdm)->setupcalled = dm->setupcalled;
14038221697SMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
14138221697SMatthew G. Knepley   ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr);
14238221697SMatthew G. Knepley   ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr);
14338221697SMatthew G. Knepley   ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr);
144be4c1c3eSMatthew G. Knepley   if (dm->coordinateDM) {
145be4c1c3eSMatthew G. Knepley     DM           ncdm;
146be4c1c3eSMatthew G. Knepley     PetscSection cs;
1475a0206caSToby Isaac     PetscInt     pEnd = -1, pEndMax = -1;
148be4c1c3eSMatthew G. Knepley 
149e87a4003SBarry Smith     ierr = DMGetSection(dm->coordinateDM, &cs);CHKERRQ(ierr);
150be4c1c3eSMatthew G. Knepley     if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);}
1515a0206caSToby Isaac     ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
1525a0206caSToby Isaac     if (pEndMax >= 0) {
153be4c1c3eSMatthew G. Knepley       ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr);
154e87a4003SBarry Smith       ierr = DMSetSection(ncdm, cs);CHKERRQ(ierr);
155a61e840bSMatthew G. Knepley       ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr);
156be4c1c3eSMatthew G. Knepley       ierr = DMDestroy(&ncdm);CHKERRQ(ierr);
157be4c1c3eSMatthew G. Knepley     }
158be4c1c3eSMatthew G. Knepley   }
159a3219837SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
160a3219837SMatthew G. Knepley   ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr);
16138221697SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr);
16238221697SMatthew G. Knepley   if (coords) {
16338221697SMatthew G. Knepley     ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr);
16438221697SMatthew G. Knepley   } else {
16538221697SMatthew G. Knepley     ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr);
16638221697SMatthew G. Knepley     if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);}
16738221697SMatthew G. Knepley   }
16890b157c4SStefano Zampini   {
16990b157c4SStefano Zampini     PetscBool             isper;
170c6b900c6SMatthew G. Knepley     const PetscReal      *maxCell, *L;
1715dc8c3f7SMatthew G. Knepley     const DMBoundaryType *bd;
17290b157c4SStefano Zampini     ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr);
17390b157c4SStefano Zampini     ierr = DMSetPeriodicity(*newdm, isper, maxCell,  L,  bd);CHKERRQ(ierr);
174c6b900c6SMatthew G. Knepley   }
17534aa8a36SMatthew G. Knepley   {
17634aa8a36SMatthew G. Knepley     PetscBool useCone, useClosure;
17734aa8a36SMatthew G. Knepley 
17834aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure);CHKERRQ(ierr);
17934aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
18034aa8a36SMatthew G. Knepley   }
18138221697SMatthew G. Knepley   PetscFunctionReturn(0);
18238221697SMatthew G. Knepley }
18338221697SMatthew G. Knepley 
1849a42bb27SBarry Smith /*@C
185564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
1869a42bb27SBarry Smith 
1878472ad0fSDave May    Logically Collective on DM
1889a42bb27SBarry Smith 
1899a42bb27SBarry Smith    Input Parameter:
1909a42bb27SBarry Smith +  da - initial distributed array
191e9e886b6SKarl Rupp .  ctype - the vector type, currently either VECSTANDARD, VECCUDA, or VECVIENNACL
1929a42bb27SBarry Smith 
1939a42bb27SBarry Smith    Options Database:
194dd85299cSBarry Smith .   -dm_vec_type ctype
1959a42bb27SBarry Smith 
1969a42bb27SBarry Smith    Level: intermediate
1979a42bb27SBarry Smith 
198a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType(), DMSetMatType(), DMGetMatType()
1999a42bb27SBarry Smith @*/
20019fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
2019a42bb27SBarry Smith {
2029a42bb27SBarry Smith   PetscErrorCode ierr;
2039a42bb27SBarry Smith 
2049a42bb27SBarry Smith   PetscFunctionBegin;
2059a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
2069a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
20719fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
2089a42bb27SBarry Smith   PetscFunctionReturn(0);
2099a42bb27SBarry Smith }
2109a42bb27SBarry Smith 
211c0dedaeaSBarry Smith /*@C
212c0dedaeaSBarry Smith        DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
213c0dedaeaSBarry Smith 
2148472ad0fSDave May    Logically Collective on DM
215c0dedaeaSBarry Smith 
216c0dedaeaSBarry Smith    Input Parameter:
217c0dedaeaSBarry Smith .  da - initial distributed array
218c0dedaeaSBarry Smith 
219c0dedaeaSBarry Smith    Output Parameter:
220c0dedaeaSBarry Smith .  ctype - the vector type
221c0dedaeaSBarry Smith 
222c0dedaeaSBarry Smith    Level: intermediate
223c0dedaeaSBarry Smith 
224a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMSetMatType(), DMGetMatType(), DMSetVecType()
225c0dedaeaSBarry Smith @*/
226c0dedaeaSBarry Smith PetscErrorCode  DMGetVecType(DM da,VecType *ctype)
227c0dedaeaSBarry Smith {
228c0dedaeaSBarry Smith   PetscFunctionBegin;
229c0dedaeaSBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
230c0dedaeaSBarry Smith   *ctype = da->vectype;
231c0dedaeaSBarry Smith   PetscFunctionReturn(0);
232c0dedaeaSBarry Smith }
233c0dedaeaSBarry Smith 
2345f1ad066SMatthew G Knepley /*@
23534f98d34SBarry Smith   VecGetDM - Gets the DM defining the data layout of the vector
2365f1ad066SMatthew G Knepley 
2375f1ad066SMatthew G Knepley   Not collective
2385f1ad066SMatthew G Knepley 
2395f1ad066SMatthew G Knepley   Input Parameter:
2405f1ad066SMatthew G Knepley . v - The Vec
2415f1ad066SMatthew G Knepley 
2425f1ad066SMatthew G Knepley   Output Parameter:
2435f1ad066SMatthew G Knepley . dm - The DM
2445f1ad066SMatthew G Knepley 
2455f1ad066SMatthew G Knepley   Level: intermediate
2465f1ad066SMatthew G Knepley 
2475f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2485f1ad066SMatthew G Knepley @*/
2495f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm)
2505f1ad066SMatthew G Knepley {
2515f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2525f1ad066SMatthew G Knepley 
2535f1ad066SMatthew G Knepley   PetscFunctionBegin;
2545f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
2555f1ad066SMatthew G Knepley   PetscValidPointer(dm,2);
2565f1ad066SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
2575f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2585f1ad066SMatthew G Knepley }
2595f1ad066SMatthew G Knepley 
2605f1ad066SMatthew G Knepley /*@
261d9805387SMatthew G. Knepley   VecSetDM - Sets the DM defining the data layout of the vector.
2625f1ad066SMatthew G Knepley 
2635f1ad066SMatthew G Knepley   Not collective
2645f1ad066SMatthew G Knepley 
2655f1ad066SMatthew G Knepley   Input Parameters:
2665f1ad066SMatthew G Knepley + v - The Vec
2675f1ad066SMatthew G Knepley - dm - The DM
2685f1ad066SMatthew G Knepley 
269d9805387SMatthew G. Knepley   Note: 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.
270d9805387SMatthew G. Knepley 
2715f1ad066SMatthew G Knepley   Level: intermediate
2725f1ad066SMatthew G Knepley 
2735f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2745f1ad066SMatthew G Knepley @*/
2755f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm)
2765f1ad066SMatthew G Knepley {
2775f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2785f1ad066SMatthew G Knepley 
2795f1ad066SMatthew G Knepley   PetscFunctionBegin;
2805f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
281d7f50e27SLisandro Dalcin   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
2825f1ad066SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
2835f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2845f1ad066SMatthew G Knepley }
2855f1ad066SMatthew G Knepley 
286521d9a4cSLisandro Dalcin /*@C
2878f1509bcSBarry Smith        DMSetISColoringType - Sets the type of coloring, global or local, that is created by the DM
2888f1509bcSBarry Smith 
2898f1509bcSBarry Smith    Logically Collective on DM
2908f1509bcSBarry Smith 
2918f1509bcSBarry Smith    Input Parameters:
2928f1509bcSBarry Smith +  dm - the DM context
2938f1509bcSBarry Smith -  ctype - the matrix type
2948f1509bcSBarry Smith 
2958f1509bcSBarry Smith    Options Database:
2968f1509bcSBarry Smith .   -dm_is_coloring_type - global or local
2978f1509bcSBarry Smith 
2988f1509bcSBarry Smith    Level: intermediate
2998f1509bcSBarry Smith 
3008f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(),
3018f1509bcSBarry Smith           DMGetISColoringType()
3028f1509bcSBarry Smith @*/
3038f1509bcSBarry Smith PetscErrorCode  DMSetISColoringType(DM dm,ISColoringType ctype)
3048f1509bcSBarry Smith {
3058f1509bcSBarry Smith   PetscFunctionBegin;
3068f1509bcSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3078f1509bcSBarry Smith   dm->coloringtype = ctype;
3088f1509bcSBarry Smith   PetscFunctionReturn(0);
3098f1509bcSBarry Smith }
3108f1509bcSBarry Smith 
3118f1509bcSBarry Smith /*@C
3128f1509bcSBarry Smith        DMGetISColoringType - Gets the type of coloring, global or local, that is created by the DM
313521d9a4cSLisandro Dalcin 
314521d9a4cSLisandro Dalcin    Logically Collective on DM
315521d9a4cSLisandro Dalcin 
316521d9a4cSLisandro Dalcin    Input Parameter:
3178f1509bcSBarry Smith .  dm - the DM context
3188f1509bcSBarry Smith 
3198f1509bcSBarry Smith    Output Parameter:
3208f1509bcSBarry Smith .  ctype - the matrix type
3218f1509bcSBarry Smith 
3228f1509bcSBarry Smith    Options Database:
3238f1509bcSBarry Smith .   -dm_is_coloring_type - global or local
3248f1509bcSBarry Smith 
3258f1509bcSBarry Smith    Level: intermediate
3268f1509bcSBarry Smith 
3278f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(),
3288f1509bcSBarry Smith           DMGetISColoringType()
3298f1509bcSBarry Smith @*/
3308f1509bcSBarry Smith PetscErrorCode  DMGetISColoringType(DM dm,ISColoringType *ctype)
3318f1509bcSBarry Smith {
3328f1509bcSBarry Smith   PetscFunctionBegin;
3338f1509bcSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3348f1509bcSBarry Smith   *ctype = dm->coloringtype;
3358f1509bcSBarry Smith   PetscFunctionReturn(0);
3368f1509bcSBarry Smith }
3378f1509bcSBarry Smith 
3388f1509bcSBarry Smith /*@C
3398f1509bcSBarry Smith        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
3408f1509bcSBarry Smith 
3418f1509bcSBarry Smith    Logically Collective on DM
3428f1509bcSBarry Smith 
3438f1509bcSBarry Smith    Input Parameters:
344521d9a4cSLisandro Dalcin +  dm - the DM context
345a2b5a043SBarry Smith -  ctype - the matrix type
346521d9a4cSLisandro Dalcin 
347521d9a4cSLisandro Dalcin    Options Database:
348521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
349521d9a4cSLisandro Dalcin 
350521d9a4cSLisandro Dalcin    Level: intermediate
351521d9a4cSLisandro Dalcin 
352a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), DMSetMatType(), DMGetMatType()
353521d9a4cSLisandro Dalcin @*/
35419fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
355521d9a4cSLisandro Dalcin {
356521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
35788f0584fSBarry Smith 
358521d9a4cSLisandro Dalcin   PetscFunctionBegin;
359521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
360521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
36119fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
362521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
363521d9a4cSLisandro Dalcin }
364521d9a4cSLisandro Dalcin 
365c0dedaeaSBarry Smith /*@C
366c0dedaeaSBarry Smith        DMGetMatType - Gets the type of matrix created with DMCreateMatrix()
367c0dedaeaSBarry Smith 
368c0dedaeaSBarry Smith    Logically Collective on DM
369c0dedaeaSBarry Smith 
370c0dedaeaSBarry Smith    Input Parameter:
371c0dedaeaSBarry Smith .  dm - the DM context
372c0dedaeaSBarry Smith 
373c0dedaeaSBarry Smith    Output Parameter:
374c0dedaeaSBarry Smith .  ctype - the matrix type
375c0dedaeaSBarry Smith 
376c0dedaeaSBarry Smith    Options Database:
377c0dedaeaSBarry Smith .   -dm_mat_type ctype
378c0dedaeaSBarry Smith 
379c0dedaeaSBarry Smith    Level: intermediate
380c0dedaeaSBarry Smith 
381a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType(), DMSetMatType(), DMGetMatType()
382c0dedaeaSBarry Smith @*/
383c0dedaeaSBarry Smith PetscErrorCode  DMGetMatType(DM dm,MatType *ctype)
384c0dedaeaSBarry Smith {
385c0dedaeaSBarry Smith   PetscFunctionBegin;
386c0dedaeaSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
387c0dedaeaSBarry Smith   *ctype = dm->mattype;
388c0dedaeaSBarry Smith   PetscFunctionReturn(0);
389c0dedaeaSBarry Smith }
390c0dedaeaSBarry Smith 
391c688c046SMatthew G Knepley /*@
39234f98d34SBarry Smith   MatGetDM - Gets the DM defining the data layout of the matrix
393c688c046SMatthew G Knepley 
394c688c046SMatthew G Knepley   Not collective
395c688c046SMatthew G Knepley 
396c688c046SMatthew G Knepley   Input Parameter:
397c688c046SMatthew G Knepley . A - The Mat
398c688c046SMatthew G Knepley 
399c688c046SMatthew G Knepley   Output Parameter:
400c688c046SMatthew G Knepley . dm - The DM
401c688c046SMatthew G Knepley 
402c688c046SMatthew G Knepley   Level: intermediate
403c688c046SMatthew G Knepley 
4048f1509bcSBarry Smith   Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with
4058f1509bcSBarry Smith                   the Mat through a PetscObjectCompose() operation
4068f1509bcSBarry Smith 
407c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType()
408c688c046SMatthew G Knepley @*/
409c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm)
410c688c046SMatthew G Knepley {
411c688c046SMatthew G Knepley   PetscErrorCode ierr;
412c688c046SMatthew G Knepley 
413c688c046SMatthew G Knepley   PetscFunctionBegin;
414c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
415c688c046SMatthew G Knepley   PetscValidPointer(dm,2);
416c688c046SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
417c688c046SMatthew G Knepley   PetscFunctionReturn(0);
418c688c046SMatthew G Knepley }
419c688c046SMatthew G Knepley 
420c688c046SMatthew G Knepley /*@
421c688c046SMatthew G Knepley   MatSetDM - Sets the DM defining the data layout of the matrix
422c688c046SMatthew G Knepley 
423c688c046SMatthew G Knepley   Not collective
424c688c046SMatthew G Knepley 
425c688c046SMatthew G Knepley   Input Parameters:
426c688c046SMatthew G Knepley + A - The Mat
427c688c046SMatthew G Knepley - dm - The DM
428c688c046SMatthew G Knepley 
429c688c046SMatthew G Knepley   Level: intermediate
430c688c046SMatthew G Knepley 
4318f1509bcSBarry Smith   Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with
4328f1509bcSBarry Smith                   the Mat through a PetscObjectCompose() operation
4338f1509bcSBarry Smith 
4348f1509bcSBarry Smith 
435c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType()
436c688c046SMatthew G Knepley @*/
437c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm)
438c688c046SMatthew G Knepley {
439c688c046SMatthew G Knepley   PetscErrorCode ierr;
440c688c046SMatthew G Knepley 
441c688c046SMatthew G Knepley   PetscFunctionBegin;
442c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4438865f1eaSKarl Rupp   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
444c688c046SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
445c688c046SMatthew G Knepley   PetscFunctionReturn(0);
446c688c046SMatthew G Knepley }
447c688c046SMatthew G Knepley 
4489a42bb27SBarry Smith /*@C
4499a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
4506757b960SDave May    DM options in the database.
4519a42bb27SBarry Smith 
4528353ddbbSDave May    Logically Collective on DM
4539a42bb27SBarry Smith 
4549a42bb27SBarry Smith    Input Parameter:
4558353ddbbSDave May +  da - the DM context
4569a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
4579a42bb27SBarry Smith 
4589a42bb27SBarry Smith    Notes:
4599a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
4609a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
4619a42bb27SBarry Smith 
4629a42bb27SBarry Smith    Level: advanced
4639a42bb27SBarry Smith 
4648353ddbbSDave May .keywords: DM, set, options, prefix, database
4659a42bb27SBarry Smith 
4669a42bb27SBarry Smith .seealso: DMSetFromOptions()
4679a42bb27SBarry Smith @*/
4687087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
4699a42bb27SBarry Smith {
4709a42bb27SBarry Smith   PetscErrorCode ierr;
4719a42bb27SBarry Smith 
4729a42bb27SBarry Smith   PetscFunctionBegin;
4739a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4749a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
475691be533SLawrence Mitchell   if (dm->sf) {
476691be533SLawrence Mitchell     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr);
477691be533SLawrence Mitchell   }
478691be533SLawrence Mitchell   if (dm->defaultSF) {
479691be533SLawrence Mitchell     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->defaultSF,prefix);CHKERRQ(ierr);
480691be533SLawrence Mitchell   }
4819a42bb27SBarry Smith   PetscFunctionReturn(0);
4829a42bb27SBarry Smith }
4839a42bb27SBarry Smith 
48431697293SDave May /*@C
48531697293SDave May    DMAppendOptionsPrefix - Appends to the prefix used for searching for all
48631697293SDave May    DM options in the database.
48731697293SDave May 
48831697293SDave May    Logically Collective on DM
48931697293SDave May 
49031697293SDave May    Input Parameters:
49131697293SDave May +  dm - the DM context
49231697293SDave May -  prefix - the prefix string to prepend to all DM option requests
49331697293SDave May 
49431697293SDave May    Notes:
49531697293SDave May    A hyphen (-) must NOT be given at the beginning of the prefix name.
49631697293SDave May    The first character of all runtime options is AUTOMATICALLY the hyphen.
49731697293SDave May 
49831697293SDave May    Level: advanced
49931697293SDave May 
50031697293SDave May .keywords: DM, append, options, prefix, database
50131697293SDave May 
50231697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix()
50331697293SDave May @*/
50431697293SDave May PetscErrorCode  DMAppendOptionsPrefix(DM dm,const char prefix[])
50531697293SDave May {
50631697293SDave May   PetscErrorCode ierr;
50731697293SDave May 
50831697293SDave May   PetscFunctionBegin;
50931697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
51031697293SDave May   ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
51131697293SDave May   PetscFunctionReturn(0);
51231697293SDave May }
51331697293SDave May 
51431697293SDave May /*@C
51531697293SDave May    DMGetOptionsPrefix - Gets the prefix used for searching for all
51631697293SDave May    DM options in the database.
51731697293SDave May 
51831697293SDave May    Not Collective
51931697293SDave May 
52031697293SDave May    Input Parameters:
52131697293SDave May .  dm - the DM context
52231697293SDave May 
52331697293SDave May    Output Parameters:
52431697293SDave May .  prefix - pointer to the prefix string used is returned
52531697293SDave May 
52695452b02SPatrick Sanan    Notes:
52795452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
52831697293SDave May    sufficient length to hold the prefix.
52931697293SDave May 
53031697293SDave May    Level: advanced
53131697293SDave May 
53231697293SDave May .keywords: DM, set, options, prefix, database
53331697293SDave May 
53431697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix()
53531697293SDave May @*/
53631697293SDave May PetscErrorCode  DMGetOptionsPrefix(DM dm,const char *prefix[])
53731697293SDave May {
53831697293SDave May   PetscErrorCode ierr;
53931697293SDave May 
54031697293SDave May   PetscFunctionBegin;
54131697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
54231697293SDave May   ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
54331697293SDave May   PetscFunctionReturn(0);
54431697293SDave May }
54531697293SDave May 
54688bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct)
54788bdff64SToby Isaac {
54888bdff64SToby Isaac   PetscInt i, refct = ((PetscObject) dm)->refct;
54988bdff64SToby Isaac   DMNamedVecLink nlink;
55088bdff64SToby Isaac   PetscErrorCode ierr;
55188bdff64SToby Isaac 
55288bdff64SToby Isaac   PetscFunctionBegin;
553aab5bcd8SJed Brown   *ncrefct = 0;
55488bdff64SToby Isaac   /* count all the circular references of DM and its contained Vecs */
55588bdff64SToby Isaac   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
55688bdff64SToby Isaac     if (dm->localin[i])  refct--;
55788bdff64SToby Isaac     if (dm->globalin[i]) refct--;
55888bdff64SToby Isaac   }
55988bdff64SToby Isaac   for (nlink=dm->namedglobal; nlink; nlink=nlink->next) refct--;
56088bdff64SToby Isaac   for (nlink=dm->namedlocal; nlink; nlink=nlink->next) refct--;
56188bdff64SToby Isaac   if (dm->x) {
56288bdff64SToby Isaac     DM obj;
56388bdff64SToby Isaac     ierr = VecGetDM(dm->x, &obj);CHKERRQ(ierr);
56488bdff64SToby Isaac     if (obj == dm) refct--;
56588bdff64SToby Isaac   }
56688bdff64SToby Isaac   if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) {
56788bdff64SToby Isaac     refct--;
56888bdff64SToby Isaac     if (recurseCoarse) {
56988bdff64SToby Isaac       PetscInt coarseCount;
57088bdff64SToby Isaac 
57188bdff64SToby Isaac       ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr);
57288bdff64SToby Isaac       refct += coarseCount;
57388bdff64SToby Isaac     }
57488bdff64SToby Isaac   }
57588bdff64SToby Isaac   if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) {
57688bdff64SToby Isaac     refct--;
57788bdff64SToby Isaac     if (recurseFine) {
57888bdff64SToby Isaac       PetscInt fineCount;
57988bdff64SToby Isaac 
58088bdff64SToby Isaac       ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr);
58188bdff64SToby Isaac       refct += fineCount;
58288bdff64SToby Isaac     }
58388bdff64SToby Isaac   }
58488bdff64SToby Isaac   *ncrefct = refct;
58588bdff64SToby Isaac   PetscFunctionReturn(0);
58688bdff64SToby Isaac }
58788bdff64SToby Isaac 
588354557abSToby Isaac PetscErrorCode DMDestroyLabelLinkList(DM dm)
589354557abSToby Isaac {
590354557abSToby Isaac   PetscErrorCode ierr;
591354557abSToby Isaac 
592354557abSToby Isaac   PetscFunctionBegin;
593354557abSToby Isaac   if (!--(dm->labels->refct)) {
594354557abSToby Isaac     DMLabelLink next = dm->labels->next;
595354557abSToby Isaac 
596354557abSToby Isaac     /* destroy the labels */
597354557abSToby Isaac     while (next) {
598354557abSToby Isaac       DMLabelLink tmp = next->next;
599354557abSToby Isaac 
600354557abSToby Isaac       ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr);
601354557abSToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
602354557abSToby Isaac       next = tmp;
603354557abSToby Isaac     }
604354557abSToby Isaac     ierr = PetscFree(dm->labels);CHKERRQ(ierr);
605354557abSToby Isaac   }
606354557abSToby Isaac   PetscFunctionReturn(0);
607354557abSToby Isaac }
608354557abSToby Isaac 
60947c6ae99SBarry Smith /*@
6108472ad0fSDave May     DMDestroy - Destroys a vector packer or DM.
61147c6ae99SBarry Smith 
61247c6ae99SBarry Smith     Collective on DM
61347c6ae99SBarry Smith 
61447c6ae99SBarry Smith     Input Parameter:
61547c6ae99SBarry Smith .   dm - the DM object to destroy
61647c6ae99SBarry Smith 
61747c6ae99SBarry Smith     Level: developer
61847c6ae99SBarry Smith 
619e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
62047c6ae99SBarry Smith 
62147c6ae99SBarry Smith @*/
622fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
62347c6ae99SBarry Smith {
62488bdff64SToby Isaac   PetscInt       i, cnt;
625dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
62647c6ae99SBarry Smith   PetscErrorCode ierr;
62747c6ae99SBarry Smith 
62847c6ae99SBarry Smith   PetscFunctionBegin;
6296bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
6306bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
63187e657c6SBarry Smith 
63288bdff64SToby Isaac   /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */
63388bdff64SToby Isaac   ierr = DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt);CHKERRQ(ierr);
63488bdff64SToby Isaac   --((PetscObject)(*dm))->refct;
63588bdff64SToby Isaac   if (--cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
636732e2eb9SMatthew G Knepley   /*
637732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
638732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
639732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
640732e2eb9SMatthew G Knepley   */
6416bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
6426bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
643732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
6446bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
6456bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
646732e2eb9SMatthew G Knepley   }
647f490541aSPeter Brune   nnext=(*dm)->namedglobal;
6480298fd71SBarry Smith   (*dm)->namedglobal = NULL;
649f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */
6502348bcf4SPeter Brune     nnext = nlink->next;
6512348bcf4SPeter Brune     if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name);
6522348bcf4SPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
6532348bcf4SPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
6542348bcf4SPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
6552348bcf4SPeter Brune   }
656f490541aSPeter Brune   nnext=(*dm)->namedlocal;
6570298fd71SBarry Smith   (*dm)->namedlocal = NULL;
658f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */
659f490541aSPeter Brune     nnext = nlink->next;
660f490541aSPeter Brune     if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name);
661f490541aSPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
662f490541aSPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
663f490541aSPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
664f490541aSPeter Brune   }
6652348bcf4SPeter Brune 
666b17ce1afSJed Brown   /* Destroy the list of hooks */
667c833c3b5SJed Brown   {
668c833c3b5SJed Brown     DMCoarsenHookLink link,next;
669b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
670b17ce1afSJed Brown       next = link->next;
671b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
672b17ce1afSJed Brown     }
6730298fd71SBarry Smith     (*dm)->coarsenhook = NULL;
674c833c3b5SJed Brown   }
675c833c3b5SJed Brown   {
676c833c3b5SJed Brown     DMRefineHookLink link,next;
677c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
678c833c3b5SJed Brown       next = link->next;
679c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
680c833c3b5SJed Brown     }
6810298fd71SBarry Smith     (*dm)->refinehook = NULL;
682c833c3b5SJed Brown   }
683be081cd6SPeter Brune   {
684be081cd6SPeter Brune     DMSubDomainHookLink link,next;
685be081cd6SPeter Brune     for (link=(*dm)->subdomainhook; link; link=next) {
686be081cd6SPeter Brune       next = link->next;
687be081cd6SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
688be081cd6SPeter Brune     }
6890298fd71SBarry Smith     (*dm)->subdomainhook = NULL;
690be081cd6SPeter Brune   }
691baf369e7SPeter Brune   {
692baf369e7SPeter Brune     DMGlobalToLocalHookLink link,next;
693baf369e7SPeter Brune     for (link=(*dm)->gtolhook; link; link=next) {
694baf369e7SPeter Brune       next = link->next;
695baf369e7SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
696baf369e7SPeter Brune     }
6970298fd71SBarry Smith     (*dm)->gtolhook = NULL;
698baf369e7SPeter Brune   }
699d4d07f1eSToby Isaac   {
700d4d07f1eSToby Isaac     DMLocalToGlobalHookLink link,next;
701d4d07f1eSToby Isaac     for (link=(*dm)->ltoghook; link; link=next) {
702d4d07f1eSToby Isaac       next = link->next;
703d4d07f1eSToby Isaac       ierr = PetscFree(link);CHKERRQ(ierr);
704d4d07f1eSToby Isaac     }
705d4d07f1eSToby Isaac     (*dm)->ltoghook = NULL;
706d4d07f1eSToby Isaac   }
707aa1993deSMatthew G Knepley   /* Destroy the work arrays */
708aa1993deSMatthew G Knepley   {
709aa1993deSMatthew G Knepley     DMWorkLink link,next;
710aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
711aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
712aa1993deSMatthew G Knepley       next = link->next;
713aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
714aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
715aa1993deSMatthew G Knepley     }
7160298fd71SBarry Smith     (*dm)->workin = NULL;
717aa1993deSMatthew G Knepley   }
718c58f1c22SToby Isaac   if (!--((*dm)->labels->refct)) {
719c58f1c22SToby Isaac     DMLabelLink next = (*dm)->labels->next;
720c58f1c22SToby Isaac 
721c58f1c22SToby Isaac     /* destroy the labels */
722c58f1c22SToby Isaac     while (next) {
723c58f1c22SToby Isaac       DMLabelLink tmp = next->next;
724c58f1c22SToby Isaac 
725c58f1c22SToby Isaac       ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr);
726c58f1c22SToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
727c58f1c22SToby Isaac       next = tmp;
728c58f1c22SToby Isaac     }
729c58f1c22SToby Isaac     ierr = PetscFree((*dm)->labels);CHKERRQ(ierr);
730c58f1c22SToby Isaac   }
731e5e52638SMatthew G. Knepley   ierr = DMClearFields(*dm);CHKERRQ(ierr);
732e6f8dbb6SToby Isaac   {
733e6f8dbb6SToby Isaac     DMBoundary next = (*dm)->boundary;
734e6f8dbb6SToby Isaac     while (next) {
735e6f8dbb6SToby Isaac       DMBoundary b = next;
736e6f8dbb6SToby Isaac 
737e6f8dbb6SToby Isaac       next = b->next;
738e6f8dbb6SToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
739e6f8dbb6SToby Isaac     }
740e6f8dbb6SToby Isaac   }
741b17ce1afSJed Brown 
74252536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr);
74352536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr);
74452536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr);
74552536dc3SBarry Smith 
7461a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
7471a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
7481a266240SBarry Smith   }
74987e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
75071cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
7514dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
7526bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
7536bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
754073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
75588ed4aceSMatthew G Knepley 
75688ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
75788ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
7588b1ab98fSJed Brown   ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr);
759fba222abSToby Isaac   ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr);
760fba222abSToby Isaac   ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr);
76188ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
76288ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
763736995cdSBlaise Bourdin   if ((*dm)->useNatural) {
764736995cdSBlaise Bourdin     if ((*dm)->sfNatural) {
7658e4ac7eaSMatthew G. Knepley       ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr);
766736995cdSBlaise Bourdin     }
767736995cdSBlaise Bourdin     ierr = PetscObjectDereference((PetscObject) (*dm)->sfMigration);CHKERRQ(ierr);
768736995cdSBlaise Bourdin   }
76988bdff64SToby Isaac   if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) {
77088bdff64SToby Isaac     ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr);
77188bdff64SToby Isaac   }
772a8fb8f29SToby Isaac   ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr);
77388bdff64SToby Isaac   if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) {
77488bdff64SToby Isaac     ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr);
77588bdff64SToby Isaac   }
77688bdff64SToby Isaac   ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr);
777f19dbd58SToby Isaac   ierr = DMFieldDestroy(&(*dm)->coordinateField);CHKERRQ(ierr);
7786636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
7796636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
7806636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
7815dc8c3f7SMatthew G. Knepley   ierr = PetscFree3((*dm)->L,(*dm)->maxCell,(*dm)->bdtype);CHKERRQ(ierr);
7826636e97aSMatthew G Knepley 
783e5e52638SMatthew G. Knepley   ierr = DMClearDS(*dm);CHKERRQ(ierr);
78414f150ffSMatthew G. Knepley   ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr);
785e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
786e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr);
787732e2eb9SMatthew G Knepley 
788ed3c66a1SDave May   if ((*dm)->ops->destroy) {
7896bf464f9SBarry Smith     ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
790ed3c66a1SDave May   }
791435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
792732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
79347c6ae99SBarry Smith   PetscFunctionReturn(0);
79447c6ae99SBarry Smith }
79547c6ae99SBarry Smith 
796d7bf68aeSBarry Smith /*@
797d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
798d7bf68aeSBarry Smith 
799d7bf68aeSBarry Smith     Collective on DM
800d7bf68aeSBarry Smith 
801d7bf68aeSBarry Smith     Input Parameter:
802d7bf68aeSBarry Smith .   dm - the DM object to setup
803d7bf68aeSBarry Smith 
804d7bf68aeSBarry Smith     Level: developer
805d7bf68aeSBarry Smith 
806e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
807d7bf68aeSBarry Smith 
808d7bf68aeSBarry Smith @*/
8097087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
810d7bf68aeSBarry Smith {
811d7bf68aeSBarry Smith   PetscErrorCode ierr;
812d7bf68aeSBarry Smith 
813d7bf68aeSBarry Smith   PetscFunctionBegin;
814171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8158387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
816d7bf68aeSBarry Smith   if (dm->ops->setup) {
817d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
818d7bf68aeSBarry Smith   }
8198387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
820d7bf68aeSBarry Smith   PetscFunctionReturn(0);
821d7bf68aeSBarry Smith }
822d7bf68aeSBarry Smith 
823d7bf68aeSBarry Smith /*@
824d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
825d7bf68aeSBarry Smith 
826d7bf68aeSBarry Smith     Collective on DM
827d7bf68aeSBarry Smith 
828d7bf68aeSBarry Smith     Input Parameter:
829d7bf68aeSBarry Smith .   dm - the DM object to set options for
830d7bf68aeSBarry Smith 
831732e2eb9SMatthew G Knepley     Options Database:
8324164ae61SDominic Meiser +   -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
8334164ae61SDominic Meiser .   -dm_vec_type <type>  - type of vector to create inside DM
8344164ae61SDominic Meiser .   -dm_mat_type <type>  - type of matrix to create inside DM
8358f1509bcSBarry Smith -   -dm_is_coloring_type - <global or local>
836732e2eb9SMatthew G Knepley 
837d7bf68aeSBarry Smith     Level: developer
838d7bf68aeSBarry Smith 
839e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
840d7bf68aeSBarry Smith 
841d7bf68aeSBarry Smith @*/
8427087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm)
843d7bf68aeSBarry Smith {
8447781c08eSBarry Smith   char           typeName[256];
845ca266f36SBarry Smith   PetscBool      flg;
846d7bf68aeSBarry Smith   PetscErrorCode ierr;
847d7bf68aeSBarry Smith 
848d7bf68aeSBarry Smith   PetscFunctionBegin;
849171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
85049be4549SMatthew G. Knepley   dm->setfromoptionscalled = PETSC_TRUE;
85149be4549SMatthew G. Knepley   if (dm->sf) {ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr);}
85249be4549SMatthew G. Knepley   if (dm->defaultSF) {ierr = PetscSFSetFromOptions(dm->defaultSF);CHKERRQ(ierr);}
8533194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
8540298fd71SBarry Smith   ierr = PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,NULL);CHKERRQ(ierr);
855a264d7a6SBarry Smith   ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
856f9ba7244SBarry Smith   if (flg) {
857f9ba7244SBarry Smith     ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
858f9ba7244SBarry Smith   }
859a264d7a6SBarry Smith   ierr = PetscOptionsFList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype ? dm->mattype : typeName,typeName,sizeof(typeName),&flg);CHKERRQ(ierr);
860073dac72SJed Brown   if (flg) {
861521d9a4cSLisandro Dalcin     ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
862073dac72SJed Brown   }
8638f1509bcSBarry Smith   ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr);
864f9ba7244SBarry Smith   if (dm->ops->setfromoptions) {
865e55864a3SBarry Smith     ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr);
866f9ba7244SBarry Smith   }
867f9ba7244SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
8680633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr);
86982fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
870d7bf68aeSBarry Smith   PetscFunctionReturn(0);
871d7bf68aeSBarry Smith }
872d7bf68aeSBarry Smith 
873fc9bc008SSatish Balay /*@C
874224748a4SBarry Smith     DMView - Views a DM
87547c6ae99SBarry Smith 
87647c6ae99SBarry Smith     Collective on DM
87747c6ae99SBarry Smith 
87847c6ae99SBarry Smith     Input Parameter:
87947c6ae99SBarry Smith +   dm - the DM object to view
88047c6ae99SBarry Smith -   v - the viewer
88147c6ae99SBarry Smith 
882224748a4SBarry Smith     Level: beginner
88347c6ae99SBarry Smith 
884e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
88547c6ae99SBarry Smith 
88647c6ae99SBarry Smith @*/
8877087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
88847c6ae99SBarry Smith {
88947c6ae99SBarry Smith   PetscErrorCode    ierr;
89032c0f0efSBarry Smith   PetscBool         isbinary;
89176a8abe0SBarry Smith   PetscMPIInt       size;
89276a8abe0SBarry Smith   PetscViewerFormat format;
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith   PetscFunctionBegin;
895171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8963014e516SBarry Smith   if (!v) {
897ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr);
8983014e516SBarry Smith   }
8998bfd1ab9SVaclav Hapla   ierr = PetscViewerCheckWritable(v);CHKERRQ(ierr);
90076a8abe0SBarry Smith   ierr = PetscViewerGetFormat(v,&format);CHKERRQ(ierr);
90176a8abe0SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr);
90276a8abe0SBarry Smith   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
90398c3331eSBarry Smith   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr);
90432c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
90532c0f0efSBarry Smith   if (isbinary) {
90655849f57SBarry Smith     PetscInt classid = DM_FILE_CLASSID;
90732c0f0efSBarry Smith     char     type[256];
90832c0f0efSBarry Smith 
90932c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
91032c0f0efSBarry Smith     ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
91132c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
91232c0f0efSBarry Smith   }
9130c010503SBarry Smith   if (dm->ops->view) {
9140c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
91547c6ae99SBarry Smith   }
91647c6ae99SBarry Smith   PetscFunctionReturn(0);
91747c6ae99SBarry Smith }
91847c6ae99SBarry Smith 
91947c6ae99SBarry Smith /*@
9208472ad0fSDave May     DMCreateGlobalVector - Creates a global vector from a DM object
92147c6ae99SBarry Smith 
92247c6ae99SBarry Smith     Collective on DM
92347c6ae99SBarry Smith 
92447c6ae99SBarry Smith     Input Parameter:
92547c6ae99SBarry Smith .   dm - the DM object
92647c6ae99SBarry Smith 
92747c6ae99SBarry Smith     Output Parameter:
92847c6ae99SBarry Smith .   vec - the global vector
92947c6ae99SBarry Smith 
930073dac72SJed Brown     Level: beginner
93147c6ae99SBarry Smith 
932e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
93347c6ae99SBarry Smith 
93447c6ae99SBarry Smith @*/
9357087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
93647c6ae99SBarry Smith {
93747c6ae99SBarry Smith   PetscErrorCode ierr;
93847c6ae99SBarry Smith 
93947c6ae99SBarry Smith   PetscFunctionBegin;
940171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
94147c6ae99SBarry Smith   ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
94247c6ae99SBarry Smith   PetscFunctionReturn(0);
94347c6ae99SBarry Smith }
94447c6ae99SBarry Smith 
94547c6ae99SBarry Smith /*@
9468472ad0fSDave May     DMCreateLocalVector - Creates a local vector from a DM object
94747c6ae99SBarry Smith 
94847c6ae99SBarry Smith     Not Collective
94947c6ae99SBarry Smith 
95047c6ae99SBarry Smith     Input Parameter:
95147c6ae99SBarry Smith .   dm - the DM object
95247c6ae99SBarry Smith 
95347c6ae99SBarry Smith     Output Parameter:
95447c6ae99SBarry Smith .   vec - the local vector
95547c6ae99SBarry Smith 
956073dac72SJed Brown     Level: beginner
95747c6ae99SBarry Smith 
958e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
95947c6ae99SBarry Smith 
96047c6ae99SBarry Smith @*/
9617087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
96247c6ae99SBarry Smith {
96347c6ae99SBarry Smith   PetscErrorCode ierr;
96447c6ae99SBarry Smith 
96547c6ae99SBarry Smith   PetscFunctionBegin;
966171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
96747c6ae99SBarry Smith   ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
96847c6ae99SBarry Smith   PetscFunctionReturn(0);
96947c6ae99SBarry Smith }
97047c6ae99SBarry Smith 
9711411c6eeSJed Brown /*@
9721411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
9731411c6eeSJed Brown 
9741411c6eeSJed Brown    Collective on DM
9751411c6eeSJed Brown 
9761411c6eeSJed Brown    Input Parameter:
9771411c6eeSJed Brown .  dm - the DM that provides the mapping
9781411c6eeSJed Brown 
9791411c6eeSJed Brown    Output Parameter:
9801411c6eeSJed Brown .  ltog - the mapping
9811411c6eeSJed Brown 
9821411c6eeSJed Brown    Level: intermediate
9831411c6eeSJed Brown 
9841411c6eeSJed Brown    Notes:
9851411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
9861411c6eeSJed Brown    MatSetLocalToGlobalMapping().
9871411c6eeSJed Brown 
988fc31e74dSBarry Smith .seealso: DMCreateLocalVector()
9891411c6eeSJed Brown @*/
9907087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
9911411c6eeSJed Brown {
9920be3e97aSMatthew G. Knepley   PetscInt       bs = -1, bsLocal[2], bsMinMax[2];
9931411c6eeSJed Brown   PetscErrorCode ierr;
9941411c6eeSJed Brown 
9951411c6eeSJed Brown   PetscFunctionBegin;
9961411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9971411c6eeSJed Brown   PetscValidPointer(ltog,2);
9981411c6eeSJed Brown   if (!dm->ltogmap) {
99937d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
100037d0c07bSMatthew G Knepley 
1001e87a4003SBarry Smith     ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
100237d0c07bSMatthew G Knepley     if (section) {
1003a974ec88SMatthew G. Knepley       const PetscInt *cdofs;
100437d0c07bSMatthew G Knepley       PetscInt       *ltog;
1005ccf3bd66SMatthew G. Knepley       PetscInt        pStart, pEnd, n, p, k, l;
100637d0c07bSMatthew G Knepley 
1007e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
100837d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
1009ccf3bd66SMatthew G. Knepley       ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr);
1010ccf3bd66SMatthew G. Knepley       ierr = PetscMalloc1(n, &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
101137d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
1012a974ec88SMatthew G. Knepley         PetscInt bdof, cdof, dof, off, c, cind = 0;
101337d0c07bSMatthew G Knepley 
101437d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
101537d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
1016a974ec88SMatthew G. Knepley         ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr);
1017a974ec88SMatthew G. Knepley         ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr);
101837d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
10191a7dc684SMatthew G. Knepley         /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */
10201a7dc684SMatthew G. Knepley         bdof = cdof && (dof-cdof) ? 1 : dof;
10211a7dc684SMatthew G. Knepley         if (dof) {
1022b190aa46SMatthew G. Knepley           if (bs < 0)          {bs = bdof;}
1023b190aa46SMatthew G. Knepley           else if (bs != bdof) {bs = 1;}
10241a7dc684SMatthew G. Knepley         }
102537d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
1026a974ec88SMatthew G. Knepley           if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c;
1027a974ec88SMatthew G. Knepley           else                                     ltog[l] = (off < 0 ? -(off+1) : off) + c;
102837d0c07bSMatthew G Knepley         }
102937d0c07bSMatthew G Knepley       }
1030bff27382SMatthew G. Knepley       /* Must have same blocksize on all procs (some might have no points) */
10310be3e97aSMatthew G. Knepley       bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs;
10320be3e97aSMatthew G. Knepley       ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr);
10330be3e97aSMatthew G. Knepley       if (bsMinMax[0] != bsMinMax[1]) {bs = 1;}
10340be3e97aSMatthew G. Knepley       else                            {bs = bsMinMax[0];}
10357591dbb2SMatthew G. Knepley       bs = bs < 0 ? 1 : bs;
10367591dbb2SMatthew G. Knepley       /* Must reduce indices by blocksize */
1037ccf3bd66SMatthew G. Knepley       if (bs > 1) {
1038ccf3bd66SMatthew G. Knepley         for (l = 0, k = 0; l < n; l += bs, ++k) ltog[k] = ltog[l]/bs;
1039ccf3bd66SMatthew G. Knepley         n /= bs;
1040ccf3bd66SMatthew G. Knepley       }
1041ccf3bd66SMatthew G. Knepley       ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
10423bb1ff40SBarry Smith       ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr);
104337d0c07bSMatthew G Knepley     } else {
1044184d77edSJed Brown       if (!dm->ops->getlocaltoglobalmapping) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
1045184d77edSJed Brown       ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr);
10461411c6eeSJed Brown     }
104737d0c07bSMatthew G Knepley   }
10481411c6eeSJed Brown   *ltog = dm->ltogmap;
10491411c6eeSJed Brown   PetscFunctionReturn(0);
10501411c6eeSJed Brown }
10511411c6eeSJed Brown 
10521411c6eeSJed Brown /*@
10531411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
10541411c6eeSJed Brown 
10551411c6eeSJed Brown    Not Collective
10561411c6eeSJed Brown 
10571411c6eeSJed Brown    Input Parameter:
10581411c6eeSJed Brown .  dm - the DM with block structure
10591411c6eeSJed Brown 
10601411c6eeSJed Brown    Output Parameter:
10611411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
10621411c6eeSJed Brown 
10631411c6eeSJed Brown    Level: intermediate
10641411c6eeSJed Brown 
1065fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping()
10661411c6eeSJed Brown @*/
10677087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
10681411c6eeSJed Brown {
10691411c6eeSJed Brown   PetscFunctionBegin;
10701411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10711411c6eeSJed Brown   PetscValidPointer(bs,2);
10721411c6eeSJed Brown   if (dm->bs < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DM does not have enough information to provide a block size yet");
10731411c6eeSJed Brown   *bs = dm->bs;
10741411c6eeSJed Brown   PetscFunctionReturn(0);
10751411c6eeSJed Brown }
10761411c6eeSJed Brown 
107747c6ae99SBarry Smith /*@
10788472ad0fSDave May     DMCreateInterpolation - Gets interpolation matrix between two DM objects
107947c6ae99SBarry Smith 
108047c6ae99SBarry Smith     Collective on DM
108147c6ae99SBarry Smith 
108247c6ae99SBarry Smith     Input Parameter:
108347c6ae99SBarry Smith +   dm1 - the DM object
108447c6ae99SBarry Smith -   dm2 - the second, finer DM object
108547c6ae99SBarry Smith 
108647c6ae99SBarry Smith     Output Parameter:
108747c6ae99SBarry Smith +  mat - the interpolation
108847c6ae99SBarry Smith -  vec - the scaling (optional)
108947c6ae99SBarry Smith 
109047c6ae99SBarry Smith     Level: developer
109147c6ae99SBarry Smith 
109295452b02SPatrick Sanan     Notes:
109395452b02SPatrick Sanan     For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
109485afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
1095d52bd9f3SBarry Smith 
10961f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
1097d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
109885afcc9aSBarry Smith 
109985afcc9aSBarry Smith 
11003ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction()
110147c6ae99SBarry Smith 
110247c6ae99SBarry Smith @*/
1103e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
110447c6ae99SBarry Smith {
110547c6ae99SBarry Smith   PetscErrorCode ierr;
110647c6ae99SBarry Smith 
110747c6ae99SBarry Smith   PetscFunctionBegin;
1108171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
1109171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
1110c7d20fa0SStefano Zampini   PetscValidPointer(mat,3);
1111c7d20fa0SStefano Zampini   if (!dm1->ops->createinterpolation) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DMCreateInterpolation not implemented for type %s",((PetscObject)dm1)->type_name);
1112cea54e9dSPatrick Farrell   ierr = PetscLogEventBegin(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
111325296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
1114cea54e9dSPatrick Farrell   ierr = PetscLogEventEnd(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
111547c6ae99SBarry Smith   PetscFunctionReturn(0);
111647c6ae99SBarry Smith }
111747c6ae99SBarry Smith 
11183ad4599aSBarry Smith /*@
11193ad4599aSBarry Smith     DMCreateRestriction - Gets restriction matrix between two DM objects
11203ad4599aSBarry Smith 
11213ad4599aSBarry Smith     Collective on DM
11223ad4599aSBarry Smith 
11233ad4599aSBarry Smith     Input Parameter:
11243ad4599aSBarry Smith +   dm1 - the DM object
11253ad4599aSBarry Smith -   dm2 - the second, finer DM object
11263ad4599aSBarry Smith 
11273ad4599aSBarry Smith     Output Parameter:
11283ad4599aSBarry Smith .  mat - the restriction
11293ad4599aSBarry Smith 
11303ad4599aSBarry Smith 
11313ad4599aSBarry Smith     Level: developer
11323ad4599aSBarry Smith 
113395452b02SPatrick Sanan     Notes:
113495452b02SPatrick Sanan     For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
11353ad4599aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
11363ad4599aSBarry Smith 
11373ad4599aSBarry Smith 
11383ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation()
11393ad4599aSBarry Smith 
11403ad4599aSBarry Smith @*/
11413ad4599aSBarry Smith PetscErrorCode  DMCreateRestriction(DM dm1,DM dm2,Mat *mat)
11423ad4599aSBarry Smith {
11433ad4599aSBarry Smith   PetscErrorCode ierr;
11443ad4599aSBarry Smith 
11453ad4599aSBarry Smith   PetscFunctionBegin;
11463ad4599aSBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
11473ad4599aSBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
11483ad4599aSBarry Smith   ierr = PetscLogEventBegin(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr);
11497294143fSBarry Smith   if (!dm1->ops->createrestriction) SETERRQ(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DMCreateRestriction not implemented for this type");
11503ad4599aSBarry Smith   ierr = (*dm1->ops->createrestriction)(dm1,dm2,mat);CHKERRQ(ierr);
11513ad4599aSBarry Smith   ierr = PetscLogEventEnd(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr);
11523ad4599aSBarry Smith   PetscFunctionReturn(0);
11533ad4599aSBarry Smith }
11543ad4599aSBarry Smith 
115547c6ae99SBarry Smith /*@
11568472ad0fSDave May     DMCreateInjection - Gets injection matrix between two DM objects
115747c6ae99SBarry Smith 
115847c6ae99SBarry Smith     Collective on DM
115947c6ae99SBarry Smith 
116047c6ae99SBarry Smith     Input Parameter:
116147c6ae99SBarry Smith +   dm1 - the DM object
116247c6ae99SBarry Smith -   dm2 - the second, finer DM object
116347c6ae99SBarry Smith 
116447c6ae99SBarry Smith     Output Parameter:
11656dbf9973SLawrence Mitchell .   mat - the injection
116647c6ae99SBarry Smith 
116747c6ae99SBarry Smith     Level: developer
116847c6ae99SBarry Smith 
116995452b02SPatrick Sanan    Notes:
117095452b02SPatrick Sanan     For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
117185afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
117285afcc9aSBarry Smith 
1173e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
117447c6ae99SBarry Smith 
117547c6ae99SBarry Smith @*/
11766dbf9973SLawrence Mitchell PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,Mat *mat)
117747c6ae99SBarry Smith {
117847c6ae99SBarry Smith   PetscErrorCode ierr;
117947c6ae99SBarry Smith 
118047c6ae99SBarry Smith   PetscFunctionBegin;
1181171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
1182171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
11830c4c9125SBarry Smith   if (!dm1->ops->getinjection) SETERRQ(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DMCreateInjection not implemented for this type");
11846dbf9973SLawrence Mitchell   ierr = (*dm1->ops->getinjection)(dm1,dm2,mat);CHKERRQ(ierr);
118547c6ae99SBarry Smith   PetscFunctionReturn(0);
118647c6ae99SBarry Smith }
118747c6ae99SBarry Smith 
1188b412c318SBarry Smith /*@
1189bd041c0cSMatthew G. Knepley   DMCreateMassMatrix - Gets mass matrix between two DM objects, M_ij = \int \phi_i \psi_j
1190bd041c0cSMatthew G. Knepley 
1191bd041c0cSMatthew G. Knepley   Collective on DM
1192bd041c0cSMatthew G. Knepley 
1193bd041c0cSMatthew G. Knepley   Input Parameter:
1194bd041c0cSMatthew G. Knepley + dm1 - the DM object
1195bd041c0cSMatthew G. Knepley - dm2 - the second, finer DM object
1196bd041c0cSMatthew G. Knepley 
1197bd041c0cSMatthew G. Knepley   Output Parameter:
1198bd041c0cSMatthew G. Knepley . mat - the interpolation
1199bd041c0cSMatthew G. Knepley 
1200bd041c0cSMatthew G. Knepley   Level: developer
1201bd041c0cSMatthew G. Knepley 
1202bd041c0cSMatthew G. Knepley .seealso DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection()
1203bd041c0cSMatthew G. Knepley @*/
1204bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix(DM dm1, DM dm2, Mat *mat)
1205bd041c0cSMatthew G. Knepley {
1206bd041c0cSMatthew G. Knepley   PetscErrorCode ierr;
1207bd041c0cSMatthew G. Knepley 
1208bd041c0cSMatthew G. Knepley   PetscFunctionBegin;
1209bd041c0cSMatthew G. Knepley   PetscValidHeaderSpecific(dm1, DM_CLASSID, 1);
1210bd041c0cSMatthew G. Knepley   PetscValidHeaderSpecific(dm2, DM_CLASSID, 2);
1211bd041c0cSMatthew G. Knepley   ierr = (*dm1->ops->createmassmatrix)(dm1, dm2, mat);CHKERRQ(ierr);
1212bd041c0cSMatthew G. Knepley   PetscFunctionReturn(0);
1213bd041c0cSMatthew G. Knepley }
1214bd041c0cSMatthew G. Knepley 
1215bd041c0cSMatthew G. Knepley /*@
1216b412c318SBarry Smith     DMCreateColoring - Gets coloring for a DM
121747c6ae99SBarry Smith 
121847c6ae99SBarry Smith     Collective on DM
121947c6ae99SBarry Smith 
122047c6ae99SBarry Smith     Input Parameter:
122147c6ae99SBarry Smith +   dm - the DM object
12225bdb020cSBarry Smith -   ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL
122347c6ae99SBarry Smith 
122447c6ae99SBarry Smith     Output Parameter:
122547c6ae99SBarry Smith .   coloring - the coloring
122647c6ae99SBarry Smith 
122747c6ae99SBarry Smith     Level: developer
122847c6ae99SBarry Smith 
1229b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType()
123047c6ae99SBarry Smith 
1231aab9d709SJed Brown @*/
1232b412c318SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring)
123347c6ae99SBarry Smith {
123447c6ae99SBarry Smith   PetscErrorCode ierr;
123547c6ae99SBarry Smith 
123647c6ae99SBarry Smith   PetscFunctionBegin;
1237171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1238ce94432eSBarry Smith   if (!dm->ops->getcoloring) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No coloring for this type of DM yet");
1239b412c318SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr);
124047c6ae99SBarry Smith   PetscFunctionReturn(0);
124147c6ae99SBarry Smith }
124247c6ae99SBarry Smith 
1243b412c318SBarry Smith /*@
12448472ad0fSDave May     DMCreateMatrix - Gets empty Jacobian for a DM
124547c6ae99SBarry Smith 
124647c6ae99SBarry Smith     Collective on DM
124747c6ae99SBarry Smith 
124847c6ae99SBarry Smith     Input Parameter:
1249b412c318SBarry Smith .   dm - the DM object
125047c6ae99SBarry Smith 
125147c6ae99SBarry Smith     Output Parameter:
125247c6ae99SBarry Smith .   mat - the empty Jacobian
125347c6ae99SBarry Smith 
1254073dac72SJed Brown     Level: beginner
125547c6ae99SBarry Smith 
125695452b02SPatrick Sanan     Notes:
125795452b02SPatrick Sanan     This properly preallocates the number of nonzeros in the sparse matrix so you
125894013140SBarry Smith        do not need to do it yourself.
125994013140SBarry Smith 
126094013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
12617889ec69SBarry Smith        the nonzero pattern call DMSetMatrixPreallocateOnly()
126294013140SBarry Smith 
126394013140SBarry Smith        For structured grid problems, when you call MatView() on this matrix it is displayed using the global natural ordering, NOT in the ordering used
126494013140SBarry Smith        internally by PETSc.
126594013140SBarry Smith 
126694013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
1267aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
126894013140SBarry Smith 
1269b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType()
127047c6ae99SBarry Smith 
1271aab9d709SJed Brown @*/
1272b412c318SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,Mat *mat)
127347c6ae99SBarry Smith {
127447c6ae99SBarry Smith   PetscErrorCode ierr;
127547c6ae99SBarry Smith 
127647c6ae99SBarry Smith   PetscFunctionBegin;
1277171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1278607a6623SBarry Smith   ierr = MatInitializePackage();CHKERRQ(ierr);
1279c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1280c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
1281b412c318SBarry Smith   ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr);
1282e571a35bSMatthew G. Knepley   /* Handle nullspace and near nullspace */
1283e5e52638SMatthew G. Knepley   if (dm->Nf) {
1284e571a35bSMatthew G. Knepley     MatNullSpace nullSpace;
1285e571a35bSMatthew G. Knepley     PetscInt     Nf;
1286e571a35bSMatthew G. Knepley 
1287e5e52638SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
1288e571a35bSMatthew G. Knepley     if (Nf == 1) {
1289e571a35bSMatthew G. Knepley       if (dm->nullspaceConstructors[0]) {
1290e571a35bSMatthew G. Knepley         ierr = (*dm->nullspaceConstructors[0])(dm, 0, &nullSpace);CHKERRQ(ierr);
1291e571a35bSMatthew G. Knepley         ierr = MatSetNullSpace(*mat, nullSpace);CHKERRQ(ierr);
1292e571a35bSMatthew G. Knepley         ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);
1293e571a35bSMatthew G. Knepley       }
1294e571a35bSMatthew G. Knepley       if (dm->nearnullspaceConstructors[0]) {
1295e571a35bSMatthew G. Knepley         ierr = (*dm->nearnullspaceConstructors[0])(dm, 0, &nullSpace);CHKERRQ(ierr);
1296e571a35bSMatthew G. Knepley         ierr = MatSetNearNullSpace(*mat, nullSpace);CHKERRQ(ierr);
1297e571a35bSMatthew G. Knepley         ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);
1298e571a35bSMatthew G. Knepley       }
1299e571a35bSMatthew G. Knepley     }
1300e571a35bSMatthew G. Knepley   }
130147c6ae99SBarry Smith   PetscFunctionReturn(0);
130247c6ae99SBarry Smith }
130347c6ae99SBarry Smith 
1304732e2eb9SMatthew G Knepley /*@
1305950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
1306732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
1307732e2eb9SMatthew G Knepley 
13088472ad0fSDave May   Logically Collective on DM
1309732e2eb9SMatthew G Knepley 
1310732e2eb9SMatthew G Knepley   Input Parameter:
1311732e2eb9SMatthew G Knepley + dm - the DM
1312732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
1313732e2eb9SMatthew G Knepley 
1314732e2eb9SMatthew G Knepley   Level: developer
1315b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly()
1316732e2eb9SMatthew G Knepley @*/
1317732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
1318732e2eb9SMatthew G Knepley {
1319732e2eb9SMatthew G Knepley   PetscFunctionBegin;
1320732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1321732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
1322732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
1323732e2eb9SMatthew G Knepley }
1324732e2eb9SMatthew G Knepley 
1325b06ff27eSHong Zhang /*@
1326b06ff27eSHong Zhang   DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created
1327b06ff27eSHong Zhang     but the array for values will not be allocated.
1328b06ff27eSHong Zhang 
1329b06ff27eSHong Zhang   Logically Collective on DM
1330b06ff27eSHong Zhang 
1331b06ff27eSHong Zhang   Input Parameter:
1332b06ff27eSHong Zhang + dm - the DM
1333b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture
1334b06ff27eSHong Zhang 
1335b06ff27eSHong Zhang   Level: developer
1336b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly()
1337b06ff27eSHong Zhang @*/
1338b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only)
1339b06ff27eSHong Zhang {
1340b06ff27eSHong Zhang   PetscFunctionBegin;
1341b06ff27eSHong Zhang   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1342b06ff27eSHong Zhang   dm->structure_only = only;
1343b06ff27eSHong Zhang   PetscFunctionReturn(0);
1344b06ff27eSHong Zhang }
1345b06ff27eSHong Zhang 
1346a89ea682SMatthew G Knepley /*@C
1347aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1348a89ea682SMatthew G Knepley 
1349a89ea682SMatthew G Knepley   Not Collective
1350a89ea682SMatthew G Knepley 
1351a89ea682SMatthew G Knepley   Input Parameters:
1352a89ea682SMatthew G Knepley + dm - the DM object
1353aa1993deSMatthew G Knepley . count - The minium size
135469291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT)
1355a89ea682SMatthew G Knepley 
1356a89ea682SMatthew G Knepley   Output Parameter:
1357a89ea682SMatthew G Knepley . array - the work array
1358a89ea682SMatthew G Knepley 
1359a89ea682SMatthew G Knepley   Level: developer
1360a89ea682SMatthew G Knepley 
1361a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
1362a89ea682SMatthew G Knepley @*/
136369291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem)
1364a89ea682SMatthew G Knepley {
1365a89ea682SMatthew G Knepley   PetscErrorCode ierr;
1366aa1993deSMatthew G Knepley   DMWorkLink     link;
136769291d52SBarry Smith   PetscMPIInt    dsize;
1368a89ea682SMatthew G Knepley 
1369a89ea682SMatthew G Knepley   PetscFunctionBegin;
1370a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1371aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1372aa1993deSMatthew G Knepley   if (dm->workin) {
1373aa1993deSMatthew G Knepley     link       = dm->workin;
1374aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
1375aa1993deSMatthew G Knepley   } else {
1376b00a9115SJed Brown     ierr = PetscNewLog(dm,&link);CHKERRQ(ierr);
1377a89ea682SMatthew G Knepley   }
137869291d52SBarry Smith   ierr = MPI_Type_size(dtype,&dsize);CHKERRQ(ierr);
13795056fcd2SBarry Smith   if (((size_t)dsize*count) > link->bytes) {
1380aa1993deSMatthew G Knepley     ierr        = PetscFree(link->mem);CHKERRQ(ierr);
1381854ce69bSBarry Smith     ierr        = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr);
1382854ce69bSBarry Smith     link->bytes = dsize*count;
1383aa1993deSMatthew G Knepley   }
1384aa1993deSMatthew G Knepley   link->next   = dm->workout;
1385aa1993deSMatthew G Knepley   dm->workout  = link;
1386aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
1387a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
1388a89ea682SMatthew G Knepley }
1389a89ea682SMatthew G Knepley 
1390aa1993deSMatthew G Knepley /*@C
1391aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1392aa1993deSMatthew G Knepley 
1393aa1993deSMatthew G Knepley   Not Collective
1394aa1993deSMatthew G Knepley 
1395aa1993deSMatthew G Knepley   Input Parameters:
1396aa1993deSMatthew G Knepley + dm - the DM object
1397aa1993deSMatthew G Knepley . count - The minium size
139869291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT
1399aa1993deSMatthew G Knepley 
1400aa1993deSMatthew G Knepley   Output Parameter:
1401aa1993deSMatthew G Knepley . array - the work array
1402aa1993deSMatthew G Knepley 
1403aa1993deSMatthew G Knepley   Level: developer
1404aa1993deSMatthew G Knepley 
140595452b02SPatrick Sanan   Developer Notes:
140695452b02SPatrick Sanan     count and dtype are ignored, they are only needed for DMGetWorkArray()
1407aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
1408aa1993deSMatthew G Knepley @*/
140969291d52SBarry Smith PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem)
1410aa1993deSMatthew G Knepley {
1411aa1993deSMatthew G Knepley   DMWorkLink *p,link;
1412aa1993deSMatthew G Knepley 
1413aa1993deSMatthew G Knepley   PetscFunctionBegin;
1414aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1415aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1416aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
1417aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
1418aa1993deSMatthew G Knepley       *p           = link->next;
1419aa1993deSMatthew G Knepley       link->next   = dm->workin;
1420aa1993deSMatthew G Knepley       dm->workin   = link;
14210298fd71SBarry Smith       *(void**)mem = NULL;
1422aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
1423aa1993deSMatthew G Knepley     }
1424aa1993deSMatthew G Knepley   }
1425aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
1426aa1993deSMatthew G Knepley }
1427e7c4fc90SDmitry Karpeev 
1428435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1429435a35e8SMatthew G Knepley {
1430435a35e8SMatthew G Knepley   PetscFunctionBegin;
1431435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
143282f516ccSBarry Smith   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1433435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
1434435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1435435a35e8SMatthew G Knepley }
1436435a35e8SMatthew G Knepley 
14370a50eb56SMatthew G. Knepley PetscErrorCode DMGetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
14380a50eb56SMatthew G. Knepley {
14390a50eb56SMatthew G. Knepley   PetscFunctionBegin;
14400a50eb56SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1441f9d4088aSMatthew G. Knepley   PetscValidPointer(nullsp, 3);
14420a50eb56SMatthew G. Knepley   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
14430a50eb56SMatthew G. Knepley   *nullsp = dm->nullspaceConstructors[field];
14440a50eb56SMatthew G. Knepley   PetscFunctionReturn(0);
14450a50eb56SMatthew G. Knepley }
14460a50eb56SMatthew G. Knepley 
1447f9d4088aSMatthew G. Knepley PetscErrorCode DMSetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1448f9d4088aSMatthew G. Knepley {
1449f9d4088aSMatthew G. Knepley   PetscFunctionBegin;
1450f9d4088aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1451f9d4088aSMatthew G. Knepley   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1452f9d4088aSMatthew G. Knepley   dm->nearnullspaceConstructors[field] = nullsp;
1453f9d4088aSMatthew G. Knepley   PetscFunctionReturn(0);
1454f9d4088aSMatthew G. Knepley }
1455f9d4088aSMatthew G. Knepley 
1456f9d4088aSMatthew G. Knepley PetscErrorCode DMGetNearNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (**nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1457f9d4088aSMatthew G. Knepley {
1458f9d4088aSMatthew G. Knepley   PetscFunctionBegin;
1459f9d4088aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1460f9d4088aSMatthew G. Knepley   PetscValidPointer(nullsp, 3);
1461f9d4088aSMatthew G. Knepley   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1462f9d4088aSMatthew G. Knepley   *nullsp = dm->nearnullspaceConstructors[field];
1463f9d4088aSMatthew G. Knepley   PetscFunctionReturn(0);
1464f9d4088aSMatthew G. Knepley }
1465f9d4088aSMatthew G. Knepley 
14664f3b5142SJed Brown /*@C
14674d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
14684d343eeaSMatthew G Knepley 
14694d343eeaSMatthew G Knepley   Not collective
14704d343eeaSMatthew G Knepley 
14714d343eeaSMatthew G Knepley   Input Parameter:
14724d343eeaSMatthew G Knepley . dm - the DM object
14734d343eeaSMatthew G Knepley 
14744d343eeaSMatthew G Knepley   Output Parameters:
14750298fd71SBarry Smith + numFields  - The number of fields (or NULL if not requested)
14760298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested)
14770298fd71SBarry Smith - fields     - The global indices for each field (or NULL if not requested)
14784d343eeaSMatthew G Knepley 
14794d343eeaSMatthew G Knepley   Level: intermediate
14804d343eeaSMatthew G Knepley 
148121c9b008SJed Brown   Notes:
148221c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
148321c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
148421c9b008SJed Brown   PetscFree().
148521c9b008SJed Brown 
14864d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
14874d343eeaSMatthew G Knepley @*/
148837d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
14894d343eeaSMatthew G Knepley {
149037d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
14914d343eeaSMatthew G Knepley   PetscErrorCode ierr;
14924d343eeaSMatthew G Knepley 
14934d343eeaSMatthew G Knepley   PetscFunctionBegin;
14944d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
149569ca1f37SDmitry Karpeev   if (numFields) {
149669ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
149769ca1f37SDmitry Karpeev     *numFields = 0;
149869ca1f37SDmitry Karpeev   }
149937d0c07bSMatthew G Knepley   if (fieldNames) {
150037d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
15010298fd71SBarry Smith     *fieldNames = NULL;
150269ca1f37SDmitry Karpeev   }
150369ca1f37SDmitry Karpeev   if (fields) {
150469ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
15050298fd71SBarry Smith     *fields = NULL;
150669ca1f37SDmitry Karpeev   }
1507e87a4003SBarry Smith   ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
150837d0c07bSMatthew G Knepley   if (section) {
15093a544194SStefano Zampini     PetscInt *fieldSizes, *fieldNc, **fieldIndices;
151037d0c07bSMatthew G Knepley     PetscInt nF, f, pStart, pEnd, p;
151137d0c07bSMatthew G Knepley 
1512e87a4003SBarry Smith     ierr = DMGetGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
151337d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
15143a544194SStefano Zampini     ierr = PetscMalloc3(nF,&fieldSizes,nF,&fieldNc,nF,&fieldIndices);CHKERRQ(ierr);
151537d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
151637d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
151737d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
15183a544194SStefano Zampini       ierr          = PetscSectionGetFieldComponents(section, f, &fieldNc[f]);CHKERRQ(ierr);
151937d0c07bSMatthew G Knepley     }
152037d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
152137d0c07bSMatthew G Knepley       PetscInt gdof;
152237d0c07bSMatthew G Knepley 
152337d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
152437d0c07bSMatthew G Knepley       if (gdof > 0) {
152537d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
15263a544194SStefano Zampini           PetscInt fdof, fcdof, fpdof;
152737d0c07bSMatthew G Knepley 
152837d0c07bSMatthew G Knepley           ierr  = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
152937d0c07bSMatthew G Knepley           ierr  = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
15303a544194SStefano Zampini           fpdof = fdof-fcdof;
15313a544194SStefano Zampini           if (fpdof && fpdof != fieldNc[f]) {
15323a544194SStefano Zampini             /* Layout does not admit a pointwise block size */
15333a544194SStefano Zampini             fieldNc[f] = 1;
15343a544194SStefano Zampini           }
15353a544194SStefano Zampini           fieldSizes[f] += fpdof;
153637d0c07bSMatthew G Knepley         }
153737d0c07bSMatthew G Knepley       }
153837d0c07bSMatthew G Knepley     }
153937d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
1540785e854fSJed Brown       ierr          = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr);
154137d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
154237d0c07bSMatthew G Knepley     }
154337d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
154437d0c07bSMatthew G Knepley       PetscInt gdof, goff;
154537d0c07bSMatthew G Knepley 
154637d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
154737d0c07bSMatthew G Knepley       if (gdof > 0) {
154837d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
154937d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
155037d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
155137d0c07bSMatthew G Knepley 
155237d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
155337d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
155437d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
155537d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
155637d0c07bSMatthew G Knepley           }
155737d0c07bSMatthew G Knepley         }
155837d0c07bSMatthew G Knepley       }
155937d0c07bSMatthew G Knepley     }
15608865f1eaSKarl Rupp     if (numFields) *numFields = nF;
156137d0c07bSMatthew G Knepley     if (fieldNames) {
1562785e854fSJed Brown       ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr);
156337d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
156437d0c07bSMatthew G Knepley         const char *fieldName;
156537d0c07bSMatthew G Knepley 
156637d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
156737d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr);
156837d0c07bSMatthew G Knepley       }
156937d0c07bSMatthew G Knepley     }
157037d0c07bSMatthew G Knepley     if (fields) {
1571785e854fSJed Brown       ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr);
157237d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
15733a544194SStefano Zampini         PetscInt bs, in[2], out[2];
15743a544194SStefano Zampini 
157582f516ccSBarry Smith         ierr  = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
15763a544194SStefano Zampini         in[0] = -fieldNc[f];
15773a544194SStefano Zampini         in[1] = fieldNc[f];
15783a544194SStefano Zampini         ierr  = MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
15793a544194SStefano Zampini         bs    = (-out[0] == out[1]) ? out[1] : 1;
15803a544194SStefano Zampini         ierr  = ISSetBlockSize((*fields)[f], bs);CHKERRQ(ierr);
158137d0c07bSMatthew G Knepley       }
158237d0c07bSMatthew G Knepley     }
15833a544194SStefano Zampini     ierr = PetscFree3(fieldSizes,fieldNc,fieldIndices);CHKERRQ(ierr);
15848865f1eaSKarl Rupp   } else if (dm->ops->createfieldis) {
15858865f1eaSKarl Rupp     ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);
158669ca1f37SDmitry Karpeev   }
15874d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
15884d343eeaSMatthew G Knepley }
15894d343eeaSMatthew G Knepley 
159016621825SDmitry Karpeev 
159116621825SDmitry Karpeev /*@C
159216621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
159316621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
159416621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1595e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1596e7c4fc90SDmitry Karpeev 
1597e7c4fc90SDmitry Karpeev   Not collective
1598e7c4fc90SDmitry Karpeev 
1599e7c4fc90SDmitry Karpeev   Input Parameter:
1600e7c4fc90SDmitry Karpeev . dm - the DM object
1601e7c4fc90SDmitry Karpeev 
1602e7c4fc90SDmitry Karpeev   Output Parameters:
16030298fd71SBarry Smith + len       - The number of subproblems in the field decomposition (or NULL if not requested)
16040298fd71SBarry Smith . namelist  - The name for each field (or NULL if not requested)
16050298fd71SBarry Smith . islist    - The global indices for each field (or NULL if not requested)
16060298fd71SBarry Smith - dmlist    - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
1607e7c4fc90SDmitry Karpeev 
1608e7c4fc90SDmitry Karpeev   Level: intermediate
1609e7c4fc90SDmitry Karpeev 
1610e7c4fc90SDmitry Karpeev   Notes:
1611e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1612e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1613e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1614e7c4fc90SDmitry Karpeev 
1615e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1616e7c4fc90SDmitry Karpeev @*/
161716621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1618e7c4fc90SDmitry Karpeev {
1619e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1620e7c4fc90SDmitry Karpeev 
1621e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1622e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
16238865f1eaSKarl Rupp   if (len) {
16248865f1eaSKarl Rupp     PetscValidPointer(len,2);
16258865f1eaSKarl Rupp     *len = 0;
16268865f1eaSKarl Rupp   }
16278865f1eaSKarl Rupp   if (namelist) {
16288865f1eaSKarl Rupp     PetscValidPointer(namelist,3);
16298865f1eaSKarl Rupp     *namelist = 0;
16308865f1eaSKarl Rupp   }
16318865f1eaSKarl Rupp   if (islist) {
16328865f1eaSKarl Rupp     PetscValidPointer(islist,4);
16338865f1eaSKarl Rupp     *islist = 0;
16348865f1eaSKarl Rupp   }
16358865f1eaSKarl Rupp   if (dmlist) {
16368865f1eaSKarl Rupp     PetscValidPointer(dmlist,5);
16378865f1eaSKarl Rupp     *dmlist = 0;
16388865f1eaSKarl Rupp   }
1639f3f0edfdSDmitry Karpeev   /*
1640f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1641f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1642f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1643f3f0edfdSDmitry Karpeev    */
1644ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
164516621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1646435a35e8SMatthew G Knepley     PetscSection section;
1647435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1648435a35e8SMatthew G Knepley 
1649e87a4003SBarry Smith     ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
1650435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1651435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1652f25d98f1SMatthew G. Knepley       if (len) *len = numFields;
165303dc3394SMatthew G. Knepley       if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);}
165403dc3394SMatthew G. Knepley       if (islist)   {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);}
165503dc3394SMatthew G. Knepley       if (dmlist)   {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);}
1656435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1657435a35e8SMatthew G Knepley         const char *fieldName;
1658435a35e8SMatthew G Knepley 
165903dc3394SMatthew G. Knepley         ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr);
166003dc3394SMatthew G. Knepley         if (namelist) {
1661435a35e8SMatthew G Knepley           ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1662435a35e8SMatthew G Knepley           ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr);
1663435a35e8SMatthew G Knepley         }
166403dc3394SMatthew G. Knepley       }
1665435a35e8SMatthew G Knepley     } else {
166669ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1667e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
16680298fd71SBarry Smith       if (dmlist) *dmlist = NULL;
1669e7c4fc90SDmitry Karpeev     }
16708865f1eaSKarl Rupp   } else {
167116621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr);
167216621825SDmitry Karpeev   }
167316621825SDmitry Karpeev   PetscFunctionReturn(0);
167416621825SDmitry Karpeev }
167516621825SDmitry Karpeev 
1676564cec59SMatthew G. Knepley /*@
1677435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1678435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1679435a35e8SMatthew G Knepley 
1680435a35e8SMatthew G Knepley   Not collective
1681435a35e8SMatthew G Knepley 
1682435a35e8SMatthew G Knepley   Input Parameters:
16832adcc780SMatthew G. Knepley + dm        - The DM object
16842adcc780SMatthew G. Knepley . numFields - The number of fields in this subproblem
16852adcc780SMatthew G. Knepley - fields    - The field numbers of the selected fields
1686435a35e8SMatthew G Knepley 
1687435a35e8SMatthew G Knepley   Output Parameters:
16882adcc780SMatthew G. Knepley + is - The global indices for the subproblem
16892adcc780SMatthew G. Knepley - subdm - The DM for the subproblem
1690435a35e8SMatthew G Knepley 
16915d3b26e6SMatthew G. Knepley   Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed
16925d3b26e6SMatthew G. Knepley 
1693435a35e8SMatthew G Knepley   Level: intermediate
1694435a35e8SMatthew G Knepley 
16955d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1696435a35e8SMatthew G Knepley @*/
169737bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1698435a35e8SMatthew G Knepley {
1699435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1700435a35e8SMatthew G Knepley 
1701435a35e8SMatthew G Knepley   PetscFunctionBegin;
1702435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1703435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
17048865f1eaSKarl Rupp   if (is) PetscValidPointer(is,4);
17058865f1eaSKarl Rupp   if (subdm) PetscValidPointer(subdm,5);
1706435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1707435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
170882f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1709435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1710435a35e8SMatthew G Knepley }
1711435a35e8SMatthew G Knepley 
17122adcc780SMatthew G. Knepley /*@C
17132adcc780SMatthew G. Knepley   DMCreateSuperDM - Returns an arrays of ISes and DM encapsulating a superproblem defined by the DMs passed in.
17142adcc780SMatthew G. Knepley 
17152adcc780SMatthew G. Knepley   Not collective
17162adcc780SMatthew G. Knepley 
17172adcc780SMatthew G. Knepley   Input Parameter:
17182adcc780SMatthew G. Knepley + dms - The DM objects
17192adcc780SMatthew G. Knepley - len - The number of DMs
17202adcc780SMatthew G. Knepley 
17212adcc780SMatthew G. Knepley   Output Parameters:
1722a42bd24dSMatthew G. Knepley + is - The global indices for the subproblem, or NULL
17232adcc780SMatthew G. Knepley - superdm - The DM for the superproblem
17242adcc780SMatthew G. Knepley 
17255d3b26e6SMatthew G. Knepley   Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed
17265d3b26e6SMatthew G. Knepley 
17272adcc780SMatthew G. Knepley   Level: intermediate
17282adcc780SMatthew G. Knepley 
17295d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
17302adcc780SMatthew G. Knepley @*/
17312adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt len, IS **is, DM *superdm)
17322adcc780SMatthew G. Knepley {
17332adcc780SMatthew G. Knepley   PetscInt       i;
17342adcc780SMatthew G. Knepley   PetscErrorCode ierr;
17352adcc780SMatthew G. Knepley 
17362adcc780SMatthew G. Knepley   PetscFunctionBegin;
17372adcc780SMatthew G. Knepley   PetscValidPointer(dms,1);
17382adcc780SMatthew G. Knepley   for (i = 0; i < len; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);}
17392adcc780SMatthew G. Knepley   if (is) PetscValidPointer(is,3);
1740a42bd24dSMatthew G. Knepley   PetscValidPointer(superdm,4);
17412adcc780SMatthew G. Knepley   if (len < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %D", len);
17422adcc780SMatthew G. Knepley   if (len) {
1743a42bd24dSMatthew G. Knepley     if (dms[0]->ops->createsuperdm) {ierr = (*dms[0]->ops->createsuperdm)(dms, len, is, superdm);CHKERRQ(ierr);}
1744a42bd24dSMatthew G. Knepley     else SETERRQ(PetscObjectComm((PetscObject) dms[0]), PETSC_ERR_SUP, "This type has no DMCreateSuperDM implementation defined");
17452adcc780SMatthew G. Knepley   }
17462adcc780SMatthew G. Knepley   PetscFunctionReturn(0);
17472adcc780SMatthew G. Knepley }
17482adcc780SMatthew G. Knepley 
174916621825SDmitry Karpeev 
175016621825SDmitry Karpeev /*@C
17518d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
17528d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
17538d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
17548d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
17558d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
175616621825SDmitry Karpeev 
175716621825SDmitry Karpeev   Not collective
175816621825SDmitry Karpeev 
175916621825SDmitry Karpeev   Input Parameter:
176016621825SDmitry Karpeev . dm - the DM object
176116621825SDmitry Karpeev 
176216621825SDmitry Karpeev   Output Parameters:
17630298fd71SBarry Smith + len         - The number of subproblems in the domain decomposition (or NULL if not requested)
17640298fd71SBarry Smith . namelist    - The name for each subdomain (or NULL if not requested)
17650298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested)
17660298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested)
17670298fd71SBarry Smith - dmlist      - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
176816621825SDmitry Karpeev 
176916621825SDmitry Karpeev   Level: intermediate
177016621825SDmitry Karpeev 
177116621825SDmitry Karpeev   Notes:
177216621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
177316621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
177416621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
177516621825SDmitry Karpeev 
17768d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
177716621825SDmitry Karpeev @*/
17788d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
177916621825SDmitry Karpeev {
178016621825SDmitry Karpeev   PetscErrorCode      ierr;
1781be081cd6SPeter Brune   DMSubDomainHookLink link;
1782be081cd6SPeter Brune   PetscInt            i,l;
178316621825SDmitry Karpeev 
178416621825SDmitry Karpeev   PetscFunctionBegin;
178516621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
178614a18fd3SPeter Brune   if (len)           {PetscValidPointer(len,2);            *len         = 0;}
17870298fd71SBarry Smith   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = NULL;}
17880298fd71SBarry Smith   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = NULL;}
17890298fd71SBarry Smith   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = NULL;}
17900298fd71SBarry Smith   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = NULL;}
1791f3f0edfdSDmitry Karpeev   /*
1792f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1793f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1794f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1795f3f0edfdSDmitry Karpeev    */
1796ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
179716621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
1798be081cd6SPeter Brune     ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr);
179914a18fd3SPeter Brune     /* copy subdomain hooks and context over to the subdomain DMs */
1800f891f5b9SPatrick Sanan     if (dmlist && *dmlist) {
1801be081cd6SPeter Brune       for (i = 0; i < l; i++) {
1802be081cd6SPeter Brune         for (link=dm->subdomainhook; link; link=link->next) {
1803be081cd6SPeter Brune           if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);}
1804be081cd6SPeter Brune         }
1805648262bbSPatrick Sanan         if (dm->ctx) (*dmlist)[i]->ctx = dm->ctx;
1806e7c4fc90SDmitry Karpeev       }
180714a18fd3SPeter Brune     }
180814a18fd3SPeter Brune     if (len) *len = l;
180914a18fd3SPeter Brune   }
1810e30e807fSPeter Brune   PetscFunctionReturn(0);
1811e30e807fSPeter Brune }
1812e30e807fSPeter Brune 
1813e30e807fSPeter Brune 
1814e30e807fSPeter Brune /*@C
1815e30e807fSPeter Brune   DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector
1816e30e807fSPeter Brune 
1817e30e807fSPeter Brune   Not collective
1818e30e807fSPeter Brune 
1819e30e807fSPeter Brune   Input Parameters:
1820e30e807fSPeter Brune + dm - the DM object
1821e30e807fSPeter Brune . n  - the number of subdomain scatters
1822e30e807fSPeter Brune - subdms - the local subdomains
1823e30e807fSPeter Brune 
1824e30e807fSPeter Brune   Output Parameters:
1825e30e807fSPeter Brune + n     - the number of scatters returned
1826e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain
1827e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain
1828e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts)
1829e30e807fSPeter Brune 
183095452b02SPatrick Sanan   Notes:
183195452b02SPatrick Sanan     This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution
1832e30e807fSPeter Brune   of general nonlinear problems with overlapping subdomain methods.  While merely having index sets that enable subsets
1833e30e807fSPeter Brune   of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of
1834e30e807fSPeter Brune   solution and residual data.
1835e30e807fSPeter Brune 
1836e30e807fSPeter Brune   Level: developer
1837e30e807fSPeter Brune 
1838e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1839e30e807fSPeter Brune @*/
1840e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat)
1841e30e807fSPeter Brune {
1842e30e807fSPeter Brune   PetscErrorCode ierr;
1843e30e807fSPeter Brune 
1844e30e807fSPeter Brune   PetscFunctionBegin;
1845e30e807fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1846e30e807fSPeter Brune   PetscValidPointer(subdms,3);
1847e30e807fSPeter Brune   if (dm->ops->createddscatters) {
1848e30e807fSPeter Brune     ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr);
18496668ed41SLisandro Dalcin   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateDomainDecompositionScatter implementation defined");
1850e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1851e7c4fc90SDmitry Karpeev }
1852e7c4fc90SDmitry Karpeev 
185347c6ae99SBarry Smith /*@
185447c6ae99SBarry Smith   DMRefine - Refines a DM object
185547c6ae99SBarry Smith 
185647c6ae99SBarry Smith   Collective on DM
185747c6ae99SBarry Smith 
185847c6ae99SBarry Smith   Input Parameter:
185947c6ae99SBarry Smith + dm   - the DM object
186091d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
186147c6ae99SBarry Smith 
186247c6ae99SBarry Smith   Output Parameter:
18630298fd71SBarry Smith . dmf - the refined DM, or NULL
1864ae0a1c52SMatthew G Knepley 
18650298fd71SBarry Smith   Note: If no refinement was done, the return value is NULL
186647c6ae99SBarry Smith 
186747c6ae99SBarry Smith   Level: developer
186847c6ae99SBarry Smith 
1869e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
187047c6ae99SBarry Smith @*/
18717087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
187247c6ae99SBarry Smith {
187347c6ae99SBarry Smith   PetscErrorCode   ierr;
1874c833c3b5SJed Brown   DMRefineHookLink link;
187547c6ae99SBarry Smith 
187647c6ae99SBarry Smith   PetscFunctionBegin;
1877732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18781ac00216SMatthew G. Knepley   ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr);
1879fef3a512SBarry Smith   if (!dm->ops->refine) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM cannot refine");
188047c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
18814057135bSMatthew G Knepley   if (*dmf) {
188243842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
18838865f1eaSKarl Rupp 
18848cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
18858865f1eaSKarl Rupp 
1886644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
18870598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1888656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
18898865f1eaSKarl Rupp 
1890e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1891c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
18928865f1eaSKarl Rupp       if (link->refinehook) {
18938865f1eaSKarl Rupp         ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);
18948865f1eaSKarl Rupp       }
1895c833c3b5SJed Brown     }
1896c833c3b5SJed Brown   }
18971ac00216SMatthew G. Knepley   ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr);
1898c833c3b5SJed Brown   PetscFunctionReturn(0);
1899c833c3b5SJed Brown }
1900c833c3b5SJed Brown 
1901bb9467b5SJed Brown /*@C
1902c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1903c833c3b5SJed Brown 
1904c833c3b5SJed Brown    Logically Collective
1905c833c3b5SJed Brown 
1906c833c3b5SJed Brown    Input Arguments:
1907c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1908c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1909c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
19100298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1911c833c3b5SJed Brown 
1912c833c3b5SJed Brown    Calling sequence of refinehook:
1913c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1914c833c3b5SJed Brown 
1915c833c3b5SJed Brown +  coarse - coarse level DM
1916c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1917c833c3b5SJed Brown -  ctx - optional user-defined function context
1918c833c3b5SJed Brown 
1919c833c3b5SJed Brown    Calling sequence for interphook:
1920c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1921c833c3b5SJed Brown 
1922c833c3b5SJed Brown +  coarse - coarse level DM
1923c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1924c833c3b5SJed Brown .  fine - fine level DM to update
1925c833c3b5SJed Brown -  ctx - optional user-defined function context
1926c833c3b5SJed Brown 
1927c833c3b5SJed Brown    Level: advanced
1928c833c3b5SJed Brown 
1929c833c3b5SJed Brown    Notes:
1930c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1931c833c3b5SJed Brown 
1932c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1933c833c3b5SJed Brown 
1934bb9467b5SJed Brown    This function is currently not available from Fortran.
1935bb9467b5SJed Brown 
1936c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1937c833c3b5SJed Brown @*/
1938c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1939c833c3b5SJed Brown {
1940c833c3b5SJed Brown   PetscErrorCode   ierr;
1941c833c3b5SJed Brown   DMRefineHookLink link,*p;
1942c833c3b5SJed Brown 
1943c833c3b5SJed Brown   PetscFunctionBegin;
1944c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
19453d8e3701SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
19463d8e3701SJed Brown     if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0);
19473d8e3701SJed Brown   }
194895dccacaSBarry Smith   ierr             = PetscNew(&link);CHKERRQ(ierr);
1949c833c3b5SJed Brown   link->refinehook = refinehook;
1950c833c3b5SJed Brown   link->interphook = interphook;
1951c833c3b5SJed Brown   link->ctx        = ctx;
19520298fd71SBarry Smith   link->next       = NULL;
1953c833c3b5SJed Brown   *p               = link;
1954c833c3b5SJed Brown   PetscFunctionReturn(0);
1955c833c3b5SJed Brown }
1956c833c3b5SJed Brown 
19573d8e3701SJed Brown /*@C
19583d8e3701SJed Brown    DMRefineHookRemove - remove a callback from the list of hooks to be run when interpolating a nonlinear problem to a finer grid
19593d8e3701SJed Brown 
19603d8e3701SJed Brown    Logically Collective
19613d8e3701SJed Brown 
19623d8e3701SJed Brown    Input Arguments:
19633d8e3701SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
19643d8e3701SJed Brown .  refinehook - function to run when setting up a coarser level
19653d8e3701SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
19663d8e3701SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
19673d8e3701SJed Brown 
19683d8e3701SJed Brown    Level: advanced
19693d8e3701SJed Brown 
19703d8e3701SJed Brown    Notes:
19713d8e3701SJed Brown    This function does nothing if the hook is not in the list.
19723d8e3701SJed Brown 
19733d8e3701SJed Brown    This function is currently not available from Fortran.
19743d8e3701SJed Brown 
19753d8e3701SJed Brown .seealso: DMCoarsenHookRemove(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
19763d8e3701SJed Brown @*/
19773d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
19783d8e3701SJed Brown {
19793d8e3701SJed Brown   PetscErrorCode   ierr;
19803d8e3701SJed Brown   DMRefineHookLink link,*p;
19813d8e3701SJed Brown 
19823d8e3701SJed Brown   PetscFunctionBegin;
19833d8e3701SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
19843d8e3701SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */
19853d8e3701SJed Brown     if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) {
19863d8e3701SJed Brown       link = *p;
19873d8e3701SJed Brown       *p = link->next;
19883d8e3701SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
19893d8e3701SJed Brown       break;
19903d8e3701SJed Brown     }
19913d8e3701SJed Brown   }
19923d8e3701SJed Brown   PetscFunctionReturn(0);
19933d8e3701SJed Brown }
19943d8e3701SJed Brown 
1995c833c3b5SJed Brown /*@
1996c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1997c833c3b5SJed Brown 
1998c833c3b5SJed Brown    Collective if any hooks are
1999c833c3b5SJed Brown 
2000c833c3b5SJed Brown    Input Arguments:
2001c833c3b5SJed Brown +  coarse - coarser DM to use as a base
2002e91eccc2SStefano Zampini .  interp - interpolation matrix, apply using MatInterpolate()
2003c833c3b5SJed Brown -  fine - finer DM to update
2004c833c3b5SJed Brown 
2005c833c3b5SJed Brown    Level: developer
2006c833c3b5SJed Brown 
2007c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
2008c833c3b5SJed Brown @*/
2009c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
2010c833c3b5SJed Brown {
2011c833c3b5SJed Brown   PetscErrorCode   ierr;
2012c833c3b5SJed Brown   DMRefineHookLink link;
2013c833c3b5SJed Brown 
2014c833c3b5SJed Brown   PetscFunctionBegin;
2015c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
20168865f1eaSKarl Rupp     if (link->interphook) {
20178865f1eaSKarl Rupp       ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);
20188865f1eaSKarl Rupp     }
20194057135bSMatthew G Knepley   }
202047c6ae99SBarry Smith   PetscFunctionReturn(0);
202147c6ae99SBarry Smith }
202247c6ae99SBarry Smith 
2023eb3f98d2SBarry Smith /*@
2024eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
2025eb3f98d2SBarry Smith 
2026eb3f98d2SBarry Smith     Not Collective
2027eb3f98d2SBarry Smith 
2028eb3f98d2SBarry Smith     Input Parameter:
2029eb3f98d2SBarry Smith .   dm - the DM object
2030eb3f98d2SBarry Smith 
2031eb3f98d2SBarry Smith     Output Parameter:
2032eb3f98d2SBarry Smith .   level - number of refinements
2033eb3f98d2SBarry Smith 
2034eb3f98d2SBarry Smith     Level: developer
2035eb3f98d2SBarry Smith 
20366a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
2037eb3f98d2SBarry Smith 
2038eb3f98d2SBarry Smith @*/
2039eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
2040eb3f98d2SBarry Smith {
2041eb3f98d2SBarry Smith   PetscFunctionBegin;
2042eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2043eb3f98d2SBarry Smith   *level = dm->levelup;
2044eb3f98d2SBarry Smith   PetscFunctionReturn(0);
2045eb3f98d2SBarry Smith }
2046eb3f98d2SBarry Smith 
2047fef3a512SBarry Smith /*@
2048fef3a512SBarry Smith     DMSetRefineLevel - Set's the number of refinements that have generated this DM.
2049fef3a512SBarry Smith 
2050fef3a512SBarry Smith     Not Collective
2051fef3a512SBarry Smith 
2052fef3a512SBarry Smith     Input Parameter:
2053fef3a512SBarry Smith +   dm - the DM object
2054fef3a512SBarry Smith -   level - number of refinements
2055fef3a512SBarry Smith 
2056fef3a512SBarry Smith     Level: advanced
2057fef3a512SBarry Smith 
205895452b02SPatrick Sanan     Notes:
205995452b02SPatrick Sanan     This value is used by PCMG to determine how many multigrid levels to use
2060fef3a512SBarry Smith 
2061fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
2062fef3a512SBarry Smith 
2063fef3a512SBarry Smith @*/
2064fef3a512SBarry Smith PetscErrorCode  DMSetRefineLevel(DM dm,PetscInt level)
2065fef3a512SBarry Smith {
2066fef3a512SBarry Smith   PetscFunctionBegin;
2067fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2068fef3a512SBarry Smith   dm->levelup = level;
2069fef3a512SBarry Smith   PetscFunctionReturn(0);
2070fef3a512SBarry Smith }
2071fef3a512SBarry Smith 
2072bb9467b5SJed Brown /*@C
2073baf369e7SPeter Brune    DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called
2074baf369e7SPeter Brune 
2075baf369e7SPeter Brune    Logically Collective
2076baf369e7SPeter Brune 
2077baf369e7SPeter Brune    Input Arguments:
2078baf369e7SPeter Brune +  dm - the DM
2079baf369e7SPeter Brune .  beginhook - function to run at the beginning of DMGlobalToLocalBegin()
2080baf369e7SPeter Brune .  endhook - function to run after DMGlobalToLocalEnd() has completed
20810298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2082baf369e7SPeter Brune 
2083baf369e7SPeter Brune    Calling sequence for beginhook:
2084baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
2085baf369e7SPeter Brune 
2086baf369e7SPeter Brune +  dm - global DM
2087baf369e7SPeter Brune .  g - global vector
2088baf369e7SPeter Brune .  mode - mode
2089baf369e7SPeter Brune .  l - local vector
2090baf369e7SPeter Brune -  ctx - optional user-defined function context
2091baf369e7SPeter Brune 
2092baf369e7SPeter Brune 
2093baf369e7SPeter Brune    Calling sequence for endhook:
2094ec4806b8SPeter Brune $    endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
2095baf369e7SPeter Brune 
2096baf369e7SPeter Brune +  global - global DM
2097baf369e7SPeter Brune -  ctx - optional user-defined function context
2098baf369e7SPeter Brune 
2099baf369e7SPeter Brune    Level: advanced
2100baf369e7SPeter Brune 
2101baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2102baf369e7SPeter Brune @*/
2103baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
2104baf369e7SPeter Brune {
2105baf369e7SPeter Brune   PetscErrorCode          ierr;
2106baf369e7SPeter Brune   DMGlobalToLocalHookLink link,*p;
2107baf369e7SPeter Brune 
2108baf369e7SPeter Brune   PetscFunctionBegin;
2109baf369e7SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2110baf369e7SPeter Brune   for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
211195dccacaSBarry Smith   ierr            = PetscNew(&link);CHKERRQ(ierr);
2112baf369e7SPeter Brune   link->beginhook = beginhook;
2113baf369e7SPeter Brune   link->endhook   = endhook;
2114baf369e7SPeter Brune   link->ctx       = ctx;
21150298fd71SBarry Smith   link->next      = NULL;
2116baf369e7SPeter Brune   *p              = link;
2117baf369e7SPeter Brune   PetscFunctionReturn(0);
2118baf369e7SPeter Brune }
2119baf369e7SPeter Brune 
21204c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx)
21214c274da1SToby Isaac {
21224c274da1SToby Isaac   Mat cMat;
21234c274da1SToby Isaac   Vec cVec;
21244c274da1SToby Isaac   PetscSection section, cSec;
21254c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
21264c274da1SToby Isaac   PetscErrorCode ierr;
21274c274da1SToby Isaac 
21284c274da1SToby Isaac   PetscFunctionBegin;
21294c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
21304c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
21314c274da1SToby Isaac   if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) {
21325db9a05bSToby Isaac     PetscInt nRows;
21335db9a05bSToby Isaac 
21345db9a05bSToby Isaac     ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr);
21355db9a05bSToby Isaac     if (nRows <= 0) PetscFunctionReturn(0);
2136e87a4003SBarry Smith     ierr = DMGetSection(dm,&section);CHKERRQ(ierr);
21377711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
21384c274da1SToby Isaac     ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr);
21394c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
21404c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
21414c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
21424c274da1SToby Isaac       if (dof) {
21434c274da1SToby Isaac         PetscScalar *vals;
21444c274da1SToby Isaac         ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr);
21454c274da1SToby Isaac         ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr);
21464c274da1SToby Isaac       }
21474c274da1SToby Isaac     }
21484c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
21494c274da1SToby Isaac   }
21504c274da1SToby Isaac   PetscFunctionReturn(0);
21514c274da1SToby Isaac }
21524c274da1SToby Isaac 
215347c6ae99SBarry Smith /*@
215401729b5cSPatrick Sanan     DMGlobalToLocal - update local vectors from global vector
215501729b5cSPatrick Sanan 
215601729b5cSPatrick Sanan     Neighbor-wise Collective on DM
215701729b5cSPatrick Sanan 
215801729b5cSPatrick Sanan     Input Parameters:
215901729b5cSPatrick Sanan +   dm - the DM object
216001729b5cSPatrick Sanan .   g - the global vector
216101729b5cSPatrick Sanan .   mode - INSERT_VALUES or ADD_VALUES
216201729b5cSPatrick Sanan -   l - the local vector
216301729b5cSPatrick Sanan 
216401729b5cSPatrick Sanan     Notes:
216501729b5cSPatrick Sanan     The communication involved in this update can be overlapped with computation by using
216601729b5cSPatrick Sanan     DMGlobalToLocalBegin() and DMGlobalToLocalEnd().
216701729b5cSPatrick Sanan 
216801729b5cSPatrick Sanan     Level: beginner
216901729b5cSPatrick Sanan 
217001729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
217101729b5cSPatrick Sanan 
217201729b5cSPatrick Sanan @*/
217301729b5cSPatrick Sanan PetscErrorCode DMGlobalToLocal(DM dm,Vec g,InsertMode mode,Vec l)
217401729b5cSPatrick Sanan {
217501729b5cSPatrick Sanan   PetscErrorCode ierr;
217601729b5cSPatrick Sanan 
217701729b5cSPatrick Sanan   PetscFunctionBegin;
217801729b5cSPatrick Sanan   ierr = DMGlobalToLocalBegin(dm,g,mode,l);CHKERRQ(ierr);
217901729b5cSPatrick Sanan   ierr = DMGlobalToLocalEnd(dm,g,mode,l);CHKERRQ(ierr);
218001729b5cSPatrick Sanan   PetscFunctionReturn(0);
218101729b5cSPatrick Sanan }
218201729b5cSPatrick Sanan 
218301729b5cSPatrick Sanan /*@
218447c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
218547c6ae99SBarry Smith 
218647c6ae99SBarry Smith     Neighbor-wise Collective on DM
218747c6ae99SBarry Smith 
218847c6ae99SBarry Smith     Input Parameters:
218947c6ae99SBarry Smith +   dm - the DM object
219047c6ae99SBarry Smith .   g - the global vector
219147c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
219247c6ae99SBarry Smith -   l - the local vector
219347c6ae99SBarry Smith 
219401729b5cSPatrick Sanan     Level: intermediate
219547c6ae99SBarry Smith 
219601729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
219747c6ae99SBarry Smith 
219847c6ae99SBarry Smith @*/
21997087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
220047c6ae99SBarry Smith {
22017128ae9fSMatthew G Knepley   PetscSF                 sf;
220247c6ae99SBarry Smith   PetscErrorCode          ierr;
2203baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
220447c6ae99SBarry Smith 
220547c6ae99SBarry Smith   PetscFunctionBegin;
2206171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2207baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
22088865f1eaSKarl Rupp     if (link->beginhook) {
22098865f1eaSKarl Rupp       ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);
22108865f1eaSKarl Rupp     }
2211baf369e7SPeter Brune   }
22127128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
22137128ae9fSMatthew G Knepley   if (sf) {
2214ae5cfb4aSMatthew G. Knepley     const PetscScalar *gArray;
2215ae5cfb4aSMatthew G. Knepley     PetscScalar       *lArray;
22167128ae9fSMatthew G Knepley 
221782f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
22187128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
2219ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
22207128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
22217128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
2222ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
22237128ae9fSMatthew G Knepley   } else {
222433907cc2SStefano Zampini     if (!dm->ops->globaltolocalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalBegin() for type %s",((PetscObject)dm)->type_name);
2225843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
22267128ae9fSMatthew G Knepley   }
222747c6ae99SBarry Smith   PetscFunctionReturn(0);
222847c6ae99SBarry Smith }
222947c6ae99SBarry Smith 
223047c6ae99SBarry Smith /*@
223147c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
223247c6ae99SBarry Smith 
223347c6ae99SBarry Smith     Neighbor-wise Collective on DM
223447c6ae99SBarry Smith 
223547c6ae99SBarry Smith     Input Parameters:
223647c6ae99SBarry Smith +   dm - the DM object
223747c6ae99SBarry Smith .   g - the global vector
223847c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
223947c6ae99SBarry Smith -   l - the local vector
224047c6ae99SBarry Smith 
224101729b5cSPatrick Sanan     Level: intermediate
224247c6ae99SBarry Smith 
224301729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
224447c6ae99SBarry Smith 
224547c6ae99SBarry Smith @*/
22467087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
224747c6ae99SBarry Smith {
22487128ae9fSMatthew G Knepley   PetscSF                 sf;
224947c6ae99SBarry Smith   PetscErrorCode          ierr;
2250ae5cfb4aSMatthew G. Knepley   const PetscScalar      *gArray;
2251ae5cfb4aSMatthew G. Knepley   PetscScalar            *lArray;
2252baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
225347c6ae99SBarry Smith 
225447c6ae99SBarry Smith   PetscFunctionBegin;
2255171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
22567128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
22577128ae9fSMatthew G Knepley   if (sf) {
225882f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
22597128ae9fSMatthew G Knepley 
22607128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
2261ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
22627128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
22637128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
2264ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
22657128ae9fSMatthew G Knepley   } else {
226633907cc2SStefano Zampini     if (!dm->ops->globaltolocalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalEnd() for type %s",((PetscObject)dm)->type_name);
2267843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
22687128ae9fSMatthew G Knepley   }
22694c274da1SToby Isaac   ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr);
2270baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
2271baf369e7SPeter Brune     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
2272baf369e7SPeter Brune   }
227347c6ae99SBarry Smith   PetscFunctionReturn(0);
227447c6ae99SBarry Smith }
227547c6ae99SBarry Smith 
2276d4d07f1eSToby Isaac /*@C
2277d4d07f1eSToby Isaac    DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called
2278d4d07f1eSToby Isaac 
2279d4d07f1eSToby Isaac    Logically Collective
2280d4d07f1eSToby Isaac 
2281d4d07f1eSToby Isaac    Input Arguments:
2282d4d07f1eSToby Isaac +  dm - the DM
2283d4d07f1eSToby Isaac .  beginhook - function to run at the beginning of DMLocalToGlobalBegin()
2284d4d07f1eSToby Isaac .  endhook - function to run after DMLocalToGlobalEnd() has completed
2285d4d07f1eSToby Isaac -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2286d4d07f1eSToby Isaac 
2287d4d07f1eSToby Isaac    Calling sequence for beginhook:
2288d4d07f1eSToby Isaac $    beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
2289d4d07f1eSToby Isaac 
2290d4d07f1eSToby Isaac +  dm - global DM
2291d4d07f1eSToby Isaac .  l - local vector
2292d4d07f1eSToby Isaac .  mode - mode
2293d4d07f1eSToby Isaac .  g - global vector
2294d4d07f1eSToby Isaac -  ctx - optional user-defined function context
2295d4d07f1eSToby Isaac 
2296d4d07f1eSToby Isaac 
2297d4d07f1eSToby Isaac    Calling sequence for endhook:
2298d4d07f1eSToby Isaac $    endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
2299d4d07f1eSToby Isaac 
2300d4d07f1eSToby Isaac +  global - global DM
2301d4d07f1eSToby Isaac .  l - local vector
2302d4d07f1eSToby Isaac .  mode - mode
2303d4d07f1eSToby Isaac .  g - global vector
2304d4d07f1eSToby Isaac -  ctx - optional user-defined function context
2305d4d07f1eSToby Isaac 
2306d4d07f1eSToby Isaac    Level: advanced
2307d4d07f1eSToby Isaac 
2308d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2309d4d07f1eSToby Isaac @*/
2310d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
2311d4d07f1eSToby Isaac {
2312d4d07f1eSToby Isaac   PetscErrorCode          ierr;
2313d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link,*p;
2314d4d07f1eSToby Isaac 
2315d4d07f1eSToby Isaac   PetscFunctionBegin;
2316d4d07f1eSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2317d4d07f1eSToby Isaac   for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
231895dccacaSBarry Smith   ierr            = PetscNew(&link);CHKERRQ(ierr);
2319d4d07f1eSToby Isaac   link->beginhook = beginhook;
2320d4d07f1eSToby Isaac   link->endhook   = endhook;
2321d4d07f1eSToby Isaac   link->ctx       = ctx;
2322d4d07f1eSToby Isaac   link->next      = NULL;
2323d4d07f1eSToby Isaac   *p              = link;
2324d4d07f1eSToby Isaac   PetscFunctionReturn(0);
2325d4d07f1eSToby Isaac }
2326d4d07f1eSToby Isaac 
23274c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx)
23284c274da1SToby Isaac {
23294c274da1SToby Isaac   Mat cMat;
23304c274da1SToby Isaac   Vec cVec;
23314c274da1SToby Isaac   PetscSection section, cSec;
23324c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
23334c274da1SToby Isaac   PetscErrorCode ierr;
23344c274da1SToby Isaac 
23354c274da1SToby Isaac   PetscFunctionBegin;
23364c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
23374c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
23384c274da1SToby Isaac   if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) {
23395db9a05bSToby Isaac     PetscInt nRows;
23405db9a05bSToby Isaac 
23415db9a05bSToby Isaac     ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr);
23425db9a05bSToby Isaac     if (nRows <= 0) PetscFunctionReturn(0);
2343e87a4003SBarry Smith     ierr = DMGetSection(dm,&section);CHKERRQ(ierr);
23447711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
23454c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
23464c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
23474c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
23484c274da1SToby Isaac       if (dof) {
23494c274da1SToby Isaac         PetscInt d;
23504c274da1SToby Isaac         PetscScalar *vals;
23514c274da1SToby Isaac         ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr);
23524c274da1SToby Isaac         ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr);
23534c274da1SToby Isaac         /* for this to be the true transpose, we have to zero the values that
23544c274da1SToby Isaac          * we just extracted */
23554c274da1SToby Isaac         for (d = 0; d < dof; d++) {
23564c274da1SToby Isaac           vals[d] = 0.;
23574c274da1SToby Isaac         }
23584c274da1SToby Isaac       }
23594c274da1SToby Isaac     }
23604c274da1SToby Isaac     ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr);
23614c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
23624c274da1SToby Isaac   }
23634c274da1SToby Isaac   PetscFunctionReturn(0);
23644c274da1SToby Isaac }
236501729b5cSPatrick Sanan /*@
236601729b5cSPatrick Sanan     DMLocalToGlobal - updates global vectors from local vectors
236701729b5cSPatrick Sanan 
236801729b5cSPatrick Sanan     Neighbor-wise Collective on DM
236901729b5cSPatrick Sanan 
237001729b5cSPatrick Sanan     Input Parameters:
237101729b5cSPatrick Sanan +   dm - the DM object
237201729b5cSPatrick Sanan .   l - the local vector
237301729b5cSPatrick Sanan .   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.
237401729b5cSPatrick Sanan -   g - the global vector
237501729b5cSPatrick Sanan 
237601729b5cSPatrick Sanan     Notes:
237701729b5cSPatrick Sanan     The communication involved in this update can be overlapped with computation by using
237801729b5cSPatrick Sanan     DMLocalToGlobalBegin() and DMLocalToGlobalEnd().
237901729b5cSPatrick Sanan 
238001729b5cSPatrick Sanan     In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation.
238101729b5cSPatrick Sanan            INSERT_VALUES is not supported for DMDA; in that case simply compute the values directly into a global vector instead of a local one.
238201729b5cSPatrick Sanan 
238301729b5cSPatrick Sanan     Level: beginner
238401729b5cSPatrick Sanan 
238501729b5cSPatrick Sanan .seealso DMLocalToGlobalBegin(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
238601729b5cSPatrick Sanan 
238701729b5cSPatrick Sanan @*/
238801729b5cSPatrick Sanan PetscErrorCode DMLocalToGlobal(DM dm,Vec l,InsertMode mode,Vec g)
238901729b5cSPatrick Sanan {
239001729b5cSPatrick Sanan   PetscErrorCode ierr;
239101729b5cSPatrick Sanan 
239201729b5cSPatrick Sanan   PetscFunctionBegin;
239301729b5cSPatrick Sanan   ierr = DMLocalToGlobalBegin(dm,l,mode,g);CHKERRQ(ierr);
239401729b5cSPatrick Sanan   ierr = DMLocalToGlobalEnd(dm,l,mode,g);CHKERRQ(ierr);
239501729b5cSPatrick Sanan   PetscFunctionReturn(0);
239601729b5cSPatrick Sanan }
23974c274da1SToby Isaac 
239847c6ae99SBarry Smith /*@
239901729b5cSPatrick Sanan     DMLocalToGlobalBegin - begins updating global vectors from local vectors
24009a42bb27SBarry Smith 
24019a42bb27SBarry Smith     Neighbor-wise Collective on DM
24029a42bb27SBarry Smith 
24039a42bb27SBarry Smith     Input Parameters:
24049a42bb27SBarry Smith +   dm - the DM object
2405f6813fd5SJed Brown .   l - the local vector
24061eb28f2eSBarry 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.
24071eb28f2eSBarry Smith -   g - the global vector
24089a42bb27SBarry Smith 
240995452b02SPatrick Sanan     Notes:
241095452b02SPatrick Sanan     In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation.
241184330215SMatthew G. Knepley            INSERT_VALUES is not supported for DMDA, in that case simply compute the values directly into a global vector instead of a local one.
24129a42bb27SBarry Smith 
241301729b5cSPatrick Sanan     Level: intermediate
24149a42bb27SBarry Smith 
241501729b5cSPatrick Sanan .seealso DMLocalToGlobal(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
24169a42bb27SBarry Smith 
24179a42bb27SBarry Smith @*/
24187087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
24199a42bb27SBarry Smith {
24207128ae9fSMatthew G Knepley   PetscSF                 sf;
242184330215SMatthew G. Knepley   PetscSection            s, gs;
2422d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
2423ae5cfb4aSMatthew G. Knepley   const PetscScalar      *lArray;
2424ae5cfb4aSMatthew G. Knepley   PetscScalar            *gArray;
242584330215SMatthew G. Knepley   PetscBool               isInsert;
242684330215SMatthew G. Knepley   PetscErrorCode          ierr;
24279a42bb27SBarry Smith 
24289a42bb27SBarry Smith   PetscFunctionBegin;
2429171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2430d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
2431d4d07f1eSToby Isaac     if (link->beginhook) {
2432d4d07f1eSToby Isaac       ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr);
2433d4d07f1eSToby Isaac     }
2434d4d07f1eSToby Isaac   }
24354c274da1SToby Isaac   ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr);
24367128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
2437e87a4003SBarry Smith   ierr = DMGetSection(dm, &s);CHKERRQ(ierr);
24387128ae9fSMatthew G Knepley   switch (mode) {
24397128ae9fSMatthew G Knepley   case INSERT_VALUES:
24407128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
2441304ab55fSMatthew G. Knepley   case INSERT_BC_VALUES:
244284330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
24437128ae9fSMatthew G Knepley   case ADD_VALUES:
24447128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
2445304ab55fSMatthew G. Knepley   case ADD_BC_VALUES:
244684330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
24477128ae9fSMatthew G Knepley   default:
244882f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
24497128ae9fSMatthew G Knepley   }
245084330215SMatthew G. Knepley   if (sf && !isInsert) {
2451ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
24527128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
2453a9b180a6SBarry Smith     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
2454ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
245584330215SMatthew G. Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
245684330215SMatthew G. Knepley   } else if (s && isInsert) {
245784330215SMatthew G. Knepley     PetscInt gStart, pStart, pEnd, p;
245884330215SMatthew G. Knepley 
2459e87a4003SBarry Smith     ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr);
246084330215SMatthew G. Knepley     ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
246184330215SMatthew G. Knepley     ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr);
2462ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
246384330215SMatthew G. Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
246484330215SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
2465b3b16f48SMatthew G. Knepley       PetscInt dof, gdof, cdof, gcdof, off, goff, d, e;
246684330215SMatthew G. Knepley 
246784330215SMatthew G. Knepley       ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr);
246803442857SMatthew G. Knepley       ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr);
246984330215SMatthew G. Knepley       ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr);
2470b3b16f48SMatthew G. Knepley       ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr);
247184330215SMatthew G. Knepley       ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr);
247284330215SMatthew G. Knepley       ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr);
2473b3b16f48SMatthew G. Knepley       /* Ignore off-process data and points with no global data */
247403442857SMatthew G. Knepley       if (!gdof || goff < 0) continue;
2475b3b16f48SMatthew G. Knepley       if (dof != gdof) SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %d dof: %d gdof: %d cdof: %d gcdof: %d", p, dof, gdof, cdof, gcdof);
2476b3b16f48SMatthew G. Knepley       /* If no constraints are enforced in the global vector */
2477b3b16f48SMatthew G. Knepley       if (!gcdof) {
247884330215SMatthew G. Knepley         for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d];
2479b3b16f48SMatthew G. Knepley       /* If constraints are enforced in the global vector */
2480b3b16f48SMatthew G. Knepley       } else if (cdof == gcdof) {
248184330215SMatthew G. Knepley         const PetscInt *cdofs;
248284330215SMatthew G. Knepley         PetscInt        cind = 0;
248384330215SMatthew G. Knepley 
248484330215SMatthew G. Knepley         ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr);
2485b3b16f48SMatthew G. Knepley         for (d = 0, e = 0; d < dof; ++d) {
248684330215SMatthew G. Knepley           if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;}
2487b3b16f48SMatthew G. Knepley           gArray[goff-gStart+e++] = lArray[off+d];
248884330215SMatthew G. Knepley         }
2489b3b16f48SMatthew G. Knepley       } else SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes, p: %d dof: %d gdof: %d cdof: %d gcdof: %d", p, dof, gdof, cdof, gcdof);
249084330215SMatthew G. Knepley     }
2491ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
24927128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
24937128ae9fSMatthew G Knepley   } else {
2494843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
24957128ae9fSMatthew G Knepley   }
24969a42bb27SBarry Smith   PetscFunctionReturn(0);
24979a42bb27SBarry Smith }
24989a42bb27SBarry Smith 
24999a42bb27SBarry Smith /*@
25009a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
250147c6ae99SBarry Smith 
250247c6ae99SBarry Smith     Neighbor-wise Collective on DM
250347c6ae99SBarry Smith 
250447c6ae99SBarry Smith     Input Parameters:
250547c6ae99SBarry Smith +   dm - the DM object
2506f6813fd5SJed Brown .   l - the local vector
250747c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
2508f6813fd5SJed Brown -   g - the global vector
250947c6ae99SBarry Smith 
251001729b5cSPatrick Sanan     Level: intermediate
251147c6ae99SBarry Smith 
2512e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
251347c6ae99SBarry Smith 
251447c6ae99SBarry Smith @*/
25157087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
251647c6ae99SBarry Smith {
25177128ae9fSMatthew G Knepley   PetscSF                 sf;
251884330215SMatthew G. Knepley   PetscSection            s;
2519d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
252084330215SMatthew G. Knepley   PetscBool               isInsert;
252184330215SMatthew G. Knepley   PetscErrorCode          ierr;
252247c6ae99SBarry Smith 
252347c6ae99SBarry Smith   PetscFunctionBegin;
2524171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
25257128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
2526e87a4003SBarry Smith   ierr = DMGetSection(dm, &s);CHKERRQ(ierr);
25277128ae9fSMatthew G Knepley   switch (mode) {
25287128ae9fSMatthew G Knepley   case INSERT_VALUES:
25297128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
253084330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
25317128ae9fSMatthew G Knepley   case ADD_VALUES:
25327128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
253384330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
25347128ae9fSMatthew G Knepley   default:
253582f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
25367128ae9fSMatthew G Knepley   }
253784330215SMatthew G. Knepley   if (sf && !isInsert) {
2538ae5cfb4aSMatthew G. Knepley     const PetscScalar *lArray;
2539ae5cfb4aSMatthew G. Knepley     PetscScalar       *gArray;
254084330215SMatthew G. Knepley 
2541ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
25427128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
2543a9b180a6SBarry Smith     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
2544ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
25457128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
254684330215SMatthew G. Knepley   } else if (s && isInsert) {
25477128ae9fSMatthew G Knepley   } else {
2548843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
25497128ae9fSMatthew G Knepley   }
2550d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
2551d4d07f1eSToby Isaac     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
2552d4d07f1eSToby Isaac   }
255347c6ae99SBarry Smith   PetscFunctionReturn(0);
255447c6ae99SBarry Smith }
255547c6ae99SBarry Smith 
2556f089877aSRichard Tran Mills /*@
2557bc0a1609SRichard Tran Mills    DMLocalToLocalBegin - Maps from a local vector (including ghost points
2558bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2559d78e899eSRichard Tran Mills    points in the second are set correctly. Must be followed by DMLocalToLocalEnd().
2560f089877aSRichard Tran Mills 
2561bc0a1609SRichard Tran Mills    Neighbor-wise Collective on DM and Vec
2562f089877aSRichard Tran Mills 
2563f089877aSRichard Tran Mills    Input Parameters:
2564f089877aSRichard Tran Mills +  dm - the DM object
2565bc0a1609SRichard Tran Mills .  g - the original local vector
2566bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2567f089877aSRichard Tran Mills 
2568bc0a1609SRichard Tran Mills    Output Parameter:
2569bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2570f089877aSRichard Tran Mills 
2571f089877aSRichard Tran Mills    Level: intermediate
2572f089877aSRichard Tran Mills 
2573bc0a1609SRichard Tran Mills    Notes:
2574bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2575bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2576bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2577bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2578bc0a1609SRichard Tran Mills 
2579bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, begin
2580bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2581f089877aSRichard Tran Mills 
2582f089877aSRichard Tran Mills @*/
2583f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
2584f089877aSRichard Tran Mills {
2585f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2586f089877aSRichard Tran Mills 
2587f089877aSRichard Tran Mills   PetscFunctionBegin;
2588f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2589bb358533SPatrick Sanan   if (!dm->ops->localtolocalbegin) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps");
2590f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2591f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2592f089877aSRichard Tran Mills }
2593f089877aSRichard Tran Mills 
2594f089877aSRichard Tran Mills /*@
2595bc0a1609SRichard Tran Mills    DMLocalToLocalEnd - Maps from a local vector (including ghost points
2596bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2597d78e899eSRichard Tran Mills    points in the second are set correctly. Must be preceded by DMLocalToLocalBegin().
2598f089877aSRichard Tran Mills 
2599bc0a1609SRichard Tran Mills    Neighbor-wise Collective on DM and Vec
2600f089877aSRichard Tran Mills 
2601f089877aSRichard Tran Mills    Input Parameters:
2602bc0a1609SRichard Tran Mills +  da - the DM object
2603bc0a1609SRichard Tran Mills .  g - the original local vector
2604bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2605f089877aSRichard Tran Mills 
2606bc0a1609SRichard Tran Mills    Output Parameter:
2607bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2608f089877aSRichard Tran Mills 
2609f089877aSRichard Tran Mills    Level: intermediate
2610f089877aSRichard Tran Mills 
2611bc0a1609SRichard Tran Mills    Notes:
2612bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2613bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2614bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2615bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2616bc0a1609SRichard Tran Mills 
2617bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, end
2618bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2619f089877aSRichard Tran Mills 
2620f089877aSRichard Tran Mills @*/
2621f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
2622f089877aSRichard Tran Mills {
2623f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2624f089877aSRichard Tran Mills 
2625f089877aSRichard Tran Mills   PetscFunctionBegin;
2626f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2627bb358533SPatrick Sanan   if (!dm->ops->localtolocalend) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps");
2628f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2629f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2630f089877aSRichard Tran Mills }
2631f089877aSRichard Tran Mills 
2632f089877aSRichard Tran Mills 
263347c6ae99SBarry Smith /*@
263447c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
263547c6ae99SBarry Smith 
263647c6ae99SBarry Smith     Collective on DM
263747c6ae99SBarry Smith 
263847c6ae99SBarry Smith     Input Parameter:
263947c6ae99SBarry Smith +   dm - the DM object
264091d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
264147c6ae99SBarry Smith 
264247c6ae99SBarry Smith     Output Parameter:
264347c6ae99SBarry Smith .   dmc - the coarsened DM
264447c6ae99SBarry Smith 
264547c6ae99SBarry Smith     Level: developer
264647c6ae99SBarry Smith 
2647e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
264847c6ae99SBarry Smith 
264947c6ae99SBarry Smith @*/
26507087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
265147c6ae99SBarry Smith {
265247c6ae99SBarry Smith   PetscErrorCode    ierr;
2653b17ce1afSJed Brown   DMCoarsenHookLink link;
265447c6ae99SBarry Smith 
265547c6ae99SBarry Smith   PetscFunctionBegin;
2656171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2657fef3a512SBarry Smith   if (!dm->ops->coarsen) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM cannot coarsen");
265847a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
265947c6ae99SBarry Smith   ierr                      = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
26608892b4c3SMatthew G. Knepley   if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced");
2661a8fb8f29SToby Isaac   ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr);
266243842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
26638cd211a4SJed Brown   ierr                      = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
2664644e2e5bSBarry Smith   (*dmc)->ctx               = dm->ctx;
26650598a293SJed Brown   (*dmc)->levelup           = dm->levelup;
2666656b349aSBarry Smith   (*dmc)->leveldown         = dm->leveldown + 1;
2667e4b4b23bSJed Brown   ierr                      = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
2668b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
2669b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
2670b17ce1afSJed Brown   }
267147a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
2672b17ce1afSJed Brown   PetscFunctionReturn(0);
2673b17ce1afSJed Brown }
2674b17ce1afSJed Brown 
2675bb9467b5SJed Brown /*@C
2676b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
2677b17ce1afSJed Brown 
2678b17ce1afSJed Brown    Logically Collective
2679b17ce1afSJed Brown 
2680b17ce1afSJed Brown    Input Arguments:
2681b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
2682b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
2683b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
26840298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2685b17ce1afSJed Brown 
2686b17ce1afSJed Brown    Calling sequence of coarsenhook:
2687b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
2688b17ce1afSJed Brown 
2689b17ce1afSJed Brown +  fine - fine level DM
2690b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
2691b17ce1afSJed Brown -  ctx - optional user-defined function context
2692b17ce1afSJed Brown 
2693b17ce1afSJed Brown    Calling sequence for restricthook:
2694c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
2695b17ce1afSJed Brown 
2696b17ce1afSJed Brown +  fine - fine level DM
2697b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
2698c833c3b5SJed Brown .  rscale - scaling vector for restriction
2699c833c3b5SJed Brown .  inject - matrix restricting by injection
2700b17ce1afSJed Brown .  coarse - coarse level DM to update
2701b17ce1afSJed Brown -  ctx - optional user-defined function context
2702b17ce1afSJed Brown 
2703b17ce1afSJed Brown    Level: advanced
2704b17ce1afSJed Brown 
2705b17ce1afSJed Brown    Notes:
2706b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
2707b17ce1afSJed Brown 
2708b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
2709b17ce1afSJed Brown 
2710b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2711b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
2712b17ce1afSJed Brown 
2713bb9467b5SJed Brown    This function is currently not available from Fortran.
2714bb9467b5SJed Brown 
2715dc822a44SJed Brown .seealso: DMCoarsenHookRemove(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2716b17ce1afSJed Brown @*/
2717b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2718b17ce1afSJed Brown {
2719b17ce1afSJed Brown   PetscErrorCode    ierr;
2720b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
2721b17ce1afSJed Brown 
2722b17ce1afSJed Brown   PetscFunctionBegin;
2723b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
27241e3d8eccSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
27251e3d8eccSJed Brown     if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0);
27261e3d8eccSJed Brown   }
272795dccacaSBarry Smith   ierr               = PetscNew(&link);CHKERRQ(ierr);
2728b17ce1afSJed Brown   link->coarsenhook  = coarsenhook;
2729b17ce1afSJed Brown   link->restricthook = restricthook;
2730b17ce1afSJed Brown   link->ctx          = ctx;
27310298fd71SBarry Smith   link->next         = NULL;
2732b17ce1afSJed Brown   *p                 = link;
2733b17ce1afSJed Brown   PetscFunctionReturn(0);
2734b17ce1afSJed Brown }
2735b17ce1afSJed Brown 
2736dc822a44SJed Brown /*@C
2737dc822a44SJed Brown    DMCoarsenHookRemove - remove a callback from the list of hooks to be run when restricting a nonlinear problem to the coarse grid
2738dc822a44SJed Brown 
2739dc822a44SJed Brown    Logically Collective
2740dc822a44SJed Brown 
2741dc822a44SJed Brown    Input Arguments:
2742dc822a44SJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
2743dc822a44SJed Brown .  coarsenhook - function to run when setting up a coarser level
2744dc822a44SJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
2745dc822a44SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2746dc822a44SJed Brown 
2747dc822a44SJed Brown    Level: advanced
2748dc822a44SJed Brown 
2749dc822a44SJed Brown    Notes:
2750dc822a44SJed Brown    This function does nothing if the hook is not in the list.
2751dc822a44SJed Brown 
2752dc822a44SJed Brown    This function is currently not available from Fortran.
2753dc822a44SJed Brown 
2754dc822a44SJed Brown .seealso: DMCoarsenHookAdd(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2755dc822a44SJed Brown @*/
2756dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2757dc822a44SJed Brown {
2758dc822a44SJed Brown   PetscErrorCode    ierr;
2759dc822a44SJed Brown   DMCoarsenHookLink link,*p;
2760dc822a44SJed Brown 
2761dc822a44SJed Brown   PetscFunctionBegin;
2762dc822a44SJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
2763dc822a44SJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */
2764dc822a44SJed Brown     if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) {
2765dc822a44SJed Brown       link = *p;
2766dc822a44SJed Brown       *p = link->next;
2767dc822a44SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
2768dc822a44SJed Brown       break;
2769dc822a44SJed Brown     }
2770dc822a44SJed Brown   }
2771dc822a44SJed Brown   PetscFunctionReturn(0);
2772dc822a44SJed Brown }
2773dc822a44SJed Brown 
2774dc822a44SJed Brown 
2775b17ce1afSJed Brown /*@
2776b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
2777b17ce1afSJed Brown 
2778b17ce1afSJed Brown    Collective if any hooks are
2779b17ce1afSJed Brown 
2780b17ce1afSJed Brown    Input Arguments:
2781b17ce1afSJed Brown +  fine - finer DM to use as a base
2782b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
2783e91eccc2SStefano Zampini .  rscale - scaling vector for restriction
2784b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
2785e91eccc2SStefano Zampini -  coarse - coarser DM to update
2786b17ce1afSJed Brown 
2787b17ce1afSJed Brown    Level: developer
2788b17ce1afSJed Brown 
2789b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
2790b17ce1afSJed Brown @*/
2791b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
2792b17ce1afSJed Brown {
2793b17ce1afSJed Brown   PetscErrorCode    ierr;
2794b17ce1afSJed Brown   DMCoarsenHookLink link;
2795b17ce1afSJed Brown 
2796b17ce1afSJed Brown   PetscFunctionBegin;
2797b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
27988865f1eaSKarl Rupp     if (link->restricthook) {
27998865f1eaSKarl Rupp       ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);
28008865f1eaSKarl Rupp     }
2801b17ce1afSJed Brown   }
280247c6ae99SBarry Smith   PetscFunctionReturn(0);
280347c6ae99SBarry Smith }
280447c6ae99SBarry Smith 
2805bb9467b5SJed Brown /*@C
2806be081cd6SPeter Brune    DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid
28075dbd56e3SPeter Brune 
28085dbd56e3SPeter Brune    Logically Collective
28095dbd56e3SPeter Brune 
28105dbd56e3SPeter Brune    Input Arguments:
28115dbd56e3SPeter Brune +  global - global DM
2812ec4806b8SPeter Brune .  ddhook - function to run to pass data to the decomposition DM upon its creation
28135dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
28140298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
28155dbd56e3SPeter Brune 
2816ec4806b8SPeter Brune 
2817ec4806b8SPeter Brune    Calling sequence for ddhook:
2818ec4806b8SPeter Brune $    ddhook(DM global,DM block,void *ctx)
2819ec4806b8SPeter Brune 
2820ec4806b8SPeter Brune +  global - global DM
2821ec4806b8SPeter Brune .  block  - block DM
2822ec4806b8SPeter Brune -  ctx - optional user-defined function context
2823ec4806b8SPeter Brune 
28245dbd56e3SPeter Brune    Calling sequence for restricthook:
2825ec4806b8SPeter Brune $    restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx)
28265dbd56e3SPeter Brune 
28275dbd56e3SPeter Brune +  global - global DM
28285dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
28295dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
2830ec4806b8SPeter Brune .  block  - block DM
28315dbd56e3SPeter Brune -  ctx - optional user-defined function context
28325dbd56e3SPeter Brune 
28335dbd56e3SPeter Brune    Level: advanced
28345dbd56e3SPeter Brune 
28355dbd56e3SPeter Brune    Notes:
2836ec4806b8SPeter Brune    This function is only needed if auxiliary data needs to be set up on subdomain DMs.
28375dbd56e3SPeter Brune 
28385dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
28395dbd56e3SPeter Brune 
28405dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2841ec4806b8SPeter Brune    extract the global information from its context (instead of from the SNES).
28425dbd56e3SPeter Brune 
2843bb9467b5SJed Brown    This function is currently not available from Fortran.
2844bb9467b5SJed Brown 
28455dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
28465dbd56e3SPeter Brune @*/
2847be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
28485dbd56e3SPeter Brune {
28495dbd56e3SPeter Brune   PetscErrorCode      ierr;
2850be081cd6SPeter Brune   DMSubDomainHookLink link,*p;
28515dbd56e3SPeter Brune 
28525dbd56e3SPeter Brune   PetscFunctionBegin;
28535dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
2854b3a6b972SJed Brown   for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
2855b3a6b972SJed Brown     if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0);
2856b3a6b972SJed Brown   }
285795dccacaSBarry Smith   ierr               = PetscNew(&link);CHKERRQ(ierr);
28585dbd56e3SPeter Brune   link->restricthook = restricthook;
2859be081cd6SPeter Brune   link->ddhook       = ddhook;
28605dbd56e3SPeter Brune   link->ctx          = ctx;
28610298fd71SBarry Smith   link->next         = NULL;
28625dbd56e3SPeter Brune   *p                 = link;
28635dbd56e3SPeter Brune   PetscFunctionReturn(0);
28645dbd56e3SPeter Brune }
28655dbd56e3SPeter Brune 
2866b3a6b972SJed Brown /*@C
2867b3a6b972SJed Brown    DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid
2868b3a6b972SJed Brown 
2869b3a6b972SJed Brown    Logically Collective
2870b3a6b972SJed Brown 
2871b3a6b972SJed Brown    Input Arguments:
2872b3a6b972SJed Brown +  global - global DM
2873b3a6b972SJed Brown .  ddhook - function to run to pass data to the decomposition DM upon its creation
2874b3a6b972SJed Brown .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
2875b3a6b972SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2876b3a6b972SJed Brown 
2877b3a6b972SJed Brown    Level: advanced
2878b3a6b972SJed Brown 
2879b3a6b972SJed Brown    Notes:
2880b3a6b972SJed Brown 
2881b3a6b972SJed Brown    This function is currently not available from Fortran.
2882b3a6b972SJed Brown 
2883b3a6b972SJed Brown .seealso: DMSubDomainHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2884b3a6b972SJed Brown @*/
2885b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
2886b3a6b972SJed Brown {
2887b3a6b972SJed Brown   PetscErrorCode      ierr;
2888b3a6b972SJed Brown   DMSubDomainHookLink link,*p;
2889b3a6b972SJed Brown 
2890b3a6b972SJed Brown   PetscFunctionBegin;
2891b3a6b972SJed Brown   PetscValidHeaderSpecific(global,DM_CLASSID,1);
2892b3a6b972SJed Brown   for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */
2893b3a6b972SJed Brown     if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) {
2894b3a6b972SJed Brown       link = *p;
2895b3a6b972SJed Brown       *p = link->next;
2896b3a6b972SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
2897b3a6b972SJed Brown       break;
2898b3a6b972SJed Brown     }
2899b3a6b972SJed Brown   }
2900b3a6b972SJed Brown   PetscFunctionReturn(0);
2901b3a6b972SJed Brown }
2902b3a6b972SJed Brown 
29035dbd56e3SPeter Brune /*@
2904be081cd6SPeter Brune    DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd()
29055dbd56e3SPeter Brune 
29065dbd56e3SPeter Brune    Collective if any hooks are
29075dbd56e3SPeter Brune 
29085dbd56e3SPeter Brune    Input Arguments:
29095dbd56e3SPeter Brune +  fine - finer DM to use as a base
2910be081cd6SPeter Brune .  oscatter - scatter from domain global vector filling subdomain global vector with overlap
2911be081cd6SPeter Brune .  gscatter - scatter from domain global vector filling subdomain local vector with ghosts
29125dbd56e3SPeter Brune -  coarse - coarer DM to update
29135dbd56e3SPeter Brune 
29145dbd56e3SPeter Brune    Level: developer
29155dbd56e3SPeter Brune 
29165dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
29175dbd56e3SPeter Brune @*/
2918be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm)
29195dbd56e3SPeter Brune {
29205dbd56e3SPeter Brune   PetscErrorCode      ierr;
2921be081cd6SPeter Brune   DMSubDomainHookLink link;
29225dbd56e3SPeter Brune 
29235dbd56e3SPeter Brune   PetscFunctionBegin;
2924be081cd6SPeter Brune   for (link=global->subdomainhook; link; link=link->next) {
29258865f1eaSKarl Rupp     if (link->restricthook) {
29268865f1eaSKarl Rupp       ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr);
29278865f1eaSKarl Rupp     }
29285dbd56e3SPeter Brune   }
29295dbd56e3SPeter Brune   PetscFunctionReturn(0);
29305dbd56e3SPeter Brune }
29315dbd56e3SPeter Brune 
29325fe1f584SPeter Brune /*@
29336a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
29345fe1f584SPeter Brune 
29355fe1f584SPeter Brune     Not Collective
29365fe1f584SPeter Brune 
29375fe1f584SPeter Brune     Input Parameter:
29385fe1f584SPeter Brune .   dm - the DM object
29395fe1f584SPeter Brune 
29405fe1f584SPeter Brune     Output Parameter:
29416a7d9d85SPeter Brune .   level - number of coarsenings
29425fe1f584SPeter Brune 
29435fe1f584SPeter Brune     Level: developer
29445fe1f584SPeter Brune 
29456a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
29465fe1f584SPeter Brune 
29475fe1f584SPeter Brune @*/
29485fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
29495fe1f584SPeter Brune {
29505fe1f584SPeter Brune   PetscFunctionBegin;
29515fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
29525fe1f584SPeter Brune   *level = dm->leveldown;
29535fe1f584SPeter Brune   PetscFunctionReturn(0);
29545fe1f584SPeter Brune }
29555fe1f584SPeter Brune 
29569a64c4a8SMatthew G. Knepley /*@
29579a64c4a8SMatthew G. Knepley     DMSetCoarsenLevel - Sets the number of coarsenings that have generated this DM.
29589a64c4a8SMatthew G. Knepley 
29599a64c4a8SMatthew G. Knepley     Not Collective
29609a64c4a8SMatthew G. Knepley 
29619a64c4a8SMatthew G. Knepley     Input Parameters:
29629a64c4a8SMatthew G. Knepley +   dm - the DM object
29639a64c4a8SMatthew G. Knepley -   level - number of coarsenings
29649a64c4a8SMatthew G. Knepley 
29659a64c4a8SMatthew G. Knepley     Level: developer
29669a64c4a8SMatthew G. Knepley 
29679a64c4a8SMatthew G. Knepley .seealso DMCoarsen(), DMGetCoarsenLevel(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
29689a64c4a8SMatthew G. Knepley @*/
29699a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level)
29709a64c4a8SMatthew G. Knepley {
29719a64c4a8SMatthew G. Knepley   PetscFunctionBegin;
29729a64c4a8SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
29739a64c4a8SMatthew G. Knepley   dm->leveldown = level;
29749a64c4a8SMatthew G. Knepley   PetscFunctionReturn(0);
29759a64c4a8SMatthew G. Knepley }
29769a64c4a8SMatthew G. Knepley 
29775fe1f584SPeter Brune 
29785fe1f584SPeter Brune 
297947c6ae99SBarry Smith /*@C
298047c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
298147c6ae99SBarry Smith 
298247c6ae99SBarry Smith     Collective on DM
298347c6ae99SBarry Smith 
298447c6ae99SBarry Smith     Input Parameter:
298547c6ae99SBarry Smith +   dm - the DM object
298647c6ae99SBarry Smith -   nlevels - the number of levels of refinement
298747c6ae99SBarry Smith 
298847c6ae99SBarry Smith     Output Parameter:
298947c6ae99SBarry Smith .   dmf - the refined DM hierarchy
299047c6ae99SBarry Smith 
299147c6ae99SBarry Smith     Level: developer
299247c6ae99SBarry Smith 
2993e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
299447c6ae99SBarry Smith 
299547c6ae99SBarry Smith @*/
29967087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
299747c6ae99SBarry Smith {
299847c6ae99SBarry Smith   PetscErrorCode ierr;
299947c6ae99SBarry Smith 
300047c6ae99SBarry Smith   PetscFunctionBegin;
3001171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3002ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
300347c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
300447c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
300547c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
300647c6ae99SBarry Smith   } else if (dm->ops->refine) {
300747c6ae99SBarry Smith     PetscInt i;
300847c6ae99SBarry Smith 
3009ce94432eSBarry Smith     ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr);
301047c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
3011ce94432eSBarry Smith       ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr);
301247c6ae99SBarry Smith     }
3013ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
301447c6ae99SBarry Smith   PetscFunctionReturn(0);
301547c6ae99SBarry Smith }
301647c6ae99SBarry Smith 
301747c6ae99SBarry Smith /*@C
301847c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
301947c6ae99SBarry Smith 
302047c6ae99SBarry Smith     Collective on DM
302147c6ae99SBarry Smith 
302247c6ae99SBarry Smith     Input Parameter:
302347c6ae99SBarry Smith +   dm - the DM object
302447c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
302547c6ae99SBarry Smith 
302647c6ae99SBarry Smith     Output Parameter:
302747c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
302847c6ae99SBarry Smith 
302947c6ae99SBarry Smith     Level: developer
303047c6ae99SBarry Smith 
3031e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
303247c6ae99SBarry Smith 
303347c6ae99SBarry Smith @*/
30347087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
303547c6ae99SBarry Smith {
303647c6ae99SBarry Smith   PetscErrorCode ierr;
303747c6ae99SBarry Smith 
303847c6ae99SBarry Smith   PetscFunctionBegin;
3039171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3040ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
304147c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
304247c6ae99SBarry Smith   PetscValidPointer(dmc,3);
304347c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
304447c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
304547c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
304647c6ae99SBarry Smith     PetscInt i;
304747c6ae99SBarry Smith 
3048ce94432eSBarry Smith     ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr);
304947c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
3050ce94432eSBarry Smith       ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr);
305147c6ae99SBarry Smith     }
3052ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
305347c6ae99SBarry Smith   PetscFunctionReturn(0);
305447c6ae99SBarry Smith }
305547c6ae99SBarry Smith 
305647c6ae99SBarry Smith /*@
3057e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
305847c6ae99SBarry Smith    grids associated with two DMs.
305947c6ae99SBarry Smith 
306047c6ae99SBarry Smith    Collective on DM
306147c6ae99SBarry Smith 
306247c6ae99SBarry Smith    Input Parameters:
306347c6ae99SBarry Smith +  dmc - the coarse grid DM
306447c6ae99SBarry Smith -  dmf - the fine grid DM
306547c6ae99SBarry Smith 
306647c6ae99SBarry Smith    Output Parameters:
306747c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
306847c6ae99SBarry Smith 
306947c6ae99SBarry Smith    Level: intermediate
307047c6ae99SBarry Smith 
307147c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
307247c6ae99SBarry Smith 
3073e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
307447c6ae99SBarry Smith @*/
3075e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
307647c6ae99SBarry Smith {
307747c6ae99SBarry Smith   PetscErrorCode ierr;
307847c6ae99SBarry Smith 
307947c6ae99SBarry Smith   PetscFunctionBegin;
3080171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
3081171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
308247c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
308347c6ae99SBarry Smith   PetscFunctionReturn(0);
308447c6ae99SBarry Smith }
308547c6ae99SBarry Smith 
30861a266240SBarry Smith /*@C
30871a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
30881a266240SBarry Smith 
30891a266240SBarry Smith     Not Collective
30901a266240SBarry Smith 
30911a266240SBarry Smith     Input Parameters:
30921a266240SBarry Smith +   dm - the DM object
30931a266240SBarry Smith -   destroy - the destroy function
30941a266240SBarry Smith 
30951a266240SBarry Smith     Level: intermediate
30961a266240SBarry Smith 
3097e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
30981a266240SBarry Smith 
3099f07f9ceaSJed Brown @*/
31001a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
31011a266240SBarry Smith {
31021a266240SBarry Smith   PetscFunctionBegin;
3103171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31041a266240SBarry Smith   dm->ctxdestroy = destroy;
31051a266240SBarry Smith   PetscFunctionReturn(0);
31061a266240SBarry Smith }
31071a266240SBarry Smith 
3108b07ff414SBarry Smith /*@
31091b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
311047c6ae99SBarry Smith 
311147c6ae99SBarry Smith     Not Collective
311247c6ae99SBarry Smith 
311347c6ae99SBarry Smith     Input Parameters:
311447c6ae99SBarry Smith +   dm - the DM object
311547c6ae99SBarry Smith -   ctx - the user context
311647c6ae99SBarry Smith 
311747c6ae99SBarry Smith     Level: intermediate
311847c6ae99SBarry Smith 
3119e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
312047c6ae99SBarry Smith 
312147c6ae99SBarry Smith @*/
31221b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
312347c6ae99SBarry Smith {
312447c6ae99SBarry Smith   PetscFunctionBegin;
3125171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
312647c6ae99SBarry Smith   dm->ctx = ctx;
312747c6ae99SBarry Smith   PetscFunctionReturn(0);
312847c6ae99SBarry Smith }
312947c6ae99SBarry Smith 
313047c6ae99SBarry Smith /*@
31311b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
313247c6ae99SBarry Smith 
313347c6ae99SBarry Smith     Not Collective
313447c6ae99SBarry Smith 
313547c6ae99SBarry Smith     Input Parameter:
313647c6ae99SBarry Smith .   dm - the DM object
313747c6ae99SBarry Smith 
313847c6ae99SBarry Smith     Output Parameter:
313947c6ae99SBarry Smith .   ctx - the user context
314047c6ae99SBarry Smith 
314147c6ae99SBarry Smith     Level: intermediate
314247c6ae99SBarry Smith 
3143e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
314447c6ae99SBarry Smith 
314547c6ae99SBarry Smith @*/
31461b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
314747c6ae99SBarry Smith {
314847c6ae99SBarry Smith   PetscFunctionBegin;
3149171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31501b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
315147c6ae99SBarry Smith   PetscFunctionReturn(0);
315247c6ae99SBarry Smith }
315347c6ae99SBarry Smith 
315408da532bSDmitry Karpeev /*@C
3155df3898eeSBarry Smith     DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI.
315608da532bSDmitry Karpeev 
315708da532bSDmitry Karpeev     Logically Collective on DM
315808da532bSDmitry Karpeev 
315908da532bSDmitry Karpeev     Input Parameter:
316008da532bSDmitry Karpeev +   dm - the DM object
31610298fd71SBarry Smith -   f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set)
316208da532bSDmitry Karpeev 
316308da532bSDmitry Karpeev     Level: intermediate
316408da532bSDmitry Karpeev 
3165835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(),
316608da532bSDmitry Karpeev          DMSetJacobian()
316708da532bSDmitry Karpeev 
316808da532bSDmitry Karpeev @*/
316908da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
317008da532bSDmitry Karpeev {
317108da532bSDmitry Karpeev   PetscFunctionBegin;
317208da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
317308da532bSDmitry Karpeev   PetscFunctionReturn(0);
317408da532bSDmitry Karpeev }
317508da532bSDmitry Karpeev 
317608da532bSDmitry Karpeev /*@
317708da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
317808da532bSDmitry Karpeev 
317908da532bSDmitry Karpeev     Not Collective
318008da532bSDmitry Karpeev 
318108da532bSDmitry Karpeev     Input Parameter:
318208da532bSDmitry Karpeev .   dm - the DM object to destroy
318308da532bSDmitry Karpeev 
318408da532bSDmitry Karpeev     Output Parameter:
318508da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
318608da532bSDmitry Karpeev 
318708da532bSDmitry Karpeev     Level: developer
318808da532bSDmitry Karpeev 
318974e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
319008da532bSDmitry Karpeev 
319108da532bSDmitry Karpeev @*/
319208da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
319308da532bSDmitry Karpeev {
319408da532bSDmitry Karpeev   PetscFunctionBegin;
319508da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
319608da532bSDmitry Karpeev   PetscFunctionReturn(0);
319708da532bSDmitry Karpeev }
319808da532bSDmitry Karpeev 
319908da532bSDmitry Karpeev /*@C
320008da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
320108da532bSDmitry Karpeev 
320208da532bSDmitry Karpeev     Logically Collective on DM
320308da532bSDmitry Karpeev 
320408da532bSDmitry Karpeev     Input Parameters:
3205907376e6SBarry Smith .   dm - the DM object
320608da532bSDmitry Karpeev 
320708da532bSDmitry Karpeev     Output parameters:
320808da532bSDmitry Karpeev +   xl - lower bound
320908da532bSDmitry Karpeev -   xu - upper bound
321008da532bSDmitry Karpeev 
3211907376e6SBarry Smith     Level: advanced
3212907376e6SBarry Smith 
321395452b02SPatrick Sanan     Notes:
321495452b02SPatrick Sanan     This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds()
321508da532bSDmitry Karpeev 
321674e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
321708da532bSDmitry Karpeev 
321808da532bSDmitry Karpeev @*/
321908da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
322008da532bSDmitry Karpeev {
322108da532bSDmitry Karpeev   PetscErrorCode ierr;
32225fd66863SKarl Rupp 
322308da532bSDmitry Karpeev   PetscFunctionBegin;
322408da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
322508da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
322608da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
322708da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr);
32288865f1eaSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
322908da532bSDmitry Karpeev   PetscFunctionReturn(0);
323008da532bSDmitry Karpeev }
323108da532bSDmitry Karpeev 
3232b0ae01b7SPeter Brune /*@
3233b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
3234b0ae01b7SPeter Brune 
3235b0ae01b7SPeter Brune     Not Collective
3236b0ae01b7SPeter Brune 
3237b0ae01b7SPeter Brune     Input Parameter:
3238b0ae01b7SPeter Brune .   dm - the DM object
3239b0ae01b7SPeter Brune 
3240b0ae01b7SPeter Brune     Output Parameter:
3241b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
3242b0ae01b7SPeter Brune 
3243b0ae01b7SPeter Brune     Level: developer
3244b0ae01b7SPeter Brune 
3245b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
3246b0ae01b7SPeter Brune 
3247b0ae01b7SPeter Brune @*/
3248b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
3249b0ae01b7SPeter Brune {
3250b0ae01b7SPeter Brune   PetscFunctionBegin;
3251b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
3252b0ae01b7SPeter Brune   PetscFunctionReturn(0);
3253b0ae01b7SPeter Brune }
3254b0ae01b7SPeter Brune 
32553ad4599aSBarry Smith /*@
32563ad4599aSBarry Smith     DMHasCreateRestriction - does the DM object have a method of providing a restriction?
32573ad4599aSBarry Smith 
32583ad4599aSBarry Smith     Not Collective
32593ad4599aSBarry Smith 
32603ad4599aSBarry Smith     Input Parameter:
32613ad4599aSBarry Smith .   dm - the DM object
32623ad4599aSBarry Smith 
32633ad4599aSBarry Smith     Output Parameter:
32643ad4599aSBarry Smith .   flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction().
32653ad4599aSBarry Smith 
32663ad4599aSBarry Smith     Level: developer
32673ad4599aSBarry Smith 
32683ad4599aSBarry Smith .seealso DMHasFunction(), DMCreateRestriction()
32693ad4599aSBarry Smith 
32703ad4599aSBarry Smith @*/
32713ad4599aSBarry Smith PetscErrorCode  DMHasCreateRestriction(DM dm,PetscBool  *flg)
32723ad4599aSBarry Smith {
32733ad4599aSBarry Smith   PetscFunctionBegin;
32743ad4599aSBarry Smith   *flg =  (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE;
32753ad4599aSBarry Smith   PetscFunctionReturn(0);
32763ad4599aSBarry Smith }
32773ad4599aSBarry Smith 
3278a7058e45SLawrence Mitchell 
3279a7058e45SLawrence Mitchell /*@
3280a7058e45SLawrence Mitchell     DMHasCreateInjection - does the DM object have a method of providing an injection?
3281a7058e45SLawrence Mitchell 
3282a7058e45SLawrence Mitchell     Not Collective
3283a7058e45SLawrence Mitchell 
3284a7058e45SLawrence Mitchell     Input Parameter:
3285a7058e45SLawrence Mitchell .   dm - the DM object
3286a7058e45SLawrence Mitchell 
3287a7058e45SLawrence Mitchell     Output Parameter:
3288a7058e45SLawrence Mitchell .   flg - PETSC_TRUE if the DM has facilities for DMCreateInjection().
3289a7058e45SLawrence Mitchell 
3290a7058e45SLawrence Mitchell     Level: developer
3291a7058e45SLawrence Mitchell 
3292a7058e45SLawrence Mitchell .seealso DMHasFunction(), DMCreateInjection()
3293a7058e45SLawrence Mitchell 
3294a7058e45SLawrence Mitchell @*/
3295a7058e45SLawrence Mitchell PetscErrorCode  DMHasCreateInjection(DM dm,PetscBool  *flg)
3296a7058e45SLawrence Mitchell {
32974a7a4c06SLawrence Mitchell   PetscErrorCode ierr;
3298a7058e45SLawrence Mitchell   PetscFunctionBegin;
32994a7a4c06SLawrence Mitchell   if (!dm->ops->hascreateinjection) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DMHasCreateInjection not implemented for this type");
33004a7a4c06SLawrence Mitchell   ierr = (*dm->ops->hascreateinjection)(dm,flg);CHKERRQ(ierr);
3301a7058e45SLawrence Mitchell   PetscFunctionReturn(0);
3302a7058e45SLawrence Mitchell }
3303a7058e45SLawrence Mitchell 
3304748fac09SDmitry Karpeev /*@C
330508da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
330608da532bSDmitry Karpeev 
330708da532bSDmitry Karpeev     Collective on DM
330808da532bSDmitry Karpeev 
330908da532bSDmitry Karpeev     Input Parameter:
331008da532bSDmitry Karpeev +   dm - the DM object
33110298fd71SBarry Smith -   x - location to compute residual and Jacobian, if NULL is passed to those routines; will be NULL for linear problems.
331208da532bSDmitry Karpeev 
331308da532bSDmitry Karpeev     Level: developer
331408da532bSDmitry Karpeev 
331574e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
331608da532bSDmitry Karpeev 
331708da532bSDmitry Karpeev @*/
331808da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
331908da532bSDmitry Karpeev {
332008da532bSDmitry Karpeev   PetscErrorCode ierr;
33215fd66863SKarl Rupp 
332208da532bSDmitry Karpeev   PetscFunctionBegin;
332308da532bSDmitry Karpeev   if (x) {
332408da532bSDmitry Karpeev     if (!dm->x) {
332508da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
332608da532bSDmitry Karpeev     }
332708da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
33288865f1eaSKarl Rupp   } else if (dm->x) {
332908da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);CHKERRQ(ierr);
333008da532bSDmitry Karpeev   }
333108da532bSDmitry Karpeev   PetscFunctionReturn(0);
333208da532bSDmitry Karpeev }
333308da532bSDmitry Karpeev 
33340298fd71SBarry Smith PetscFunctionList DMList              = NULL;
3335264ace61SBarry Smith PetscBool         DMRegisterAllCalled = PETSC_FALSE;
3336264ace61SBarry Smith 
3337264ace61SBarry Smith /*@C
3338264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
3339264ace61SBarry Smith 
3340264ace61SBarry Smith   Collective on DM
3341264ace61SBarry Smith 
3342264ace61SBarry Smith   Input Parameters:
3343264ace61SBarry Smith + dm     - The DM object
3344264ace61SBarry Smith - method - The name of the DM type
3345264ace61SBarry Smith 
3346264ace61SBarry Smith   Options Database Key:
3347264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
3348264ace61SBarry Smith 
3349264ace61SBarry Smith   Notes:
3350e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
3351264ace61SBarry Smith 
3352264ace61SBarry Smith   Level: intermediate
3353264ace61SBarry Smith 
3354264ace61SBarry Smith .keywords: DM, set, type
3355264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
3356264ace61SBarry Smith @*/
335719fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
3358264ace61SBarry Smith {
3359264ace61SBarry Smith   PetscErrorCode (*r)(DM);
3360264ace61SBarry Smith   PetscBool      match;
3361264ace61SBarry Smith   PetscErrorCode ierr;
3362264ace61SBarry Smith 
3363264ace61SBarry Smith   PetscFunctionBegin;
3364264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
3365251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
3366264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
3367264ace61SBarry Smith 
33680f51fdf8SToby Isaac   ierr = DMRegisterAll();CHKERRQ(ierr);
33691c9cd337SJed Brown   ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr);
3370ce94432eSBarry Smith   if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
3371264ace61SBarry Smith 
3372264ace61SBarry Smith   if (dm->ops->destroy) {
3373264ace61SBarry Smith     ierr             = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
33740298fd71SBarry Smith     dm->ops->destroy = NULL;
3375264ace61SBarry Smith   }
3376264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
3377264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
3378264ace61SBarry Smith   PetscFunctionReturn(0);
3379264ace61SBarry Smith }
3380264ace61SBarry Smith 
3381264ace61SBarry Smith /*@C
3382264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
3383264ace61SBarry Smith 
3384264ace61SBarry Smith   Not Collective
3385264ace61SBarry Smith 
3386264ace61SBarry Smith   Input Parameter:
3387264ace61SBarry Smith . dm  - The DM
3388264ace61SBarry Smith 
3389264ace61SBarry Smith   Output Parameter:
3390264ace61SBarry Smith . type - The DM type name
3391264ace61SBarry Smith 
3392264ace61SBarry Smith   Level: intermediate
3393264ace61SBarry Smith 
3394264ace61SBarry Smith .keywords: DM, get, type, name
3395264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
3396264ace61SBarry Smith @*/
339719fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
3398264ace61SBarry Smith {
3399264ace61SBarry Smith   PetscErrorCode ierr;
3400264ace61SBarry Smith 
3401264ace61SBarry Smith   PetscFunctionBegin;
3402264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
3403c959eef4SJed Brown   PetscValidPointer(type,2);
3404607a6623SBarry Smith   ierr = DMRegisterAll();CHKERRQ(ierr);
3405264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
3406264ace61SBarry Smith   PetscFunctionReturn(0);
3407264ace61SBarry Smith }
3408264ace61SBarry Smith 
340967a56275SMatthew G Knepley /*@C
341067a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
341167a56275SMatthew G Knepley 
341267a56275SMatthew G Knepley   Collective on DM
341367a56275SMatthew G Knepley 
341467a56275SMatthew G Knepley   Input Parameters:
341567a56275SMatthew G Knepley + dm - the DM
341667a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
341767a56275SMatthew G Knepley 
341867a56275SMatthew G Knepley   Output Parameter:
341967a56275SMatthew G Knepley . M - pointer to new DM
342067a56275SMatthew G Knepley 
342167a56275SMatthew G Knepley   Notes:
342267a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
342367a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
342467a56275SMatthew G Knepley   of the input DM.
342567a56275SMatthew G Knepley 
342667a56275SMatthew G Knepley   Level: intermediate
342767a56275SMatthew G Knepley 
342867a56275SMatthew G Knepley .seealso: DMCreate()
342967a56275SMatthew G Knepley @*/
343019fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
343167a56275SMatthew G Knepley {
343267a56275SMatthew G Knepley   DM             B;
343367a56275SMatthew G Knepley   char           convname[256];
3434c067b6caSMatthew G. Knepley   PetscBool      sametype/*, issame */;
343567a56275SMatthew G Knepley   PetscErrorCode ierr;
343667a56275SMatthew G Knepley 
343767a56275SMatthew G Knepley   PetscFunctionBegin;
343867a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
343967a56275SMatthew G Knepley   PetscValidType(dm,1);
344067a56275SMatthew G Knepley   PetscValidPointer(M,3);
3441251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
3442c067b6caSMatthew G. Knepley   /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */
3443c067b6caSMatthew G. Knepley   if (sametype) {
3444c067b6caSMatthew G. Knepley     *M   = dm;
3445c067b6caSMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr);
3446c067b6caSMatthew G. Knepley     PetscFunctionReturn(0);
3447c067b6caSMatthew G. Knepley   } else {
34480298fd71SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM*) = NULL;
344967a56275SMatthew G Knepley 
345067a56275SMatthew G Knepley     /*
345167a56275SMatthew G Knepley        Order of precedence:
345267a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
345367a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
345467a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
345567a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
345667a56275SMatthew G Knepley        5) Use a really basic converter.
345767a56275SMatthew G Knepley     */
345867a56275SMatthew G Knepley 
345967a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
3460a126751eSBarry Smith     ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr);
3461a126751eSBarry Smith     ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr);
3462a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
3463a126751eSBarry Smith     ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
3464a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
34650005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr);
346667a56275SMatthew G Knepley     if (conv) goto foundconv;
346767a56275SMatthew G Knepley 
346867a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
346982f516ccSBarry Smith     ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr);
347067a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
3471a126751eSBarry Smith     ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr);
3472a126751eSBarry Smith     ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr);
3473a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
3474a126751eSBarry Smith     ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
3475a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
34760005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
347767a56275SMatthew G Knepley     if (conv) {
3478fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
347967a56275SMatthew G Knepley       goto foundconv;
348067a56275SMatthew G Knepley     }
348167a56275SMatthew G Knepley 
348267a56275SMatthew G Knepley #if 0
348367a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
348467a56275SMatthew G Knepley     conv = B->ops->convertfrom;
3485fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
348667a56275SMatthew G Knepley     if (conv) goto foundconv;
348767a56275SMatthew G Knepley 
348867a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
348967a56275SMatthew G Knepley     if (dm->ops->convert) {
349067a56275SMatthew G Knepley       conv = dm->ops->convert;
349167a56275SMatthew G Knepley     }
349267a56275SMatthew G Knepley     if (conv) goto foundconv;
349367a56275SMatthew G Knepley #endif
349467a56275SMatthew G Knepley 
349567a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
349682f516ccSBarry Smith     SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
349767a56275SMatthew G Knepley 
349867a56275SMatthew G Knepley foundconv:
349967a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
350067a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
350112fa691eSMatthew G. Knepley     /* Things that are independent of DM type: We should consult DMClone() here */
350290b157c4SStefano Zampini     {
350390b157c4SStefano Zampini       PetscBool             isper;
350412fa691eSMatthew G. Knepley       const PetscReal      *maxCell, *L;
350512fa691eSMatthew G. Knepley       const DMBoundaryType *bd;
350690b157c4SStefano Zampini       ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr);
350790b157c4SStefano Zampini       ierr = DMSetPeriodicity(*M, isper, maxCell,  L,  bd);CHKERRQ(ierr);
350812fa691eSMatthew G. Knepley     }
350967a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
351067a56275SMatthew G Knepley   }
351167a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
351267a56275SMatthew G Knepley   PetscFunctionReturn(0);
351367a56275SMatthew G Knepley }
3514264ace61SBarry Smith 
3515264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
3516264ace61SBarry Smith 
3517264ace61SBarry Smith /*@C
35181c84c290SBarry Smith   DMRegister -  Adds a new DM component implementation
35191c84c290SBarry Smith 
35201c84c290SBarry Smith   Not Collective
35211c84c290SBarry Smith 
35221c84c290SBarry Smith   Input Parameters:
35231c84c290SBarry Smith + name        - The name of a new user-defined creation routine
35241c84c290SBarry Smith - create_func - The creation routine itself
35251c84c290SBarry Smith 
35261c84c290SBarry Smith   Notes:
35271c84c290SBarry Smith   DMRegister() may be called multiple times to add several user-defined DMs
35281c84c290SBarry Smith 
35291c84c290SBarry Smith 
35301c84c290SBarry Smith   Sample usage:
35311c84c290SBarry Smith .vb
3532bdf89e91SBarry Smith     DMRegister("my_da", MyDMCreate);
35331c84c290SBarry Smith .ve
35341c84c290SBarry Smith 
35351c84c290SBarry Smith   Then, your DM type can be chosen with the procedural interface via
35361c84c290SBarry Smith .vb
35371c84c290SBarry Smith     DMCreate(MPI_Comm, DM *);
35381c84c290SBarry Smith     DMSetType(DM,"my_da");
35391c84c290SBarry Smith .ve
35401c84c290SBarry Smith    or at runtime via the option
35411c84c290SBarry Smith .vb
35421c84c290SBarry Smith     -da_type my_da
35431c84c290SBarry Smith .ve
3544264ace61SBarry Smith 
3545264ace61SBarry Smith   Level: advanced
35461c84c290SBarry Smith 
35471c84c290SBarry Smith .keywords: DM, register
3548bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy()
35491c84c290SBarry Smith 
3550264ace61SBarry Smith @*/
3551bdf89e91SBarry Smith PetscErrorCode  DMRegister(const char sname[],PetscErrorCode (*function)(DM))
3552264ace61SBarry Smith {
3553264ace61SBarry Smith   PetscErrorCode ierr;
3554264ace61SBarry Smith 
3555264ace61SBarry Smith   PetscFunctionBegin;
35561d36bdfdSBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
3557a240a19fSJed Brown   ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr);
3558264ace61SBarry Smith   PetscFunctionReturn(0);
3559264ace61SBarry Smith }
3560264ace61SBarry Smith 
3561b859378eSBarry Smith /*@C
356255849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
3563b859378eSBarry Smith 
3564b859378eSBarry Smith   Collective on PetscViewer
3565b859378eSBarry Smith 
3566b859378eSBarry Smith   Input Parameters:
3567b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
3568b859378eSBarry Smith            some related function before a call to DMLoad().
3569b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
3570b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
3571b859378eSBarry Smith 
3572b859378eSBarry Smith    Level: intermediate
3573b859378eSBarry Smith 
3574b859378eSBarry Smith   Notes:
357555849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
3576b859378eSBarry Smith 
3577b859378eSBarry Smith   Notes for advanced users:
3578b859378eSBarry Smith   Most users should not need to know the details of the binary storage
3579b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
3580b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
3581b859378eSBarry Smith   format is
3582b859378eSBarry Smith .vb
3583b859378eSBarry Smith      has not yet been determined
3584b859378eSBarry Smith .ve
3585b859378eSBarry Smith 
3586b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
3587b859378eSBarry Smith @*/
3588b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
3589b859378eSBarry Smith {
35909331c7a4SMatthew G. Knepley   PetscBool      isbinary, ishdf5;
3591b859378eSBarry Smith   PetscErrorCode ierr;
3592b859378eSBarry Smith 
3593b859378eSBarry Smith   PetscFunctionBegin;
3594b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
3595b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
3596fb694a9eSVaclav Hapla   ierr = PetscViewerCheckReadable(viewer);CHKERRQ(ierr);
359732c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
35989331c7a4SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
35999331c7a4SMatthew G. Knepley   if (isbinary) {
36009331c7a4SMatthew G. Knepley     PetscInt classid;
36019331c7a4SMatthew G. Knepley     char     type[256];
3602b859378eSBarry Smith 
3603060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
36049200755eSBarry Smith     if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid);
3605060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
360632c0f0efSBarry Smith     ierr = DMSetType(newdm, type);CHKERRQ(ierr);
36079331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
36089331c7a4SMatthew G. Knepley   } else if (ishdf5) {
36099331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
36109331c7a4SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()");
3611b859378eSBarry Smith   PetscFunctionReturn(0);
3612b859378eSBarry Smith }
3613b859378eSBarry Smith 
36147da65231SMatthew G Knepley /******************************** FEM Support **********************************/
36157da65231SMatthew G Knepley 
3616a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[])
3617a6dfd86eSKarl Rupp {
36181d47ebbbSSatish Balay   PetscInt       f;
36191b30c384SMatthew G Knepley   PetscErrorCode ierr;
36201b30c384SMatthew G Knepley 
36217da65231SMatthew G Knepley   PetscFunctionBegin;
362274778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
36231d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
362457622a8eSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr);
36257da65231SMatthew G Knepley   }
36267da65231SMatthew G Knepley   PetscFunctionReturn(0);
36277da65231SMatthew G Knepley }
36287da65231SMatthew G Knepley 
3629a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[])
3630a6dfd86eSKarl Rupp {
36311b30c384SMatthew G Knepley   PetscInt       f, g;
36327da65231SMatthew G Knepley   PetscErrorCode ierr;
36337da65231SMatthew G Knepley 
36347da65231SMatthew G Knepley   PetscFunctionBegin;
363574778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
36361d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
363774778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
36381d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
3639e3556bceSMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
36407da65231SMatthew G Knepley     }
364174778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
36427da65231SMatthew G Knepley   }
36437da65231SMatthew G Knepley   PetscFunctionReturn(0);
36447da65231SMatthew G Knepley }
3645e7c4fc90SDmitry Karpeev 
36466113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X)
3647e759306cSMatthew G. Knepley {
36480c5b8624SToby Isaac   PetscInt          localSize, bs;
36490c5b8624SToby Isaac   PetscMPIInt       size;
36500c5b8624SToby Isaac   Vec               x, xglob;
36510c5b8624SToby Isaac   const PetscScalar *xarray;
3652e759306cSMatthew G. Knepley   PetscErrorCode    ierr;
3653e759306cSMatthew G. Knepley 
3654e759306cSMatthew G. Knepley   PetscFunctionBegin;
36559852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRQ(ierr);
3656e759306cSMatthew G. Knepley   ierr = VecDuplicate(X, &x);CHKERRQ(ierr);
3657e759306cSMatthew G. Knepley   ierr = VecCopy(X, x);CHKERRQ(ierr);
36586113b454SMatthew G. Knepley   ierr = VecChop(x, tol);CHKERRQ(ierr);
36590c5b8624SToby Isaac   ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr);
36600c5b8624SToby Isaac   if (size > 1) {
36610c5b8624SToby Isaac     ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr);
36620c5b8624SToby Isaac     ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr);
36630c5b8624SToby Isaac     ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr);
36640c5b8624SToby Isaac     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr);
36650c5b8624SToby Isaac   } else {
36660c5b8624SToby Isaac     xglob = x;
36670c5b8624SToby Isaac   }
36680c5b8624SToby Isaac   ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr);
36690c5b8624SToby Isaac   if (size > 1) {
36700c5b8624SToby Isaac     ierr = VecDestroy(&xglob);CHKERRQ(ierr);
36710c5b8624SToby Isaac     ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr);
36720c5b8624SToby Isaac   }
3673e759306cSMatthew G. Knepley   ierr = VecDestroy(&x);CHKERRQ(ierr);
3674e759306cSMatthew G. Knepley   PetscFunctionReturn(0);
3675e759306cSMatthew G. Knepley }
3676e759306cSMatthew G. Knepley 
367788ed4aceSMatthew G Knepley /*@
3678e87a4003SBarry Smith   DMGetSection - Get the PetscSection encoding the local data layout for the DM.
367988ed4aceSMatthew G Knepley 
368088ed4aceSMatthew G Knepley   Input Parameter:
368188ed4aceSMatthew G Knepley . dm - The DM
368288ed4aceSMatthew G Knepley 
368388ed4aceSMatthew G Knepley   Output Parameter:
368488ed4aceSMatthew G Knepley . section - The PetscSection
368588ed4aceSMatthew G Knepley 
3686e5893cccSMatthew G. Knepley   Options Database Keys:
3687e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM
3688e5893cccSMatthew G. Knepley 
368988ed4aceSMatthew G Knepley   Level: intermediate
369088ed4aceSMatthew G Knepley 
369188ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
369288ed4aceSMatthew G Knepley 
3693e87a4003SBarry Smith .seealso: DMSetSection(), DMGetGlobalSection()
369488ed4aceSMatthew G Knepley @*/
3695e87a4003SBarry Smith PetscErrorCode DMGetSection(DM dm, PetscSection *section)
36960adebc6cSBarry Smith {
3697fd59a867SMatthew G. Knepley   PetscErrorCode ierr;
3698fd59a867SMatthew G. Knepley 
369988ed4aceSMatthew G Knepley   PetscFunctionBegin;
370088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
370188ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
37022f0f8703SMatthew G. Knepley   if (!dm->defaultSection && dm->ops->createdefaultsection) {
3703e5e52638SMatthew G. Knepley     PetscInt d;
3704e5e52638SMatthew G. Knepley 
3705e5e52638SMatthew G. Knepley     if (dm->setfromoptionscalled) for (d = 0; d < dm->Nds; ++d) {ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr);}
37062f0f8703SMatthew G. Knepley     ierr = (*dm->ops->createdefaultsection)(dm);CHKERRQ(ierr);
3707ae71db08SMatthew G. Knepley     if (dm->defaultSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->defaultSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);}
37082f0f8703SMatthew G. Knepley   }
370988ed4aceSMatthew G Knepley   *section = dm->defaultSection;
371088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
371188ed4aceSMatthew G Knepley }
371288ed4aceSMatthew G Knepley 
371388ed4aceSMatthew G Knepley /*@
3714e87a4003SBarry Smith   DMSetSection - Set the PetscSection encoding the local data layout for the DM.
371588ed4aceSMatthew G Knepley 
371688ed4aceSMatthew G Knepley   Input Parameters:
371788ed4aceSMatthew G Knepley + dm - The DM
371888ed4aceSMatthew G Knepley - section - The PetscSection
371988ed4aceSMatthew G Knepley 
372088ed4aceSMatthew G Knepley   Level: intermediate
372188ed4aceSMatthew G Knepley 
372288ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
372388ed4aceSMatthew G Knepley 
3724e87a4003SBarry Smith .seealso: DMSetSection(), DMGetGlobalSection()
372588ed4aceSMatthew G Knepley @*/
3726e87a4003SBarry Smith PetscErrorCode DMSetSection(DM dm, PetscSection section)
37270adebc6cSBarry Smith {
3728c473ab19SMatthew G. Knepley   PetscInt       numFields = 0;
3729af122d2aSMatthew G Knepley   PetscInt       f;
373088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
373188ed4aceSMatthew G Knepley 
373288ed4aceSMatthew G Knepley   PetscFunctionBegin;
373388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3734c473ab19SMatthew G. Knepley   if (section) {
37351d799100SJed Brown     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
37361d799100SJed Brown     ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
3737c473ab19SMatthew G. Knepley   }
373888ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
373988ed4aceSMatthew G Knepley   dm->defaultSection = section;
3740c473ab19SMatthew G. Knepley   if (section) {ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);}
3741af122d2aSMatthew G Knepley   if (numFields) {
3742af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
3743af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
37440f21e855SMatthew G. Knepley       PetscObject disc;
3745af122d2aSMatthew G Knepley       const char *name;
3746af122d2aSMatthew G Knepley 
3747af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
374844a7f3ddSMatthew G. Knepley       ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr);
37490f21e855SMatthew G. Knepley       ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr);
3750af122d2aSMatthew G Knepley     }
3751af122d2aSMatthew G Knepley   }
3752e87a4003SBarry Smith   /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */
37531d799100SJed Brown   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
375488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
375588ed4aceSMatthew G Knepley }
375688ed4aceSMatthew G Knepley 
37579435951eSToby Isaac /*@
37589435951eSToby Isaac   DMGetDefaultConstraints - Get the PetscSection and Mat the specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation.
37599435951eSToby Isaac 
3760e228b242SToby Isaac   not collective
3761e228b242SToby Isaac 
37629435951eSToby Isaac   Input Parameter:
37639435951eSToby Isaac . dm - The DM
37649435951eSToby Isaac 
37659435951eSToby Isaac   Output Parameter:
37669435951eSToby Isaac + 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.
37679435951eSToby Isaac - 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.
37689435951eSToby Isaac 
37699435951eSToby Isaac   Level: advanced
37709435951eSToby Isaac 
37719435951eSToby Isaac   Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat.
37729435951eSToby Isaac 
37739435951eSToby Isaac .seealso: DMSetDefaultConstraints()
37749435951eSToby Isaac @*/
37759435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat)
37769435951eSToby Isaac {
37779435951eSToby Isaac   PetscErrorCode ierr;
37789435951eSToby Isaac 
37799435951eSToby Isaac   PetscFunctionBegin;
37809435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
37819435951eSToby Isaac   if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);}
378245a75d81SToby Isaac   if (section) {*section = dm->defaultConstraintSection;}
378345a75d81SToby Isaac   if (mat) {*mat = dm->defaultConstraintMat;}
37849435951eSToby Isaac   PetscFunctionReturn(0);
37859435951eSToby Isaac }
37869435951eSToby Isaac 
37879435951eSToby Isaac /*@
37889435951eSToby Isaac   DMSetDefaultConstraints - Set the PetscSection and Mat the specify the local constraint interpolation.
37899435951eSToby Isaac 
37909435951eSToby Isaac   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, l[s[i]] = c[i], where the scatter s is defined by the PetscSection returned by DMGetDefaultConstraintMatrix().
37919435951eSToby Isaac 
37929435951eSToby Isaac   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.
37939435951eSToby Isaac 
3794e228b242SToby Isaac   collective on dm
3795e228b242SToby Isaac 
37969435951eSToby Isaac   Input Parameters:
37979435951eSToby Isaac + dm - The DM
3798e228b242SToby Isaac + 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).
3799e228b242SToby Isaac - 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).
38009435951eSToby Isaac 
38019435951eSToby Isaac   Level: advanced
38029435951eSToby Isaac 
38039435951eSToby Isaac   Note: This increments the references of the PetscSection and the Mat, so they user can destroy them
38049435951eSToby Isaac 
38059435951eSToby Isaac .seealso: DMGetDefaultConstraints()
38069435951eSToby Isaac @*/
38079435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat)
38089435951eSToby Isaac {
3809e228b242SToby Isaac   PetscMPIInt result;
38109435951eSToby Isaac   PetscErrorCode ierr;
38119435951eSToby Isaac 
38129435951eSToby Isaac   PetscFunctionBegin;
38139435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3814e228b242SToby Isaac   if (section) {
3815e228b242SToby Isaac     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
3816e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr);
3817f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator");
3818e228b242SToby Isaac   }
3819e228b242SToby Isaac   if (mat) {
3820e228b242SToby Isaac     PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
3821e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr);
3822f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator");
3823e228b242SToby Isaac   }
38249435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
38259435951eSToby Isaac   ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr);
38269435951eSToby Isaac   dm->defaultConstraintSection = section;
38279435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
38289435951eSToby Isaac   ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr);
38299435951eSToby Isaac   dm->defaultConstraintMat = mat;
38309435951eSToby Isaac   PetscFunctionReturn(0);
38319435951eSToby Isaac }
38329435951eSToby Isaac 
3833497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
3834507e4973SMatthew G. Knepley /*
3835507e4973SMatthew G. Knepley   DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections.
3836507e4973SMatthew G. Knepley 
3837507e4973SMatthew G. Knepley   Input Parameters:
3838507e4973SMatthew G. Knepley + dm - The DM
3839507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout
3840507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout
3841507e4973SMatthew G. Knepley 
3842507e4973SMatthew G. Knepley   Level: intermediate
3843507e4973SMatthew G. Knepley 
3844507e4973SMatthew G. Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
3845507e4973SMatthew G. Knepley */
3846f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection)
3847507e4973SMatthew G. Knepley {
3848507e4973SMatthew G. Knepley   MPI_Comm        comm;
3849507e4973SMatthew G. Knepley   PetscLayout     layout;
3850507e4973SMatthew G. Knepley   const PetscInt *ranges;
3851507e4973SMatthew G. Knepley   PetscInt        pStart, pEnd, p, nroots;
3852507e4973SMatthew G. Knepley   PetscMPIInt     size, rank;
3853507e4973SMatthew G. Knepley   PetscBool       valid = PETSC_TRUE, gvalid;
3854507e4973SMatthew G. Knepley   PetscErrorCode  ierr;
3855507e4973SMatthew G. Knepley 
3856507e4973SMatthew G. Knepley   PetscFunctionBegin;
3857507e4973SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
3858507e4973SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3859507e4973SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
3860507e4973SMatthew G. Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
3861507e4973SMatthew G. Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
3862507e4973SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
3863507e4973SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
3864507e4973SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
3865507e4973SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
3866507e4973SMatthew G. Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
3867507e4973SMatthew G. Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
3868507e4973SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
3869f741bcd2SMatthew G. Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d;
3870507e4973SMatthew G. Knepley 
3871507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
3872507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
3873507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
3874507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
3875507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
3876507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
3877507e4973SMatthew G. Knepley     if (!gdof) continue; /* Censored point */
3878507e4973SMatthew G. Knepley     if ((gdof < 0 ? -(gdof+1) : gdof) != dof) {ierr = PetscSynchronizedPrintf(comm, "[%d]Global dof %d for point %d not equal to local dof %d\n", rank, gdof, p, dof);CHKERRQ(ierr); valid = PETSC_FALSE;}
3879507e4973SMatthew G. Knepley     if (gcdof && (gcdof != cdof)) {ierr = PetscSynchronizedPrintf(comm, "[%d]Global constraints %d for point %d not equal to local constraints %d\n", rank, gcdof, p, cdof);CHKERRQ(ierr); valid = PETSC_FALSE;}
3880507e4973SMatthew G. Knepley     if (gdof < 0) {
3881507e4973SMatthew G. Knepley       gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
3882507e4973SMatthew G. Knepley       for (d = 0; d < gsize; ++d) {
3883507e4973SMatthew G. Knepley         PetscInt offset = -(goff+1) + d, r;
3884507e4973SMatthew G. Knepley 
3885507e4973SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
3886507e4973SMatthew G. Knepley         if (r < 0) r = -(r+2);
3887507e4973SMatthew G. Knepley         if ((r < 0) || (r >= size)) {ierr = PetscSynchronizedPrintf(comm, "[%d]Point %d mapped to invalid process %d (%d, %d)\n", rank, p, r, gdof, goff);CHKERRQ(ierr); valid = PETSC_FALSE;break;}
3888507e4973SMatthew G. Knepley       }
3889507e4973SMatthew G. Knepley     }
3890507e4973SMatthew G. Knepley   }
3891507e4973SMatthew G. Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
3892507e4973SMatthew G. Knepley   ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);
3893b2566f29SBarry Smith   ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr);
3894507e4973SMatthew G. Knepley   if (!gvalid) {
3895507e4973SMatthew G. Knepley     ierr = DMView(dm, NULL);CHKERRQ(ierr);
3896507e4973SMatthew G. Knepley     SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections");
3897507e4973SMatthew G. Knepley   }
3898507e4973SMatthew G. Knepley   PetscFunctionReturn(0);
3899507e4973SMatthew G. Knepley }
3900f741bcd2SMatthew G. Knepley #endif
3901507e4973SMatthew G. Knepley 
390288ed4aceSMatthew G Knepley /*@
3903e87a4003SBarry Smith   DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM.
390488ed4aceSMatthew G Knepley 
39058b1ab98fSJed Brown   Collective on DM
39068b1ab98fSJed Brown 
390788ed4aceSMatthew G Knepley   Input Parameter:
390888ed4aceSMatthew G Knepley . dm - The DM
390988ed4aceSMatthew G Knepley 
391088ed4aceSMatthew G Knepley   Output Parameter:
391188ed4aceSMatthew G Knepley . section - The PetscSection
391288ed4aceSMatthew G Knepley 
391388ed4aceSMatthew G Knepley   Level: intermediate
391488ed4aceSMatthew G Knepley 
391588ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
391688ed4aceSMatthew G Knepley 
3917e87a4003SBarry Smith .seealso: DMSetSection(), DMGetSection()
391888ed4aceSMatthew G Knepley @*/
3919e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section)
39200adebc6cSBarry Smith {
392188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
392288ed4aceSMatthew G Knepley 
392388ed4aceSMatthew G Knepley   PetscFunctionBegin;
392488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
392588ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
392688ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
3927fd59a867SMatthew G. Knepley     PetscSection s;
3928fd59a867SMatthew G. Knepley 
3929e87a4003SBarry Smith     ierr = DMGetSection(dm, &s);CHKERRQ(ierr);
3930fd59a867SMatthew G. Knepley     if (!s)  SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection in order to create a global PetscSection");
393133907cc2SStefano Zampini     if (!dm->sf) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a point PetscSF in order to create a global PetscSection");
393215b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
3933cf06b437SMatthew G. Knepley     ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr);
3934ce94432eSBarry Smith     ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->defaultGlobalSection, &dm->map);CHKERRQ(ierr);
3935685405a1SBarry Smith     ierr = PetscSectionViewFromOptions(dm->defaultGlobalSection, NULL, "-global_section_view");CHKERRQ(ierr);
393688ed4aceSMatthew G Knepley   }
393788ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
393888ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
393988ed4aceSMatthew G Knepley }
394088ed4aceSMatthew G Knepley 
3941b21d0597SMatthew G Knepley /*@
3942e87a4003SBarry Smith   DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM.
3943b21d0597SMatthew G Knepley 
3944b21d0597SMatthew G Knepley   Input Parameters:
3945b21d0597SMatthew G Knepley + dm - The DM
39465080bbdbSMatthew G Knepley - section - The PetscSection, or NULL
3947b21d0597SMatthew G Knepley 
3948b21d0597SMatthew G Knepley   Level: intermediate
3949b21d0597SMatthew G Knepley 
3950b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
3951b21d0597SMatthew G Knepley 
3952e87a4003SBarry Smith .seealso: DMGetGlobalSection(), DMSetSection()
3953b21d0597SMatthew G Knepley @*/
3954e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section)
39550adebc6cSBarry Smith {
3956b21d0597SMatthew G Knepley   PetscErrorCode ierr;
3957b21d0597SMatthew G Knepley 
3958b21d0597SMatthew G Knepley   PetscFunctionBegin;
3959b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
39605080bbdbSMatthew G Knepley   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
39611d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
3962b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
3963b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
3964497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
3965f741bcd2SMatthew G. Knepley   if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->defaultSection, section);CHKERRQ(ierr);}
3966507e4973SMatthew G. Knepley #endif
3967b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3968b21d0597SMatthew G Knepley }
3969b21d0597SMatthew G Knepley 
397088ed4aceSMatthew G Knepley /*@
397188ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
397288ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
397388ed4aceSMatthew G Knepley 
397488ed4aceSMatthew G Knepley   Input Parameter:
397588ed4aceSMatthew G Knepley . dm - The DM
397688ed4aceSMatthew G Knepley 
397788ed4aceSMatthew G Knepley   Output Parameter:
397888ed4aceSMatthew G Knepley . sf - The PetscSF
397988ed4aceSMatthew G Knepley 
398088ed4aceSMatthew G Knepley   Level: intermediate
398188ed4aceSMatthew G Knepley 
398288ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
398388ed4aceSMatthew G Knepley 
398488ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
398588ed4aceSMatthew G Knepley @*/
39860adebc6cSBarry Smith PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf)
39870adebc6cSBarry Smith {
398888ed4aceSMatthew G Knepley   PetscInt       nroots;
398988ed4aceSMatthew G Knepley   PetscErrorCode ierr;
399088ed4aceSMatthew G Knepley 
399188ed4aceSMatthew G Knepley   PetscFunctionBegin;
399288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
399388ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
399433907cc2SStefano Zampini   if (!dm->defaultSF) {
399533907cc2SStefano Zampini     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->defaultSF);CHKERRQ(ierr);
399633907cc2SStefano Zampini   }
39970298fd71SBarry Smith   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
399888ed4aceSMatthew G Knepley   if (nroots < 0) {
399988ed4aceSMatthew G Knepley     PetscSection section, gSection;
400088ed4aceSMatthew G Knepley 
4001e87a4003SBarry Smith     ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
400231ea6d37SMatthew G Knepley     if (section) {
4003e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr);
400488ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
400531ea6d37SMatthew G Knepley     } else {
40060298fd71SBarry Smith       *sf = NULL;
400731ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
400831ea6d37SMatthew G Knepley     }
400988ed4aceSMatthew G Knepley   }
401088ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
401188ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
401288ed4aceSMatthew G Knepley }
401388ed4aceSMatthew G Knepley 
401488ed4aceSMatthew G Knepley /*@
401588ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
401688ed4aceSMatthew G Knepley 
401788ed4aceSMatthew G Knepley   Input Parameters:
401888ed4aceSMatthew G Knepley + dm - The DM
401988ed4aceSMatthew G Knepley - sf - The PetscSF
402088ed4aceSMatthew G Knepley 
402188ed4aceSMatthew G Knepley   Level: intermediate
402288ed4aceSMatthew G Knepley 
402388ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
402488ed4aceSMatthew G Knepley 
402588ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
402688ed4aceSMatthew G Knepley @*/
40270adebc6cSBarry Smith PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf)
40280adebc6cSBarry Smith {
402988ed4aceSMatthew G Knepley   PetscErrorCode ierr;
403088ed4aceSMatthew G Knepley 
403188ed4aceSMatthew G Knepley   PetscFunctionBegin;
403288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
403333907cc2SStefano Zampini   if (sf) {
403488ed4aceSMatthew G Knepley     PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
403533907cc2SStefano Zampini     ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
403633907cc2SStefano Zampini   }
403788ed4aceSMatthew G Knepley   ierr          = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
403888ed4aceSMatthew G Knepley   dm->defaultSF = sf;
403988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
404088ed4aceSMatthew G Knepley }
404188ed4aceSMatthew G Knepley 
404288ed4aceSMatthew G Knepley /*@C
404388ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
404488ed4aceSMatthew G Knepley   describing the data layout.
404588ed4aceSMatthew G Knepley 
404688ed4aceSMatthew G Knepley   Input Parameters:
404788ed4aceSMatthew G Knepley + dm - The DM
404888ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
404988ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
405088ed4aceSMatthew G Knepley 
405188ed4aceSMatthew G Knepley   Level: intermediate
405288ed4aceSMatthew G Knepley 
405388ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
405488ed4aceSMatthew G Knepley @*/
405588ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
405688ed4aceSMatthew G Knepley {
405782f516ccSBarry Smith   MPI_Comm       comm;
405888ed4aceSMatthew G Knepley   PetscLayout    layout;
405988ed4aceSMatthew G Knepley   const PetscInt *ranges;
406088ed4aceSMatthew G Knepley   PetscInt       *local;
406188ed4aceSMatthew G Knepley   PetscSFNode    *remote;
4062ecd73843SMatthew G. Knepley   PetscInt       pStart, pEnd, p, nroots, nleaves = 0, l;
406388ed4aceSMatthew G Knepley   PetscMPIInt    size, rank;
406488ed4aceSMatthew G Knepley   PetscErrorCode ierr;
406588ed4aceSMatthew G Knepley 
406688ed4aceSMatthew G Knepley   PetscFunctionBegin;
406788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4068367003a6SStefano Zampini   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
406988ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
407088ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
407188ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
407288ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
407388ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
407488ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
407588ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
407688ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
407788ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4078ecd73843SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
40796636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
408088ed4aceSMatthew G Knepley 
40816636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
40826636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4083235fbf56SMatthew G. Knepley     if (gcdof > (gdof < 0 ? -(gdof+1) : gdof)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d has %d constraints > %d dof", p, gcdof, (gdof < 0 ? -(gdof+1) : gdof));
40846636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
408588ed4aceSMatthew G Knepley   }
4086785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr);
4087785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr);
408888ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
40891f588964SMatthew G Knepley     const PetscInt *cind;
40906636e97aSMatthew G Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
409188ed4aceSMatthew G Knepley 
409288ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
409388ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
409488ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
409588ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
409688ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
40976636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
409888ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
40996636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
41006636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
41016636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
4102057b4bcdSMatthew G Knepley       if (gsize != dof) SETERRQ4(comm, PETSC_ERR_ARG_WRONG, "Global dof %d for point %d is neither the constrained size %d, nor the unconstrained %d", gsize, p, dof-cdof, dof);
41036636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
41046636e97aSMatthew G Knepley     }
410588ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
410688ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
410788ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
410888ed4aceSMatthew G Knepley     }
410988ed4aceSMatthew G Knepley     if (gdof < 0) {
41106636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
411188ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
411288ed4aceSMatthew G Knepley 
411305376888SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
411431d3f06eSJed Brown         if (r < 0) r = -(r+2);
411505376888SMatthew G. Knepley         if ((r < 0) || (r >= size)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %d mapped to invalid process %d (%d, %d)", p, r, gdof, goff);
411688ed4aceSMatthew G Knepley         remote[l].rank  = r;
411788ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
411888ed4aceSMatthew G Knepley       }
411988ed4aceSMatthew G Knepley     } else {
41206636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
412188ed4aceSMatthew G Knepley         remote[l].rank  = rank;
412288ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
412388ed4aceSMatthew G Knepley       }
412488ed4aceSMatthew G Knepley     }
412588ed4aceSMatthew G Knepley   }
41266636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
412788ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
412888ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
412988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
413088ed4aceSMatthew G Knepley }
4131af122d2aSMatthew G Knepley 
4132b21d0597SMatthew G Knepley /*@
4133b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
4134b21d0597SMatthew G Knepley 
4135b21d0597SMatthew G Knepley   Input Parameter:
4136b21d0597SMatthew G Knepley . dm - The DM
4137b21d0597SMatthew G Knepley 
4138b21d0597SMatthew G Knepley   Output Parameter:
4139b21d0597SMatthew G Knepley . sf - The PetscSF
4140b21d0597SMatthew G Knepley 
4141b21d0597SMatthew G Knepley   Level: intermediate
4142b21d0597SMatthew G Knepley 
4143b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
4144b21d0597SMatthew G Knepley 
4145057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
4146b21d0597SMatthew G Knepley @*/
41470adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf)
41480adebc6cSBarry Smith {
4149b21d0597SMatthew G Knepley   PetscFunctionBegin;
4150b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4151b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
4152b21d0597SMatthew G Knepley   *sf = dm->sf;
4153b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4154b21d0597SMatthew G Knepley }
4155b21d0597SMatthew G Knepley 
4156057b4bcdSMatthew G Knepley /*@
4157057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
4158057b4bcdSMatthew G Knepley 
4159057b4bcdSMatthew G Knepley   Input Parameters:
4160057b4bcdSMatthew G Knepley + dm - The DM
4161057b4bcdSMatthew G Knepley - sf - The PetscSF
4162057b4bcdSMatthew G Knepley 
4163057b4bcdSMatthew G Knepley   Level: intermediate
4164057b4bcdSMatthew G Knepley 
4165057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
4166057b4bcdSMatthew G Knepley @*/
41670adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf)
41680adebc6cSBarry Smith {
4169057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
4170057b4bcdSMatthew G Knepley 
4171057b4bcdSMatthew G Knepley   PetscFunctionBegin;
4172057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
417333907cc2SStefano Zampini   if (sf) {
417433907cc2SStefano Zampini     PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
4175057b4bcdSMatthew G Knepley     ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
417633907cc2SStefano Zampini   }
417733907cc2SStefano Zampini   ierr   = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
4178057b4bcdSMatthew G Knepley   dm->sf = sf;
4179057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
4180057b4bcdSMatthew G Knepley }
4181057b4bcdSMatthew G Knepley 
418234aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc)
418334aa8a36SMatthew G. Knepley {
418434aa8a36SMatthew G. Knepley   PetscClassId   id;
418534aa8a36SMatthew G. Knepley   PetscErrorCode ierr;
418634aa8a36SMatthew G. Knepley 
418734aa8a36SMatthew G. Knepley   PetscFunctionBegin;
418834aa8a36SMatthew G. Knepley   ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
418934aa8a36SMatthew G. Knepley   if (id == PETSCFE_CLASSID) {
419034aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
419134aa8a36SMatthew G. Knepley   } else if (id == PETSCFV_CLASSID) {
419234aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr);
419317c1d62eSMatthew G. Knepley   } else {
419417c1d62eSMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
419534aa8a36SMatthew G. Knepley   }
419634aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
419734aa8a36SMatthew G. Knepley }
419834aa8a36SMatthew G. Knepley 
419944a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew)
420044a7f3ddSMatthew G. Knepley {
420144a7f3ddSMatthew G. Knepley   RegionField   *tmpr;
420244a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf, f;
420344a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
420444a7f3ddSMatthew G. Knepley 
420544a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
420644a7f3ddSMatthew G. Knepley   if (Nf >= NfNew) PetscFunctionReturn(0);
420744a7f3ddSMatthew G. Knepley   ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr);
420844a7f3ddSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f];
420944a7f3ddSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL;}
421044a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
421144a7f3ddSMatthew G. Knepley   dm->Nf     = NfNew;
421244a7f3ddSMatthew G. Knepley   dm->fields = tmpr;
421344a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
421444a7f3ddSMatthew G. Knepley }
421544a7f3ddSMatthew G. Knepley 
421644a7f3ddSMatthew G. Knepley /*@
421744a7f3ddSMatthew G. Knepley   DMClearFields - Remove all fields from the DM
421844a7f3ddSMatthew G. Knepley 
421944a7f3ddSMatthew G. Knepley   Logically collective on DM
422044a7f3ddSMatthew G. Knepley 
422144a7f3ddSMatthew G. Knepley   Input Parameter:
422244a7f3ddSMatthew G. Knepley . dm - The DM
422344a7f3ddSMatthew G. Knepley 
422444a7f3ddSMatthew G. Knepley   Level: intermediate
422544a7f3ddSMatthew G. Knepley 
422644a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField()
422744a7f3ddSMatthew G. Knepley @*/
422844a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm)
422944a7f3ddSMatthew G. Knepley {
423044a7f3ddSMatthew G. Knepley   PetscInt       f;
423144a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
423244a7f3ddSMatthew G. Knepley 
423344a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
423444a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
423544a7f3ddSMatthew G. Knepley   for (f = 0; f < dm->Nf; ++f) {
423644a7f3ddSMatthew G. Knepley     ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
423744a7f3ddSMatthew G. Knepley     ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
423844a7f3ddSMatthew G. Knepley   }
423944a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
424044a7f3ddSMatthew G. Knepley   dm->fields = NULL;
424144a7f3ddSMatthew G. Knepley   dm->Nf     = 0;
424244a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
424344a7f3ddSMatthew G. Knepley }
424444a7f3ddSMatthew G. Knepley 
4245689b5837SMatthew G. Knepley /*@
4246689b5837SMatthew G. Knepley   DMGetNumFields - Get the number of fields in the DM
4247689b5837SMatthew G. Knepley 
4248689b5837SMatthew G. Knepley   Not collective
4249689b5837SMatthew G. Knepley 
4250689b5837SMatthew G. Knepley   Input Parameter:
4251689b5837SMatthew G. Knepley . dm - The DM
4252689b5837SMatthew G. Knepley 
4253689b5837SMatthew G. Knepley   Output Parameter:
4254689b5837SMatthew G. Knepley . Nf - The number of fields
4255689b5837SMatthew G. Knepley 
4256689b5837SMatthew G. Knepley   Level: intermediate
4257689b5837SMatthew G. Knepley 
4258689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField()
4259689b5837SMatthew G. Knepley @*/
42600f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
42610f21e855SMatthew G. Knepley {
42620f21e855SMatthew G. Knepley   PetscFunctionBegin;
42630f21e855SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
426444a7f3ddSMatthew G. Knepley   PetscValidPointer(numFields, 2);
426544a7f3ddSMatthew G. Knepley   *numFields = dm->Nf;
4266af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4267af122d2aSMatthew G Knepley }
4268af122d2aSMatthew G Knepley 
4269689b5837SMatthew G. Knepley /*@
4270689b5837SMatthew G. Knepley   DMSetNumFields - Set the number of fields in the DM
4271689b5837SMatthew G. Knepley 
4272689b5837SMatthew G. Knepley   Logically collective on DM
4273689b5837SMatthew G. Knepley 
4274689b5837SMatthew G. Knepley   Input Parameters:
4275689b5837SMatthew G. Knepley + dm - The DM
4276689b5837SMatthew G. Knepley - Nf - The number of fields
4277689b5837SMatthew G. Knepley 
4278689b5837SMatthew G. Knepley   Level: intermediate
4279689b5837SMatthew G. Knepley 
4280689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField()
4281689b5837SMatthew G. Knepley @*/
4282af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
4283af122d2aSMatthew G Knepley {
42840f21e855SMatthew G. Knepley   PetscInt       Nf, f;
4285af122d2aSMatthew G Knepley   PetscErrorCode ierr;
4286af122d2aSMatthew G Knepley 
4287af122d2aSMatthew G Knepley   PetscFunctionBegin;
4288af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
428944a7f3ddSMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
42900f21e855SMatthew G. Knepley   for (f = Nf; f < numFields; ++f) {
42910f21e855SMatthew G. Knepley     PetscContainer obj;
42920f21e855SMatthew G. Knepley 
42930f21e855SMatthew G. Knepley     ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr);
429444a7f3ddSMatthew G. Knepley     ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr);
42950f21e855SMatthew G. Knepley     ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr);
4296af122d2aSMatthew G Knepley   }
4297af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4298af122d2aSMatthew G Knepley }
4299af122d2aSMatthew G Knepley 
4300c1929be8SMatthew G. Knepley /*@
4301c1929be8SMatthew G. Knepley   DMGetField - Return the discretization object for a given DM field
4302c1929be8SMatthew G. Knepley 
4303c1929be8SMatthew G. Knepley   Not collective
4304c1929be8SMatthew G. Knepley 
4305c1929be8SMatthew G. Knepley   Input Parameters:
4306c1929be8SMatthew G. Knepley + dm - The DM
4307c1929be8SMatthew G. Knepley - f  - The field number
4308c1929be8SMatthew G. Knepley 
430944a7f3ddSMatthew G. Knepley   Output Parameters:
431044a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh
431144a7f3ddSMatthew G. Knepley - field - The discretization object
4312c1929be8SMatthew G. Knepley 
431344a7f3ddSMatthew G. Knepley   Level: intermediate
4314c1929be8SMatthew G. Knepley 
431544a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField()
4316c1929be8SMatthew G. Knepley @*/
431744a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field)
4318af122d2aSMatthew G Knepley {
4319af122d2aSMatthew G Knepley   PetscFunctionBegin;
4320af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
432144a7f3ddSMatthew G. Knepley   PetscValidPointer(field, 3);
432244a7f3ddSMatthew G. Knepley   if ((f < 0) || (f >= dm->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, dm->Nf);
432344a7f3ddSMatthew G. Knepley   if (label) *label = dm->fields[f].label;
432444a7f3ddSMatthew G. Knepley   if (field) *field = dm->fields[f].disc;
4325decb47aaSMatthew G. Knepley   PetscFunctionReturn(0);
4326decb47aaSMatthew G. Knepley }
4327decb47aaSMatthew G. Knepley 
4328c1929be8SMatthew G. Knepley /*@
4329c1929be8SMatthew G. Knepley   DMSetField - Set the discretization object for a given DM field
4330c1929be8SMatthew G. Knepley 
4331c1929be8SMatthew G. Knepley   Logically collective on DM
4332c1929be8SMatthew G. Knepley 
4333c1929be8SMatthew G. Knepley   Input Parameters:
4334c1929be8SMatthew G. Knepley + dm    - The DM
4335c1929be8SMatthew G. Knepley . f     - The field number
433644a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
4337c1929be8SMatthew G. Knepley - field - The discretization object
4338c1929be8SMatthew G. Knepley 
433944a7f3ddSMatthew G. Knepley   Level: intermediate
4340c1929be8SMatthew G. Knepley 
434144a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField()
4342c1929be8SMatthew G. Knepley @*/
434344a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field)
4344decb47aaSMatthew G. Knepley {
4345decb47aaSMatthew G. Knepley   PetscErrorCode ierr;
4346decb47aaSMatthew G. Knepley 
4347decb47aaSMatthew G. Knepley   PetscFunctionBegin;
4348decb47aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4349e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
435044a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 4);
4351e5e52638SMatthew G. Knepley   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
435244a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr);
435344a7f3ddSMatthew G. Knepley   ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
435444a7f3ddSMatthew G. Knepley   ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
435544a7f3ddSMatthew G. Knepley   dm->fields[f].label = label;
435644a7f3ddSMatthew G. Knepley   dm->fields[f].disc  = field;
435744a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
435844a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
435934aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr);
43602df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
436144a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
436244a7f3ddSMatthew G. Knepley }
436344a7f3ddSMatthew G. Knepley 
436444a7f3ddSMatthew G. Knepley /*@
436544a7f3ddSMatthew G. Knepley   DMAddField - Add the discretization object for the given DM field
436644a7f3ddSMatthew G. Knepley 
436744a7f3ddSMatthew G. Knepley   Logically collective on DM
436844a7f3ddSMatthew G. Knepley 
436944a7f3ddSMatthew G. Knepley   Input Parameters:
437044a7f3ddSMatthew G. Knepley + dm    - The DM
437144a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
437244a7f3ddSMatthew G. Knepley - field - The discretization object
437344a7f3ddSMatthew G. Knepley 
437444a7f3ddSMatthew G. Knepley   Level: intermediate
437544a7f3ddSMatthew G. Knepley 
437644a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField()
437744a7f3ddSMatthew G. Knepley @*/
437844a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field)
437944a7f3ddSMatthew G. Knepley {
438044a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf;
438144a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
438244a7f3ddSMatthew G. Knepley 
438344a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
438444a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
438544a7f3ddSMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
438644a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 3);
438744a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr);
438844a7f3ddSMatthew G. Knepley   dm->fields[Nf].label = label;
438944a7f3ddSMatthew G. Knepley   dm->fields[Nf].disc  = field;
439044a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
439144a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
439234aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr);
43932df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
4394af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4395af122d2aSMatthew G Knepley }
43966636e97aSMatthew G Knepley 
4397e5e52638SMatthew G. Knepley /*@
4398e5e52638SMatthew G. Knepley   DMCopyFields - Copy the discretizations for the DM into another DM
4399e5e52638SMatthew G. Knepley 
4400e5e52638SMatthew G. Knepley   Collective on DM
4401e5e52638SMatthew G. Knepley 
4402e5e52638SMatthew G. Knepley   Input Parameter:
4403e5e52638SMatthew G. Knepley . dm - The DM
4404e5e52638SMatthew G. Knepley 
4405e5e52638SMatthew G. Knepley   Output Parameter:
4406e5e52638SMatthew G. Knepley . newdm - The DM
4407e5e52638SMatthew G. Knepley 
4408e5e52638SMatthew G. Knepley   Level: advanced
4409e5e52638SMatthew G. Knepley 
4410e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS()
4411e5e52638SMatthew G. Knepley @*/
4412e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm)
4413e5e52638SMatthew G. Knepley {
4414e5e52638SMatthew G. Knepley   PetscInt       Nf, f;
4415e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4416e5e52638SMatthew G. Knepley 
4417e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4418e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
4419e5e52638SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4420e5e52638SMatthew G. Knepley   ierr = DMClearFields(newdm);CHKERRQ(ierr);
4421e5e52638SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4422e5e52638SMatthew G. Knepley     DMLabel     label;
4423e5e52638SMatthew G. Knepley     PetscObject field;
442434aa8a36SMatthew G. Knepley     PetscBool   useCone, useClosure;
4425e5e52638SMatthew G. Knepley 
4426e5e52638SMatthew G. Knepley     ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr);
4427e5e52638SMatthew G. Knepley     ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr);
442834aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr);
442934aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr);
443034aa8a36SMatthew G. Knepley   }
443134aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
443234aa8a36SMatthew G. Knepley }
443334aa8a36SMatthew G. Knepley 
443434aa8a36SMatthew G. Knepley /*@
443534aa8a36SMatthew G. Knepley   DMGetAdjacency - Returns the flags for determining variable influence
443634aa8a36SMatthew G. Knepley 
443734aa8a36SMatthew G. Knepley   Not collective
443834aa8a36SMatthew G. Knepley 
443934aa8a36SMatthew G. Knepley   Input Parameters:
444034aa8a36SMatthew G. Knepley + dm - The DM object
444134aa8a36SMatthew G. Knepley - f  - The field number, or PETSC_DEFAULT for the default adjacency
444234aa8a36SMatthew G. Knepley 
444334aa8a36SMatthew G. Knepley   Output Parameter:
444434aa8a36SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
444534aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
444634aa8a36SMatthew G. Knepley 
444734aa8a36SMatthew G. Knepley   Notes:
444834aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
444934aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
445034aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4451*979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
445234aa8a36SMatthew G. Knepley 
445334aa8a36SMatthew G. Knepley   Level: developer
445434aa8a36SMatthew G. Knepley 
445534aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField()
445634aa8a36SMatthew G. Knepley @*/
445734aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure)
445834aa8a36SMatthew G. Knepley {
445934aa8a36SMatthew G. Knepley   PetscFunctionBegin;
446034aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
446134aa8a36SMatthew G. Knepley   if (useCone) PetscValidPointer(useCone, 3);
446234aa8a36SMatthew G. Knepley   if (useClosure) PetscValidPointer(useClosure, 4);
446334aa8a36SMatthew G. Knepley   if (f < 0) {
446434aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->adjacency[0];
446534aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->adjacency[1];
446634aa8a36SMatthew G. Knepley   } else {
446734aa8a36SMatthew G. Knepley     PetscInt       Nf;
446834aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
446934aa8a36SMatthew G. Knepley 
447034aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
447134aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
447234aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->fields[f].adjacency[0];
447334aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->fields[f].adjacency[1];
447434aa8a36SMatthew G. Knepley   }
447534aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
447634aa8a36SMatthew G. Knepley }
447734aa8a36SMatthew G. Knepley 
447834aa8a36SMatthew G. Knepley /*@
447934aa8a36SMatthew G. Knepley   DMSetAdjacency - Set the flags for determining variable influence
448034aa8a36SMatthew G. Knepley 
448134aa8a36SMatthew G. Knepley   Not collective
448234aa8a36SMatthew G. Knepley 
448334aa8a36SMatthew G. Knepley   Input Parameters:
448434aa8a36SMatthew G. Knepley + dm         - The DM object
448534aa8a36SMatthew G. Knepley . f          - The field number
448634aa8a36SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
448734aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
448834aa8a36SMatthew G. Knepley 
448934aa8a36SMatthew G. Knepley   Notes:
449034aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
449134aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
449234aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4493*979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
449434aa8a36SMatthew G. Knepley 
449534aa8a36SMatthew G. Knepley   Level: developer
449634aa8a36SMatthew G. Knepley 
449734aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField()
449834aa8a36SMatthew G. Knepley @*/
449934aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure)
450034aa8a36SMatthew G. Knepley {
450134aa8a36SMatthew G. Knepley   PetscFunctionBegin;
450234aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
450334aa8a36SMatthew G. Knepley   if (f < 0) {
450434aa8a36SMatthew G. Knepley     dm->adjacency[0] = useCone;
450534aa8a36SMatthew G. Knepley     dm->adjacency[1] = useClosure;
450634aa8a36SMatthew G. Knepley   } else {
450734aa8a36SMatthew G. Knepley     PetscInt       Nf;
450834aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
450934aa8a36SMatthew G. Knepley 
451034aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
451134aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
451234aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[0] = useCone;
451334aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[1] = useClosure;
4514e5e52638SMatthew G. Knepley   }
4515e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4516e5e52638SMatthew G. Knepley }
4517e5e52638SMatthew G. Knepley 
4518b0441da4SMatthew G. Knepley /*@
4519b0441da4SMatthew G. Knepley   DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined
4520b0441da4SMatthew G. Knepley 
4521b0441da4SMatthew G. Knepley   Not collective
4522b0441da4SMatthew G. Knepley 
4523b0441da4SMatthew G. Knepley   Input Parameters:
4524b0441da4SMatthew G. Knepley . dm - The DM object
4525b0441da4SMatthew G. Knepley 
4526b0441da4SMatthew G. Knepley   Output Parameter:
4527b0441da4SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
4528b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4529b0441da4SMatthew G. Knepley 
4530b0441da4SMatthew G. Knepley   Notes:
4531b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4532b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4533b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4534b0441da4SMatthew G. Knepley 
4535b0441da4SMatthew G. Knepley   Level: developer
4536b0441da4SMatthew G. Knepley 
4537b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField()
4538b0441da4SMatthew G. Knepley @*/
4539b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure)
4540b0441da4SMatthew G. Knepley {
4541b0441da4SMatthew G. Knepley   PetscInt       Nf;
4542b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4543b0441da4SMatthew G. Knepley 
4544b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4545b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4546b0441da4SMatthew G. Knepley   if (useCone) PetscValidPointer(useCone, 3);
4547b0441da4SMatthew G. Knepley   if (useClosure) PetscValidPointer(useClosure, 4);
4548b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4549b0441da4SMatthew G. Knepley   if (!Nf) {
4550b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4551b0441da4SMatthew G. Knepley   } else {
4552b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4553b0441da4SMatthew G. Knepley   }
4554b0441da4SMatthew G. Knepley   PetscFunctionReturn(0);
4555b0441da4SMatthew G. Knepley }
4556b0441da4SMatthew G. Knepley 
4557b0441da4SMatthew G. Knepley /*@
4558b0441da4SMatthew G. Knepley   DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined
4559b0441da4SMatthew G. Knepley 
4560b0441da4SMatthew G. Knepley   Not collective
4561b0441da4SMatthew G. Knepley 
4562b0441da4SMatthew G. Knepley   Input Parameters:
4563b0441da4SMatthew G. Knepley + dm         - The DM object
4564b0441da4SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
4565b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4566b0441da4SMatthew G. Knepley 
4567b0441da4SMatthew G. Knepley   Notes:
4568b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4569b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4570b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4571b0441da4SMatthew G. Knepley 
4572b0441da4SMatthew G. Knepley   Level: developer
4573b0441da4SMatthew G. Knepley 
4574b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField()
4575b0441da4SMatthew G. Knepley @*/
4576b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure)
4577b0441da4SMatthew G. Knepley {
4578b0441da4SMatthew G. Knepley   PetscInt       Nf;
4579b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4580b0441da4SMatthew G. Knepley 
4581b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4582b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4583b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4584b0441da4SMatthew G. Knepley   if (!Nf) {
4585b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4586b0441da4SMatthew G. Knepley   } else {
4587b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4588b0441da4SMatthew G. Knepley   }
4589b0441da4SMatthew G. Knepley   PetscFunctionReturn(0);
4590b0441da4SMatthew G. Knepley }
4591b0441da4SMatthew G. Knepley 
4592e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew)
4593e5e52638SMatthew G. Knepley {
4594e5e52638SMatthew G. Knepley   DMSpace       *tmpd;
4595e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
4596e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4597e5e52638SMatthew G. Knepley 
4598e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4599e5e52638SMatthew G. Knepley   if (Nds >= NdsNew) PetscFunctionReturn(0);
4600e5e52638SMatthew G. Knepley   ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr);
4601e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s];
4602e5e52638SMatthew G. Knepley   for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL;}
4603e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4604e5e52638SMatthew G. Knepley   dm->Nds   = NdsNew;
4605e5e52638SMatthew G. Knepley   dm->probs = tmpd;
4606e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4607e5e52638SMatthew G. Knepley }
4608e5e52638SMatthew G. Knepley 
4609e5e52638SMatthew G. Knepley /*@
4610e5e52638SMatthew G. Knepley   DMGetNumDS - Get the number of discrete systems in the DM
4611e5e52638SMatthew G. Knepley 
4612e5e52638SMatthew G. Knepley   Not collective
4613e5e52638SMatthew G. Knepley 
4614e5e52638SMatthew G. Knepley   Input Parameter:
4615e5e52638SMatthew G. Knepley . dm - The DM
4616e5e52638SMatthew G. Knepley 
4617e5e52638SMatthew G. Knepley   Output Parameter:
4618e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects
4619e5e52638SMatthew G. Knepley 
4620e5e52638SMatthew G. Knepley   Level: intermediate
4621e5e52638SMatthew G. Knepley 
4622e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS()
4623e5e52638SMatthew G. Knepley @*/
4624e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds)
4625e5e52638SMatthew G. Knepley {
4626e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4627e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4628e5e52638SMatthew G. Knepley   PetscValidPointer(Nds, 2);
4629e5e52638SMatthew G. Knepley   *Nds = dm->Nds;
4630e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4631e5e52638SMatthew G. Knepley }
4632e5e52638SMatthew G. Knepley 
4633e5e52638SMatthew G. Knepley /*@
4634e5e52638SMatthew G. Knepley   DMClearDS - Remove all discrete systems from the DM
4635e5e52638SMatthew G. Knepley 
4636e5e52638SMatthew G. Knepley   Logically collective on DM
4637e5e52638SMatthew G. Knepley 
4638e5e52638SMatthew G. Knepley   Input Parameter:
4639e5e52638SMatthew G. Knepley . dm - The DM
4640e5e52638SMatthew G. Knepley 
4641e5e52638SMatthew G. Knepley   Level: intermediate
4642e5e52638SMatthew G. Knepley 
4643e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField()
4644e5e52638SMatthew G. Knepley @*/
4645e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm)
4646e5e52638SMatthew G. Knepley {
4647e5e52638SMatthew G. Knepley   PetscInt       s;
4648e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4649e5e52638SMatthew G. Knepley 
4650e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4651e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4652e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4653e5e52638SMatthew G. Knepley     ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
4654e5e52638SMatthew G. Knepley     ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr);
4655e5e52638SMatthew G. Knepley   }
4656e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4657e5e52638SMatthew G. Knepley   dm->probs = NULL;
4658e5e52638SMatthew G. Knepley   dm->Nds   = 0;
4659e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4660e5e52638SMatthew G. Knepley }
4661e5e52638SMatthew G. Knepley 
4662e5e52638SMatthew G. Knepley /*@
4663e5e52638SMatthew G. Knepley   DMGetDS - Get the default PetscDS
4664e5e52638SMatthew G. Knepley 
4665e5e52638SMatthew G. Knepley   Not collective
4666e5e52638SMatthew G. Knepley 
4667e5e52638SMatthew G. Knepley   Input Parameter:
4668e5e52638SMatthew G. Knepley . dm    - The DM
4669e5e52638SMatthew G. Knepley 
4670e5e52638SMatthew G. Knepley   Output Parameter:
4671e5e52638SMatthew G. Knepley . prob - The default PetscDS
4672e5e52638SMatthew G. Knepley 
4673e5e52638SMatthew G. Knepley   Level: intermediate
4674e5e52638SMatthew G. Knepley 
4675e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS()
4676e5e52638SMatthew G. Knepley @*/
4677e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob)
4678e5e52638SMatthew G. Knepley {
4679b0143b4dSMatthew G. Knepley   PetscErrorCode ierr;
4680b0143b4dSMatthew G. Knepley 
4681e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4682e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4683e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 2);
4684b0143b4dSMatthew G. Knepley   if (dm->Nds <= 0) {
4685b0143b4dSMatthew G. Knepley     PetscDS ds;
4686b0143b4dSMatthew G. Knepley 
4687b0143b4dSMatthew G. Knepley     ierr = PetscDSCreate(PetscObjectComm((PetscObject) dm), &ds);CHKERRQ(ierr);
4688b0143b4dSMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, ds);CHKERRQ(ierr);
4689b0143b4dSMatthew G. Knepley     ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
4690b0143b4dSMatthew G. Knepley   }
4691b0143b4dSMatthew G. Knepley   *prob = dm->probs[0].ds;
4692e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4693e5e52638SMatthew G. Knepley }
4694e5e52638SMatthew G. Knepley 
4695e5e52638SMatthew G. Knepley /*@
4696e5e52638SMatthew G. Knepley   DMGetCellDS - Get the PetscDS defined on a given cell
4697e5e52638SMatthew G. Knepley 
4698e5e52638SMatthew G. Knepley   Not collective
4699e5e52638SMatthew G. Knepley 
4700e5e52638SMatthew G. Knepley   Input Parameters:
4701e5e52638SMatthew G. Knepley + dm    - The DM
4702e5e52638SMatthew G. Knepley - point - Cell for the DS
4703e5e52638SMatthew G. Knepley 
4704e5e52638SMatthew G. Knepley   Output Parameter:
4705e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell
4706e5e52638SMatthew G. Knepley 
4707e5e52638SMatthew G. Knepley   Level: developer
4708e5e52638SMatthew G. Knepley 
4709b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS()
4710e5e52638SMatthew G. Knepley @*/
4711e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob)
4712e5e52638SMatthew G. Knepley {
4713e5e52638SMatthew G. Knepley   PetscDS        probDef = NULL;
4714e5e52638SMatthew G. Knepley   PetscInt       s;
4715e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4716e5e52638SMatthew G. Knepley 
4717e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4718e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4719e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 3);
4720e5e52638SMatthew G. Knepley   *prob = NULL;
4721e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4722e5e52638SMatthew G. Knepley     PetscInt val;
4723e5e52638SMatthew G. Knepley 
4724e5e52638SMatthew G. Knepley     if (!dm->probs[s].label) {probDef = dm->probs[s].ds;}
4725e5e52638SMatthew G. Knepley     else {
4726e5e52638SMatthew G. Knepley       ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr);
4727e5e52638SMatthew G. Knepley       if (val >= 0) {*prob = dm->probs[s].ds; break;}
4728e5e52638SMatthew G. Knepley     }
4729e5e52638SMatthew G. Knepley   }
4730e5e52638SMatthew G. Knepley   if (!*prob) *prob = probDef;
4731e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4732e5e52638SMatthew G. Knepley }
4733e5e52638SMatthew G. Knepley 
4734e5e52638SMatthew G. Knepley /*@
4735e5e52638SMatthew G. Knepley   DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel
4736e5e52638SMatthew G. Knepley 
4737e5e52638SMatthew G. Knepley   Not collective
4738e5e52638SMatthew G. Knepley 
4739e5e52638SMatthew G. Knepley   Input Parameters:
4740e5e52638SMatthew G. Knepley + dm    - The DM
4741e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh
4742e5e52638SMatthew G. Knepley 
4743e5e52638SMatthew G. Knepley   Output Parameter:
4744e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given region
4745e5e52638SMatthew G. Knepley 
4746e5e52638SMatthew G. Knepley   Note: If the label is missing, this function returns an error
4747e5e52638SMatthew G. Knepley 
4748e5e52638SMatthew G. Knepley   Level: advanced
4749e5e52638SMatthew G. Knepley 
4750e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
4751e5e52638SMatthew G. Knepley @*/
4752e5e52638SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, PetscDS *ds)
4753e5e52638SMatthew G. Knepley {
4754e5e52638SMatthew G. Knepley   PetscInt Nds = dm->Nds, s;
4755e5e52638SMatthew G. Knepley 
4756e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4757e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4758e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
4759e5e52638SMatthew G. Knepley   PetscValidPointer(ds, 3);
4760e5e52638SMatthew G. Knepley   *ds = NULL;
4761e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
4762e5e52638SMatthew G. Knepley     if (dm->probs[s].label == label) {*ds = dm->probs[s].ds; PetscFunctionReturn(0);}
4763e5e52638SMatthew G. Knepley   }
47642df9ee95SMatthew G. Knepley   PetscFunctionReturn(0);
4765e5e52638SMatthew G. Knepley }
4766e5e52638SMatthew G. Knepley 
4767e5e52638SMatthew G. Knepley /*@
4768e5e52638SMatthew G. Knepley   DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number
4769e5e52638SMatthew G. Knepley 
4770e5e52638SMatthew G. Knepley   Not collective
4771e5e52638SMatthew G. Knepley 
4772e5e52638SMatthew G. Knepley   Input Parameters:
4773e5e52638SMatthew G. Knepley + dm  - The DM
4774e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds)
4775e5e52638SMatthew G. Knepley 
4776e5e52638SMatthew G. Knepley   Output Parameters:
4777e5e52638SMatthew G. Knepley + label - The region label
4778e5e52638SMatthew G. Knepley - prob  - The PetscDS defined on the given region
4779e5e52638SMatthew G. Knepley 
4780e5e52638SMatthew G. Knepley   Level: advanced
4781e5e52638SMatthew G. Knepley 
4782e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
4783e5e52638SMatthew G. Knepley @*/
4784e5e52638SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, PetscDS *ds)
4785e5e52638SMatthew G. Knepley {
4786e5e52638SMatthew G. Knepley   PetscInt       Nds;
4787e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4788e5e52638SMatthew G. Knepley 
4789e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4790e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4791e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
4792e5e52638SMatthew G. Knepley   if ((num < 0) || (num >= Nds)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Region number %D is not in [0, %D)", num, Nds);
4793e5e52638SMatthew G. Knepley   if (label) {
4794e5e52638SMatthew G. Knepley     PetscValidPointer(label, 3);
4795e5e52638SMatthew G. Knepley     *label = dm->probs[num].label;
4796e5e52638SMatthew G. Knepley   }
4797e5e52638SMatthew G. Knepley   if (ds) {
4798e5e52638SMatthew G. Knepley     PetscValidPointer(ds, 4);
4799e5e52638SMatthew G. Knepley     *ds = dm->probs[num].ds;
4800e5e52638SMatthew G. Knepley   }
4801e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4802e5e52638SMatthew G. Knepley }
4803e5e52638SMatthew G. Knepley 
4804e5e52638SMatthew G. Knepley /*@
4805e5e52638SMatthew G. Knepley   DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel
4806e5e52638SMatthew G. Knepley 
4807e5e52638SMatthew G. Knepley   Collective on DM
4808e5e52638SMatthew G. Knepley 
4809e5e52638SMatthew G. Knepley   Input Parameters:
4810e5e52638SMatthew G. Knepley + dm    - The DM
4811e5e52638SMatthew G. Knepley . label - The DMLabel defining the mesh region, or NULL for the entire mesh
4812e5e52638SMatthew G. Knepley - prob - The PetscDS defined on the given cell
4813e5e52638SMatthew G. Knepley 
4814e5e52638SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM.
4815e5e52638SMatthew G. Knepley 
4816e5e52638SMatthew G. Knepley   Level: advanced
4817e5e52638SMatthew G. Knepley 
4818e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMGetDS(), DMGetCellDS()
4819e5e52638SMatthew G. Knepley @*/
4820e5e52638SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, PetscDS ds)
4821e5e52638SMatthew G. Knepley {
4822e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
4823e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4824e5e52638SMatthew G. Knepley 
4825e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4826e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4827e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
4828e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3);
4829e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
4830e5e52638SMatthew G. Knepley     if (dm->probs[s].label == label) {
4831e5e52638SMatthew G. Knepley       dm->probs[s].ds = ds;
4832e5e52638SMatthew G. Knepley       PetscFunctionReturn(0);
4833e5e52638SMatthew G. Knepley     }
4834e5e52638SMatthew G. Knepley   }
48351b5e6740SSatish Balay   ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr);
4836e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
4837e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr);
4838e5e52638SMatthew G. Knepley   if (!label) {
4839e5e52638SMatthew G. Knepley     /* Put the NULL label at the front, so it is returned as the default */
4840e5e52638SMatthew G. Knepley     for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s];
4841e5e52638SMatthew G. Knepley     Nds = 0;
4842e5e52638SMatthew G. Knepley   }
4843e5e52638SMatthew G. Knepley   dm->probs[Nds].label = label;
4844e5e52638SMatthew G. Knepley   dm->probs[Nds].ds    = ds;
4845e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4846e5e52638SMatthew G. Knepley }
4847e5e52638SMatthew G. Knepley 
4848e5e52638SMatthew G. Knepley /*@
4849e5e52638SMatthew G. Knepley   DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM
4850e5e52638SMatthew G. Knepley 
4851e5e52638SMatthew G. Knepley   Collective on DM
4852e5e52638SMatthew G. Knepley 
4853e5e52638SMatthew G. Knepley   Input Parameter:
4854e5e52638SMatthew G. Knepley . dm - The DM
4855e5e52638SMatthew G. Knepley 
4856e5e52638SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM.
4857e5e52638SMatthew G. Knepley 
4858e5e52638SMatthew G. Knepley   Level: intermediate
4859e5e52638SMatthew G. Knepley 
4860e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
4861e5e52638SMatthew G. Knepley @*/
4862e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm)
4863e5e52638SMatthew G. Knepley {
4864e5e52638SMatthew G. Knepley   MPI_Comm       comm;
4865e5e52638SMatthew G. Knepley   PetscDS        prob, probh = NULL;
48660122748bSMatthew G. Knepley   PetscInt       dimEmbed, f, s, field = 0, fieldh = 0;
4867e5e52638SMatthew G. Knepley   PetscBool      doSetup = PETSC_TRUE;
4868e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4869e5e52638SMatthew G. Knepley 
4870e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4871e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4872e5e52638SMatthew G. Knepley   if (!dm->fields) PetscFunctionReturn(0);
4873e5e52638SMatthew G. Knepley   /* Can only handle two label cases right now:
4874e5e52638SMatthew G. Knepley    1) NULL
4875e5e52638SMatthew G. Knepley    2) Hybrid cells
4876e5e52638SMatthew G. Knepley   */
4877e5e52638SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr);
4878e5e52638SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr);
4879e5e52638SMatthew G. Knepley   /* Create default DS */
4880e5e52638SMatthew G. Knepley   ierr = DMGetRegionDS(dm, NULL, &prob);CHKERRQ(ierr);
48812df9ee95SMatthew G. Knepley   if (!prob) {
48822df9ee95SMatthew G. Knepley     ierr = PetscDSCreate(comm, &prob);CHKERRQ(ierr);
48832df9ee95SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, prob);CHKERRQ(ierr);
48842df9ee95SMatthew G. Knepley     ierr = PetscDSDestroy(&prob);CHKERRQ(ierr);
48852df9ee95SMatthew G. Knepley     ierr = DMGetRegionDS(dm, NULL, &prob);CHKERRQ(ierr);
48862df9ee95SMatthew G. Knepley   }
4887e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(prob, dimEmbed);CHKERRQ(ierr);
4888e5e52638SMatthew G. Knepley   /* Optionally create hybrid DS */
4889e5e52638SMatthew G. Knepley   for (f = 0; f < dm->Nf; ++f) {
4890e5e52638SMatthew G. Knepley     DMLabel  label = dm->fields[f].label;
4891e5e52638SMatthew G. Knepley     PetscInt lStart, lEnd;
4892e5e52638SMatthew G. Knepley 
4893e5e52638SMatthew G. Knepley     if (label) {
48940122748bSMatthew G. Knepley       DM       plex;
48950122748bSMatthew G. Knepley       PetscInt depth, pMax[4];
48960122748bSMatthew G. Knepley 
48970122748bSMatthew G. Knepley       ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr);
48980122748bSMatthew G. Knepley       ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr);
48990122748bSMatthew G. Knepley       ierr = DMPlexGetHybridBounds(plex, depth >= 0 ? &pMax[depth] : NULL, depth>1 ? &pMax[depth-1] : NULL, depth>2 ? &pMax[1] : NULL, &pMax[0]);CHKERRQ(ierr);
49000122748bSMatthew G. Knepley       ierr = DMDestroy(&plex);CHKERRQ(ierr);
49010122748bSMatthew G. Knepley 
4902e5e52638SMatthew G. Knepley       ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr);
4903e5e52638SMatthew G. Knepley       if (lStart < pMax[depth]) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only support labels over hybrid cells right now");
4904e5e52638SMatthew G. Knepley       ierr = PetscDSCreate(comm, &probh);CHKERRQ(ierr);
4905e5e52638SMatthew G. Knepley       ierr = DMSetRegionDS(dm, label, probh);CHKERRQ(ierr);
4906e5e52638SMatthew G. Knepley       ierr = PetscDSSetHybrid(probh, PETSC_TRUE);CHKERRQ(ierr);
4907e5e52638SMatthew G. Knepley       ierr = PetscDSSetCoordinateDimension(probh, dimEmbed);CHKERRQ(ierr);
4908e5e52638SMatthew G. Knepley       break;
4909e5e52638SMatthew G. Knepley     }
4910e5e52638SMatthew G. Knepley   }
4911e5e52638SMatthew G. Knepley   /* Set fields in DSes */
4912e5e52638SMatthew G. Knepley   for (f = 0; f < dm->Nf; ++f) {
4913e5e52638SMatthew G. Knepley     DMLabel     label = dm->fields[f].label;
4914e5e52638SMatthew G. Knepley     PetscObject disc  = dm->fields[f].disc;
4915e5e52638SMatthew G. Knepley 
4916e5e52638SMatthew G. Knepley     if (!label) {
4917e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(prob,  field++,  disc);CHKERRQ(ierr);
4918e5e52638SMatthew G. Knepley       if (probh) {
4919e5e52638SMatthew G. Knepley         PetscFE subfe;
4920e5e52638SMatthew G. Knepley 
4921e5e52638SMatthew G. Knepley         ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, &subfe);CHKERRQ(ierr);
4922e5e52638SMatthew G. Knepley         ierr = PetscDSSetDiscretization(probh, fieldh++, (PetscObject) subfe);CHKERRQ(ierr);
4923e5e52638SMatthew G. Knepley       }
4924e5e52638SMatthew G. Knepley     } else {
4925e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(probh, fieldh++, disc);CHKERRQ(ierr);
4926e5e52638SMatthew G. Knepley     }
4927e5e52638SMatthew G. Knepley     /* We allow people to have placeholder fields and construct the Section by hand */
4928e5e52638SMatthew G. Knepley     {
4929e5e52638SMatthew G. Knepley       PetscClassId id;
4930e5e52638SMatthew G. Knepley 
4931e5e52638SMatthew G. Knepley       ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
4932e5e52638SMatthew G. Knepley       if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE;
4933e5e52638SMatthew G. Knepley     }
4934e5e52638SMatthew G. Knepley   }
4935e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&probh);CHKERRQ(ierr);
4936e5e52638SMatthew G. Knepley   /* Setup DSes */
4937e5e52638SMatthew G. Knepley   if (doSetup) {
4938e5e52638SMatthew G. Knepley     for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);}
4939e5e52638SMatthew G. Knepley   }
4940e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4941e5e52638SMatthew G. Knepley }
4942e5e52638SMatthew G. Knepley 
4943e5e52638SMatthew G. Knepley /*@
4944e5e52638SMatthew G. Knepley   DMCopyDS - Copy the discrete systems for the DM into another DM
4945e5e52638SMatthew G. Knepley 
4946e5e52638SMatthew G. Knepley   Collective on DM
4947e5e52638SMatthew G. Knepley 
4948e5e52638SMatthew G. Knepley   Input Parameter:
4949e5e52638SMatthew G. Knepley . dm - The DM
4950e5e52638SMatthew G. Knepley 
4951e5e52638SMatthew G. Knepley   Output Parameter:
4952e5e52638SMatthew G. Knepley . newdm - The DM
4953e5e52638SMatthew G. Knepley 
4954e5e52638SMatthew G. Knepley   Level: advanced
4955e5e52638SMatthew G. Knepley 
4956e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
4957e5e52638SMatthew G. Knepley @*/
4958e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm)
4959e5e52638SMatthew G. Knepley {
4960e5e52638SMatthew G. Knepley   PetscInt       Nds, s;
4961e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4962e5e52638SMatthew G. Knepley 
4963e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4964e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
4965e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
4966e5e52638SMatthew G. Knepley   ierr = DMClearDS(newdm);CHKERRQ(ierr);
4967e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
4968e5e52638SMatthew G. Knepley     DMLabel label;
4969e5e52638SMatthew G. Knepley     PetscDS ds;
4970e5e52638SMatthew G. Knepley 
4971e5e52638SMatthew G. Knepley     ierr = DMGetRegionNumDS(dm, s, &label, &ds);CHKERRQ(ierr);
4972e5e52638SMatthew G. Knepley     ierr = DMSetRegionDS(newdm, label, ds);CHKERRQ(ierr);
4973e5e52638SMatthew G. Knepley   }
4974e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4975e5e52638SMatthew G. Knepley }
4976e5e52638SMatthew G. Knepley 
4977e5e52638SMatthew G. Knepley /*@
4978e5e52638SMatthew G. Knepley   DMCopyDisc - Copy the fields and discrete systems for the DM into another DM
4979e5e52638SMatthew G. Knepley 
4980e5e52638SMatthew G. Knepley   Collective on DM
4981e5e52638SMatthew G. Knepley 
4982e5e52638SMatthew G. Knepley   Input Parameter:
4983e5e52638SMatthew G. Knepley . dm - The DM
4984e5e52638SMatthew G. Knepley 
4985e5e52638SMatthew G. Knepley   Output Parameter:
4986e5e52638SMatthew G. Knepley . newdm - The DM
4987e5e52638SMatthew G. Knepley 
4988e5e52638SMatthew G. Knepley   Level: advanced
4989e5e52638SMatthew G. Knepley 
4990e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS()
4991e5e52638SMatthew G. Knepley @*/
4992e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm)
4993e5e52638SMatthew G. Knepley {
4994e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4995e5e52638SMatthew G. Knepley 
4996e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4997e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
4998e5e52638SMatthew G. Knepley   ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr);
4999e5e52638SMatthew G. Knepley   ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr);
5000e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5001e5e52638SMatthew G. Knepley }
5002e5e52638SMatthew G. Knepley 
5003b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx)
5004b64e0483SPeter Brune {
5005b64e0483SPeter Brune   DM dm_coord,dmc_coord;
5006b64e0483SPeter Brune   PetscErrorCode ierr;
5007b64e0483SPeter Brune   Vec coords,ccoords;
50086dbf9973SLawrence Mitchell   Mat inject;
5009b64e0483SPeter Brune   PetscFunctionBegin;
5010b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
5011b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr);
5012b64e0483SPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
5013b64e0483SPeter Brune   ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr);
5014b64e0483SPeter Brune   if (coords && !ccoords) {
5015b64e0483SPeter Brune     ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr);
50166668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
50176dbf9973SLawrence Mitchell     ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr);
50182adcf181SLawrence Mitchell     ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr);
50196dbf9973SLawrence Mitchell     ierr = MatDestroy(&inject);CHKERRQ(ierr);
5020b64e0483SPeter Brune     ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr);
5021b64e0483SPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
5022b64e0483SPeter Brune   }
5023b64e0483SPeter Brune   PetscFunctionReturn(0);
5024b64e0483SPeter Brune }
5025b64e0483SPeter Brune 
502603dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx)
502703dadc2fSPeter Brune {
502803dadc2fSPeter Brune   DM dm_coord,subdm_coord;
502903dadc2fSPeter Brune   PetscErrorCode ierr;
503003dadc2fSPeter Brune   Vec coords,ccoords,clcoords;
503103dadc2fSPeter Brune   VecScatter *scat_i,*scat_g;
503203dadc2fSPeter Brune   PetscFunctionBegin;
503303dadc2fSPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
503403dadc2fSPeter Brune   ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr);
503503dadc2fSPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
503603dadc2fSPeter Brune   ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr);
503703dadc2fSPeter Brune   if (coords && !ccoords) {
503803dadc2fSPeter Brune     ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr);
50396668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
504003dadc2fSPeter Brune     ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr);
504124640c55SToby Isaac     ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr);
504203dadc2fSPeter Brune     ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr);
504303dadc2fSPeter Brune     ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
504403dadc2fSPeter Brune     ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
504503dadc2fSPeter Brune     ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
504603dadc2fSPeter Brune     ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
504703dadc2fSPeter Brune     ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr);
504803dadc2fSPeter Brune     ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr);
504903dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr);
505003dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr);
505103dadc2fSPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
505203dadc2fSPeter Brune     ierr = VecDestroy(&clcoords);CHKERRQ(ierr);
505303dadc2fSPeter Brune     ierr = PetscFree(scat_i);CHKERRQ(ierr);
505403dadc2fSPeter Brune     ierr = PetscFree(scat_g);CHKERRQ(ierr);
505503dadc2fSPeter Brune   }
505603dadc2fSPeter Brune   PetscFunctionReturn(0);
505703dadc2fSPeter Brune }
505803dadc2fSPeter Brune 
5059c73cfb54SMatthew G. Knepley /*@
5060c73cfb54SMatthew G. Knepley   DMGetDimension - Return the topological dimension of the DM
5061c73cfb54SMatthew G. Knepley 
5062c73cfb54SMatthew G. Knepley   Not collective
5063c73cfb54SMatthew G. Knepley 
5064c73cfb54SMatthew G. Knepley   Input Parameter:
5065c73cfb54SMatthew G. Knepley . dm - The DM
5066c73cfb54SMatthew G. Knepley 
5067c73cfb54SMatthew G. Knepley   Output Parameter:
5068c73cfb54SMatthew G. Knepley . dim - The topological dimension
5069c73cfb54SMatthew G. Knepley 
5070c73cfb54SMatthew G. Knepley   Level: beginner
5071c73cfb54SMatthew G. Knepley 
5072c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate()
5073c73cfb54SMatthew G. Knepley @*/
5074c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim)
5075c73cfb54SMatthew G. Knepley {
5076c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5077c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5078c73cfb54SMatthew G. Knepley   PetscValidPointer(dim, 2);
5079c73cfb54SMatthew G. Knepley   *dim = dm->dim;
5080c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5081c73cfb54SMatthew G. Knepley }
5082c73cfb54SMatthew G. Knepley 
5083c73cfb54SMatthew G. Knepley /*@
5084c73cfb54SMatthew G. Knepley   DMSetDimension - Set the topological dimension of the DM
5085c73cfb54SMatthew G. Knepley 
5086c73cfb54SMatthew G. Knepley   Collective on dm
5087c73cfb54SMatthew G. Knepley 
5088c73cfb54SMatthew G. Knepley   Input Parameters:
5089c73cfb54SMatthew G. Knepley + dm - The DM
5090c73cfb54SMatthew G. Knepley - dim - The topological dimension
5091c73cfb54SMatthew G. Knepley 
5092c73cfb54SMatthew G. Knepley   Level: beginner
5093c73cfb54SMatthew G. Knepley 
5094c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate()
5095c73cfb54SMatthew G. Knepley @*/
5096c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim)
5097c73cfb54SMatthew G. Knepley {
5098e5e52638SMatthew G. Knepley   PetscDS        ds;
5099f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5100f17e8794SMatthew G. Knepley 
5101c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5102c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5103c73cfb54SMatthew G. Knepley   PetscValidLogicalCollectiveInt(dm, dim, 2);
5104c73cfb54SMatthew G. Knepley   dm->dim = dim;
5105e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5106e5e52638SMatthew G. Knepley   if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);}
5107c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5108c73cfb54SMatthew G. Knepley }
5109c73cfb54SMatthew G. Knepley 
5110793f3fe5SMatthew G. Knepley /*@
5111793f3fe5SMatthew G. Knepley   DMGetDimPoints - Get the half-open interval for all points of a given dimension
5112793f3fe5SMatthew G. Knepley 
5113793f3fe5SMatthew G. Knepley   Collective on DM
5114793f3fe5SMatthew G. Knepley 
5115793f3fe5SMatthew G. Knepley   Input Parameters:
5116793f3fe5SMatthew G. Knepley + dm - the DM
5117793f3fe5SMatthew G. Knepley - dim - the dimension
5118793f3fe5SMatthew G. Knepley 
5119793f3fe5SMatthew G. Knepley   Output Parameters:
5120793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension
5121793f3fe5SMatthew G. Knepley . pEnd - The first point following points of the given dimension
5122793f3fe5SMatthew G. Knepley 
5123793f3fe5SMatthew G. Knepley   Note:
5124793f3fe5SMatthew G. Knepley   The points are vertices in the Hasse diagram encoding the topology. This is explained in
5125ebfe4b0dSMatthew G. Knepley   http://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme,
5126793f3fe5SMatthew G. Knepley   then the interval is empty.
5127793f3fe5SMatthew G. Knepley 
5128793f3fe5SMatthew G. Knepley   Level: intermediate
5129793f3fe5SMatthew G. Knepley 
5130793f3fe5SMatthew G. Knepley .keywords: point, Hasse Diagram, dimension
5131793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum()
5132793f3fe5SMatthew G. Knepley @*/
5133793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
5134793f3fe5SMatthew G. Knepley {
5135793f3fe5SMatthew G. Knepley   PetscInt       d;
5136793f3fe5SMatthew G. Knepley   PetscErrorCode ierr;
5137793f3fe5SMatthew G. Knepley 
5138793f3fe5SMatthew G. Knepley   PetscFunctionBegin;
5139793f3fe5SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5140793f3fe5SMatthew G. Knepley   ierr = DMGetDimension(dm, &d);CHKERRQ(ierr);
5141793f3fe5SMatthew G. Knepley   if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d);
5142793f3fe5SMatthew G. Knepley   ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr);
5143793f3fe5SMatthew G. Knepley   PetscFunctionReturn(0);
5144793f3fe5SMatthew G. Knepley }
5145793f3fe5SMatthew G. Knepley 
51466636e97aSMatthew G Knepley /*@
51476636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
51486636e97aSMatthew G Knepley 
51496636e97aSMatthew G Knepley   Collective on DM
51506636e97aSMatthew G Knepley 
51516636e97aSMatthew G Knepley   Input Parameters:
51526636e97aSMatthew G Knepley + dm - the DM
51536636e97aSMatthew G Knepley - c - coordinate vector
51546636e97aSMatthew G Knepley 
51552dd40e9bSPatrick Sanan   Notes:
51562dd40e9bSPatrick Sanan   The coordinates do include those for ghost points, which are in the local vector.
51572dd40e9bSPatrick Sanan 
51582dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
51596636e97aSMatthew G Knepley 
51606636e97aSMatthew G Knepley   Level: intermediate
51616636e97aSMatthew G Knepley 
51626636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
51632dd40e9bSPatrick Sanan .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
51646636e97aSMatthew G Knepley @*/
51656636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
51666636e97aSMatthew G Knepley {
51676636e97aSMatthew G Knepley   PetscErrorCode ierr;
51686636e97aSMatthew G Knepley 
51696636e97aSMatthew G Knepley   PetscFunctionBegin;
51706636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
51716636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
51726636e97aSMatthew G Knepley   ierr            = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
51736636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
51746636e97aSMatthew G Knepley   dm->coordinates = c;
51756636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
5176b64e0483SPeter Brune   ierr            = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
517703dadc2fSPeter Brune   ierr            = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
51786636e97aSMatthew G Knepley   PetscFunctionReturn(0);
51796636e97aSMatthew G Knepley }
51806636e97aSMatthew G Knepley 
51816636e97aSMatthew G Knepley /*@
51826636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
51836636e97aSMatthew G Knepley 
51847058e716SVaclav Hapla   Not collective
51856636e97aSMatthew G Knepley 
51866636e97aSMatthew G Knepley    Input Parameters:
51876636e97aSMatthew G Knepley +  dm - the DM
51886636e97aSMatthew G Knepley -  c - coordinate vector
51896636e97aSMatthew G Knepley 
51902dd40e9bSPatrick Sanan   Notes:
51916636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
51926636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
51936636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
51946636e97aSMatthew G Knepley 
51952dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
51962dd40e9bSPatrick Sanan 
51976636e97aSMatthew G Knepley   Level: intermediate
51986636e97aSMatthew G Knepley 
51996636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
52006636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
52016636e97aSMatthew G Knepley @*/
52026636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
52036636e97aSMatthew G Knepley {
52046636e97aSMatthew G Knepley   PetscErrorCode ierr;
52056636e97aSMatthew G Knepley 
52066636e97aSMatthew G Knepley   PetscFunctionBegin;
52076636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
52086636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
52096636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
52106636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
52118865f1eaSKarl Rupp 
52126636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
52138865f1eaSKarl Rupp 
52146636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
52156636e97aSMatthew G Knepley   PetscFunctionReturn(0);
52166636e97aSMatthew G Knepley }
52176636e97aSMatthew G Knepley 
52186636e97aSMatthew G Knepley /*@
52196636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
52206636e97aSMatthew G Knepley 
5221c4a54dccSVaclav Hapla   Collective on DM
52226636e97aSMatthew G Knepley 
52236636e97aSMatthew G Knepley   Input Parameter:
52246636e97aSMatthew G Knepley . dm - the DM
52256636e97aSMatthew G Knepley 
52266636e97aSMatthew G Knepley   Output Parameter:
52276636e97aSMatthew G Knepley . c - global coordinate vector
52286636e97aSMatthew G Knepley 
52296636e97aSMatthew G Knepley   Note:
52306636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
52316636e97aSMatthew G Knepley 
52326636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
52336636e97aSMatthew G Knepley 
52346636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
52356636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
52366636e97aSMatthew G Knepley 
52376636e97aSMatthew G Knepley   Level: intermediate
52386636e97aSMatthew G Knepley 
52396636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
52406636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
52416636e97aSMatthew G Knepley @*/
52426636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
52436636e97aSMatthew G Knepley {
52446636e97aSMatthew G Knepley   PetscErrorCode ierr;
52456636e97aSMatthew G Knepley 
52466636e97aSMatthew G Knepley   PetscFunctionBegin;
52476636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
52486636e97aSMatthew G Knepley   PetscValidPointer(c,2);
52491f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
52500298fd71SBarry Smith     DM cdm = NULL;
52516636e97aSMatthew G Knepley 
52526636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
52536636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
52546636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
52556636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
52566636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
52576636e97aSMatthew G Knepley   }
52586636e97aSMatthew G Knepley   *c = dm->coordinates;
52596636e97aSMatthew G Knepley   PetscFunctionReturn(0);
52606636e97aSMatthew G Knepley }
52616636e97aSMatthew G Knepley 
52626636e97aSMatthew G Knepley /*@
526381e9a530SVaclav Hapla   DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards.
526481e9a530SVaclav Hapla 
526581e9a530SVaclav Hapla   Collective on DM
526681e9a530SVaclav Hapla 
526781e9a530SVaclav Hapla   Input Parameter:
526881e9a530SVaclav Hapla . dm - the DM
526981e9a530SVaclav Hapla 
527081e9a530SVaclav Hapla   Level: advanced
527181e9a530SVaclav Hapla 
527281e9a530SVaclav Hapla .keywords: distributed array, get, corners, nodes, local indices, coordinates
527381e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective()
527481e9a530SVaclav Hapla @*/
527581e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm)
527681e9a530SVaclav Hapla {
527781e9a530SVaclav Hapla   DM cdm = NULL;
527881e9a530SVaclav Hapla   PetscErrorCode ierr;
527981e9a530SVaclav Hapla 
528081e9a530SVaclav Hapla   PetscFunctionBegin;
528181e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
528281e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) {
528381e9a530SVaclav Hapla     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
528481e9a530SVaclav Hapla     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
528581e9a530SVaclav Hapla     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
528681e9a530SVaclav Hapla     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
528781e9a530SVaclav Hapla     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
528881e9a530SVaclav Hapla   }
528981e9a530SVaclav Hapla   PetscFunctionReturn(0);
529081e9a530SVaclav Hapla }
529181e9a530SVaclav Hapla 
529281e9a530SVaclav Hapla /*@
52936636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
52946636e97aSMatthew G Knepley 
52956636e97aSMatthew G Knepley   Collective on DM
52966636e97aSMatthew G Knepley 
52976636e97aSMatthew G Knepley   Input Parameter:
52986636e97aSMatthew G Knepley . dm - the DM
52996636e97aSMatthew G Knepley 
53006636e97aSMatthew G Knepley   Output Parameter:
53016636e97aSMatthew G Knepley . c - coordinate vector
53026636e97aSMatthew G Knepley 
53036636e97aSMatthew G Knepley   Note:
53046636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
53056636e97aSMatthew G Knepley 
53066636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
53076636e97aSMatthew G Knepley 
53086636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
53096636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
53106636e97aSMatthew G Knepley 
53116636e97aSMatthew G Knepley   Level: intermediate
53126636e97aSMatthew G Knepley 
53136636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
531481e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective()
53156636e97aSMatthew G Knepley @*/
53166636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
53176636e97aSMatthew G Knepley {
53186636e97aSMatthew G Knepley   PetscErrorCode ierr;
53196636e97aSMatthew G Knepley 
53206636e97aSMatthew G Knepley   PetscFunctionBegin;
53216636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
53226636e97aSMatthew G Knepley   PetscValidPointer(c,2);
532381e9a530SVaclav Hapla   ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr);
53246636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
53256636e97aSMatthew G Knepley   PetscFunctionReturn(0);
53266636e97aSMatthew G Knepley }
53276636e97aSMatthew G Knepley 
532881e9a530SVaclav Hapla /*@
532981e9a530SVaclav Hapla   DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called.
533081e9a530SVaclav Hapla 
533181e9a530SVaclav Hapla   Not collective
533281e9a530SVaclav Hapla 
533381e9a530SVaclav Hapla   Input Parameter:
533481e9a530SVaclav Hapla . dm - the DM
533581e9a530SVaclav Hapla 
533681e9a530SVaclav Hapla   Output Parameter:
533781e9a530SVaclav Hapla . c - coordinate vector
533881e9a530SVaclav Hapla 
533981e9a530SVaclav Hapla   Level: advanced
534081e9a530SVaclav Hapla 
534181e9a530SVaclav Hapla .keywords: distributed array, get, corners, nodes, local indices, coordinates
534281e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
534381e9a530SVaclav Hapla @*/
534481e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c)
534581e9a530SVaclav Hapla {
534681e9a530SVaclav Hapla   PetscFunctionBegin;
534781e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
534881e9a530SVaclav Hapla   PetscValidPointer(c,2);
534981e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called");
53506636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
53516636e97aSMatthew G Knepley   PetscFunctionReturn(0);
53526636e97aSMatthew G Knepley }
53536636e97aSMatthew G Knepley 
53542db98f8dSVaclav Hapla /*@
53552db98f8dSVaclav Hapla   DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout.
53562db98f8dSVaclav Hapla 
53572db98f8dSVaclav Hapla   Not collective
53582db98f8dSVaclav Hapla 
53592db98f8dSVaclav Hapla   Input Parameter:
53602db98f8dSVaclav Hapla + dm - the DM
53612db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned
53622db98f8dSVaclav Hapla 
53632db98f8dSVaclav Hapla   Output Parameter:
53642db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates
53652db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p
53662db98f8dSVaclav Hapla 
53672db98f8dSVaclav Hapla   Note:
53682db98f8dSVaclav Hapla   DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective.
53692db98f8dSVaclav Hapla 
53702db98f8dSVaclav Hapla   This creates a new vector, so the user SHOULD destroy this vector
53712db98f8dSVaclav Hapla 
53722db98f8dSVaclav Hapla   Each process has the local and ghost coordinates
53732db98f8dSVaclav Hapla 
53742db98f8dSVaclav Hapla   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
53752db98f8dSVaclav Hapla   and (x_0,y_0,z_0,x_1,y_1,z_1...)
53762db98f8dSVaclav Hapla 
53772db98f8dSVaclav Hapla   Level: advanced
53782db98f8dSVaclav Hapla 
53792db98f8dSVaclav Hapla .keywords: distributed array, get, corners, nodes, local indices, coordinates
53802db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
53812db98f8dSVaclav Hapla @*/
53822db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord)
53832db98f8dSVaclav Hapla {
53842db98f8dSVaclav Hapla   PetscSection        cs, newcs;
53852db98f8dSVaclav Hapla   Vec                 coords;
53862db98f8dSVaclav Hapla   const PetscScalar   *arr;
53872db98f8dSVaclav Hapla   PetscScalar         *newarr=NULL;
53882db98f8dSVaclav Hapla   PetscInt            n;
53892db98f8dSVaclav Hapla   PetscErrorCode      ierr;
53902db98f8dSVaclav Hapla 
53912db98f8dSVaclav Hapla   PetscFunctionBegin;
53922db98f8dSVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
53932db98f8dSVaclav Hapla   PetscValidHeaderSpecific(p, IS_CLASSID, 2);
53942db98f8dSVaclav Hapla   if (pCoordSection) PetscValidPointer(pCoordSection, 3);
53952db98f8dSVaclav Hapla   if (pCoord) PetscValidPointer(pCoord, 4);
53962db98f8dSVaclav Hapla   if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set");
53972db98f8dSVaclav Hapla   if (!dm->coordinateDM || !dm->coordinateDM->defaultSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported");
53982db98f8dSVaclav Hapla   cs = dm->coordinateDM->defaultSection;
53992db98f8dSVaclav Hapla   coords = dm->coordinatesLocal;
54002db98f8dSVaclav Hapla   ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr);
54012db98f8dSVaclav Hapla   ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr);
54022db98f8dSVaclav Hapla   ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr);
54032db98f8dSVaclav Hapla   if (pCoord) {
54042db98f8dSVaclav Hapla     ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr);
54052db98f8dSVaclav Hapla     /* set array in two steps to mimic PETSC_OWN_POINTER */
54062db98f8dSVaclav Hapla     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr);
54072db98f8dSVaclav Hapla     ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr);
5408ad9ac99dSVaclav Hapla   } else {
5409ad9ac99dSVaclav Hapla     ierr = PetscFree(newarr);CHKERRQ(ierr);
54102db98f8dSVaclav Hapla   }
5411ad9ac99dSVaclav Hapla   if (pCoordSection) {*pCoordSection = newcs;}
5412ad9ac99dSVaclav Hapla   else               {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);}
54132db98f8dSVaclav Hapla   PetscFunctionReturn(0);
54142db98f8dSVaclav Hapla }
54152db98f8dSVaclav Hapla 
5416f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field)
5417f19dbd58SToby Isaac {
5418f19dbd58SToby Isaac   PetscErrorCode ierr;
5419f19dbd58SToby Isaac 
5420f19dbd58SToby Isaac   PetscFunctionBegin;
5421f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5422f19dbd58SToby Isaac   PetscValidPointer(field,2);
5423f19dbd58SToby Isaac   if (!dm->coordinateField) {
5424f19dbd58SToby Isaac     if (dm->ops->createcoordinatefield) {
5425f19dbd58SToby Isaac       ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr);
5426f19dbd58SToby Isaac     }
5427f19dbd58SToby Isaac   }
5428f19dbd58SToby Isaac   *field = dm->coordinateField;
5429f19dbd58SToby Isaac   PetscFunctionReturn(0);
5430f19dbd58SToby Isaac }
5431f19dbd58SToby Isaac 
5432f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field)
5433f19dbd58SToby Isaac {
5434f19dbd58SToby Isaac   PetscErrorCode ierr;
5435f19dbd58SToby Isaac 
5436f19dbd58SToby Isaac   PetscFunctionBegin;
5437f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5438f19dbd58SToby Isaac   if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2);
5439c4e6da2cSBarry Smith   ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr);
5440f19dbd58SToby Isaac   ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr);
5441f19dbd58SToby Isaac   dm->coordinateField = field;
5442f19dbd58SToby Isaac   PetscFunctionReturn(0);
5443f19dbd58SToby Isaac }
5444f19dbd58SToby Isaac 
54456636e97aSMatthew G Knepley /*@
54461cfe2091SMatthew G. Knepley   DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates
54476636e97aSMatthew G Knepley 
54486636e97aSMatthew G Knepley   Collective on DM
54496636e97aSMatthew G Knepley 
54506636e97aSMatthew G Knepley   Input Parameter:
54516636e97aSMatthew G Knepley . dm - the DM
54526636e97aSMatthew G Knepley 
54536636e97aSMatthew G Knepley   Output Parameter:
54546636e97aSMatthew G Knepley . cdm - coordinate DM
54556636e97aSMatthew G Knepley 
54566636e97aSMatthew G Knepley   Level: intermediate
54576636e97aSMatthew G Knepley 
54586636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
54591cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
54606636e97aSMatthew G Knepley @*/
54616636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
54626636e97aSMatthew G Knepley {
54636636e97aSMatthew G Knepley   PetscErrorCode ierr;
54646636e97aSMatthew G Knepley 
54656636e97aSMatthew G Knepley   PetscFunctionBegin;
54666636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
54676636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
54686636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
5469308f8a94SToby Isaac     DM cdm;
5470308f8a94SToby Isaac 
547182f516ccSBarry Smith     if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM");
5472308f8a94SToby Isaac     ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr);
5473308f8a94SToby Isaac     /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup
5474308f8a94SToby Isaac      * until the call to CreateCoordinateDM) */
5475308f8a94SToby Isaac     ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
5476308f8a94SToby Isaac     dm->coordinateDM = cdm;
54776636e97aSMatthew G Knepley   }
54786636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
54796636e97aSMatthew G Knepley   PetscFunctionReturn(0);
54806636e97aSMatthew G Knepley }
5481e87bb0d3SMatthew G Knepley 
54821cfe2091SMatthew G. Knepley /*@
54831cfe2091SMatthew G. Knepley   DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates
54841cfe2091SMatthew G. Knepley 
54851cfe2091SMatthew G. Knepley   Logically Collective on DM
54861cfe2091SMatthew G. Knepley 
54871cfe2091SMatthew G. Knepley   Input Parameters:
54881cfe2091SMatthew G. Knepley + dm - the DM
54891cfe2091SMatthew G. Knepley - cdm - coordinate DM
54901cfe2091SMatthew G. Knepley 
54911cfe2091SMatthew G. Knepley   Level: intermediate
54921cfe2091SMatthew G. Knepley 
54931cfe2091SMatthew G. Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
54941cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
54951cfe2091SMatthew G. Knepley @*/
54961cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm)
54971cfe2091SMatthew G. Knepley {
54981cfe2091SMatthew G. Knepley   PetscErrorCode ierr;
54991cfe2091SMatthew G. Knepley 
55001cfe2091SMatthew G. Knepley   PetscFunctionBegin;
55011cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55021cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(cdm,DM_CLASSID,2);
5503f26b38b9SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
55041cfe2091SMatthew G. Knepley   ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
55051cfe2091SMatthew G. Knepley   dm->coordinateDM = cdm;
55061cfe2091SMatthew G. Knepley   PetscFunctionReturn(0);
55071cfe2091SMatthew G. Knepley }
55081cfe2091SMatthew G. Knepley 
550946e270d4SMatthew G. Knepley /*@
551046e270d4SMatthew G. Knepley   DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values.
551146e270d4SMatthew G. Knepley 
551246e270d4SMatthew G. Knepley   Not Collective
551346e270d4SMatthew G. Knepley 
551446e270d4SMatthew G. Knepley   Input Parameter:
551546e270d4SMatthew G. Knepley . dm - The DM object
551646e270d4SMatthew G. Knepley 
551746e270d4SMatthew G. Knepley   Output Parameter:
551846e270d4SMatthew G. Knepley . dim - The embedding dimension
551946e270d4SMatthew G. Knepley 
552046e270d4SMatthew G. Knepley   Level: intermediate
552146e270d4SMatthew G. Knepley 
552246e270d4SMatthew G. Knepley .keywords: mesh, coordinates
5523e87a4003SBarry Smith .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetSection(), DMSetSection()
552446e270d4SMatthew G. Knepley @*/
552546e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim)
552646e270d4SMatthew G. Knepley {
552746e270d4SMatthew G. Knepley   PetscFunctionBegin;
552846e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
552946e270d4SMatthew G. Knepley   PetscValidPointer(dim, 2);
55309a9a41abSToby Isaac   if (dm->dimEmbed == PETSC_DEFAULT) {
55319a9a41abSToby Isaac     dm->dimEmbed = dm->dim;
55329a9a41abSToby Isaac   }
553346e270d4SMatthew G. Knepley   *dim = dm->dimEmbed;
553446e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
553546e270d4SMatthew G. Knepley }
553646e270d4SMatthew G. Knepley 
553746e270d4SMatthew G. Knepley /*@
553846e270d4SMatthew G. Knepley   DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values.
553946e270d4SMatthew G. Knepley 
554046e270d4SMatthew G. Knepley   Not Collective
554146e270d4SMatthew G. Knepley 
554246e270d4SMatthew G. Knepley   Input Parameters:
554346e270d4SMatthew G. Knepley + dm  - The DM object
554446e270d4SMatthew G. Knepley - dim - The embedding dimension
554546e270d4SMatthew G. Knepley 
554646e270d4SMatthew G. Knepley   Level: intermediate
554746e270d4SMatthew G. Knepley 
554846e270d4SMatthew G. Knepley .keywords: mesh, coordinates
5549e87a4003SBarry Smith .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetSection(), DMSetSection()
555046e270d4SMatthew G. Knepley @*/
555146e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim)
555246e270d4SMatthew G. Knepley {
5553e5e52638SMatthew G. Knepley   PetscDS        ds;
5554f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5555f17e8794SMatthew G. Knepley 
555646e270d4SMatthew G. Knepley   PetscFunctionBegin;
555746e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
555846e270d4SMatthew G. Knepley   dm->dimEmbed = dim;
5559e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5560e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr);
556146e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
556246e270d4SMatthew G. Knepley }
556346e270d4SMatthew G. Knepley 
5564e8abe2deSMatthew G. Knepley /*@
5565e8abe2deSMatthew G. Knepley   DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh.
5566e8abe2deSMatthew G. Knepley 
5567116501dfSVaclav Hapla   Collective on DM
5568e8abe2deSMatthew G. Knepley 
5569e8abe2deSMatthew G. Knepley   Input Parameter:
5570e8abe2deSMatthew G. Knepley . dm - The DM object
5571e8abe2deSMatthew G. Knepley 
5572e8abe2deSMatthew G. Knepley   Output Parameter:
5573e8abe2deSMatthew G. Knepley . section - The PetscSection object
5574e8abe2deSMatthew G. Knepley 
5575e8abe2deSMatthew G. Knepley   Level: intermediate
5576e8abe2deSMatthew G. Knepley 
5577e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates
5578e87a4003SBarry Smith .seealso: DMGetCoordinateDM(), DMGetSection(), DMSetSection()
5579e8abe2deSMatthew G. Knepley @*/
5580e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section)
5581e8abe2deSMatthew G. Knepley {
5582e8abe2deSMatthew G. Knepley   DM             cdm;
5583e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5584e8abe2deSMatthew G. Knepley 
5585e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5586e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5587e8abe2deSMatthew G. Knepley   PetscValidPointer(section, 2);
5588e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
5589e87a4003SBarry Smith   ierr = DMGetSection(cdm, section);CHKERRQ(ierr);
5590e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5591e8abe2deSMatthew G. Knepley }
5592e8abe2deSMatthew G. Knepley 
5593e8abe2deSMatthew G. Knepley /*@
5594e8abe2deSMatthew G. Knepley   DMSetCoordinateSection - Set the layout of coordinate values over the mesh.
5595e8abe2deSMatthew G. Knepley 
5596e8abe2deSMatthew G. Knepley   Not Collective
5597e8abe2deSMatthew G. Knepley 
5598e8abe2deSMatthew G. Knepley   Input Parameters:
5599e8abe2deSMatthew G. Knepley + dm      - The DM object
560046e270d4SMatthew G. Knepley . dim     - The embedding dimension, or PETSC_DETERMINE
5601e8abe2deSMatthew G. Knepley - section - The PetscSection object
5602e8abe2deSMatthew G. Knepley 
5603e8abe2deSMatthew G. Knepley   Level: intermediate
5604e8abe2deSMatthew G. Knepley 
5605e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates
5606e87a4003SBarry Smith .seealso: DMGetCoordinateSection(), DMGetSection(), DMSetSection()
5607e8abe2deSMatthew G. Knepley @*/
560846e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section)
5609e8abe2deSMatthew G. Knepley {
5610e8abe2deSMatthew G. Knepley   DM             cdm;
5611e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5612e8abe2deSMatthew G. Knepley 
5613e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5614e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
561546e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3);
5616e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
5617e87a4003SBarry Smith   ierr = DMSetSection(cdm, section);CHKERRQ(ierr);
561846e270d4SMatthew G. Knepley   if (dim == PETSC_DETERMINE) {
56194c1069a6SMatthew G. Knepley     PetscInt d = PETSC_DEFAULT;
562046e270d4SMatthew G. Knepley     PetscInt pStart, pEnd, vStart, vEnd, v, dd;
562146e270d4SMatthew G. Knepley 
562246e270d4SMatthew G. Knepley     ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
562346e270d4SMatthew G. Knepley     ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
562446e270d4SMatthew G. Knepley     pStart = PetscMax(vStart, pStart);
562546e270d4SMatthew G. Knepley     pEnd   = PetscMin(vEnd, pEnd);
562646e270d4SMatthew G. Knepley     for (v = pStart; v < pEnd; ++v) {
562746e270d4SMatthew G. Knepley       ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr);
562846e270d4SMatthew G. Knepley       if (dd) {d = dd; break;}
562946e270d4SMatthew G. Knepley     }
5630ebfe4b0dSMatthew G. Knepley     if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);}
563146e270d4SMatthew G. Knepley   }
5632e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5633e8abe2deSMatthew G. Knepley }
5634e8abe2deSMatthew G. Knepley 
56355dc8c3f7SMatthew G. Knepley /*@C
563690b157c4SStefano Zampini   DMGetPeriodicity - Get the description of mesh periodicity
56375dc8c3f7SMatthew G. Knepley 
56385dc8c3f7SMatthew G. Knepley   Input Parameters:
563990b157c4SStefano Zampini . dm      - The DM object
564090b157c4SStefano Zampini 
564190b157c4SStefano Zampini   Output Parameters:
564290b157c4SStefano Zampini + per     - Whether the DM is periodic or not
56435dc8c3f7SMatthew G. Knepley . maxCell - Over distances greater than this, we can assume a point has crossed over to another sheet, when trying to localize cell coordinates
56445dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
56455dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
56465dc8c3f7SMatthew G. Knepley 
56475dc8c3f7SMatthew G. Knepley   Level: developer
56485dc8c3f7SMatthew G. Knepley 
56495dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
56505dc8c3f7SMatthew G. Knepley @*/
565190b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd)
5652c6b900c6SMatthew G. Knepley {
5653c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
5654c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
565590b157c4SStefano Zampini   if (per)     *per     = dm->periodic;
5656c6b900c6SMatthew G. Knepley   if (L)       *L       = dm->L;
5657c6b900c6SMatthew G. Knepley   if (maxCell) *maxCell = dm->maxCell;
56585dc8c3f7SMatthew G. Knepley   if (bd)      *bd      = dm->bdtype;
5659c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
5660c6b900c6SMatthew G. Knepley }
5661c6b900c6SMatthew G. Knepley 
56625dc8c3f7SMatthew G. Knepley /*@C
56635dc8c3f7SMatthew G. Knepley   DMSetPeriodicity - Set the description of mesh periodicity
56645dc8c3f7SMatthew G. Knepley 
56655dc8c3f7SMatthew G. Knepley   Input Parameters:
56665dc8c3f7SMatthew G. Knepley + dm      - The DM object
566790b157c4SStefano Zampini . per     - Whether the DM is periodic or not. If maxCell is not provided, coordinates need to be localized
56685dc8c3f7SMatthew G. Knepley . maxCell - Over distances greater than this, we can assume a point has crossed over to another sheet, when trying to localize cell coordinates
56695dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
56705dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
56715dc8c3f7SMatthew G. Knepley 
56725dc8c3f7SMatthew G. Knepley   Level: developer
56735dc8c3f7SMatthew G. Knepley 
56745dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
56755dc8c3f7SMatthew G. Knepley @*/
567690b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[])
5677c6b900c6SMatthew G. Knepley {
5678c6b900c6SMatthew G. Knepley   PetscInt       dim, d;
5679c6b900c6SMatthew G. Knepley   PetscErrorCode ierr;
5680c6b900c6SMatthew G. Knepley 
5681c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
5682c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
568390b157c4SStefano Zampini   PetscValidLogicalCollectiveBool(dm,per,2);
568490b157c4SStefano Zampini   if (maxCell) {
568590b157c4SStefano Zampini     PetscValidPointer(maxCell,3);
568690b157c4SStefano Zampini     PetscValidPointer(L,4);
568790b157c4SStefano Zampini     PetscValidPointer(bd,5);
568890b157c4SStefano Zampini   }
56895dc8c3f7SMatthew G. Knepley   ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr);
56905dc8c3f7SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
569190b157c4SStefano Zampini   if (maxCell) {
56925dc8c3f7SMatthew G. Knepley     ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr);
56935dc8c3f7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];}
569490b157c4SStefano Zampini   }
5695072d7d67SStefano Zampini   dm->periodic = per;
5696c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
5697c6b900c6SMatthew G. Knepley }
5698c6b900c6SMatthew G. Knepley 
56992e17dfb7SMatthew G. Knepley /*@
57002e17dfb7SMatthew G. Knepley   DMLocalizeCoordinate - If a mesh is periodic (a torus with lengths L_i, some of which can be infinite), project the coordinate onto [0, L_i) in each dimension.
57012e17dfb7SMatthew G. Knepley 
57022e17dfb7SMatthew G. Knepley   Input Parameters:
57032e17dfb7SMatthew G. Knepley + dm     - The DM
570465da65dcSMatthew G. Knepley . in     - The input coordinate point (dim numbers)
570565da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i
57062e17dfb7SMatthew G. Knepley 
57072e17dfb7SMatthew G. Knepley   Output Parameter:
57082e17dfb7SMatthew G. Knepley . out - The localized coordinate point
57092e17dfb7SMatthew G. Knepley 
57102e17dfb7SMatthew G. Knepley   Level: developer
57112e17dfb7SMatthew G. Knepley 
57122e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
57132e17dfb7SMatthew G. Knepley @*/
571465da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[])
57152e17dfb7SMatthew G. Knepley {
57162e17dfb7SMatthew G. Knepley   PetscInt       dim, d;
57172e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
57182e17dfb7SMatthew G. Knepley 
57192e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
57202e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr);
57212e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
57222e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
57232e17dfb7SMatthew G. Knepley   } else {
572465da65dcSMatthew G. Knepley     if (endpoint) {
572565da65dcSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
5726da3333bfSMatthew G. Knepley         if ((PetscAbsReal(PetscRealPart(in[d])/dm->L[d] - PetscFloorReal(PetscRealPart(in[d])/dm->L[d])) < PETSC_SMALL) && (PetscRealPart(in[d])/dm->L[d] > PETSC_SMALL)) {
5727da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1);
572865da65dcSMatthew G. Knepley         } else {
5729da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
573065da65dcSMatthew G. Knepley         }
573165da65dcSMatthew G. Knepley       }
573265da65dcSMatthew G. Knepley     } else {
57332e17dfb7SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
57341118d4bcSLisandro Dalcin         out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
57352e17dfb7SMatthew G. Knepley       }
57362e17dfb7SMatthew G. Knepley     }
573765da65dcSMatthew G. Knepley   }
57382e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
57392e17dfb7SMatthew G. Knepley }
57402e17dfb7SMatthew G. Knepley 
57412e17dfb7SMatthew G. Knepley /*
57422e17dfb7SMatthew G. Knepley   DMLocalizeCoordinate_Internal - If a mesh is periodic, and the input point is far from the anchor, pick the coordinate sheet of the torus which moves it closer.
57432e17dfb7SMatthew G. Knepley 
57442e17dfb7SMatthew G. Knepley   Input Parameters:
57452e17dfb7SMatthew G. Knepley + dm     - The DM
57462e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
57472e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
57482e17dfb7SMatthew G. Knepley - in     - The input coordinate point (dim numbers)
57492e17dfb7SMatthew G. Knepley 
57502e17dfb7SMatthew G. Knepley   Output Parameter:
57512e17dfb7SMatthew G. Knepley . out - The localized coordinate point
57522e17dfb7SMatthew G. Knepley 
57532e17dfb7SMatthew G. Knepley   Level: developer
57542e17dfb7SMatthew G. Knepley 
57552e17dfb7SMatthew G. Knepley   Note: This is meant to get a set of coordinates close to each other, as in a cell. The anchor is usually the one of the vertices on a containing cell
57562e17dfb7SMatthew G. Knepley 
57572e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
57582e17dfb7SMatthew G. Knepley */
57592e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
57602e17dfb7SMatthew G. Knepley {
57612e17dfb7SMatthew G. Knepley   PetscInt d;
57622e17dfb7SMatthew G. Knepley 
57632e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
57642e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
57652e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
57662e17dfb7SMatthew G. Knepley   } else {
57672e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5768908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
57692e17dfb7SMatthew G. Knepley         out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
57702e17dfb7SMatthew G. Knepley       } else {
57712e17dfb7SMatthew G. Knepley         out[d] = in[d];
57722e17dfb7SMatthew G. Knepley       }
57732e17dfb7SMatthew G. Knepley     }
57742e17dfb7SMatthew G. Knepley   }
57752e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
57762e17dfb7SMatthew G. Knepley }
57772e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[])
57782e17dfb7SMatthew G. Knepley {
57792e17dfb7SMatthew G. Knepley   PetscInt d;
57802e17dfb7SMatthew G. Knepley 
57812e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
57822e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
57832e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
57842e17dfb7SMatthew G. Knepley   } else {
57852e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5786908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) {
57872e17dfb7SMatthew G. Knepley         out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d];
57882e17dfb7SMatthew G. Knepley       } else {
57892e17dfb7SMatthew G. Knepley         out[d] = in[d];
57902e17dfb7SMatthew G. Knepley       }
57912e17dfb7SMatthew G. Knepley     }
57922e17dfb7SMatthew G. Knepley   }
57932e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
57942e17dfb7SMatthew G. Knepley }
57952e17dfb7SMatthew G. Knepley 
57962e17dfb7SMatthew G. Knepley /*
57972e17dfb7SMatthew G. Knepley   DMLocalizeAddCoordinate_Internal - If a mesh is periodic, and the input point is far from the anchor, pick the coordinate sheet of the torus which moves it closer.
57982e17dfb7SMatthew G. Knepley 
57992e17dfb7SMatthew G. Knepley   Input Parameters:
58002e17dfb7SMatthew G. Knepley + dm     - The DM
58012e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
58022e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
58032e17dfb7SMatthew G. Knepley . in     - The input coordinate delta (dim numbers)
58042e17dfb7SMatthew G. Knepley - out    - The input coordinate point (dim numbers)
58052e17dfb7SMatthew G. Knepley 
58062e17dfb7SMatthew G. Knepley   Output Parameter:
58072e17dfb7SMatthew G. Knepley . out    - The localized coordinate in + out
58082e17dfb7SMatthew G. Knepley 
58092e17dfb7SMatthew G. Knepley   Level: developer
58102e17dfb7SMatthew G. Knepley 
58112e17dfb7SMatthew G. Knepley   Note: This is meant to get a set of coordinates close to each other, as in a cell. The anchor is usually the one of the vertices on a containing cell
58122e17dfb7SMatthew G. Knepley 
58132e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate()
58142e17dfb7SMatthew G. Knepley */
58152e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
58162e17dfb7SMatthew G. Knepley {
58172e17dfb7SMatthew G. Knepley   PetscInt d;
58182e17dfb7SMatthew G. Knepley 
58192e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
58202e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
58212e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] += in[d];
58222e17dfb7SMatthew G. Knepley   } else {
58232e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5824908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
58252e17dfb7SMatthew G. Knepley         out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
58262e17dfb7SMatthew G. Knepley       } else {
58272e17dfb7SMatthew G. Knepley         out[d] += in[d];
58282e17dfb7SMatthew G. Knepley       }
58292e17dfb7SMatthew G. Knepley     }
58302e17dfb7SMatthew G. Knepley   }
58312e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
58322e17dfb7SMatthew G. Knepley }
58332e17dfb7SMatthew G. Knepley 
583436447a5eSToby Isaac /*@
58358f700142SStefano Zampini   DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process
58368f700142SStefano Zampini 
58378f700142SStefano Zampini   Not collective
583836447a5eSToby Isaac 
583936447a5eSToby Isaac   Input Parameter:
584036447a5eSToby Isaac . dm - The DM
584136447a5eSToby Isaac 
584236447a5eSToby Isaac   Output Parameter:
584336447a5eSToby Isaac   areLocalized - True if localized
584436447a5eSToby Isaac 
584536447a5eSToby Isaac   Level: developer
584636447a5eSToby Isaac 
58478f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity()
584836447a5eSToby Isaac @*/
58498f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized)
585036447a5eSToby Isaac {
585136447a5eSToby Isaac   DM             cdm;
585236447a5eSToby Isaac   PetscSection   coordSection;
585346a3a80fSLisandro Dalcin   PetscInt       cStart, cEnd, sStart, sEnd, c, dof;
585446a3a80fSLisandro Dalcin   PetscBool      isPlex, alreadyLocalized;
585536447a5eSToby Isaac   PetscErrorCode ierr;
585636447a5eSToby Isaac 
585736447a5eSToby Isaac   PetscFunctionBegin;
585836447a5eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
585946a3a80fSLisandro Dalcin   PetscValidPointer(areLocalized, 2);
58608b09590cSToby Isaac   *areLocalized = PETSC_FALSE;
586146a3a80fSLisandro Dalcin 
586236447a5eSToby Isaac   /* We need some generic way of refering to cells/vertices */
586336447a5eSToby Isaac   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
586436447a5eSToby Isaac   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
586546a3a80fSLisandro Dalcin   ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr);
586646a3a80fSLisandro Dalcin   if (!isPlex) SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM");
586746a3a80fSLisandro Dalcin 
586846a3a80fSLisandro Dalcin   ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr);
586936447a5eSToby Isaac   ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr);
587036447a5eSToby Isaac   alreadyLocalized = PETSC_FALSE;
587146a3a80fSLisandro Dalcin   for (c = cStart; c < cEnd; ++c) {
587246a3a80fSLisandro Dalcin     if (c < sStart || c >= sEnd) continue;
587336447a5eSToby Isaac     ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr);
587446a3a80fSLisandro Dalcin     if (dof) { alreadyLocalized = PETSC_TRUE; break; }
587536447a5eSToby Isaac   }
58768f700142SStefano Zampini   *areLocalized = alreadyLocalized;
587736447a5eSToby Isaac   PetscFunctionReturn(0);
587836447a5eSToby Isaac }
587936447a5eSToby Isaac 
58808f700142SStefano Zampini /*@
58818f700142SStefano Zampini   DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells
58828f700142SStefano Zampini 
58838f700142SStefano Zampini   Collective on dm
58848f700142SStefano Zampini 
58858f700142SStefano Zampini   Input Parameter:
58868f700142SStefano Zampini . dm - The DM
58878f700142SStefano Zampini 
58888f700142SStefano Zampini   Output Parameter:
58898f700142SStefano Zampini   areLocalized - True if localized
58908f700142SStefano Zampini 
58918f700142SStefano Zampini   Level: developer
58928f700142SStefano Zampini 
58938f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal()
58948f700142SStefano Zampini @*/
58958f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized)
58968f700142SStefano Zampini {
58978f700142SStefano Zampini   PetscBool      localized;
58988f700142SStefano Zampini   PetscErrorCode ierr;
58998f700142SStefano Zampini 
59008f700142SStefano Zampini   PetscFunctionBegin;
59018f700142SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
59028f700142SStefano Zampini   PetscValidPointer(areLocalized, 2);
59038f700142SStefano Zampini   ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr);
59048f700142SStefano Zampini   ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
59058f700142SStefano Zampini   PetscFunctionReturn(0);
59068f700142SStefano Zampini }
590736447a5eSToby Isaac 
59082e17dfb7SMatthew G. Knepley /*@
5909492b8470SStefano Zampini   DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces
59102e17dfb7SMatthew G. Knepley 
59118f700142SStefano Zampini   Collective on dm
59128f700142SStefano Zampini 
59132e17dfb7SMatthew G. Knepley   Input Parameter:
59142e17dfb7SMatthew G. Knepley . dm - The DM
59152e17dfb7SMatthew G. Knepley 
59162e17dfb7SMatthew G. Knepley   Level: developer
59172e17dfb7SMatthew G. Knepley 
59188f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate()
59192e17dfb7SMatthew G. Knepley @*/
59202e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm)
59212e17dfb7SMatthew G. Knepley {
59222e17dfb7SMatthew G. Knepley   DM             cdm;
59232e17dfb7SMatthew G. Knepley   PetscSection   coordSection, cSection;
59242e17dfb7SMatthew G. Knepley   Vec            coordinates,  cVec;
59253e922f36SToby Isaac   PetscScalar   *coords, *coords2, *anchor, *localized;
59263e922f36SToby Isaac   PetscInt       Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize;
5927e0ae35bbSToby Isaac   PetscBool      alreadyLocalized, alreadyLocalizedGlobal;
59283e922f36SToby Isaac   PetscInt       maxHeight = 0, h;
59293e922f36SToby Isaac   PetscInt       *pStart = NULL, *pEnd = NULL;
59302e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
59312e17dfb7SMatthew G. Knepley 
59322e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
59332e17dfb7SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
593492c9c85fSStefano Zampini   if (!dm->periodic) PetscFunctionReturn(0);
5935f7cbd40bSStefano Zampini   ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr);
5936f7cbd40bSStefano Zampini   if (alreadyLocalized) PetscFunctionReturn(0);
5937f7cbd40bSStefano Zampini 
59382e17dfb7SMatthew G. Knepley   /* We need some generic way of refering to cells/vertices */
59392e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
59402e17dfb7SMatthew G. Knepley   {
59412e17dfb7SMatthew G. Knepley     PetscBool isplex;
59422e17dfb7SMatthew G. Knepley 
59432e17dfb7SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr);
59442e17dfb7SMatthew G. Knepley     if (isplex) {
59452e17dfb7SMatthew G. Knepley       ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr);
59463e922f36SToby Isaac       ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr);
594769291d52SBarry Smith       ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
59483e922f36SToby Isaac       pEnd = &pStart[maxHeight + 1];
59493e922f36SToby Isaac       newStart = vStart;
59503e922f36SToby Isaac       newEnd   = vEnd;
59513e922f36SToby Isaac       for (h = 0; h <= maxHeight; h++) {
59523e922f36SToby Isaac         ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr);
59533e922f36SToby Isaac         newStart = PetscMin(newStart,pStart[h]);
59543e922f36SToby Isaac         newEnd   = PetscMax(newEnd,pEnd[h]);
59553e922f36SToby Isaac       }
59562e17dfb7SMatthew G. Knepley     } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM");
59572e17dfb7SMatthew G. Knepley   }
59582e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
595943eeeb2dSStefano Zampini   if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector");
59602e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
59613e922f36SToby Isaac   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
5962e0ae35bbSToby Isaac   ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr);
59633e922f36SToby Isaac 
59642e17dfb7SMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr);
59652e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr);
59662e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr);
59672e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr);
59683e922f36SToby Isaac   ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr);
59693e922f36SToby Isaac 
597069291d52SBarry Smith   ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
59713e922f36SToby Isaac   localized = &anchor[bs];
59723e922f36SToby Isaac   alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE;
59733e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
59743e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
59753e922f36SToby Isaac 
59763e922f36SToby Isaac     for (c = cStart; c < cEnd; ++c) {
59773e922f36SToby Isaac       PetscScalar *cellCoords = NULL;
59783e922f36SToby Isaac       PetscInt     b;
59793e922f36SToby Isaac 
59803e922f36SToby Isaac       if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE;
59813e922f36SToby Isaac       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
59823e922f36SToby Isaac       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
59833e922f36SToby Isaac       for (d = 0; d < dof/bs; ++d) {
59843e922f36SToby Isaac         ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr);
59853e922f36SToby Isaac         for (b = 0; b < bs; b++) {
59863e922f36SToby Isaac           if (cellCoords[d*bs + b] != localized[b]) break;
59873e922f36SToby Isaac         }
59883e922f36SToby Isaac         if (b < bs) break;
59893e922f36SToby Isaac       }
59903e922f36SToby Isaac       if (d < dof/bs) {
59913e922f36SToby Isaac         if (c >= sStart && c < sEnd) {
59923e922f36SToby Isaac           PetscInt cdof;
59933e922f36SToby Isaac 
59943e922f36SToby Isaac           ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
59953e922f36SToby Isaac           if (cdof != dof) alreadyLocalized = PETSC_FALSE;
59963e922f36SToby Isaac         }
59973e922f36SToby Isaac         ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr);
59983e922f36SToby Isaac         ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr);
59993e922f36SToby Isaac       }
60003e922f36SToby Isaac       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
60013e922f36SToby Isaac     }
60023e922f36SToby Isaac   }
60033e922f36SToby Isaac   ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
60043e922f36SToby Isaac   if (alreadyLocalizedGlobal) {
600569291d52SBarry Smith     ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
60063e922f36SToby Isaac     ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
600769291d52SBarry Smith     ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
60083e922f36SToby Isaac     PetscFunctionReturn(0);
60093e922f36SToby Isaac   }
60102e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
60112e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
60122e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr);
60132e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr);
60142e17dfb7SMatthew G. Knepley   }
60152e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr);
60162e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr);
6017c2be7e5eSLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr);
60182e17dfb7SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr);
60192e17dfb7SMatthew G. Knepley   ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr);
60202e17dfb7SMatthew G. Knepley   ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr);
60212e17dfb7SMatthew G. Knepley   ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr);
6022c2be7e5eSLisandro Dalcin   ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
60232e17dfb7SMatthew G. Knepley   ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr);
60242e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
60252e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
60262e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
60272e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(cSection,     v, &off2);CHKERRQ(ierr);
60282e17dfb7SMatthew G. Knepley     for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d];
60292e17dfb7SMatthew G. Knepley   }
60303e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
60313e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
60323e922f36SToby Isaac 
60332e17dfb7SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
60342e17dfb7SMatthew G. Knepley       PetscScalar *cellCoords = NULL;
60353e922f36SToby Isaac       PetscInt     b, cdof;
60362e17dfb7SMatthew G. Knepley 
60373e922f36SToby Isaac       ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr);
60383e922f36SToby Isaac       if (!cdof) continue;
60392e17dfb7SMatthew G. Knepley       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
60402e17dfb7SMatthew G. Knepley       ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr);
60412e17dfb7SMatthew G. Knepley       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
60422e17dfb7SMatthew G. Knepley       for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);}
60432e17dfb7SMatthew G. Knepley       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
60442e17dfb7SMatthew G. Knepley     }
60453e922f36SToby Isaac   }
604669291d52SBarry Smith   ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
604769291d52SBarry Smith   ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
6048c2be7e5eSLisandro Dalcin   ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
60492e17dfb7SMatthew G. Knepley   ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr);
60502e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr);
60512e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr);
60522e17dfb7SMatthew G. Knepley   ierr = VecDestroy(&cVec);CHKERRQ(ierr);
60532e17dfb7SMatthew G. Knepley   ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
60542e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
60552e17dfb7SMatthew G. Knepley }
60562e17dfb7SMatthew G. Knepley 
6057e87bb0d3SMatthew G Knepley /*@
60583a93e3b7SToby Isaac   DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells
6059e87bb0d3SMatthew G Knepley 
60603a93e3b7SToby Isaac   Collective on Vec v (see explanation below)
6061e87bb0d3SMatthew G Knepley 
6062e87bb0d3SMatthew G Knepley   Input Parameters:
6063e87bb0d3SMatthew G Knepley + dm - The DM
60643a93e3b7SToby Isaac . v - The Vec of points
606562a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST
60663a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point.
6067e87bb0d3SMatthew G Knepley 
606861e3bb9bSMatthew G Knepley   Output Parameter:
606962a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used
607062a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points.
60713a93e3b7SToby Isaac 
6072e87bb0d3SMatthew G Knepley 
6073e87bb0d3SMatthew G Knepley   Level: developer
607461e3bb9bSMatthew G Knepley 
607562a38674SMatthew G. Knepley   Notes:
60763a93e3b7SToby Isaac   To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator.
607762a38674SMatthew G. Knepley   To do a search of all the cells in the distributed mesh, v should have the same communicator as dm.
60783a93e3b7SToby Isaac 
60793a93e3b7SToby Isaac   If *cellSF is NULL on input, a PetscSF will be created.
608062a38674SMatthew G. Knepley   If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses.
60813a93e3b7SToby Isaac 
60823a93e3b7SToby Isaac   An array that maps each point to its containing cell can be obtained with
60833a93e3b7SToby Isaac 
608462a38674SMatthew G. Knepley $    const PetscSFNode *cells;
608562a38674SMatthew G. Knepley $    PetscInt           nFound;
6086a6216909SToby Isaac $    const PetscInt    *found;
608762a38674SMatthew G. Knepley $
6088a6216909SToby Isaac $    PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells);
60893a93e3b7SToby Isaac 
60903a93e3b7SToby Isaac   Where cells[i].rank is the rank of the cell containing point found[i] (or i if found == NULL), and cells[i].index is
60913a93e3b7SToby Isaac   the index of the cell in its rank's local numbering.
60923a93e3b7SToby Isaac 
609361e3bb9bSMatthew G Knepley .keywords: point location, mesh
609462a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType
609561e3bb9bSMatthew G Knepley @*/
609662a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF)
6097e87bb0d3SMatthew G Knepley {
6098735aa83eSMatthew G Knepley   PetscErrorCode ierr;
6099735aa83eSMatthew G Knepley 
6100e87bb0d3SMatthew G Knepley   PetscFunctionBegin;
6101e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6102e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
6103e0fc9d1bSMatthew G. Knepley   PetscValidPointer(cellSF,4);
61043a93e3b7SToby Isaac   if (*cellSF) {
61053a93e3b7SToby Isaac     PetscMPIInt result;
61063a93e3b7SToby Isaac 
6107e0fc9d1bSMatthew G. Knepley     PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4);
6108a4f09dd6SDave May     ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRQ(ierr);
61093a93e3b7SToby Isaac     if (result != MPI_IDENT && result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"cellSF must have a communicator congruent to v's");
6110e0fc9d1bSMatthew G. Knepley   } else {
61113a93e3b7SToby Isaac     ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr);
61123a93e3b7SToby Isaac   }
611347a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
6114735aa83eSMatthew G Knepley   if (dm->ops->locatepoints) {
611562a38674SMatthew G. Knepley     ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr);
611682f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM");
611747a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
6118e87bb0d3SMatthew G Knepley   PetscFunctionReturn(0);
6119e87bb0d3SMatthew G Knepley }
612014f150ffSMatthew G. Knepley 
6121f4d763aaSMatthew G. Knepley /*@
6122f4d763aaSMatthew G. Knepley   DMGetOutputDM - Retrieve the DM associated with the layout for output
6123f4d763aaSMatthew G. Knepley 
61248f700142SStefano Zampini   Collective on dm
61258f700142SStefano Zampini 
6126f4d763aaSMatthew G. Knepley   Input Parameter:
6127f4d763aaSMatthew G. Knepley . dm - The original DM
6128f4d763aaSMatthew G. Knepley 
6129f4d763aaSMatthew G. Knepley   Output Parameter:
6130f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output
6131f4d763aaSMatthew G. Knepley 
6132f4d763aaSMatthew G. Knepley   Level: intermediate
6133f4d763aaSMatthew G. Knepley 
6134e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection()
6135f4d763aaSMatthew G. Knepley @*/
613614f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm)
613714f150ffSMatthew G. Knepley {
6138c26acbdeSMatthew G. Knepley   PetscSection   section;
61392d4e4a49SMatthew G. Knepley   PetscBool      hasConstraints, ghasConstraints;
614014f150ffSMatthew G. Knepley   PetscErrorCode ierr;
614114f150ffSMatthew G. Knepley 
614214f150ffSMatthew G. Knepley   PetscFunctionBegin;
614314f150ffSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
614414f150ffSMatthew G. Knepley   PetscValidPointer(odm,2);
6145e87a4003SBarry Smith   ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
6146c26acbdeSMatthew G. Knepley   ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr);
6147127fe6b9SMatthew G. Knepley   ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
61482d4e4a49SMatthew G. Knepley   if (!ghasConstraints) {
6149c26acbdeSMatthew G. Knepley     *odm = dm;
6150c26acbdeSMatthew G. Knepley     PetscFunctionReturn(0);
6151c26acbdeSMatthew G. Knepley   }
615214f150ffSMatthew G. Knepley   if (!dm->dmBC) {
6153c26acbdeSMatthew G. Knepley     PetscSection newSection, gsection;
615414f150ffSMatthew G. Knepley     PetscSF      sf;
615514f150ffSMatthew G. Knepley 
615614f150ffSMatthew G. Knepley     ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr);
6157e5e52638SMatthew G. Knepley     ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr);
615814f150ffSMatthew G. Knepley     ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr);
6159e87a4003SBarry Smith     ierr = DMSetSection(dm->dmBC, newSection);CHKERRQ(ierr);
616014f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);
616114f150ffSMatthew G. Knepley     ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr);
616215b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr);
6163e87a4003SBarry Smith     ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr);
616414f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr);
616514f150ffSMatthew G. Knepley   }
616614f150ffSMatthew G. Knepley   *odm = dm->dmBC;
616714f150ffSMatthew G. Knepley   PetscFunctionReturn(0);
616814f150ffSMatthew G. Knepley }
6169f4d763aaSMatthew G. Knepley 
6170f4d763aaSMatthew G. Knepley /*@
6171cdb7a50dSMatthew G. Knepley   DMGetOutputSequenceNumber - Retrieve the sequence number/value for output
6172f4d763aaSMatthew G. Knepley 
6173f4d763aaSMatthew G. Knepley   Input Parameter:
6174f4d763aaSMatthew G. Knepley . dm - The original DM
6175f4d763aaSMatthew G. Knepley 
6176cdb7a50dSMatthew G. Knepley   Output Parameters:
6177cdb7a50dSMatthew G. Knepley + num - The output sequence number
6178cdb7a50dSMatthew G. Knepley - val - The output sequence value
6179f4d763aaSMatthew G. Knepley 
6180f4d763aaSMatthew G. Knepley   Level: intermediate
6181f4d763aaSMatthew G. Knepley 
6182f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6183f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6184f4d763aaSMatthew G. Knepley 
6185f4d763aaSMatthew G. Knepley .seealso: VecView()
6186f4d763aaSMatthew G. Knepley @*/
6187cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val)
6188f4d763aaSMatthew G. Knepley {
6189f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6190f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6191cdb7a50dSMatthew G. Knepley   if (num) {PetscValidPointer(num,2); *num = dm->outputSequenceNum;}
6192cdb7a50dSMatthew G. Knepley   if (val) {PetscValidPointer(val,3);*val = dm->outputSequenceVal;}
6193f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6194f4d763aaSMatthew G. Knepley }
6195f4d763aaSMatthew G. Knepley 
6196f4d763aaSMatthew G. Knepley /*@
6197cdb7a50dSMatthew G. Knepley   DMSetOutputSequenceNumber - Set the sequence number/value for output
6198f4d763aaSMatthew G. Knepley 
6199f4d763aaSMatthew G. Knepley   Input Parameters:
6200f4d763aaSMatthew G. Knepley + dm - The original DM
6201cdb7a50dSMatthew G. Knepley . num - The output sequence number
6202cdb7a50dSMatthew G. Knepley - val - The output sequence value
6203f4d763aaSMatthew G. Knepley 
6204f4d763aaSMatthew G. Knepley   Level: intermediate
6205f4d763aaSMatthew G. Knepley 
6206f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6207f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6208f4d763aaSMatthew G. Knepley 
6209f4d763aaSMatthew G. Knepley .seealso: VecView()
6210f4d763aaSMatthew G. Knepley @*/
6211cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val)
6212f4d763aaSMatthew G. Knepley {
6213f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6214f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6215f4d763aaSMatthew G. Knepley   dm->outputSequenceNum = num;
6216cdb7a50dSMatthew G. Knepley   dm->outputSequenceVal = val;
6217cdb7a50dSMatthew G. Knepley   PetscFunctionReturn(0);
6218cdb7a50dSMatthew G. Knepley }
6219cdb7a50dSMatthew G. Knepley 
6220cdb7a50dSMatthew G. Knepley /*@C
6221cdb7a50dSMatthew G. Knepley   DMOutputSequenceLoad - Retrieve the sequence value from a Viewer
6222cdb7a50dSMatthew G. Knepley 
6223cdb7a50dSMatthew G. Knepley   Input Parameters:
6224cdb7a50dSMatthew G. Knepley + dm   - The original DM
6225cdb7a50dSMatthew G. Knepley . name - The sequence name
6226cdb7a50dSMatthew G. Knepley - num  - The output sequence number
6227cdb7a50dSMatthew G. Knepley 
6228cdb7a50dSMatthew G. Knepley   Output Parameter:
6229cdb7a50dSMatthew G. Knepley . val  - The output sequence value
6230cdb7a50dSMatthew G. Knepley 
6231cdb7a50dSMatthew G. Knepley   Level: intermediate
6232cdb7a50dSMatthew G. Knepley 
6233cdb7a50dSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6234cdb7a50dSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6235cdb7a50dSMatthew G. Knepley 
6236cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView()
6237cdb7a50dSMatthew G. Knepley @*/
6238cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val)
6239cdb7a50dSMatthew G. Knepley {
6240cdb7a50dSMatthew G. Knepley   PetscBool      ishdf5;
6241cdb7a50dSMatthew G. Knepley   PetscErrorCode ierr;
6242cdb7a50dSMatthew G. Knepley 
6243cdb7a50dSMatthew G. Knepley   PetscFunctionBegin;
6244cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6245cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
6246cdb7a50dSMatthew G. Knepley   PetscValidPointer(val,4);
6247cdb7a50dSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr);
6248cdb7a50dSMatthew G. Knepley   if (ishdf5) {
6249cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
6250cdb7a50dSMatthew G. Knepley     PetscScalar value;
6251cdb7a50dSMatthew G. Knepley 
625239d25373SMatthew G. Knepley     ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr);
62534aeb217fSMatthew G. Knepley     *val = PetscRealPart(value);
6254cdb7a50dSMatthew G. Knepley #endif
6255cdb7a50dSMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()");
6256f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6257f4d763aaSMatthew G. Knepley }
62588e4ac7eaSMatthew G. Knepley 
62598e4ac7eaSMatthew G. Knepley /*@
62608e4ac7eaSMatthew G. Knepley   DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution
62618e4ac7eaSMatthew G. Knepley 
62628e4ac7eaSMatthew G. Knepley   Not collective
62638e4ac7eaSMatthew G. Knepley 
62648e4ac7eaSMatthew G. Knepley   Input Parameter:
62658e4ac7eaSMatthew G. Knepley . dm - The DM
62668e4ac7eaSMatthew G. Knepley 
62678e4ac7eaSMatthew G. Knepley   Output Parameter:
62688e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution
62698e4ac7eaSMatthew G. Knepley 
62708e4ac7eaSMatthew G. Knepley   Level: beginner
62718e4ac7eaSMatthew G. Knepley 
62728e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate()
62738e4ac7eaSMatthew G. Knepley @*/
62748e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural)
62758e4ac7eaSMatthew G. Knepley {
62768e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
62778e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
62788e4ac7eaSMatthew G. Knepley   PetscValidPointer(useNatural, 2);
62798e4ac7eaSMatthew G. Knepley   *useNatural = dm->useNatural;
62808e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
62818e4ac7eaSMatthew G. Knepley }
62828e4ac7eaSMatthew G. Knepley 
62838e4ac7eaSMatthew G. Knepley /*@
62845d3b26e6SMatthew G. Knepley   DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution
62858e4ac7eaSMatthew G. Knepley 
62868e4ac7eaSMatthew G. Knepley   Collective on dm
62878e4ac7eaSMatthew G. Knepley 
62888e4ac7eaSMatthew G. Knepley   Input Parameters:
62898e4ac7eaSMatthew G. Knepley + dm - The DM
62908e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution
62918e4ac7eaSMatthew G. Knepley 
62925d3b26e6SMatthew G. Knepley   Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM()
62935d3b26e6SMatthew G. Knepley 
62948e4ac7eaSMatthew G. Knepley   Level: beginner
62958e4ac7eaSMatthew G. Knepley 
62965d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM()
62978e4ac7eaSMatthew G. Knepley @*/
62988e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural)
62998e4ac7eaSMatthew G. Knepley {
63008e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
63018e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
63028833efb5SBlaise Bourdin   PetscValidLogicalCollectiveBool(dm, useNatural, 2);
63038e4ac7eaSMatthew G. Knepley   dm->useNatural = useNatural;
63048e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
63058e4ac7eaSMatthew G. Knepley }
6306c58f1c22SToby Isaac 
6307c58f1c22SToby Isaac 
6308c58f1c22SToby Isaac /*@C
6309c58f1c22SToby Isaac   DMCreateLabel - Create a label of the given name if it does not already exist
6310c58f1c22SToby Isaac 
6311c58f1c22SToby Isaac   Not Collective
6312c58f1c22SToby Isaac 
6313c58f1c22SToby Isaac   Input Parameters:
6314c58f1c22SToby Isaac + dm   - The DM object
6315c58f1c22SToby Isaac - name - The label name
6316c58f1c22SToby Isaac 
6317c58f1c22SToby Isaac   Level: intermediate
6318c58f1c22SToby Isaac 
6319c58f1c22SToby Isaac .keywords: mesh
6320c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6321c58f1c22SToby Isaac @*/
6322c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[])
6323c58f1c22SToby Isaac {
6324c58f1c22SToby Isaac   DMLabelLink    next  = dm->labels->next;
6325c58f1c22SToby Isaac   PetscBool      flg   = PETSC_FALSE;
6326d67d17b1SMatthew G. Knepley   const char    *lname;
6327c58f1c22SToby Isaac   PetscErrorCode ierr;
6328c58f1c22SToby Isaac 
6329c58f1c22SToby Isaac   PetscFunctionBegin;
6330c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6331c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6332c58f1c22SToby Isaac   while (next) {
6333d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6334d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
6335c58f1c22SToby Isaac     if (flg) break;
6336c58f1c22SToby Isaac     next = next->next;
6337c58f1c22SToby Isaac   }
6338c58f1c22SToby Isaac   if (!flg) {
6339c58f1c22SToby Isaac     DMLabelLink tmpLabel;
6340c58f1c22SToby Isaac 
6341c58f1c22SToby Isaac     ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
6342d67d17b1SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, name, &tmpLabel->label);CHKERRQ(ierr);
6343c58f1c22SToby Isaac     tmpLabel->output = PETSC_TRUE;
6344c58f1c22SToby Isaac     tmpLabel->next   = dm->labels->next;
6345c58f1c22SToby Isaac     dm->labels->next = tmpLabel;
6346c58f1c22SToby Isaac   }
6347c58f1c22SToby Isaac   PetscFunctionReturn(0);
6348c58f1c22SToby Isaac }
6349c58f1c22SToby Isaac 
6350c58f1c22SToby Isaac /*@C
6351c58f1c22SToby Isaac   DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default
6352c58f1c22SToby Isaac 
6353c58f1c22SToby Isaac   Not Collective
6354c58f1c22SToby Isaac 
6355c58f1c22SToby Isaac   Input Parameters:
6356c58f1c22SToby Isaac + dm   - The DM object
6357c58f1c22SToby Isaac . name - The label name
6358c58f1c22SToby Isaac - point - The mesh point
6359c58f1c22SToby Isaac 
6360c58f1c22SToby Isaac   Output Parameter:
6361c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label
6362c58f1c22SToby Isaac 
6363c58f1c22SToby Isaac   Level: beginner
6364c58f1c22SToby Isaac 
6365c58f1c22SToby Isaac .keywords: mesh
6366c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS()
6367c58f1c22SToby Isaac @*/
6368c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value)
6369c58f1c22SToby Isaac {
6370c58f1c22SToby Isaac   DMLabel        label;
6371c58f1c22SToby Isaac   PetscErrorCode ierr;
6372c58f1c22SToby Isaac 
6373c58f1c22SToby Isaac   PetscFunctionBegin;
6374c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6375c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6376c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
637713903a91SSatish Balay   if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name);
6378c58f1c22SToby Isaac   ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr);
6379c58f1c22SToby Isaac   PetscFunctionReturn(0);
6380c58f1c22SToby Isaac }
6381c58f1c22SToby Isaac 
6382c58f1c22SToby Isaac /*@C
6383c58f1c22SToby Isaac   DMSetLabelValue - Add a point to a Sieve Label with given value
6384c58f1c22SToby Isaac 
6385c58f1c22SToby Isaac   Not Collective
6386c58f1c22SToby Isaac 
6387c58f1c22SToby Isaac   Input Parameters:
6388c58f1c22SToby Isaac + dm   - The DM object
6389c58f1c22SToby Isaac . name - The label name
6390c58f1c22SToby Isaac . point - The mesh point
6391c58f1c22SToby Isaac - value - The label value for this point
6392c58f1c22SToby Isaac 
6393c58f1c22SToby Isaac   Output Parameter:
6394c58f1c22SToby Isaac 
6395c58f1c22SToby Isaac   Level: beginner
6396c58f1c22SToby Isaac 
6397c58f1c22SToby Isaac .keywords: mesh
6398c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue()
6399c58f1c22SToby Isaac @*/
6400c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6401c58f1c22SToby Isaac {
6402c58f1c22SToby Isaac   DMLabel        label;
6403c58f1c22SToby Isaac   PetscErrorCode ierr;
6404c58f1c22SToby Isaac 
6405c58f1c22SToby Isaac   PetscFunctionBegin;
6406c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6407c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6408c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6409c58f1c22SToby Isaac   if (!label) {
6410c58f1c22SToby Isaac     ierr = DMCreateLabel(dm, name);CHKERRQ(ierr);
6411c58f1c22SToby Isaac     ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6412c58f1c22SToby Isaac   }
6413c58f1c22SToby Isaac   ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr);
6414c58f1c22SToby Isaac   PetscFunctionReturn(0);
6415c58f1c22SToby Isaac }
6416c58f1c22SToby Isaac 
6417c58f1c22SToby Isaac /*@C
6418c58f1c22SToby Isaac   DMClearLabelValue - Remove a point from a Sieve Label with given value
6419c58f1c22SToby Isaac 
6420c58f1c22SToby Isaac   Not Collective
6421c58f1c22SToby Isaac 
6422c58f1c22SToby Isaac   Input Parameters:
6423c58f1c22SToby Isaac + dm   - The DM object
6424c58f1c22SToby Isaac . name - The label name
6425c58f1c22SToby Isaac . point - The mesh point
6426c58f1c22SToby Isaac - value - The label value for this point
6427c58f1c22SToby Isaac 
6428c58f1c22SToby Isaac   Output Parameter:
6429c58f1c22SToby Isaac 
6430c58f1c22SToby Isaac   Level: beginner
6431c58f1c22SToby Isaac 
6432c58f1c22SToby Isaac .keywords: mesh
6433c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS()
6434c58f1c22SToby Isaac @*/
6435c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6436c58f1c22SToby Isaac {
6437c58f1c22SToby Isaac   DMLabel        label;
6438c58f1c22SToby Isaac   PetscErrorCode ierr;
6439c58f1c22SToby Isaac 
6440c58f1c22SToby Isaac   PetscFunctionBegin;
6441c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6442c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6443c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6444c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6445c58f1c22SToby Isaac   ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr);
6446c58f1c22SToby Isaac   PetscFunctionReturn(0);
6447c58f1c22SToby Isaac }
6448c58f1c22SToby Isaac 
6449c58f1c22SToby Isaac /*@C
6450c58f1c22SToby Isaac   DMGetLabelSize - Get the number of different integer ids in a Label
6451c58f1c22SToby Isaac 
6452c58f1c22SToby Isaac   Not Collective
6453c58f1c22SToby Isaac 
6454c58f1c22SToby Isaac   Input Parameters:
6455c58f1c22SToby Isaac + dm   - The DM object
6456c58f1c22SToby Isaac - name - The label name
6457c58f1c22SToby Isaac 
6458c58f1c22SToby Isaac   Output Parameter:
6459c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist
6460c58f1c22SToby Isaac 
6461c58f1c22SToby Isaac   Level: beginner
6462c58f1c22SToby Isaac 
6463c58f1c22SToby Isaac .keywords: mesh
6464df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue()
6465c58f1c22SToby Isaac @*/
6466c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size)
6467c58f1c22SToby Isaac {
6468c58f1c22SToby Isaac   DMLabel        label;
6469c58f1c22SToby Isaac   PetscErrorCode ierr;
6470c58f1c22SToby Isaac 
6471c58f1c22SToby Isaac   PetscFunctionBegin;
6472c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6473c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6474c58f1c22SToby Isaac   PetscValidPointer(size, 3);
6475c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6476c58f1c22SToby Isaac   *size = 0;
6477c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6478c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr);
6479c58f1c22SToby Isaac   PetscFunctionReturn(0);
6480c58f1c22SToby Isaac }
6481c58f1c22SToby Isaac 
6482c58f1c22SToby Isaac /*@C
6483c58f1c22SToby Isaac   DMGetLabelIdIS - Get the integer ids in a label
6484c58f1c22SToby Isaac 
6485c58f1c22SToby Isaac   Not Collective
6486c58f1c22SToby Isaac 
6487c58f1c22SToby Isaac   Input Parameters:
6488c58f1c22SToby Isaac + mesh - The DM object
6489c58f1c22SToby Isaac - name - The label name
6490c58f1c22SToby Isaac 
6491c58f1c22SToby Isaac   Output Parameter:
6492c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist
6493c58f1c22SToby Isaac 
6494c58f1c22SToby Isaac   Level: beginner
6495c58f1c22SToby Isaac 
6496c58f1c22SToby Isaac .keywords: mesh
6497c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize()
6498c58f1c22SToby Isaac @*/
6499c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids)
6500c58f1c22SToby Isaac {
6501c58f1c22SToby Isaac   DMLabel        label;
6502c58f1c22SToby Isaac   PetscErrorCode ierr;
6503c58f1c22SToby Isaac 
6504c58f1c22SToby Isaac   PetscFunctionBegin;
6505c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6506c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6507c58f1c22SToby Isaac   PetscValidPointer(ids, 3);
6508c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6509c58f1c22SToby Isaac   *ids = NULL;
6510dab2e251SBlaise Bourdin  if (label) {
6511c58f1c22SToby Isaac     ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr);
6512dab2e251SBlaise Bourdin   } else {
6513dab2e251SBlaise Bourdin     /* returning an empty IS */
6514dab2e251SBlaise Bourdin     ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr);
6515dab2e251SBlaise Bourdin   }
6516c58f1c22SToby Isaac   PetscFunctionReturn(0);
6517c58f1c22SToby Isaac }
6518c58f1c22SToby Isaac 
6519c58f1c22SToby Isaac /*@C
6520c58f1c22SToby Isaac   DMGetStratumSize - Get the number of points in a label stratum
6521c58f1c22SToby Isaac 
6522c58f1c22SToby Isaac   Not Collective
6523c58f1c22SToby Isaac 
6524c58f1c22SToby Isaac   Input Parameters:
6525c58f1c22SToby Isaac + dm - The DM object
6526c58f1c22SToby Isaac . name - The label name
6527c58f1c22SToby Isaac - value - The stratum value
6528c58f1c22SToby Isaac 
6529c58f1c22SToby Isaac   Output Parameter:
6530c58f1c22SToby Isaac . size - The stratum size
6531c58f1c22SToby Isaac 
6532c58f1c22SToby Isaac   Level: beginner
6533c58f1c22SToby Isaac 
6534c58f1c22SToby Isaac .keywords: mesh
6535c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds()
6536c58f1c22SToby Isaac @*/
6537c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size)
6538c58f1c22SToby Isaac {
6539c58f1c22SToby Isaac   DMLabel        label;
6540c58f1c22SToby Isaac   PetscErrorCode ierr;
6541c58f1c22SToby Isaac 
6542c58f1c22SToby Isaac   PetscFunctionBegin;
6543c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6544c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6545c58f1c22SToby Isaac   PetscValidPointer(size, 4);
6546c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6547c58f1c22SToby Isaac   *size = 0;
6548c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6549c58f1c22SToby Isaac   ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr);
6550c58f1c22SToby Isaac   PetscFunctionReturn(0);
6551c58f1c22SToby Isaac }
6552c58f1c22SToby Isaac 
6553c58f1c22SToby Isaac /*@C
6554c58f1c22SToby Isaac   DMGetStratumIS - Get the points in a label stratum
6555c58f1c22SToby Isaac 
6556c58f1c22SToby Isaac   Not Collective
6557c58f1c22SToby Isaac 
6558c58f1c22SToby Isaac   Input Parameters:
6559c58f1c22SToby Isaac + dm - The DM object
6560c58f1c22SToby Isaac . name - The label name
6561c58f1c22SToby Isaac - value - The stratum value
6562c58f1c22SToby Isaac 
6563c58f1c22SToby Isaac   Output Parameter:
6564c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value
6565c58f1c22SToby Isaac 
6566c58f1c22SToby Isaac   Level: beginner
6567c58f1c22SToby Isaac 
6568c58f1c22SToby Isaac .keywords: mesh
6569c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize()
6570c58f1c22SToby Isaac @*/
6571c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points)
6572c58f1c22SToby Isaac {
6573c58f1c22SToby Isaac   DMLabel        label;
6574c58f1c22SToby Isaac   PetscErrorCode ierr;
6575c58f1c22SToby Isaac 
6576c58f1c22SToby Isaac   PetscFunctionBegin;
6577c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6578c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6579c58f1c22SToby Isaac   PetscValidPointer(points, 4);
6580c58f1c22SToby Isaac   ierr    = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6581c58f1c22SToby Isaac   *points = NULL;
6582c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6583c58f1c22SToby Isaac   ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr);
6584c58f1c22SToby Isaac   PetscFunctionReturn(0);
6585c58f1c22SToby Isaac }
6586c58f1c22SToby Isaac 
65874de306b1SToby Isaac /*@C
65889044fa66SMatthew G. Knepley   DMSetStratumIS - Set the points in a label stratum
65894de306b1SToby Isaac 
65904de306b1SToby Isaac   Not Collective
65914de306b1SToby Isaac 
65924de306b1SToby Isaac   Input Parameters:
65934de306b1SToby Isaac + dm - The DM object
65944de306b1SToby Isaac . name - The label name
65954de306b1SToby Isaac . value - The stratum value
65964de306b1SToby Isaac - points - The stratum points
65974de306b1SToby Isaac 
65984de306b1SToby Isaac   Level: beginner
65994de306b1SToby Isaac 
66004de306b1SToby Isaac .keywords: mesh
66014de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize()
66024de306b1SToby Isaac @*/
66034de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points)
66044de306b1SToby Isaac {
66054de306b1SToby Isaac   DMLabel        label;
66064de306b1SToby Isaac   PetscErrorCode ierr;
66074de306b1SToby Isaac 
66084de306b1SToby Isaac   PetscFunctionBegin;
66094de306b1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
66104de306b1SToby Isaac   PetscValidCharPointer(name, 2);
66114de306b1SToby Isaac   PetscValidPointer(points, 4);
66124de306b1SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
66134de306b1SToby Isaac   if (!label) PetscFunctionReturn(0);
66144de306b1SToby Isaac   ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr);
66154de306b1SToby Isaac   PetscFunctionReturn(0);
66164de306b1SToby Isaac }
66174de306b1SToby Isaac 
6618c58f1c22SToby Isaac /*@C
6619c58f1c22SToby Isaac   DMClearLabelStratum - Remove all points from a stratum from a Sieve Label
6620c58f1c22SToby Isaac 
6621c58f1c22SToby Isaac   Not Collective
6622c58f1c22SToby Isaac 
6623c58f1c22SToby Isaac   Input Parameters:
6624c58f1c22SToby Isaac + dm   - The DM object
6625c58f1c22SToby Isaac . name - The label name
6626c58f1c22SToby Isaac - value - The label value for this point
6627c58f1c22SToby Isaac 
6628c58f1c22SToby Isaac   Output Parameter:
6629c58f1c22SToby Isaac 
6630c58f1c22SToby Isaac   Level: beginner
6631c58f1c22SToby Isaac 
6632c58f1c22SToby Isaac .keywords: mesh
6633c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue()
6634c58f1c22SToby Isaac @*/
6635c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value)
6636c58f1c22SToby Isaac {
6637c58f1c22SToby Isaac   DMLabel        label;
6638c58f1c22SToby Isaac   PetscErrorCode ierr;
6639c58f1c22SToby Isaac 
6640c58f1c22SToby Isaac   PetscFunctionBegin;
6641c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6642c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6643c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6644c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6645c58f1c22SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
6646c58f1c22SToby Isaac   PetscFunctionReturn(0);
6647c58f1c22SToby Isaac }
6648c58f1c22SToby Isaac 
6649c58f1c22SToby Isaac /*@
6650c58f1c22SToby Isaac   DMGetNumLabels - Return the number of labels defined by the mesh
6651c58f1c22SToby Isaac 
6652c58f1c22SToby Isaac   Not Collective
6653c58f1c22SToby Isaac 
6654c58f1c22SToby Isaac   Input Parameter:
6655c58f1c22SToby Isaac . dm   - The DM object
6656c58f1c22SToby Isaac 
6657c58f1c22SToby Isaac   Output Parameter:
6658c58f1c22SToby Isaac . numLabels - the number of Labels
6659c58f1c22SToby Isaac 
6660c58f1c22SToby Isaac   Level: intermediate
6661c58f1c22SToby Isaac 
6662c58f1c22SToby Isaac .keywords: mesh
6663c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6664c58f1c22SToby Isaac @*/
6665c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels)
6666c58f1c22SToby Isaac {
6667c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
6668c58f1c22SToby Isaac   PetscInt  n    = 0;
6669c58f1c22SToby Isaac 
6670c58f1c22SToby Isaac   PetscFunctionBegin;
6671c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6672c58f1c22SToby Isaac   PetscValidPointer(numLabels, 2);
6673c58f1c22SToby Isaac   while (next) {++n; next = next->next;}
6674c58f1c22SToby Isaac   *numLabels = n;
6675c58f1c22SToby Isaac   PetscFunctionReturn(0);
6676c58f1c22SToby Isaac }
6677c58f1c22SToby Isaac 
6678c58f1c22SToby Isaac /*@C
6679c58f1c22SToby Isaac   DMGetLabelName - Return the name of nth label
6680c58f1c22SToby Isaac 
6681c58f1c22SToby Isaac   Not Collective
6682c58f1c22SToby Isaac 
6683c58f1c22SToby Isaac   Input Parameters:
6684c58f1c22SToby Isaac + dm - The DM object
6685c58f1c22SToby Isaac - n  - the label number
6686c58f1c22SToby Isaac 
6687c58f1c22SToby Isaac   Output Parameter:
6688c58f1c22SToby Isaac . name - the label name
6689c58f1c22SToby Isaac 
6690c58f1c22SToby Isaac   Level: intermediate
6691c58f1c22SToby Isaac 
6692c58f1c22SToby Isaac .keywords: mesh
6693c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6694c58f1c22SToby Isaac @*/
6695c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name)
6696c58f1c22SToby Isaac {
6697c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6698c58f1c22SToby Isaac   PetscInt       l    = 0;
6699d67d17b1SMatthew G. Knepley   PetscErrorCode ierr;
6700c58f1c22SToby Isaac 
6701c58f1c22SToby Isaac   PetscFunctionBegin;
6702c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6703c58f1c22SToby Isaac   PetscValidPointer(name, 3);
6704c58f1c22SToby Isaac   while (next) {
6705c58f1c22SToby Isaac     if (l == n) {
6706d67d17b1SMatthew G. Knepley       ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr);
6707c58f1c22SToby Isaac       PetscFunctionReturn(0);
6708c58f1c22SToby Isaac     }
6709c58f1c22SToby Isaac     ++l;
6710c58f1c22SToby Isaac     next = next->next;
6711c58f1c22SToby Isaac   }
6712c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
6713c58f1c22SToby Isaac }
6714c58f1c22SToby Isaac 
6715c58f1c22SToby Isaac /*@C
6716c58f1c22SToby Isaac   DMHasLabel - Determine whether the mesh has a label of a given name
6717c58f1c22SToby Isaac 
6718c58f1c22SToby Isaac   Not Collective
6719c58f1c22SToby Isaac 
6720c58f1c22SToby Isaac   Input Parameters:
6721c58f1c22SToby Isaac + dm   - The DM object
6722c58f1c22SToby Isaac - name - The label name
6723c58f1c22SToby Isaac 
6724c58f1c22SToby Isaac   Output Parameter:
6725c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present
6726c58f1c22SToby Isaac 
6727c58f1c22SToby Isaac   Level: intermediate
6728c58f1c22SToby Isaac 
6729c58f1c22SToby Isaac .keywords: mesh
6730c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6731c58f1c22SToby Isaac @*/
6732c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel)
6733c58f1c22SToby Isaac {
6734c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6735d67d17b1SMatthew G. Knepley   const char    *lname;
6736c58f1c22SToby Isaac   PetscErrorCode ierr;
6737c58f1c22SToby Isaac 
6738c58f1c22SToby Isaac   PetscFunctionBegin;
6739c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6740c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6741c58f1c22SToby Isaac   PetscValidPointer(hasLabel, 3);
6742c58f1c22SToby Isaac   *hasLabel = PETSC_FALSE;
6743c58f1c22SToby Isaac   while (next) {
6744d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6745d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr);
6746c58f1c22SToby Isaac     if (*hasLabel) break;
6747c58f1c22SToby Isaac     next = next->next;
6748c58f1c22SToby Isaac   }
6749c58f1c22SToby Isaac   PetscFunctionReturn(0);
6750c58f1c22SToby Isaac }
6751c58f1c22SToby Isaac 
6752c58f1c22SToby Isaac /*@C
6753c58f1c22SToby Isaac   DMGetLabel - Return the label of a given name, or NULL
6754c58f1c22SToby Isaac 
6755c58f1c22SToby Isaac   Not Collective
6756c58f1c22SToby Isaac 
6757c58f1c22SToby Isaac   Input Parameters:
6758c58f1c22SToby Isaac + dm   - The DM object
6759c58f1c22SToby Isaac - name - The label name
6760c58f1c22SToby Isaac 
6761c58f1c22SToby Isaac   Output Parameter:
6762c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
6763c58f1c22SToby Isaac 
6764c58f1c22SToby Isaac   Level: intermediate
6765c58f1c22SToby Isaac 
6766c58f1c22SToby Isaac .keywords: mesh
6767c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6768c58f1c22SToby Isaac @*/
6769c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label)
6770c58f1c22SToby Isaac {
6771c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6772c58f1c22SToby Isaac   PetscBool      hasLabel;
6773d67d17b1SMatthew G. Knepley   const char    *lname;
6774c58f1c22SToby Isaac   PetscErrorCode ierr;
6775c58f1c22SToby Isaac 
6776c58f1c22SToby Isaac   PetscFunctionBegin;
6777c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6778c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6779c58f1c22SToby Isaac   PetscValidPointer(label, 3);
6780c58f1c22SToby Isaac   *label = NULL;
6781c58f1c22SToby Isaac   while (next) {
6782d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6783d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
6784c58f1c22SToby Isaac     if (hasLabel) {
6785c58f1c22SToby Isaac       *label = next->label;
6786c58f1c22SToby Isaac       break;
6787c58f1c22SToby Isaac     }
6788c58f1c22SToby Isaac     next = next->next;
6789c58f1c22SToby Isaac   }
6790c58f1c22SToby Isaac   PetscFunctionReturn(0);
6791c58f1c22SToby Isaac }
6792c58f1c22SToby Isaac 
6793c58f1c22SToby Isaac /*@C
6794c58f1c22SToby Isaac   DMGetLabelByNum - Return the nth label
6795c58f1c22SToby Isaac 
6796c58f1c22SToby Isaac   Not Collective
6797c58f1c22SToby Isaac 
6798c58f1c22SToby Isaac   Input Parameters:
6799c58f1c22SToby Isaac + dm - The DM object
6800c58f1c22SToby Isaac - n  - the label number
6801c58f1c22SToby Isaac 
6802c58f1c22SToby Isaac   Output Parameter:
6803c58f1c22SToby Isaac . label - the label
6804c58f1c22SToby Isaac 
6805c58f1c22SToby Isaac   Level: intermediate
6806c58f1c22SToby Isaac 
6807c58f1c22SToby Isaac .keywords: mesh
6808c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6809c58f1c22SToby Isaac @*/
6810c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label)
6811c58f1c22SToby Isaac {
6812c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
6813c58f1c22SToby Isaac   PetscInt    l    = 0;
6814c58f1c22SToby Isaac 
6815c58f1c22SToby Isaac   PetscFunctionBegin;
6816c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6817c58f1c22SToby Isaac   PetscValidPointer(label, 3);
6818c58f1c22SToby Isaac   while (next) {
6819c58f1c22SToby Isaac     if (l == n) {
6820c58f1c22SToby Isaac       *label = next->label;
6821c58f1c22SToby Isaac       PetscFunctionReturn(0);
6822c58f1c22SToby Isaac     }
6823c58f1c22SToby Isaac     ++l;
6824c58f1c22SToby Isaac     next = next->next;
6825c58f1c22SToby Isaac   }
6826c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
6827c58f1c22SToby Isaac }
6828c58f1c22SToby Isaac 
6829c58f1c22SToby Isaac /*@C
6830c58f1c22SToby Isaac   DMAddLabel - Add the label to this mesh
6831c58f1c22SToby Isaac 
6832c58f1c22SToby Isaac   Not Collective
6833c58f1c22SToby Isaac 
6834c58f1c22SToby Isaac   Input Parameters:
6835c58f1c22SToby Isaac + dm   - The DM object
6836c58f1c22SToby Isaac - label - The DMLabel
6837c58f1c22SToby Isaac 
6838c58f1c22SToby Isaac   Level: developer
6839c58f1c22SToby Isaac 
6840c58f1c22SToby Isaac .keywords: mesh
6841c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6842c58f1c22SToby Isaac @*/
6843c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label)
6844c58f1c22SToby Isaac {
6845c58f1c22SToby Isaac   DMLabelLink    tmpLabel;
6846c58f1c22SToby Isaac   PetscBool      hasLabel;
6847d67d17b1SMatthew G. Knepley   const char    *lname;
6848c58f1c22SToby Isaac   PetscErrorCode ierr;
6849c58f1c22SToby Isaac 
6850c58f1c22SToby Isaac   PetscFunctionBegin;
6851c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6852d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
6853d67d17b1SMatthew G. Knepley   ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr);
6854d67d17b1SMatthew G. Knepley   if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname);
6855c58f1c22SToby Isaac   ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
6856c58f1c22SToby Isaac   tmpLabel->label  = label;
6857c58f1c22SToby Isaac   tmpLabel->output = PETSC_TRUE;
6858c58f1c22SToby Isaac   tmpLabel->next   = dm->labels->next;
6859c58f1c22SToby Isaac   dm->labels->next = tmpLabel;
6860c58f1c22SToby Isaac   PetscFunctionReturn(0);
6861c58f1c22SToby Isaac }
6862c58f1c22SToby Isaac 
6863c58f1c22SToby Isaac /*@C
6864c58f1c22SToby Isaac   DMRemoveLabel - Remove the label from this mesh
6865c58f1c22SToby Isaac 
6866c58f1c22SToby Isaac   Not Collective
6867c58f1c22SToby Isaac 
6868c58f1c22SToby Isaac   Input Parameters:
6869c58f1c22SToby Isaac + dm   - The DM object
6870c58f1c22SToby Isaac - name - The label name
6871c58f1c22SToby Isaac 
6872c58f1c22SToby Isaac   Output Parameter:
6873c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
6874c58f1c22SToby Isaac 
6875c58f1c22SToby Isaac   Level: developer
6876c58f1c22SToby Isaac 
6877c58f1c22SToby Isaac .keywords: mesh
6878c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6879c58f1c22SToby Isaac @*/
6880c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label)
6881c58f1c22SToby Isaac {
6882c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6883c58f1c22SToby Isaac   DMLabelLink    last = NULL;
6884c58f1c22SToby Isaac   PetscBool      hasLabel;
6885d67d17b1SMatthew G. Knepley   const char    *lname;
6886c58f1c22SToby Isaac   PetscErrorCode ierr;
6887c58f1c22SToby Isaac 
6888c58f1c22SToby Isaac   PetscFunctionBegin;
6889c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6890c58f1c22SToby Isaac   ierr   = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr);
6891c58f1c22SToby Isaac   *label = NULL;
6892c58f1c22SToby Isaac   if (!hasLabel) PetscFunctionReturn(0);
6893c58f1c22SToby Isaac   while (next) {
6894d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6895d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
6896c58f1c22SToby Isaac     if (hasLabel) {
6897c58f1c22SToby Isaac       if (last) last->next       = next->next;
6898c58f1c22SToby Isaac       else      dm->labels->next = next->next;
6899c58f1c22SToby Isaac       next->next = NULL;
6900c58f1c22SToby Isaac       *label     = next->label;
6901c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr);
6902c58f1c22SToby Isaac       if (hasLabel) {
6903c58f1c22SToby Isaac         dm->depthLabel = NULL;
6904c58f1c22SToby Isaac       }
6905c58f1c22SToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
6906c58f1c22SToby Isaac       break;
6907c58f1c22SToby Isaac     }
6908c58f1c22SToby Isaac     last = next;
6909c58f1c22SToby Isaac     next = next->next;
6910c58f1c22SToby Isaac   }
6911c58f1c22SToby Isaac   PetscFunctionReturn(0);
6912c58f1c22SToby Isaac }
6913c58f1c22SToby Isaac 
6914c58f1c22SToby Isaac /*@C
6915c58f1c22SToby Isaac   DMGetLabelOutput - Get the output flag for a given label
6916c58f1c22SToby Isaac 
6917c58f1c22SToby Isaac   Not Collective
6918c58f1c22SToby Isaac 
6919c58f1c22SToby Isaac   Input Parameters:
6920c58f1c22SToby Isaac + dm   - The DM object
6921c58f1c22SToby Isaac - name - The label name
6922c58f1c22SToby Isaac 
6923c58f1c22SToby Isaac   Output Parameter:
6924c58f1c22SToby Isaac . output - The flag for output
6925c58f1c22SToby Isaac 
6926c58f1c22SToby Isaac   Level: developer
6927c58f1c22SToby Isaac 
6928c58f1c22SToby Isaac .keywords: mesh
6929c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6930c58f1c22SToby Isaac @*/
6931c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output)
6932c58f1c22SToby Isaac {
6933c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6934d67d17b1SMatthew G. Knepley   const char    *lname;
6935c58f1c22SToby Isaac   PetscErrorCode ierr;
6936c58f1c22SToby Isaac 
6937c58f1c22SToby Isaac   PetscFunctionBegin;
6938c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6939c58f1c22SToby Isaac   PetscValidPointer(name, 2);
6940c58f1c22SToby Isaac   PetscValidPointer(output, 3);
6941c58f1c22SToby Isaac   while (next) {
6942c58f1c22SToby Isaac     PetscBool flg;
6943c58f1c22SToby Isaac 
6944d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6945d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
6946c58f1c22SToby Isaac     if (flg) {*output = next->output; PetscFunctionReturn(0);}
6947c58f1c22SToby Isaac     next = next->next;
6948c58f1c22SToby Isaac   }
6949c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
6950c58f1c22SToby Isaac }
6951c58f1c22SToby Isaac 
6952c58f1c22SToby Isaac /*@C
6953c58f1c22SToby Isaac   DMSetLabelOutput - Set the output flag for a given label
6954c58f1c22SToby Isaac 
6955c58f1c22SToby Isaac   Not Collective
6956c58f1c22SToby Isaac 
6957c58f1c22SToby Isaac   Input Parameters:
6958c58f1c22SToby Isaac + dm     - The DM object
6959c58f1c22SToby Isaac . name   - The label name
6960c58f1c22SToby Isaac - output - The flag for output
6961c58f1c22SToby Isaac 
6962c58f1c22SToby Isaac   Level: developer
6963c58f1c22SToby Isaac 
6964c58f1c22SToby Isaac .keywords: mesh
6965c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6966c58f1c22SToby Isaac @*/
6967c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output)
6968c58f1c22SToby Isaac {
6969c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6970d67d17b1SMatthew G. Knepley   const char    *lname;
6971c58f1c22SToby Isaac   PetscErrorCode ierr;
6972c58f1c22SToby Isaac 
6973c58f1c22SToby Isaac   PetscFunctionBegin;
6974c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6975c58f1c22SToby Isaac   PetscValidPointer(name, 2);
6976c58f1c22SToby Isaac   while (next) {
6977c58f1c22SToby Isaac     PetscBool flg;
6978c58f1c22SToby Isaac 
6979d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6980d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
6981c58f1c22SToby Isaac     if (flg) {next->output = output; PetscFunctionReturn(0);}
6982c58f1c22SToby Isaac     next = next->next;
6983c58f1c22SToby Isaac   }
6984c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
6985c58f1c22SToby Isaac }
6986c58f1c22SToby Isaac 
6987c58f1c22SToby Isaac 
6988c58f1c22SToby Isaac /*@
6989c58f1c22SToby Isaac   DMCopyLabels - Copy labels from one mesh to another with a superset of the points
6990c58f1c22SToby Isaac 
6991c58f1c22SToby Isaac   Collective on DM
6992c58f1c22SToby Isaac 
6993c58f1c22SToby Isaac   Input Parameter:
69942e17dfb7SMatthew G. Knepley . dmA - The DM object with initial labels
6995c58f1c22SToby Isaac 
6996c58f1c22SToby Isaac   Output Parameter:
69972e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels
6998c58f1c22SToby Isaac 
6999c58f1c22SToby Isaac   Level: intermediate
7000c58f1c22SToby Isaac 
7001c58f1c22SToby Isaac   Note: This is typically used when interpolating or otherwise adding to a mesh
7002c58f1c22SToby Isaac 
7003c58f1c22SToby Isaac .keywords: mesh
7004367003a6SStefano Zampini .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection()
7005c58f1c22SToby Isaac @*/
7006c58f1c22SToby Isaac PetscErrorCode DMCopyLabels(DM dmA, DM dmB)
7007c58f1c22SToby Isaac {
7008c58f1c22SToby Isaac   PetscInt       numLabels, l;
7009c58f1c22SToby Isaac   PetscErrorCode ierr;
7010c58f1c22SToby Isaac 
7011c58f1c22SToby Isaac   PetscFunctionBegin;
7012c58f1c22SToby Isaac   if (dmA == dmB) PetscFunctionReturn(0);
7013c58f1c22SToby Isaac   ierr = DMGetNumLabels(dmA, &numLabels);CHKERRQ(ierr);
7014c58f1c22SToby Isaac   for (l = 0; l < numLabels; ++l) {
7015c58f1c22SToby Isaac     DMLabel     label, labelNew;
7016c58f1c22SToby Isaac     const char *name;
7017c58f1c22SToby Isaac     PetscBool   flg;
7018c58f1c22SToby Isaac 
7019c58f1c22SToby Isaac     ierr = DMGetLabelName(dmA, l, &name);CHKERRQ(ierr);
7020c58f1c22SToby Isaac     ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr);
7021c58f1c22SToby Isaac     if (flg) continue;
70227d5acc75SStefano Zampini     ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr);
70237d5acc75SStefano Zampini     if (flg) continue;
7024c58f1c22SToby Isaac     ierr = DMGetLabel(dmA, name, &label);CHKERRQ(ierr);
7025c58f1c22SToby Isaac     ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr);
7026c58f1c22SToby Isaac     ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr);
7027c58f1c22SToby Isaac   }
7028c58f1c22SToby Isaac   PetscFunctionReturn(0);
7029c58f1c22SToby Isaac }
7030a8fb8f29SToby Isaac 
7031a8fb8f29SToby Isaac /*@
7032a8fb8f29SToby Isaac   DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement
7033a8fb8f29SToby Isaac 
7034a8fb8f29SToby Isaac   Input Parameter:
7035a8fb8f29SToby Isaac . dm - The DM object
7036a8fb8f29SToby Isaac 
7037a8fb8f29SToby Isaac   Output Parameter:
7038a8fb8f29SToby Isaac . cdm - The coarse DM
7039a8fb8f29SToby Isaac 
7040a8fb8f29SToby Isaac   Level: intermediate
7041a8fb8f29SToby Isaac 
7042a8fb8f29SToby Isaac .seealso: DMSetCoarseDM()
7043a8fb8f29SToby Isaac @*/
7044a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm)
7045a8fb8f29SToby Isaac {
7046a8fb8f29SToby Isaac   PetscFunctionBegin;
7047a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7048a8fb8f29SToby Isaac   PetscValidPointer(cdm, 2);
7049a8fb8f29SToby Isaac   *cdm = dm->coarseMesh;
7050a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7051a8fb8f29SToby Isaac }
7052a8fb8f29SToby Isaac 
7053a8fb8f29SToby Isaac /*@
7054a8fb8f29SToby Isaac   DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement
7055a8fb8f29SToby Isaac 
7056a8fb8f29SToby Isaac   Input Parameters:
7057a8fb8f29SToby Isaac + dm - The DM object
7058a8fb8f29SToby Isaac - cdm - The coarse DM
7059a8fb8f29SToby Isaac 
7060a8fb8f29SToby Isaac   Level: intermediate
7061a8fb8f29SToby Isaac 
7062a8fb8f29SToby Isaac .seealso: DMGetCoarseDM()
7063a8fb8f29SToby Isaac @*/
7064a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm)
7065a8fb8f29SToby Isaac {
7066a8fb8f29SToby Isaac   PetscErrorCode ierr;
7067a8fb8f29SToby Isaac 
7068a8fb8f29SToby Isaac   PetscFunctionBegin;
7069a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7070a8fb8f29SToby Isaac   if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2);
7071a8fb8f29SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
7072a8fb8f29SToby Isaac   ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr);
7073a8fb8f29SToby Isaac   dm->coarseMesh = cdm;
7074a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7075a8fb8f29SToby Isaac }
7076a8fb8f29SToby Isaac 
707788bdff64SToby Isaac /*@
707888bdff64SToby Isaac   DMGetFineDM - Get the fine mesh from which this was obtained by refinement
707988bdff64SToby Isaac 
708088bdff64SToby Isaac   Input Parameter:
708188bdff64SToby Isaac . dm - The DM object
708288bdff64SToby Isaac 
708388bdff64SToby Isaac   Output Parameter:
708488bdff64SToby Isaac . fdm - The fine DM
708588bdff64SToby Isaac 
708688bdff64SToby Isaac   Level: intermediate
708788bdff64SToby Isaac 
708888bdff64SToby Isaac .seealso: DMSetFineDM()
708988bdff64SToby Isaac @*/
709088bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm)
709188bdff64SToby Isaac {
709288bdff64SToby Isaac   PetscFunctionBegin;
709388bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
709488bdff64SToby Isaac   PetscValidPointer(fdm, 2);
709588bdff64SToby Isaac   *fdm = dm->fineMesh;
709688bdff64SToby Isaac   PetscFunctionReturn(0);
709788bdff64SToby Isaac }
709888bdff64SToby Isaac 
709988bdff64SToby Isaac /*@
710088bdff64SToby Isaac   DMSetFineDM - Set the fine mesh from which this was obtained by refinement
710188bdff64SToby Isaac 
710288bdff64SToby Isaac   Input Parameters:
710388bdff64SToby Isaac + dm - The DM object
710488bdff64SToby Isaac - fdm - The fine DM
710588bdff64SToby Isaac 
710688bdff64SToby Isaac   Level: intermediate
710788bdff64SToby Isaac 
710888bdff64SToby Isaac .seealso: DMGetFineDM()
710988bdff64SToby Isaac @*/
711088bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm)
711188bdff64SToby Isaac {
711288bdff64SToby Isaac   PetscErrorCode ierr;
711388bdff64SToby Isaac 
711488bdff64SToby Isaac   PetscFunctionBegin;
711588bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
711688bdff64SToby Isaac   if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2);
711788bdff64SToby Isaac   ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr);
711888bdff64SToby Isaac   ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr);
711988bdff64SToby Isaac   dm->fineMesh = fdm;
712088bdff64SToby Isaac   PetscFunctionReturn(0);
712188bdff64SToby Isaac }
712288bdff64SToby Isaac 
7123a6ba4734SToby Isaac /*=== DMBoundary code ===*/
7124a6ba4734SToby Isaac 
7125a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew)
7126a6ba4734SToby Isaac {
7127e5e52638SMatthew G. Knepley   PetscInt       d;
7128a6ba4734SToby Isaac   PetscErrorCode ierr;
7129a6ba4734SToby Isaac 
7130a6ba4734SToby Isaac   PetscFunctionBegin;
7131e5e52638SMatthew G. Knepley   for (d = 0; d < dm->Nds; ++d) {
7132e5e52638SMatthew G. Knepley     ierr = PetscDSCopyBoundary(dm->probs[d].ds, dmNew->probs[d].ds);CHKERRQ(ierr);
7133e5e52638SMatthew G. Knepley   }
7134a6ba4734SToby Isaac   PetscFunctionReturn(0);
7135a6ba4734SToby Isaac }
7136a6ba4734SToby Isaac 
7137a6ba4734SToby Isaac /*@C
7138a6ba4734SToby Isaac   DMAddBoundary - Add a boundary condition to the model
7139a6ba4734SToby Isaac 
7140a6ba4734SToby Isaac   Input Parameters:
71414c258f51SMatthew G. Knepley + dm          - The DM, with a PetscDS that matches the problem being constrained
7142f971fd6bSMatthew G. Knepley . type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7143a6ba4734SToby Isaac . name        - The BC name
7144a6ba4734SToby Isaac . labelname   - The label defining constrained points
7145a6ba4734SToby Isaac . field       - The field to constrain
7146e8ecbf3fSStefano Zampini . numcomps    - The number of constrained field components (0 will constrain all fields)
7147a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7148a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7149a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7150a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7151a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7152a6ba4734SToby Isaac 
7153a6ba4734SToby Isaac   Options Database Keys:
7154a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7155a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7156a6ba4734SToby Isaac 
7157a6ba4734SToby Isaac   Level: developer
7158a6ba4734SToby Isaac 
7159a6ba4734SToby Isaac .seealso: DMGetBoundary()
7160a6ba4734SToby Isaac @*/
7161a30ec4eaSSatish Balay PetscErrorCode DMAddBoundary(DM dm, DMBoundaryConditionType type, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(void), PetscInt numids, const PetscInt *ids, void *ctx)
7162a6ba4734SToby Isaac {
7163e5e52638SMatthew G. Knepley   PetscDS        ds;
7164a6ba4734SToby Isaac   PetscErrorCode ierr;
7165a6ba4734SToby Isaac 
7166a6ba4734SToby Isaac   PetscFunctionBegin;
7167a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7168e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7169e5e52638SMatthew G. Knepley   ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, numids, ids, ctx);CHKERRQ(ierr);
7170a6ba4734SToby Isaac   PetscFunctionReturn(0);
7171a6ba4734SToby Isaac }
7172a6ba4734SToby Isaac 
7173a6ba4734SToby Isaac /*@
7174a6ba4734SToby Isaac   DMGetNumBoundary - Get the number of registered BC
7175a6ba4734SToby Isaac 
7176a6ba4734SToby Isaac   Input Parameters:
7177a6ba4734SToby Isaac . dm - The mesh object
7178a6ba4734SToby Isaac 
7179a6ba4734SToby Isaac   Output Parameters:
7180a6ba4734SToby Isaac . numBd - The number of BC
7181a6ba4734SToby Isaac 
7182a6ba4734SToby Isaac   Level: intermediate
7183a6ba4734SToby Isaac 
7184a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary()
7185a6ba4734SToby Isaac @*/
7186a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd)
7187a6ba4734SToby Isaac {
7188e5e52638SMatthew G. Knepley   PetscDS        ds;
718958ebd649SToby Isaac   PetscErrorCode ierr;
7190a6ba4734SToby Isaac 
7191a6ba4734SToby Isaac   PetscFunctionBegin;
7192a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7193e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7194e5e52638SMatthew G. Knepley   ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr);
7195a6ba4734SToby Isaac   PetscFunctionReturn(0);
7196a6ba4734SToby Isaac }
7197a6ba4734SToby Isaac 
7198a6ba4734SToby Isaac /*@C
71991c531cf8SMatthew G. Knepley   DMGetBoundary - Get a model boundary condition
7200a6ba4734SToby Isaac 
7201a6ba4734SToby Isaac   Input Parameters:
7202a6ba4734SToby Isaac + dm          - The mesh object
7203a6ba4734SToby Isaac - bd          - The BC number
7204a6ba4734SToby Isaac 
7205a6ba4734SToby Isaac   Output Parameters:
7206f971fd6bSMatthew G. Knepley + type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7207a6ba4734SToby Isaac . name        - The BC name
7208a6ba4734SToby Isaac . labelname   - The label defining constrained points
7209a6ba4734SToby Isaac . field       - The field to constrain
7210a6ba4734SToby Isaac . numcomps    - The number of constrained field components
7211a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7212a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7213a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7214a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7215a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7216a6ba4734SToby Isaac 
7217a6ba4734SToby Isaac   Options Database Keys:
7218a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7219a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7220a6ba4734SToby Isaac 
7221a6ba4734SToby Isaac   Level: developer
7222a6ba4734SToby Isaac 
7223a6ba4734SToby Isaac .seealso: DMAddBoundary()
7224a6ba4734SToby Isaac @*/
7225a30ec4eaSSatish Balay PetscErrorCode DMGetBoundary(DM dm, PetscInt bd, DMBoundaryConditionType *type, const char **name, const char **labelname, PetscInt *field, PetscInt *numcomps, const PetscInt **comps, void (**func)(void), PetscInt *numids, const PetscInt **ids, void **ctx)
7226a6ba4734SToby Isaac {
7227e5e52638SMatthew G. Knepley   PetscDS        ds;
722858ebd649SToby Isaac   PetscErrorCode ierr;
7229a6ba4734SToby Isaac 
7230a6ba4734SToby Isaac   PetscFunctionBegin;
7231a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7232e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7233e5e52638SMatthew G. Knepley   ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, numids, ids, ctx);CHKERRQ(ierr);
7234a6ba4734SToby Isaac   PetscFunctionReturn(0);
7235a6ba4734SToby Isaac }
7236a6ba4734SToby Isaac 
7237e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm)
7238e6f8dbb6SToby Isaac {
7239e5e52638SMatthew G. Knepley   PetscDS        ds;
7240dff059c6SToby Isaac   DMBoundary    *lastnext;
7241e6f8dbb6SToby Isaac   DSBoundary     dsbound;
7242e6f8dbb6SToby Isaac   PetscErrorCode ierr;
7243e6f8dbb6SToby Isaac 
7244e6f8dbb6SToby Isaac   PetscFunctionBegin;
7245e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7246e5e52638SMatthew G. Knepley   dsbound = ds->boundary;
724747a1f5adSToby Isaac   if (dm->boundary) {
724847a1f5adSToby Isaac     DMBoundary next = dm->boundary;
724947a1f5adSToby Isaac 
725047a1f5adSToby Isaac     /* quick check to see if the PetscDS has changed */
725147a1f5adSToby Isaac     if (next->dsboundary == dsbound) PetscFunctionReturn(0);
725247a1f5adSToby Isaac     /* the PetscDS has changed: tear down and rebuild */
725347a1f5adSToby Isaac     while (next) {
725447a1f5adSToby Isaac       DMBoundary b = next;
725547a1f5adSToby Isaac 
725647a1f5adSToby Isaac       next = b->next;
725747a1f5adSToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
7258a6ba4734SToby Isaac     }
725947a1f5adSToby Isaac     dm->boundary = NULL;
7260a6ba4734SToby Isaac   }
726147a1f5adSToby Isaac 
7262dff059c6SToby Isaac   lastnext = &(dm->boundary);
7263e6f8dbb6SToby Isaac   while (dsbound) {
7264e6f8dbb6SToby Isaac     DMBoundary dmbound;
7265e6f8dbb6SToby Isaac 
7266e6f8dbb6SToby Isaac     ierr = PetscNew(&dmbound);CHKERRQ(ierr);
7267e6f8dbb6SToby Isaac     dmbound->dsboundary = dsbound;
7268e6f8dbb6SToby Isaac     ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr);
7269994fe344SLisandro Dalcin     if (!dmbound->label) {ierr = PetscInfo2(dm, "DSBoundary %s wants label %s, which is not in this dm.\n",dsbound->name,dsbound->labelname);CHKERRQ(ierr);}
727047a1f5adSToby Isaac     /* push on the back instead of the front so that it is in the same order as in the PetscDS */
7271dff059c6SToby Isaac     *lastnext = dmbound;
7272dff059c6SToby Isaac     lastnext = &(dmbound->next);
7273dff059c6SToby Isaac     dsbound = dsbound->next;
7274a6ba4734SToby Isaac   }
7275a6ba4734SToby Isaac   PetscFunctionReturn(0);
7276a6ba4734SToby Isaac }
7277a6ba4734SToby Isaac 
7278a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd)
7279a6ba4734SToby Isaac {
7280b95f2879SToby Isaac   DMBoundary     b;
7281a6ba4734SToby Isaac   PetscErrorCode ierr;
7282a6ba4734SToby Isaac 
7283a6ba4734SToby Isaac   PetscFunctionBegin;
7284a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7285a6ba4734SToby Isaac   PetscValidPointer(isBd, 3);
7286a6ba4734SToby Isaac   *isBd = PETSC_FALSE;
7287e6f8dbb6SToby Isaac   ierr = DMPopulateBoundary(dm);CHKERRQ(ierr);
7288b95f2879SToby Isaac   b = dm->boundary;
7289a6ba4734SToby Isaac   while (b && !(*isBd)) {
7290e6f8dbb6SToby Isaac     DMLabel    label = b->label;
7291e6f8dbb6SToby Isaac     DSBoundary dsb = b->dsboundary;
72923424c85cSToby Isaac 
72933424c85cSToby Isaac     if (label) {
7294a6ba4734SToby Isaac       PetscInt i;
7295a6ba4734SToby Isaac 
7296e6f8dbb6SToby Isaac       for (i = 0; i < dsb->numids && !(*isBd); ++i) {
7297e6f8dbb6SToby Isaac         ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr);
7298a6ba4734SToby Isaac       }
7299a6ba4734SToby Isaac     }
7300a6ba4734SToby Isaac     b = b->next;
7301a6ba4734SToby Isaac   }
7302a6ba4734SToby Isaac   PetscFunctionReturn(0);
7303a6ba4734SToby Isaac }
73044d6f44ffSToby Isaac 
73054d6f44ffSToby Isaac /*@C
73064d6f44ffSToby Isaac   DMProjectFunction - This projects the given function into the function space provided.
73074d6f44ffSToby Isaac 
73084d6f44ffSToby Isaac   Input Parameters:
73094d6f44ffSToby Isaac + dm      - The DM
73100709b2feSToby Isaac . time    - The time
73114d6f44ffSToby Isaac . funcs   - The coordinate functions to evaluate, one per field
73124d6f44ffSToby Isaac . ctxs    - Optional array of contexts to pass to each coordinate function.  ctxs itself may be null.
73134d6f44ffSToby Isaac - mode    - The insertion mode for values
73144d6f44ffSToby Isaac 
73154d6f44ffSToby Isaac   Output Parameter:
73164d6f44ffSToby Isaac . X - vector
73174d6f44ffSToby Isaac 
73184d6f44ffSToby Isaac    Calling sequence of func:
73190709b2feSToby Isaac $    func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx);
73204d6f44ffSToby Isaac 
73214d6f44ffSToby Isaac +  dim - The spatial dimension
73224d6f44ffSToby Isaac .  x   - The coordinates
73234d6f44ffSToby Isaac .  Nf  - The number of fields
73244d6f44ffSToby Isaac .  u   - The output field values
73254d6f44ffSToby Isaac -  ctx - optional user-defined function context
73264d6f44ffSToby Isaac 
73274d6f44ffSToby Isaac   Level: developer
73284d6f44ffSToby Isaac 
73292716604bSToby Isaac .seealso: DMComputeL2Diff()
73304d6f44ffSToby Isaac @*/
73310709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X)
73324d6f44ffSToby Isaac {
73334d6f44ffSToby Isaac   Vec            localX;
73344d6f44ffSToby Isaac   PetscErrorCode ierr;
73354d6f44ffSToby Isaac 
73364d6f44ffSToby Isaac   PetscFunctionBegin;
73374d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
73384d6f44ffSToby Isaac   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
73390709b2feSToby Isaac   ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
73404d6f44ffSToby Isaac   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
73414d6f44ffSToby Isaac   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
73424d6f44ffSToby Isaac   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
73434d6f44ffSToby Isaac   PetscFunctionReturn(0);
73444d6f44ffSToby Isaac }
73454d6f44ffSToby Isaac 
73460709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
73474d6f44ffSToby Isaac {
73484d6f44ffSToby Isaac   PetscErrorCode ierr;
73494d6f44ffSToby Isaac 
73504d6f44ffSToby Isaac   PetscFunctionBegin;
73514d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
73524d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
73530918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name);
73540709b2feSToby Isaac   ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
73554d6f44ffSToby Isaac   PetscFunctionReturn(0);
73564d6f44ffSToby Isaac }
73574d6f44ffSToby Isaac 
73582c53366bSMatthew 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)
73592c53366bSMatthew G. Knepley {
73602c53366bSMatthew G. Knepley   Vec            localX;
73612c53366bSMatthew G. Knepley   PetscErrorCode ierr;
73622c53366bSMatthew G. Knepley 
73632c53366bSMatthew G. Knepley   PetscFunctionBegin;
73642c53366bSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
73652c53366bSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
73662c53366bSMatthew G. Knepley   ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
73672c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
73682c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
73692c53366bSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
73702c53366bSMatthew G. Knepley   PetscFunctionReturn(0);
73712c53366bSMatthew G. Knepley }
73722c53366bSMatthew G. Knepley 
73731c531cf8SMatthew 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)
73744d6f44ffSToby Isaac {
73754d6f44ffSToby Isaac   PetscErrorCode ierr;
73764d6f44ffSToby Isaac 
73774d6f44ffSToby Isaac   PetscFunctionBegin;
73784d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
73794d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
73800918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name);
73811c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
73824d6f44ffSToby Isaac   PetscFunctionReturn(0);
73834d6f44ffSToby Isaac }
73842716604bSToby Isaac 
73858c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU,
73868c6c5593SMatthew G. Knepley                                    void (**funcs)(PetscInt, PetscInt, PetscInt,
73878c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
73888c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7389191494d9SMatthew G. Knepley                                                   PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
73908c6c5593SMatthew G. Knepley                                    InsertMode mode, Vec localX)
73918c6c5593SMatthew G. Knepley {
73928c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
73938c6c5593SMatthew G. Knepley 
73948c6c5593SMatthew G. Knepley   PetscFunctionBegin;
73958c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
73968c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,3);
73978c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,6);
73980918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
73998c6c5593SMatthew G. Knepley   ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr);
74008c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
74018c6c5593SMatthew G. Knepley }
74028c6c5593SMatthew G. Knepley 
74031c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU,
74048c6c5593SMatthew G. Knepley                                         void (**funcs)(PetscInt, PetscInt, PetscInt,
74058c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
74068c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7407191494d9SMatthew G. Knepley                                                        PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
74088c6c5593SMatthew G. Knepley                                         InsertMode mode, Vec localX)
74098c6c5593SMatthew G. Knepley {
74108c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
74118c6c5593SMatthew G. Knepley 
74128c6c5593SMatthew G. Knepley   PetscFunctionBegin;
74138c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
74148c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,6);
74158c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,9);
74160918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
74171c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr);
74188c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
74198c6c5593SMatthew G. Knepley }
74208c6c5593SMatthew G. Knepley 
74212716604bSToby Isaac /*@C
74222716604bSToby Isaac   DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h.
74232716604bSToby Isaac 
74242716604bSToby Isaac   Input Parameters:
74252716604bSToby Isaac + dm    - The DM
74260709b2feSToby Isaac . time  - The time
74272716604bSToby Isaac . funcs - The functions to evaluate for each field component
74282716604bSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7429574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
74302716604bSToby Isaac 
74312716604bSToby Isaac   Output Parameter:
74322716604bSToby Isaac . diff - The diff ||u - u_h||_2
74332716604bSToby Isaac 
74342716604bSToby Isaac   Level: developer
74352716604bSToby Isaac 
74361189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
74372716604bSToby Isaac @*/
74380709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff)
74392716604bSToby Isaac {
74402716604bSToby Isaac   PetscErrorCode ierr;
74412716604bSToby Isaac 
74422716604bSToby Isaac   PetscFunctionBegin;
74432716604bSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7444b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
74450918c465SMatthew G. Knepley   if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name);
74460709b2feSToby Isaac   ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
74472716604bSToby Isaac   PetscFunctionReturn(0);
74482716604bSToby Isaac }
7449b698f381SToby Isaac 
7450b698f381SToby Isaac /*@C
7451b698f381SToby Isaac   DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h.
7452b698f381SToby Isaac 
7453b698f381SToby Isaac   Input Parameters:
7454b698f381SToby Isaac + dm    - The DM
7455b698f381SToby Isaac , time  - The time
7456b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component
7457b698f381SToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7458574a98acSMatthew G. Knepley . X     - The coefficient vector u_h, a global vector
7459b698f381SToby Isaac - n     - The vector to project along
7460b698f381SToby Isaac 
7461b698f381SToby Isaac   Output Parameter:
7462b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2
7463b698f381SToby Isaac 
7464b698f381SToby Isaac   Level: developer
7465b698f381SToby Isaac 
7466b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff()
7467b698f381SToby Isaac @*/
7468b698f381SToby 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)
7469b698f381SToby Isaac {
7470b698f381SToby Isaac   PetscErrorCode ierr;
7471b698f381SToby Isaac 
7472b698f381SToby Isaac   PetscFunctionBegin;
7473b698f381SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7474b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
7475b698f381SToby Isaac   if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name);
7476b698f381SToby Isaac   ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr);
7477b698f381SToby Isaac   PetscFunctionReturn(0);
7478b698f381SToby Isaac }
7479b698f381SToby Isaac 
74802a16baeaSToby Isaac /*@C
74812a16baeaSToby Isaac   DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components.
74822a16baeaSToby Isaac 
74832a16baeaSToby Isaac   Input Parameters:
74842a16baeaSToby Isaac + dm    - The DM
74852a16baeaSToby Isaac . time  - The time
74862a16baeaSToby Isaac . funcs - The functions to evaluate for each field component
74872a16baeaSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7488574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
74892a16baeaSToby Isaac 
74902a16baeaSToby Isaac   Output Parameter:
74912a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2
74922a16baeaSToby Isaac 
74932a16baeaSToby Isaac   Level: developer
74942a16baeaSToby Isaac 
74951189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
74962a16baeaSToby Isaac @*/
74971189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[])
74982a16baeaSToby Isaac {
74992a16baeaSToby Isaac   PetscErrorCode ierr;
75002a16baeaSToby Isaac 
75012a16baeaSToby Isaac   PetscFunctionBegin;
75022a16baeaSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75032a16baeaSToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
75040918c465SMatthew G. Knepley   if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name);
75052a16baeaSToby Isaac   ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
75062a16baeaSToby Isaac   PetscFunctionReturn(0);
75072a16baeaSToby Isaac }
75082a16baeaSToby Isaac 
7509df0b854cSToby Isaac /*@C
7510df0b854cSToby Isaac   DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags.  Specific implementations of DM maybe have
7511cd3c525cSToby Isaac                  specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN.
7512df0b854cSToby Isaac 
7513df0b854cSToby Isaac   Collective on dm
7514df0b854cSToby Isaac 
7515df0b854cSToby Isaac   Input parameters:
7516df0b854cSToby Isaac + dm - the pre-adaptation DM object
7517a1b0c543SToby Isaac - label - label with the flags
7518df0b854cSToby Isaac 
7519df0b854cSToby Isaac   Output parameters:
75200d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced.
7521df0b854cSToby Isaac 
7522df0b854cSToby Isaac   Level: intermediate
75230d1cd5e0SMatthew G. Knepley 
75240d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine()
7525df0b854cSToby Isaac @*/
75260d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt)
7527df0b854cSToby Isaac {
7528df0b854cSToby Isaac   PetscErrorCode ierr;
7529df0b854cSToby Isaac 
7530df0b854cSToby Isaac   PetscFunctionBegin;
7531df0b854cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7532a1b0c543SToby Isaac   PetscValidPointer(label,2);
75330d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt,3);
75340d1cd5e0SMatthew G. Knepley   *dmAdapt = NULL;
75356f25b0d8SLisandro Dalcin   if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name);
75360d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr);
75370d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
75380d1cd5e0SMatthew G. Knepley }
75390d1cd5e0SMatthew G. Knepley 
75400d1cd5e0SMatthew G. Knepley /*@C
75410d1cd5e0SMatthew G. Knepley   DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library.
75420d1cd5e0SMatthew G. Knepley 
75430d1cd5e0SMatthew G. Knepley   Input Parameters:
75440d1cd5e0SMatthew G. Knepley + dm - The DM object
75450d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise.
75466f25b0d8SLisandro Dalcin - bdLabel - Label for boundary tags, which will be preserved in the output mesh. bdLabel should be NULL if there is no such label, and should be different from "_boundary_".
75470d1cd5e0SMatthew G. Knepley 
75480d1cd5e0SMatthew G. Knepley   Output Parameter:
75490d1cd5e0SMatthew G. Knepley . dmAdapt  - Pointer to the DM object containing the adapted mesh
75500d1cd5e0SMatthew G. Knepley 
75510d1cd5e0SMatthew G. Knepley   Note: The label in the adapted mesh will be registered under the name of the input DMLabel object
75520d1cd5e0SMatthew G. Knepley 
75530d1cd5e0SMatthew G. Knepley   Level: advanced
75540d1cd5e0SMatthew G. Knepley 
75550d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine()
75560d1cd5e0SMatthew G. Knepley @*/
75570d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt)
75580d1cd5e0SMatthew G. Knepley {
75590d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
75600d1cd5e0SMatthew G. Knepley 
75610d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
75620d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
75630d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(metric, VEC_CLASSID, 2);
75640d1cd5e0SMatthew G. Knepley   if (bdLabel) PetscValidPointer(bdLabel, 3);
75650d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt, 4);
75666f25b0d8SLisandro Dalcin   *dmAdapt = NULL;
75676f25b0d8SLisandro Dalcin   if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name);
75680d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr);
7569df0b854cSToby Isaac   PetscFunctionReturn(0);
7570df0b854cSToby Isaac }
7571c4088d22SMatthew G. Knepley 
7572502a2867SDave May /*@C
7573502a2867SDave May  DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors
7574502a2867SDave May 
7575502a2867SDave May  Not Collective
7576502a2867SDave May 
7577502a2867SDave May  Input Parameter:
7578502a2867SDave May  . dm    - The DM
7579502a2867SDave May 
7580502a2867SDave May  Output Parameter:
7581502a2867SDave May  . nranks - the number of neighbours
7582502a2867SDave May  . ranks - the neighbors ranks
7583502a2867SDave May 
7584502a2867SDave May  Notes:
7585502a2867SDave May  Do not free the array, it is freed when the DM is destroyed.
7586502a2867SDave May 
7587502a2867SDave May  Level: beginner
7588502a2867SDave May 
7589dee935c1SDave May  .seealso: DMDAGetNeighbors(), PetscSFGetRanks()
7590502a2867SDave May @*/
7591502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[])
7592502a2867SDave May {
7593502a2867SDave May   PetscErrorCode ierr;
7594502a2867SDave May 
7595502a2867SDave May   PetscFunctionBegin;
7596502a2867SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75970918c465SMatthew G. Knepley   if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name);
7598502a2867SDave May   ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr);
7599502a2867SDave May   PetscFunctionReturn(0);
7600502a2867SDave May }
7601502a2867SDave May 
7602531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */
7603531c7667SBarry Smith 
7604531c7667SBarry Smith /*
7605531c7667SBarry Smith     Converts the input vector to a ghosted vector and then calls the standard coloring code.
7606531c7667SBarry Smith     This has be a different function because it requires DM which is not defined in the Mat library
7607531c7667SBarry Smith */
7608531c7667SBarry Smith PetscErrorCode  MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx)
7609531c7667SBarry Smith {
7610531c7667SBarry Smith   PetscErrorCode ierr;
7611531c7667SBarry Smith 
7612531c7667SBarry Smith   PetscFunctionBegin;
7613531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7614531c7667SBarry Smith     Vec x1local;
7615531c7667SBarry Smith     DM  dm;
7616531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
7617531c7667SBarry Smith     if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM");
7618531c7667SBarry Smith     ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr);
7619531c7667SBarry Smith     ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
7620531c7667SBarry Smith     ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
7621531c7667SBarry Smith     x1   = x1local;
7622531c7667SBarry Smith   }
7623531c7667SBarry Smith   ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr);
7624531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7625531c7667SBarry Smith     DM  dm;
7626531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
7627531c7667SBarry Smith     ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr);
7628531c7667SBarry Smith   }
7629531c7667SBarry Smith   PetscFunctionReturn(0);
7630531c7667SBarry Smith }
7631531c7667SBarry Smith 
7632531c7667SBarry Smith /*@
7633531c7667SBarry Smith     MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring
7634531c7667SBarry Smith 
7635531c7667SBarry Smith     Input Parameter:
7636531c7667SBarry Smith .    coloring - the MatFDColoring object
7637531c7667SBarry Smith 
763895452b02SPatrick Sanan     Developer Notes:
763995452b02SPatrick Sanan     this routine exists because the PETSc Mat library does not know about the DM objects
7640531c7667SBarry Smith 
76411b266c99SBarry Smith     Level: advanced
76421b266c99SBarry Smith 
7643531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType
7644531c7667SBarry Smith @*/
7645531c7667SBarry Smith PetscErrorCode  MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring)
7646531c7667SBarry Smith {
7647531c7667SBarry Smith   PetscFunctionBegin;
7648531c7667SBarry Smith   coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM;
7649531c7667SBarry Smith   PetscFunctionReturn(0);
7650531c7667SBarry Smith }
76518320bc6fSPatrick Sanan 
76528320bc6fSPatrick Sanan /*@
76538320bc6fSPatrick Sanan     DMGetCompatibility - determine if two DMs are compatible
76548320bc6fSPatrick Sanan 
76558320bc6fSPatrick Sanan     Collective
76568320bc6fSPatrick Sanan 
76578320bc6fSPatrick Sanan     Input Parameters:
76588320bc6fSPatrick Sanan +    dm - the first DM
76598320bc6fSPatrick Sanan -    dm2 - the second DM
76608320bc6fSPatrick Sanan 
76618320bc6fSPatrick Sanan     Output Parameters:
76628320bc6fSPatrick Sanan +    compatible - whether or not the two DMs are compatible
76638320bc6fSPatrick Sanan -    set - whether or not the compatible value was set
76648320bc6fSPatrick Sanan 
76658320bc6fSPatrick Sanan     Notes:
76668320bc6fSPatrick Sanan     Two DMs are deemed compatible if they represent the same parallel decomposition
76678320bc6fSPatrick Sanan     of the same topology. This implies that the the section (field data) on one
76688320bc6fSPatrick Sanan     "makes sense" with respect to the topology and parallel decomposition of the other.
76698320bc6fSPatrick Sanan     Loosely speaking, compatibile DMs represent the same domain, with the same parallel
76708320bc6fSPatrick Sanan     decomposition, with different data.
76718320bc6fSPatrick Sanan 
76728320bc6fSPatrick Sanan     Typically, one would confirm compatibility if intending to simultaneously iterate
76738320bc6fSPatrick Sanan     over a pair of vectors obtained from different DMs.
76748320bc6fSPatrick Sanan 
76758320bc6fSPatrick Sanan     For example, two DMDA objects are compatible if they have the same local
76768320bc6fSPatrick Sanan     and global sizes and the same stencil width. They can have different numbers
76778320bc6fSPatrick Sanan     of degrees of freedom per node. Thus, one could use the node numbering from
76788320bc6fSPatrick Sanan     either DM in bounds for a loop over vectors derived from either DM.
76798320bc6fSPatrick Sanan 
76808320bc6fSPatrick Sanan     Consider the operation of summing data living on a 2-dof DMDA to data living
76818320bc6fSPatrick Sanan     on a 1-dof DMDA, which should be compatible, as in the following snippet.
76828320bc6fSPatrick Sanan .vb
76838320bc6fSPatrick Sanan   ...
76848320bc6fSPatrick Sanan   ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr);
76858320bc6fSPatrick Sanan   if (set && compatible)  {
76868320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
76878320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
76888320bc6fSPatrick Sanan     ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n);CHKERRQ(ierr);
76898320bc6fSPatrick Sanan     for (j=y; j<y+n; ++j) {
76908320bc6fSPatrick Sanan       for (i=x; i<x+m, ++i) {
76918320bc6fSPatrick Sanan         arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1];
76928320bc6fSPatrick Sanan       }
76938320bc6fSPatrick Sanan     }
76948320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
76958320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
76968320bc6fSPatrick Sanan   } else {
76978320bc6fSPatrick Sanan     SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible");
76988320bc6fSPatrick Sanan   }
76998320bc6fSPatrick Sanan   ...
77008320bc6fSPatrick Sanan .ve
77018320bc6fSPatrick Sanan 
77028320bc6fSPatrick Sanan     Checking compatibility might be expensive for a given implementation of DM,
77038320bc6fSPatrick Sanan     or might be impossible to unambiguously confirm or deny. For this reason,
77048320bc6fSPatrick Sanan     this function may decline to determine compatibility, and hence users should
77058320bc6fSPatrick Sanan     always check the "set" output parameter.
77068320bc6fSPatrick Sanan 
77078320bc6fSPatrick Sanan     A DM is always compatible with itself.
77088320bc6fSPatrick Sanan 
77098320bc6fSPatrick Sanan     In the current implementation, DMs which live on "unequal" communicators
77108320bc6fSPatrick Sanan     (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed
77118320bc6fSPatrick Sanan     incompatible.
77128320bc6fSPatrick Sanan 
77138320bc6fSPatrick Sanan     This function is labeled "Collective," as information about all subdomains
77148320bc6fSPatrick Sanan     is required on each rank. However, in DM implementations which store all this
77158320bc6fSPatrick Sanan     information locally, this function may be merely "Logically Collective".
77168320bc6fSPatrick Sanan 
77178320bc6fSPatrick Sanan     Developer Notes:
77188320bc6fSPatrick Sanan     Compatibility is assumed to be a symmetric concept; if DM A is compatible with DM B,
77198320bc6fSPatrick Sanan     the DM B is compatible with DM A. Thus, this function checks the implementations
77208320bc6fSPatrick Sanan     of both dm and dm2 (if they are of different types), attempting to determine
77218320bc6fSPatrick Sanan     compatibility. It is left to DM implementers to ensure that symmetry is
77228320bc6fSPatrick Sanan     preserved. The simplest way to do this is, when implementing type-specific
77238320bc6fSPatrick Sanan     logic for this function, to check for existing logic in the implementation
77248320bc6fSPatrick Sanan     of other DM types and let *set = PETSC_FALSE if found; the logic of this
77258320bc6fSPatrick Sanan     function will then call that logic.
77268320bc6fSPatrick Sanan 
77278320bc6fSPatrick Sanan     Level: advanced
77288320bc6fSPatrick Sanan 
77298320bc6fSPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA()
77308320bc6fSPatrick Sanan @*/
77318320bc6fSPatrick Sanan 
77328320bc6fSPatrick Sanan PetscErrorCode DMGetCompatibility(DM dm,DM dm2,PetscBool *compatible,PetscBool *set)
77338320bc6fSPatrick Sanan {
77348320bc6fSPatrick Sanan   PetscErrorCode ierr;
77358320bc6fSPatrick Sanan   PetscMPIInt    compareResult;
77368320bc6fSPatrick Sanan   DMType         type,type2;
77378320bc6fSPatrick Sanan   PetscBool      sameType;
77388320bc6fSPatrick Sanan 
77398320bc6fSPatrick Sanan   PetscFunctionBegin;
77408320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77418320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
77428320bc6fSPatrick Sanan 
77438320bc6fSPatrick Sanan   /* Declare a DM compatible with itself */
77448320bc6fSPatrick Sanan   if (dm == dm2) {
77458320bc6fSPatrick Sanan     *set = PETSC_TRUE;
77468320bc6fSPatrick Sanan     *compatible = PETSC_TRUE;
77478320bc6fSPatrick Sanan     PetscFunctionReturn(0);
77488320bc6fSPatrick Sanan   }
77498320bc6fSPatrick Sanan 
77508320bc6fSPatrick Sanan   /* Declare a DM incompatible with a DM that lives on an "unequal"
77518320bc6fSPatrick Sanan      communicator. Note that this does not preclude compatibility with
77528320bc6fSPatrick Sanan      DMs living on "congruent" or "similar" communicators, but this must be
77538320bc6fSPatrick Sanan      determined by the implementation-specific logic */
77548320bc6fSPatrick Sanan   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRQ(ierr);
77558320bc6fSPatrick Sanan   if (compareResult == MPI_UNEQUAL) {
77568320bc6fSPatrick Sanan     *set = PETSC_TRUE;
77578320bc6fSPatrick Sanan     *compatible = PETSC_FALSE;
77588320bc6fSPatrick Sanan     PetscFunctionReturn(0);
77598320bc6fSPatrick Sanan   }
77608320bc6fSPatrick Sanan 
77618320bc6fSPatrick Sanan   /* Pass to the implementation-specific routine, if one exists. */
77628320bc6fSPatrick Sanan   if (dm->ops->getcompatibility) {
77638320bc6fSPatrick Sanan     ierr = (*dm->ops->getcompatibility)(dm,dm2,compatible,set);CHKERRQ(ierr);
77648320bc6fSPatrick Sanan     if (*set) {
77658320bc6fSPatrick Sanan       PetscFunctionReturn(0);
77668320bc6fSPatrick Sanan     }
77678320bc6fSPatrick Sanan   }
77688320bc6fSPatrick Sanan 
77698320bc6fSPatrick Sanan   /* If dm and dm2 are of different types, then attempt to check compatibility
77708320bc6fSPatrick Sanan      with an implementation of this function from dm2 */
77718320bc6fSPatrick Sanan   ierr = DMGetType(dm,&type);CHKERRQ(ierr);
77728320bc6fSPatrick Sanan   ierr = DMGetType(dm2,&type2);CHKERRQ(ierr);
77738320bc6fSPatrick Sanan   ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr);
77748320bc6fSPatrick Sanan   if (!sameType && dm2->ops->getcompatibility) {
77758320bc6fSPatrick Sanan     ierr = (*dm2->ops->getcompatibility)(dm2,dm,compatible,set);CHKERRQ(ierr); /* Note argument order */
77768320bc6fSPatrick Sanan   } else {
77778320bc6fSPatrick Sanan     *set = PETSC_FALSE;
77788320bc6fSPatrick Sanan   }
77798320bc6fSPatrick Sanan   PetscFunctionReturn(0);
77808320bc6fSPatrick Sanan }
7781