xref: /petsc/src/dm/interface/dm.c (revision 92fd8e1efe7fa9ec717935596822d4c66b82412a)
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;
115a84ad33SLisandro Dalcin PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_Refine, DM_CreateInterpolation, DM_CreateRestriction, DM_CreateInjection, DM_CreateMatrix;
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 
16a4121054SBarry Smith /*@
17de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
18a4121054SBarry Smith 
19a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
20a4121054SBarry Smith    error when you try to use the vector.
21a4121054SBarry Smith 
22d083f849SBarry Smith   Collective
23a4121054SBarry Smith 
24a4121054SBarry Smith   Input Parameter:
25a4121054SBarry Smith . comm - The communicator for the DM object
26a4121054SBarry Smith 
27a4121054SBarry Smith   Output Parameter:
28a4121054SBarry Smith . dm - The DM object
29a4121054SBarry Smith 
30a4121054SBarry Smith   Level: beginner
31a4121054SBarry Smith 
328472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK
33a4121054SBarry Smith @*/
347087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
35a4121054SBarry Smith {
36a4121054SBarry Smith   DM             v;
37e5e52638SMatthew G. Knepley   PetscDS        ds;
38a4121054SBarry Smith   PetscErrorCode ierr;
39a4121054SBarry Smith 
40a4121054SBarry Smith   PetscFunctionBegin;
411411c6eeSJed Brown   PetscValidPointer(dm,2);
420298fd71SBarry Smith   *dm = NULL;
43607a6623SBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
44a4121054SBarry Smith 
4573107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
46e7c4fc90SDmitry Karpeev 
4749be4549SMatthew G. Knepley   v->setupcalled              = PETSC_FALSE;
4849be4549SMatthew G. Knepley   v->setfromoptionscalled     = PETSC_FALSE;
490298fd71SBarry Smith   v->ltogmap                  = NULL;
501411c6eeSJed Brown   v->bs                       = 1;
51171400e9SBarry Smith   v->coloringtype             = IS_COLORING_GLOBAL;
5288ed4aceSMatthew G Knepley   ierr                        = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
5388ed4aceSMatthew G Knepley   ierr                        = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
54c58f1c22SToby Isaac   v->labels                   = NULL;
5534aa8a36SMatthew G. Knepley   v->adjacency[0]             = PETSC_FALSE;
5634aa8a36SMatthew G. Knepley   v->adjacency[1]             = PETSC_TRUE;
57c58f1c22SToby Isaac   v->depthLabel               = NULL;
580298fd71SBarry Smith   v->defaultSection           = NULL;
590298fd71SBarry Smith   v->defaultGlobalSection     = NULL;
60fba222abSToby Isaac   v->defaultConstraintSection = NULL;
61fba222abSToby Isaac   v->defaultConstraintMat     = NULL;
62c6b900c6SMatthew G. Knepley   v->L                        = NULL;
63c6b900c6SMatthew G. Knepley   v->maxCell                  = NULL;
645dc8c3f7SMatthew G. Knepley   v->bdtype                   = NULL;
659a9a41abSToby Isaac   v->dimEmbed                 = PETSC_DEFAULT;
6696173672SStefano Zampini   v->dim                      = PETSC_DETERMINE;
67435a35e8SMatthew G Knepley   {
68435a35e8SMatthew G Knepley     PetscInt i;
69435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
700298fd71SBarry Smith       v->nullspaceConstructors[i] = NULL;
71f9d4088aSMatthew G. Knepley       v->nearnullspaceConstructors[i] = NULL;
72435a35e8SMatthew G Knepley     }
73435a35e8SMatthew G Knepley   }
74e5e52638SMatthew G. Knepley   ierr = PetscDSCreate(PetscObjectComm((PetscObject) v), &ds);CHKERRQ(ierr);
75b3cf3223SMatthew G. Knepley   ierr = DMSetRegionDS(v, NULL, NULL, ds);CHKERRQ(ierr);
76e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
7714f150ffSMatthew G. Knepley   v->dmBC = NULL;
78a8fb8f29SToby Isaac   v->coarseMesh = NULL;
79f4d763aaSMatthew G. Knepley   v->outputSequenceNum = -1;
80cdb7a50dSMatthew G. Knepley   v->outputSequenceVal = 0.0;
81c0dedaeaSBarry Smith   ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr);
82b412c318SBarry Smith   ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr);
83bcc5ffd9SToby Isaac   ierr = PetscNew(&(v->labels));CHKERRQ(ierr);
84c58f1c22SToby Isaac   v->labels->refct = 1;
854a7a4c06SLawrence Mitchell 
861411c6eeSJed Brown   *dm = v;
87a4121054SBarry Smith   PetscFunctionReturn(0);
88a4121054SBarry Smith }
89a4121054SBarry Smith 
9038221697SMatthew G. Knepley /*@
9138221697SMatthew G. Knepley   DMClone - Creates a DM object with the same topology as the original.
9238221697SMatthew G. Knepley 
93d083f849SBarry Smith   Collective
9438221697SMatthew G. Knepley 
9538221697SMatthew G. Knepley   Input Parameter:
9638221697SMatthew G. Knepley . dm - The original DM object
9738221697SMatthew G. Knepley 
9838221697SMatthew G. Knepley   Output Parameter:
9938221697SMatthew G. Knepley . newdm  - The new DM object
10038221697SMatthew G. Knepley 
10138221697SMatthew G. Knepley   Level: beginner
10238221697SMatthew G. Knepley 
10338221697SMatthew G. Knepley @*/
10438221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm)
10538221697SMatthew G. Knepley {
10638221697SMatthew G. Knepley   PetscSF        sf;
10738221697SMatthew G. Knepley   Vec            coords;
10838221697SMatthew G. Knepley   void          *ctx;
109a3219837SMatthew G. Knepley   PetscInt       dim, cdim;
11038221697SMatthew G. Knepley   PetscErrorCode ierr;
11138221697SMatthew G. Knepley 
11238221697SMatthew G. Knepley   PetscFunctionBegin;
11338221697SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
11438221697SMatthew G. Knepley   PetscValidPointer(newdm,2);
11538221697SMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject) dm), newdm);CHKERRQ(ierr);
116c58f1c22SToby Isaac   ierr = PetscFree((*newdm)->labels);CHKERRQ(ierr);
117c58f1c22SToby Isaac   dm->labels->refct++;
118c58f1c22SToby Isaac   (*newdm)->labels = dm->labels;
119c58f1c22SToby Isaac   (*newdm)->depthLabel = dm->depthLabel;
120ddf8437dSMatthew G. Knepley   (*newdm)->leveldown  = dm->leveldown;
121ddf8437dSMatthew G. Knepley   (*newdm)->levelup    = dm->levelup;
1221de53e9aSMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
1231de53e9aSMatthew G. Knepley   ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr);
12438221697SMatthew G. Knepley   if (dm->ops->clone) {
12538221697SMatthew G. Knepley     ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr);
12638221697SMatthew G. Knepley   }
1273f22bcbcSToby Isaac   (*newdm)->setupcalled = dm->setupcalled;
12838221697SMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
12938221697SMatthew G. Knepley   ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr);
13038221697SMatthew G. Knepley   ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr);
13138221697SMatthew G. Knepley   ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr);
132be4c1c3eSMatthew G. Knepley   if (dm->coordinateDM) {
133be4c1c3eSMatthew G. Knepley     DM           ncdm;
134be4c1c3eSMatthew G. Knepley     PetscSection cs;
1355a0206caSToby Isaac     PetscInt     pEnd = -1, pEndMax = -1;
136be4c1c3eSMatthew G. Knepley 
137*92fd8e1eSJed Brown     ierr = DMGetLocalSection(dm->coordinateDM, &cs);CHKERRQ(ierr);
138be4c1c3eSMatthew G. Knepley     if (cs) {ierr = PetscSectionGetChart(cs, NULL, &pEnd);CHKERRQ(ierr);}
1395a0206caSToby Isaac     ierr = MPI_Allreduce(&pEnd,&pEndMax,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
1405a0206caSToby Isaac     if (pEndMax >= 0) {
141be4c1c3eSMatthew G. Knepley       ierr = DMClone(dm->coordinateDM, &ncdm);CHKERRQ(ierr);
14283bfc06fSMatthew Knepley       ierr = DMCopyDisc(dm->coordinateDM, ncdm);CHKERRQ(ierr);
143*92fd8e1eSJed Brown       ierr = DMSetLocalSection(ncdm, cs);CHKERRQ(ierr);
144a61e840bSMatthew G. Knepley       ierr = DMSetCoordinateDM(*newdm, ncdm);CHKERRQ(ierr);
145be4c1c3eSMatthew G. Knepley       ierr = DMDestroy(&ncdm);CHKERRQ(ierr);
146be4c1c3eSMatthew G. Knepley     }
147be4c1c3eSMatthew G. Knepley   }
148a3219837SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
149a3219837SMatthew G. Knepley   ierr = DMSetCoordinateDim(*newdm, cdim);CHKERRQ(ierr);
15038221697SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr);
15138221697SMatthew G. Knepley   if (coords) {
15238221697SMatthew G. Knepley     ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr);
15338221697SMatthew G. Knepley   } else {
15438221697SMatthew G. Knepley     ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr);
15538221697SMatthew G. Knepley     if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);}
15638221697SMatthew G. Knepley   }
15790b157c4SStefano Zampini   {
15890b157c4SStefano Zampini     PetscBool             isper;
159c6b900c6SMatthew G. Knepley     const PetscReal      *maxCell, *L;
1605dc8c3f7SMatthew G. Knepley     const DMBoundaryType *bd;
16190b157c4SStefano Zampini     ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr);
16290b157c4SStefano Zampini     ierr = DMSetPeriodicity(*newdm, isper, maxCell,  L,  bd);CHKERRQ(ierr);
163c6b900c6SMatthew G. Knepley   }
16434aa8a36SMatthew G. Knepley   {
16534aa8a36SMatthew G. Knepley     PetscBool useCone, useClosure;
16634aa8a36SMatthew G. Knepley 
16734aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, &useCone, &useClosure);CHKERRQ(ierr);
16834aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(*newdm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
16934aa8a36SMatthew G. Knepley   }
17038221697SMatthew G. Knepley   PetscFunctionReturn(0);
17138221697SMatthew G. Knepley }
17238221697SMatthew G. Knepley 
1739a42bb27SBarry Smith /*@C
174564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
1759a42bb27SBarry Smith 
176d083f849SBarry Smith    Logically Collective on da
1779a42bb27SBarry Smith 
1789a42bb27SBarry Smith    Input Parameter:
1799a42bb27SBarry Smith +  da - initial distributed array
180e9e886b6SKarl Rupp .  ctype - the vector type, currently either VECSTANDARD, VECCUDA, or VECVIENNACL
1819a42bb27SBarry Smith 
1829a42bb27SBarry Smith    Options Database:
183dd85299cSBarry Smith .   -dm_vec_type ctype
1849a42bb27SBarry Smith 
1859a42bb27SBarry Smith    Level: intermediate
1869a42bb27SBarry Smith 
187a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType(), DMSetMatType(), DMGetMatType()
1889a42bb27SBarry Smith @*/
18919fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
1909a42bb27SBarry Smith {
1919a42bb27SBarry Smith   PetscErrorCode ierr;
1929a42bb27SBarry Smith 
1939a42bb27SBarry Smith   PetscFunctionBegin;
1949a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
1959a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
19619fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
1979a42bb27SBarry Smith   PetscFunctionReturn(0);
1989a42bb27SBarry Smith }
1999a42bb27SBarry Smith 
200c0dedaeaSBarry Smith /*@C
201c0dedaeaSBarry Smith        DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
202c0dedaeaSBarry Smith 
203d083f849SBarry Smith    Logically Collective on da
204c0dedaeaSBarry Smith 
205c0dedaeaSBarry Smith    Input Parameter:
206c0dedaeaSBarry Smith .  da - initial distributed array
207c0dedaeaSBarry Smith 
208c0dedaeaSBarry Smith    Output Parameter:
209c0dedaeaSBarry Smith .  ctype - the vector type
210c0dedaeaSBarry Smith 
211c0dedaeaSBarry Smith    Level: intermediate
212c0dedaeaSBarry Smith 
213a2a9ebe5SBarry Smith .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMSetMatType(), DMGetMatType(), DMSetVecType()
214c0dedaeaSBarry Smith @*/
215c0dedaeaSBarry Smith PetscErrorCode  DMGetVecType(DM da,VecType *ctype)
216c0dedaeaSBarry Smith {
217c0dedaeaSBarry Smith   PetscFunctionBegin;
218c0dedaeaSBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
219c0dedaeaSBarry Smith   *ctype = da->vectype;
220c0dedaeaSBarry Smith   PetscFunctionReturn(0);
221c0dedaeaSBarry Smith }
222c0dedaeaSBarry Smith 
2235f1ad066SMatthew G Knepley /*@
22434f98d34SBarry Smith   VecGetDM - Gets the DM defining the data layout of the vector
2255f1ad066SMatthew G Knepley 
2265f1ad066SMatthew G Knepley   Not collective
2275f1ad066SMatthew G Knepley 
2285f1ad066SMatthew G Knepley   Input Parameter:
2295f1ad066SMatthew G Knepley . v - The Vec
2305f1ad066SMatthew G Knepley 
2315f1ad066SMatthew G Knepley   Output Parameter:
2325f1ad066SMatthew G Knepley . dm - The DM
2335f1ad066SMatthew G Knepley 
2345f1ad066SMatthew G Knepley   Level: intermediate
2355f1ad066SMatthew G Knepley 
2365f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2375f1ad066SMatthew G Knepley @*/
2385f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm)
2395f1ad066SMatthew G Knepley {
2405f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2415f1ad066SMatthew G Knepley 
2425f1ad066SMatthew G Knepley   PetscFunctionBegin;
2435f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
2445f1ad066SMatthew G Knepley   PetscValidPointer(dm,2);
2455f1ad066SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
2465f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2475f1ad066SMatthew G Knepley }
2485f1ad066SMatthew G Knepley 
2495f1ad066SMatthew G Knepley /*@
250d9805387SMatthew G. Knepley   VecSetDM - Sets the DM defining the data layout of the vector.
2515f1ad066SMatthew G Knepley 
2525f1ad066SMatthew G Knepley   Not collective
2535f1ad066SMatthew G Knepley 
2545f1ad066SMatthew G Knepley   Input Parameters:
2555f1ad066SMatthew G Knepley + v - The Vec
2565f1ad066SMatthew G Knepley - dm - The DM
2575f1ad066SMatthew G Knepley 
258d9805387SMatthew 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.
259d9805387SMatthew G. Knepley 
2605f1ad066SMatthew G Knepley   Level: intermediate
2615f1ad066SMatthew G Knepley 
2625f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2635f1ad066SMatthew G Knepley @*/
2645f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm)
2655f1ad066SMatthew G Knepley {
2665f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2675f1ad066SMatthew G Knepley 
2685f1ad066SMatthew G Knepley   PetscFunctionBegin;
2695f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
270d7f50e27SLisandro Dalcin   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
2715f1ad066SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
2725f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2735f1ad066SMatthew G Knepley }
2745f1ad066SMatthew G Knepley 
275521d9a4cSLisandro Dalcin /*@C
2768f1509bcSBarry Smith        DMSetISColoringType - Sets the type of coloring, global or local, that is created by the DM
2778f1509bcSBarry Smith 
278d083f849SBarry Smith    Logically Collective on dm
2798f1509bcSBarry Smith 
2808f1509bcSBarry Smith    Input Parameters:
2818f1509bcSBarry Smith +  dm - the DM context
2828f1509bcSBarry Smith -  ctype - the matrix type
2838f1509bcSBarry Smith 
2848f1509bcSBarry Smith    Options Database:
2858f1509bcSBarry Smith .   -dm_is_coloring_type - global or local
2868f1509bcSBarry Smith 
2878f1509bcSBarry Smith    Level: intermediate
2888f1509bcSBarry Smith 
2898f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(),
2908f1509bcSBarry Smith           DMGetISColoringType()
2918f1509bcSBarry Smith @*/
2928f1509bcSBarry Smith PetscErrorCode  DMSetISColoringType(DM dm,ISColoringType ctype)
2938f1509bcSBarry Smith {
2948f1509bcSBarry Smith   PetscFunctionBegin;
2958f1509bcSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2968f1509bcSBarry Smith   dm->coloringtype = ctype;
2978f1509bcSBarry Smith   PetscFunctionReturn(0);
2988f1509bcSBarry Smith }
2998f1509bcSBarry Smith 
3008f1509bcSBarry Smith /*@C
3018f1509bcSBarry Smith        DMGetISColoringType - Gets the type of coloring, global or local, that is created by the DM
302521d9a4cSLisandro Dalcin 
303d083f849SBarry Smith    Logically Collective on dm
304521d9a4cSLisandro Dalcin 
305521d9a4cSLisandro Dalcin    Input Parameter:
3068f1509bcSBarry Smith .  dm - the DM context
3078f1509bcSBarry Smith 
3088f1509bcSBarry Smith    Output Parameter:
3098f1509bcSBarry Smith .  ctype - the matrix type
3108f1509bcSBarry Smith 
3118f1509bcSBarry Smith    Options Database:
3128f1509bcSBarry Smith .   -dm_is_coloring_type - global or local
3138f1509bcSBarry Smith 
3148f1509bcSBarry Smith    Level: intermediate
3158f1509bcSBarry Smith 
3168f1509bcSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(),
3178f1509bcSBarry Smith           DMGetISColoringType()
3188f1509bcSBarry Smith @*/
3198f1509bcSBarry Smith PetscErrorCode  DMGetISColoringType(DM dm,ISColoringType *ctype)
3208f1509bcSBarry Smith {
3218f1509bcSBarry Smith   PetscFunctionBegin;
3228f1509bcSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3238f1509bcSBarry Smith   *ctype = dm->coloringtype;
3248f1509bcSBarry Smith   PetscFunctionReturn(0);
3258f1509bcSBarry Smith }
3268f1509bcSBarry Smith 
3278f1509bcSBarry Smith /*@C
3288f1509bcSBarry Smith        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
3298f1509bcSBarry Smith 
330d083f849SBarry Smith    Logically Collective on dm
3318f1509bcSBarry Smith 
3328f1509bcSBarry Smith    Input Parameters:
333521d9a4cSLisandro Dalcin +  dm - the DM context
334a2b5a043SBarry Smith -  ctype - the matrix type
335521d9a4cSLisandro Dalcin 
336521d9a4cSLisandro Dalcin    Options Database:
337521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
338521d9a4cSLisandro Dalcin 
339521d9a4cSLisandro Dalcin    Level: intermediate
340521d9a4cSLisandro Dalcin 
341a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType(), DMSetMatType(), DMGetMatType()
342521d9a4cSLisandro Dalcin @*/
34319fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
344521d9a4cSLisandro Dalcin {
345521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
34688f0584fSBarry Smith 
347521d9a4cSLisandro Dalcin   PetscFunctionBegin;
348521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
349521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
35019fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
351521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
352521d9a4cSLisandro Dalcin }
353521d9a4cSLisandro Dalcin 
354c0dedaeaSBarry Smith /*@C
355c0dedaeaSBarry Smith        DMGetMatType - Gets the type of matrix created with DMCreateMatrix()
356c0dedaeaSBarry Smith 
357d083f849SBarry Smith    Logically Collective on dm
358c0dedaeaSBarry Smith 
359c0dedaeaSBarry Smith    Input Parameter:
360c0dedaeaSBarry Smith .  dm - the DM context
361c0dedaeaSBarry Smith 
362c0dedaeaSBarry Smith    Output Parameter:
363c0dedaeaSBarry Smith .  ctype - the matrix type
364c0dedaeaSBarry Smith 
365c0dedaeaSBarry Smith    Options Database:
366c0dedaeaSBarry Smith .   -dm_mat_type ctype
367c0dedaeaSBarry Smith 
368c0dedaeaSBarry Smith    Level: intermediate
369c0dedaeaSBarry Smith 
370a2a9ebe5SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType(), DMSetMatType(), DMGetMatType()
371c0dedaeaSBarry Smith @*/
372c0dedaeaSBarry Smith PetscErrorCode  DMGetMatType(DM dm,MatType *ctype)
373c0dedaeaSBarry Smith {
374c0dedaeaSBarry Smith   PetscFunctionBegin;
375c0dedaeaSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
376c0dedaeaSBarry Smith   *ctype = dm->mattype;
377c0dedaeaSBarry Smith   PetscFunctionReturn(0);
378c0dedaeaSBarry Smith }
379c0dedaeaSBarry Smith 
380c688c046SMatthew G Knepley /*@
38134f98d34SBarry Smith   MatGetDM - Gets the DM defining the data layout of the matrix
382c688c046SMatthew G Knepley 
383c688c046SMatthew G Knepley   Not collective
384c688c046SMatthew G Knepley 
385c688c046SMatthew G Knepley   Input Parameter:
386c688c046SMatthew G Knepley . A - The Mat
387c688c046SMatthew G Knepley 
388c688c046SMatthew G Knepley   Output Parameter:
389c688c046SMatthew G Knepley . dm - The DM
390c688c046SMatthew G Knepley 
391c688c046SMatthew G Knepley   Level: intermediate
392c688c046SMatthew G Knepley 
3938f1509bcSBarry Smith   Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with
3948f1509bcSBarry Smith                   the Mat through a PetscObjectCompose() operation
3958f1509bcSBarry Smith 
396c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType()
397c688c046SMatthew G Knepley @*/
398c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm)
399c688c046SMatthew G Knepley {
400c688c046SMatthew G Knepley   PetscErrorCode ierr;
401c688c046SMatthew G Knepley 
402c688c046SMatthew G Knepley   PetscFunctionBegin;
403c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
404c688c046SMatthew G Knepley   PetscValidPointer(dm,2);
405c688c046SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
406c688c046SMatthew G Knepley   PetscFunctionReturn(0);
407c688c046SMatthew G Knepley }
408c688c046SMatthew G Knepley 
409c688c046SMatthew G Knepley /*@
410c688c046SMatthew G Knepley   MatSetDM - Sets the DM defining the data layout of the matrix
411c688c046SMatthew G Knepley 
412c688c046SMatthew G Knepley   Not collective
413c688c046SMatthew G Knepley 
414c688c046SMatthew G Knepley   Input Parameters:
415c688c046SMatthew G Knepley + A - The Mat
416c688c046SMatthew G Knepley - dm - The DM
417c688c046SMatthew G Knepley 
418c688c046SMatthew G Knepley   Level: intermediate
419c688c046SMatthew G Knepley 
4208f1509bcSBarry Smith   Developer Note: Since the Mat class doesn't know about the DM class the DM object is associated with
4218f1509bcSBarry Smith                   the Mat through a PetscObjectCompose() operation
4228f1509bcSBarry Smith 
4238f1509bcSBarry Smith 
424c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType()
425c688c046SMatthew G Knepley @*/
426c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm)
427c688c046SMatthew G Knepley {
428c688c046SMatthew G Knepley   PetscErrorCode ierr;
429c688c046SMatthew G Knepley 
430c688c046SMatthew G Knepley   PetscFunctionBegin;
431c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4328865f1eaSKarl Rupp   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
433c688c046SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
434c688c046SMatthew G Knepley   PetscFunctionReturn(0);
435c688c046SMatthew G Knepley }
436c688c046SMatthew G Knepley 
4379a42bb27SBarry Smith /*@C
4389a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
4396757b960SDave May    DM options in the database.
4409a42bb27SBarry Smith 
441d083f849SBarry Smith    Logically Collective on dm
4429a42bb27SBarry Smith 
4439a42bb27SBarry Smith    Input Parameter:
4448353ddbbSDave May +  da - the DM context
4459a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
4469a42bb27SBarry Smith 
4479a42bb27SBarry Smith    Notes:
4489a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
4499a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
4509a42bb27SBarry Smith 
4519a42bb27SBarry Smith    Level: advanced
4529a42bb27SBarry Smith 
4539a42bb27SBarry Smith .seealso: DMSetFromOptions()
4549a42bb27SBarry Smith @*/
4557087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
4569a42bb27SBarry Smith {
4579a42bb27SBarry Smith   PetscErrorCode ierr;
4589a42bb27SBarry Smith 
4599a42bb27SBarry Smith   PetscFunctionBegin;
4609a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4619a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
462691be533SLawrence Mitchell   if (dm->sf) {
463691be533SLawrence Mitchell     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr);
464691be533SLawrence Mitchell   }
465691be533SLawrence Mitchell   if (dm->defaultSF) {
466691be533SLawrence Mitchell     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->defaultSF,prefix);CHKERRQ(ierr);
467691be533SLawrence Mitchell   }
4689a42bb27SBarry Smith   PetscFunctionReturn(0);
4699a42bb27SBarry Smith }
4709a42bb27SBarry Smith 
47131697293SDave May /*@C
47231697293SDave May    DMAppendOptionsPrefix - Appends to the prefix used for searching for all
47331697293SDave May    DM options in the database.
47431697293SDave May 
475d083f849SBarry Smith    Logically Collective on dm
47631697293SDave May 
47731697293SDave May    Input Parameters:
47831697293SDave May +  dm - the DM context
47931697293SDave May -  prefix - the prefix string to prepend to all DM option requests
48031697293SDave May 
48131697293SDave May    Notes:
48231697293SDave May    A hyphen (-) must NOT be given at the beginning of the prefix name.
48331697293SDave May    The first character of all runtime options is AUTOMATICALLY the hyphen.
48431697293SDave May 
48531697293SDave May    Level: advanced
48631697293SDave May 
48731697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix()
48831697293SDave May @*/
48931697293SDave May PetscErrorCode  DMAppendOptionsPrefix(DM dm,const char prefix[])
49031697293SDave May {
49131697293SDave May   PetscErrorCode ierr;
49231697293SDave May 
49331697293SDave May   PetscFunctionBegin;
49431697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
49531697293SDave May   ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
49631697293SDave May   PetscFunctionReturn(0);
49731697293SDave May }
49831697293SDave May 
49931697293SDave May /*@C
50031697293SDave May    DMGetOptionsPrefix - Gets the prefix used for searching for all
50131697293SDave May    DM options in the database.
50231697293SDave May 
50331697293SDave May    Not Collective
50431697293SDave May 
50531697293SDave May    Input Parameters:
50631697293SDave May .  dm - the DM context
50731697293SDave May 
50831697293SDave May    Output Parameters:
50931697293SDave May .  prefix - pointer to the prefix string used is returned
51031697293SDave May 
51195452b02SPatrick Sanan    Notes:
51295452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
51331697293SDave May    sufficient length to hold the prefix.
51431697293SDave May 
51531697293SDave May    Level: advanced
51631697293SDave May 
51731697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix()
51831697293SDave May @*/
51931697293SDave May PetscErrorCode  DMGetOptionsPrefix(DM dm,const char *prefix[])
52031697293SDave May {
52131697293SDave May   PetscErrorCode ierr;
52231697293SDave May 
52331697293SDave May   PetscFunctionBegin;
52431697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
52531697293SDave May   ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
52631697293SDave May   PetscFunctionReturn(0);
52731697293SDave May }
52831697293SDave May 
52988bdff64SToby Isaac static PetscErrorCode DMCountNonCyclicReferences(DM dm, PetscBool recurseCoarse, PetscBool recurseFine, PetscInt *ncrefct)
53088bdff64SToby Isaac {
53188bdff64SToby Isaac   PetscInt i, refct = ((PetscObject) dm)->refct;
53288bdff64SToby Isaac   DMNamedVecLink nlink;
53388bdff64SToby Isaac   PetscErrorCode ierr;
53488bdff64SToby Isaac 
53588bdff64SToby Isaac   PetscFunctionBegin;
536aab5bcd8SJed Brown   *ncrefct = 0;
53788bdff64SToby Isaac   /* count all the circular references of DM and its contained Vecs */
53888bdff64SToby Isaac   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
53988bdff64SToby Isaac     if (dm->localin[i])  refct--;
54088bdff64SToby Isaac     if (dm->globalin[i]) refct--;
54188bdff64SToby Isaac   }
54288bdff64SToby Isaac   for (nlink=dm->namedglobal; nlink; nlink=nlink->next) refct--;
54388bdff64SToby Isaac   for (nlink=dm->namedlocal; nlink; nlink=nlink->next) refct--;
54488bdff64SToby Isaac   if (dm->x) {
54588bdff64SToby Isaac     DM obj;
54688bdff64SToby Isaac     ierr = VecGetDM(dm->x, &obj);CHKERRQ(ierr);
54788bdff64SToby Isaac     if (obj == dm) refct--;
54888bdff64SToby Isaac   }
54988bdff64SToby Isaac   if (dm->coarseMesh && dm->coarseMesh->fineMesh == dm) {
55088bdff64SToby Isaac     refct--;
55188bdff64SToby Isaac     if (recurseCoarse) {
55288bdff64SToby Isaac       PetscInt coarseCount;
55388bdff64SToby Isaac 
55488bdff64SToby Isaac       ierr = DMCountNonCyclicReferences(dm->coarseMesh, PETSC_TRUE, PETSC_FALSE,&coarseCount);CHKERRQ(ierr);
55588bdff64SToby Isaac       refct += coarseCount;
55688bdff64SToby Isaac     }
55788bdff64SToby Isaac   }
55888bdff64SToby Isaac   if (dm->fineMesh && dm->fineMesh->coarseMesh == dm) {
55988bdff64SToby Isaac     refct--;
56088bdff64SToby Isaac     if (recurseFine) {
56188bdff64SToby Isaac       PetscInt fineCount;
56288bdff64SToby Isaac 
56388bdff64SToby Isaac       ierr = DMCountNonCyclicReferences(dm->fineMesh, PETSC_FALSE, PETSC_TRUE,&fineCount);CHKERRQ(ierr);
56488bdff64SToby Isaac       refct += fineCount;
56588bdff64SToby Isaac     }
56688bdff64SToby Isaac   }
56788bdff64SToby Isaac   *ncrefct = refct;
56888bdff64SToby Isaac   PetscFunctionReturn(0);
56988bdff64SToby Isaac }
57088bdff64SToby Isaac 
571354557abSToby Isaac PetscErrorCode DMDestroyLabelLinkList(DM dm)
572354557abSToby Isaac {
573354557abSToby Isaac   PetscErrorCode ierr;
574354557abSToby Isaac 
575354557abSToby Isaac   PetscFunctionBegin;
576354557abSToby Isaac   if (!--(dm->labels->refct)) {
577354557abSToby Isaac     DMLabelLink next = dm->labels->next;
578354557abSToby Isaac 
579354557abSToby Isaac     /* destroy the labels */
580354557abSToby Isaac     while (next) {
581354557abSToby Isaac       DMLabelLink tmp = next->next;
582354557abSToby Isaac 
583354557abSToby Isaac       ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr);
584354557abSToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
585354557abSToby Isaac       next = tmp;
586354557abSToby Isaac     }
587354557abSToby Isaac     ierr = PetscFree(dm->labels);CHKERRQ(ierr);
588354557abSToby Isaac   }
589354557abSToby Isaac   PetscFunctionReturn(0);
590354557abSToby Isaac }
591354557abSToby Isaac 
59247c6ae99SBarry Smith /*@
5938472ad0fSDave May     DMDestroy - Destroys a vector packer or DM.
59447c6ae99SBarry Smith 
595d083f849SBarry Smith     Collective on dm
59647c6ae99SBarry Smith 
59747c6ae99SBarry Smith     Input Parameter:
59847c6ae99SBarry Smith .   dm - the DM object to destroy
59947c6ae99SBarry Smith 
60047c6ae99SBarry Smith     Level: developer
60147c6ae99SBarry Smith 
602e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
60347c6ae99SBarry Smith 
60447c6ae99SBarry Smith @*/
605fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
60647c6ae99SBarry Smith {
60788bdff64SToby Isaac   PetscInt       i, cnt;
608dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
60947c6ae99SBarry Smith   PetscErrorCode ierr;
61047c6ae99SBarry Smith 
61147c6ae99SBarry Smith   PetscFunctionBegin;
6126bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
6136bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
61487e657c6SBarry Smith 
61588bdff64SToby Isaac   /* count all non-cyclic references in the doubly-linked list of coarse<->fine meshes */
61688bdff64SToby Isaac   ierr = DMCountNonCyclicReferences(*dm,PETSC_TRUE,PETSC_TRUE,&cnt);CHKERRQ(ierr);
61788bdff64SToby Isaac   --((PetscObject)(*dm))->refct;
61888bdff64SToby Isaac   if (--cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
619732e2eb9SMatthew G Knepley   /*
620732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
621732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
622732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
623732e2eb9SMatthew G Knepley   */
6246bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
6256bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
626732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
6276bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
6286bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
629732e2eb9SMatthew G Knepley   }
630f490541aSPeter Brune   nnext=(*dm)->namedglobal;
6310298fd71SBarry Smith   (*dm)->namedglobal = NULL;
632f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */
6332348bcf4SPeter Brune     nnext = nlink->next;
6342348bcf4SPeter 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);
6352348bcf4SPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
6362348bcf4SPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
6372348bcf4SPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
6382348bcf4SPeter Brune   }
639f490541aSPeter Brune   nnext=(*dm)->namedlocal;
6400298fd71SBarry Smith   (*dm)->namedlocal = NULL;
641f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */
642f490541aSPeter Brune     nnext = nlink->next;
643f490541aSPeter 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);
644f490541aSPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
645f490541aSPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
646f490541aSPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
647f490541aSPeter Brune   }
6482348bcf4SPeter Brune 
649b17ce1afSJed Brown   /* Destroy the list of hooks */
650c833c3b5SJed Brown   {
651c833c3b5SJed Brown     DMCoarsenHookLink link,next;
652b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
653b17ce1afSJed Brown       next = link->next;
654b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
655b17ce1afSJed Brown     }
6560298fd71SBarry Smith     (*dm)->coarsenhook = NULL;
657c833c3b5SJed Brown   }
658c833c3b5SJed Brown   {
659c833c3b5SJed Brown     DMRefineHookLink link,next;
660c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
661c833c3b5SJed Brown       next = link->next;
662c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
663c833c3b5SJed Brown     }
6640298fd71SBarry Smith     (*dm)->refinehook = NULL;
665c833c3b5SJed Brown   }
666be081cd6SPeter Brune   {
667be081cd6SPeter Brune     DMSubDomainHookLink link,next;
668be081cd6SPeter Brune     for (link=(*dm)->subdomainhook; link; link=next) {
669be081cd6SPeter Brune       next = link->next;
670be081cd6SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
671be081cd6SPeter Brune     }
6720298fd71SBarry Smith     (*dm)->subdomainhook = NULL;
673be081cd6SPeter Brune   }
674baf369e7SPeter Brune   {
675baf369e7SPeter Brune     DMGlobalToLocalHookLink link,next;
676baf369e7SPeter Brune     for (link=(*dm)->gtolhook; link; link=next) {
677baf369e7SPeter Brune       next = link->next;
678baf369e7SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
679baf369e7SPeter Brune     }
6800298fd71SBarry Smith     (*dm)->gtolhook = NULL;
681baf369e7SPeter Brune   }
682d4d07f1eSToby Isaac   {
683d4d07f1eSToby Isaac     DMLocalToGlobalHookLink link,next;
684d4d07f1eSToby Isaac     for (link=(*dm)->ltoghook; link; link=next) {
685d4d07f1eSToby Isaac       next = link->next;
686d4d07f1eSToby Isaac       ierr = PetscFree(link);CHKERRQ(ierr);
687d4d07f1eSToby Isaac     }
688d4d07f1eSToby Isaac     (*dm)->ltoghook = NULL;
689d4d07f1eSToby Isaac   }
690aa1993deSMatthew G Knepley   /* Destroy the work arrays */
691aa1993deSMatthew G Knepley   {
692aa1993deSMatthew G Knepley     DMWorkLink link,next;
693aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
694aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
695aa1993deSMatthew G Knepley       next = link->next;
696aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
697aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
698aa1993deSMatthew G Knepley     }
6990298fd71SBarry Smith     (*dm)->workin = NULL;
700aa1993deSMatthew G Knepley   }
701c58f1c22SToby Isaac   if (!--((*dm)->labels->refct)) {
702c58f1c22SToby Isaac     DMLabelLink next = (*dm)->labels->next;
703c58f1c22SToby Isaac 
704c58f1c22SToby Isaac     /* destroy the labels */
705c58f1c22SToby Isaac     while (next) {
706c58f1c22SToby Isaac       DMLabelLink tmp = next->next;
707c58f1c22SToby Isaac 
708c58f1c22SToby Isaac       ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr);
709c58f1c22SToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
710c58f1c22SToby Isaac       next = tmp;
711c58f1c22SToby Isaac     }
712c58f1c22SToby Isaac     ierr = PetscFree((*dm)->labels);CHKERRQ(ierr);
713c58f1c22SToby Isaac   }
714e5e52638SMatthew G. Knepley   ierr = DMClearFields(*dm);CHKERRQ(ierr);
715e6f8dbb6SToby Isaac   {
716e6f8dbb6SToby Isaac     DMBoundary next = (*dm)->boundary;
717e6f8dbb6SToby Isaac     while (next) {
718e6f8dbb6SToby Isaac       DMBoundary b = next;
719e6f8dbb6SToby Isaac 
720e6f8dbb6SToby Isaac       next = b->next;
721e6f8dbb6SToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
722e6f8dbb6SToby Isaac     }
723e6f8dbb6SToby Isaac   }
724b17ce1afSJed Brown 
72552536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr);
72652536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr);
72752536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr);
72852536dc3SBarry Smith 
7291a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
7301a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
7311a266240SBarry Smith   }
73287e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
73371cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
7344dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
7356bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
7366bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
737073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
73888ed4aceSMatthew G Knepley 
73988ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
74088ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
7418b1ab98fSJed Brown   ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr);
742fba222abSToby Isaac   ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr);
743fba222abSToby Isaac   ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr);
74488ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
74588ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
746736995cdSBlaise Bourdin   if ((*dm)->useNatural) {
747736995cdSBlaise Bourdin     if ((*dm)->sfNatural) {
7488e4ac7eaSMatthew G. Knepley       ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr);
749736995cdSBlaise Bourdin     }
750736995cdSBlaise Bourdin     ierr = PetscObjectDereference((PetscObject) (*dm)->sfMigration);CHKERRQ(ierr);
751736995cdSBlaise Bourdin   }
75288bdff64SToby Isaac   if ((*dm)->coarseMesh && (*dm)->coarseMesh->fineMesh == *dm) {
75388bdff64SToby Isaac     ierr = DMSetFineDM((*dm)->coarseMesh,NULL);CHKERRQ(ierr);
75488bdff64SToby Isaac   }
755a8fb8f29SToby Isaac   ierr = DMDestroy(&(*dm)->coarseMesh);CHKERRQ(ierr);
75688bdff64SToby Isaac   if ((*dm)->fineMesh && (*dm)->fineMesh->coarseMesh == *dm) {
75788bdff64SToby Isaac     ierr = DMSetCoarseDM((*dm)->fineMesh,NULL);CHKERRQ(ierr);
75888bdff64SToby Isaac   }
75988bdff64SToby Isaac   ierr = DMDestroy(&(*dm)->fineMesh);CHKERRQ(ierr);
760f19dbd58SToby Isaac   ierr = DMFieldDestroy(&(*dm)->coordinateField);CHKERRQ(ierr);
7616636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
7626636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
7636636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
7645dc8c3f7SMatthew G. Knepley   ierr = PetscFree3((*dm)->L,(*dm)->maxCell,(*dm)->bdtype);CHKERRQ(ierr);
765ca3d3a14SMatthew G. Knepley   if ((*dm)->transformDestroy) {ierr = (*(*dm)->transformDestroy)(*dm, (*dm)->transformCtx);CHKERRQ(ierr);}
766ca3d3a14SMatthew G. Knepley   ierr = DMDestroy(&(*dm)->transformDM);CHKERRQ(ierr);
767ca3d3a14SMatthew G. Knepley   ierr = VecDestroy(&(*dm)->transform);CHKERRQ(ierr);
7686636e97aSMatthew G Knepley 
769e5e52638SMatthew G. Knepley   ierr = DMClearDS(*dm);CHKERRQ(ierr);
77014f150ffSMatthew G. Knepley   ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr);
771e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
772e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr);
773732e2eb9SMatthew G Knepley 
774ed3c66a1SDave May   if ((*dm)->ops->destroy) {
7756bf464f9SBarry Smith     ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
776ed3c66a1SDave May   }
777435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
778732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
77947c6ae99SBarry Smith   PetscFunctionReturn(0);
78047c6ae99SBarry Smith }
78147c6ae99SBarry Smith 
782d7bf68aeSBarry Smith /*@
783d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
784d7bf68aeSBarry Smith 
785d083f849SBarry Smith     Collective on dm
786d7bf68aeSBarry Smith 
787d7bf68aeSBarry Smith     Input Parameter:
788d7bf68aeSBarry Smith .   dm - the DM object to setup
789d7bf68aeSBarry Smith 
790d7bf68aeSBarry Smith     Level: developer
791d7bf68aeSBarry Smith 
792e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
793d7bf68aeSBarry Smith 
794d7bf68aeSBarry Smith @*/
7957087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
796d7bf68aeSBarry Smith {
797d7bf68aeSBarry Smith   PetscErrorCode ierr;
798d7bf68aeSBarry Smith 
799d7bf68aeSBarry Smith   PetscFunctionBegin;
800171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8018387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
802d7bf68aeSBarry Smith   if (dm->ops->setup) {
803d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
804d7bf68aeSBarry Smith   }
8058387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
806d7bf68aeSBarry Smith   PetscFunctionReturn(0);
807d7bf68aeSBarry Smith }
808d7bf68aeSBarry Smith 
809d7bf68aeSBarry Smith /*@
810d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
811d7bf68aeSBarry Smith 
812d083f849SBarry Smith     Collective on dm
813d7bf68aeSBarry Smith 
814d7bf68aeSBarry Smith     Input Parameter:
815d7bf68aeSBarry Smith .   dm - the DM object to set options for
816d7bf68aeSBarry Smith 
817732e2eb9SMatthew G Knepley     Options Database:
8184164ae61SDominic Meiser +   -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
8194164ae61SDominic Meiser .   -dm_vec_type <type>  - type of vector to create inside DM
8204164ae61SDominic Meiser .   -dm_mat_type <type>  - type of matrix to create inside DM
8218f1509bcSBarry Smith -   -dm_is_coloring_type - <global or local>
822732e2eb9SMatthew G Knepley 
823d7bf68aeSBarry Smith     Level: developer
824d7bf68aeSBarry Smith 
825e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
826d7bf68aeSBarry Smith 
827d7bf68aeSBarry Smith @*/
8287087cfbeSBarry Smith PetscErrorCode DMSetFromOptions(DM dm)
829d7bf68aeSBarry Smith {
8307781c08eSBarry Smith   char           typeName[256];
831ca266f36SBarry Smith   PetscBool      flg;
832d7bf68aeSBarry Smith   PetscErrorCode ierr;
833d7bf68aeSBarry Smith 
834d7bf68aeSBarry Smith   PetscFunctionBegin;
835171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
83649be4549SMatthew G. Knepley   dm->setfromoptionscalled = PETSC_TRUE;
83749be4549SMatthew G. Knepley   if (dm->sf) {ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr);}
83849be4549SMatthew G. Knepley   if (dm->defaultSF) {ierr = PetscSFSetFromOptions(dm->defaultSF);CHKERRQ(ierr);}
8393194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
8400298fd71SBarry 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);
841a264d7a6SBarry Smith   ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
842f9ba7244SBarry Smith   if (flg) {
843f9ba7244SBarry Smith     ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
844f9ba7244SBarry Smith   }
845a264d7a6SBarry 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);
846073dac72SJed Brown   if (flg) {
847521d9a4cSLisandro Dalcin     ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
848073dac72SJed Brown   }
8498f1509bcSBarry Smith   ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","DMSetISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr);
850f9ba7244SBarry Smith   if (dm->ops->setfromoptions) {
851e55864a3SBarry Smith     ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr);
852f9ba7244SBarry Smith   }
853f9ba7244SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
8540633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) dm);CHKERRQ(ierr);
85582fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
856d7bf68aeSBarry Smith   PetscFunctionReturn(0);
857d7bf68aeSBarry Smith }
858d7bf68aeSBarry Smith 
859fc9bc008SSatish Balay /*@C
860224748a4SBarry Smith     DMView - Views a DM
86147c6ae99SBarry Smith 
862d083f849SBarry Smith     Collective on dm
86347c6ae99SBarry Smith 
86447c6ae99SBarry Smith     Input Parameter:
86547c6ae99SBarry Smith +   dm - the DM object to view
86647c6ae99SBarry Smith -   v - the viewer
86747c6ae99SBarry Smith 
868224748a4SBarry Smith     Level: beginner
86947c6ae99SBarry Smith 
870e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
87147c6ae99SBarry Smith 
87247c6ae99SBarry Smith @*/
8737087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
87447c6ae99SBarry Smith {
87547c6ae99SBarry Smith   PetscErrorCode    ierr;
87632c0f0efSBarry Smith   PetscBool         isbinary;
87776a8abe0SBarry Smith   PetscMPIInt       size;
87876a8abe0SBarry Smith   PetscViewerFormat format;
87947c6ae99SBarry Smith 
88047c6ae99SBarry Smith   PetscFunctionBegin;
881171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8823014e516SBarry Smith   if (!v) {
883ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr);
8843014e516SBarry Smith   }
8858bfd1ab9SVaclav Hapla   ierr = PetscViewerCheckWritable(v);CHKERRQ(ierr);
88676a8abe0SBarry Smith   ierr = PetscViewerGetFormat(v,&format);CHKERRQ(ierr);
88776a8abe0SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm),&size);CHKERRQ(ierr);
88876a8abe0SBarry Smith   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
88998c3331eSBarry Smith   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr);
89032c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
89132c0f0efSBarry Smith   if (isbinary) {
89255849f57SBarry Smith     PetscInt classid = DM_FILE_CLASSID;
89332c0f0efSBarry Smith     char     type[256];
89432c0f0efSBarry Smith 
89532c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
89632c0f0efSBarry Smith     ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
89732c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
89832c0f0efSBarry Smith   }
8990c010503SBarry Smith   if (dm->ops->view) {
9000c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
90147c6ae99SBarry Smith   }
90247c6ae99SBarry Smith   PetscFunctionReturn(0);
90347c6ae99SBarry Smith }
90447c6ae99SBarry Smith 
90547c6ae99SBarry Smith /*@
9068472ad0fSDave May     DMCreateGlobalVector - Creates a global vector from a DM object
90747c6ae99SBarry Smith 
908d083f849SBarry Smith     Collective on dm
90947c6ae99SBarry Smith 
91047c6ae99SBarry Smith     Input Parameter:
91147c6ae99SBarry Smith .   dm - the DM object
91247c6ae99SBarry Smith 
91347c6ae99SBarry Smith     Output Parameter:
91447c6ae99SBarry Smith .   vec - the global vector
91547c6ae99SBarry Smith 
916073dac72SJed Brown     Level: beginner
91747c6ae99SBarry Smith 
918e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
91947c6ae99SBarry Smith 
92047c6ae99SBarry Smith @*/
9217087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
92247c6ae99SBarry Smith {
92347c6ae99SBarry Smith   PetscErrorCode ierr;
92447c6ae99SBarry Smith 
92547c6ae99SBarry Smith   PetscFunctionBegin;
926171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
927b9d85ea2SLisandro Dalcin   PetscValidPointer(vec,2);
928b9d85ea2SLisandro Dalcin   if (!dm->ops->createglobalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateGlobalVector",((PetscObject)dm)->type_name);
92947c6ae99SBarry Smith   ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
93047c6ae99SBarry Smith   PetscFunctionReturn(0);
93147c6ae99SBarry Smith }
93247c6ae99SBarry Smith 
93347c6ae99SBarry Smith /*@
9348472ad0fSDave May     DMCreateLocalVector - Creates a local vector from a DM object
93547c6ae99SBarry Smith 
93647c6ae99SBarry Smith     Not Collective
93747c6ae99SBarry Smith 
93847c6ae99SBarry Smith     Input Parameter:
93947c6ae99SBarry Smith .   dm - the DM object
94047c6ae99SBarry Smith 
94147c6ae99SBarry Smith     Output Parameter:
94247c6ae99SBarry Smith .   vec - the local vector
94347c6ae99SBarry Smith 
944073dac72SJed Brown     Level: beginner
94547c6ae99SBarry Smith 
946e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
94747c6ae99SBarry Smith 
94847c6ae99SBarry Smith @*/
9497087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
95047c6ae99SBarry Smith {
95147c6ae99SBarry Smith   PetscErrorCode ierr;
95247c6ae99SBarry Smith 
95347c6ae99SBarry Smith   PetscFunctionBegin;
954171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
955b9d85ea2SLisandro Dalcin   PetscValidPointer(vec,2);
956b9d85ea2SLisandro Dalcin   if (!dm->ops->createlocalvector) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateLocalVector",((PetscObject)dm)->type_name);
95747c6ae99SBarry Smith   ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
95847c6ae99SBarry Smith   PetscFunctionReturn(0);
95947c6ae99SBarry Smith }
96047c6ae99SBarry Smith 
9611411c6eeSJed Brown /*@
9621411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
9631411c6eeSJed Brown 
964d083f849SBarry Smith    Collective on dm
9651411c6eeSJed Brown 
9661411c6eeSJed Brown    Input Parameter:
9671411c6eeSJed Brown .  dm - the DM that provides the mapping
9681411c6eeSJed Brown 
9691411c6eeSJed Brown    Output Parameter:
9701411c6eeSJed Brown .  ltog - the mapping
9711411c6eeSJed Brown 
9721411c6eeSJed Brown    Level: intermediate
9731411c6eeSJed Brown 
9741411c6eeSJed Brown    Notes:
9751411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
9761411c6eeSJed Brown    MatSetLocalToGlobalMapping().
9771411c6eeSJed Brown 
978fc31e74dSBarry Smith .seealso: DMCreateLocalVector()
9791411c6eeSJed Brown @*/
9807087cfbeSBarry Smith PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
9811411c6eeSJed Brown {
9820be3e97aSMatthew G. Knepley   PetscInt       bs = -1, bsLocal[2], bsMinMax[2];
9831411c6eeSJed Brown   PetscErrorCode ierr;
9841411c6eeSJed Brown 
9851411c6eeSJed Brown   PetscFunctionBegin;
9861411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9871411c6eeSJed Brown   PetscValidPointer(ltog,2);
9881411c6eeSJed Brown   if (!dm->ltogmap) {
98937d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
99037d0c07bSMatthew G Knepley 
991*92fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
99237d0c07bSMatthew G Knepley     if (section) {
993a974ec88SMatthew G. Knepley       const PetscInt *cdofs;
99437d0c07bSMatthew G Knepley       PetscInt       *ltog;
995ccf3bd66SMatthew G. Knepley       PetscInt        pStart, pEnd, n, p, k, l;
99637d0c07bSMatthew G Knepley 
997e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
99837d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
999ccf3bd66SMatthew G. Knepley       ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr);
1000ccf3bd66SMatthew G. Knepley       ierr = PetscMalloc1(n, &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
100137d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
1002a974ec88SMatthew G. Knepley         PetscInt bdof, cdof, dof, off, c, cind = 0;
100337d0c07bSMatthew G Knepley 
100437d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
100537d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
1006a974ec88SMatthew G. Knepley         ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr);
1007a974ec88SMatthew G. Knepley         ierr = PetscSectionGetConstraintIndices(section, p, &cdofs);CHKERRQ(ierr);
100837d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
10091a7dc684SMatthew G. Knepley         /* If you have dofs, and constraints, and they are unequal, we set the blocksize to 1 */
10101a7dc684SMatthew G. Knepley         bdof = cdof && (dof-cdof) ? 1 : dof;
10111a7dc684SMatthew G. Knepley         if (dof) {
1012b190aa46SMatthew G. Knepley           if (bs < 0)          {bs = bdof;}
1013b190aa46SMatthew G. Knepley           else if (bs != bdof) {bs = 1;}
10141a7dc684SMatthew G. Knepley         }
101537d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
1016a974ec88SMatthew G. Knepley           if ((cind < cdof) && (c == cdofs[cind])) ltog[l] = off < 0 ? off-c : off+c;
1017a974ec88SMatthew G. Knepley           else                                     ltog[l] = (off < 0 ? -(off+1) : off) + c;
101837d0c07bSMatthew G Knepley         }
101937d0c07bSMatthew G Knepley       }
1020bff27382SMatthew G. Knepley       /* Must have same blocksize on all procs (some might have no points) */
10210be3e97aSMatthew G. Knepley       bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs;
10220be3e97aSMatthew G. Knepley       ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr);
10230be3e97aSMatthew G. Knepley       if (bsMinMax[0] != bsMinMax[1]) {bs = 1;}
10240be3e97aSMatthew G. Knepley       else                            {bs = bsMinMax[0];}
10257591dbb2SMatthew G. Knepley       bs = bs < 0 ? 1 : bs;
10267591dbb2SMatthew G. Knepley       /* Must reduce indices by blocksize */
1027ccf3bd66SMatthew G. Knepley       if (bs > 1) {
1028ccf3bd66SMatthew G. Knepley         for (l = 0, k = 0; l < n; l += bs, ++k) ltog[k] = ltog[l]/bs;
1029ccf3bd66SMatthew G. Knepley         n /= bs;
1030ccf3bd66SMatthew G. Knepley       }
1031ccf3bd66SMatthew G. Knepley       ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, n, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
10323bb1ff40SBarry Smith       ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr);
103337d0c07bSMatthew G Knepley     } else {
1034b9d85ea2SLisandro Dalcin       if (!dm->ops->getlocaltoglobalmapping) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetLocalToGlobalMapping",((PetscObject)dm)->type_name);
1035184d77edSJed Brown       ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr);
10361411c6eeSJed Brown     }
103737d0c07bSMatthew G Knepley   }
10381411c6eeSJed Brown   *ltog = dm->ltogmap;
10391411c6eeSJed Brown   PetscFunctionReturn(0);
10401411c6eeSJed Brown }
10411411c6eeSJed Brown 
10421411c6eeSJed Brown /*@
10431411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
10441411c6eeSJed Brown 
10451411c6eeSJed Brown    Not Collective
10461411c6eeSJed Brown 
10471411c6eeSJed Brown    Input Parameter:
10481411c6eeSJed Brown .  dm - the DM with block structure
10491411c6eeSJed Brown 
10501411c6eeSJed Brown    Output Parameter:
10511411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
10521411c6eeSJed Brown 
10531411c6eeSJed Brown    Level: intermediate
10541411c6eeSJed Brown 
1055fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping()
10561411c6eeSJed Brown @*/
10577087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
10581411c6eeSJed Brown {
10591411c6eeSJed Brown   PetscFunctionBegin;
10601411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1061534a8f05SLisandro Dalcin   PetscValidIntPointer(bs,2);
10621411c6eeSJed 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");
10631411c6eeSJed Brown   *bs = dm->bs;
10641411c6eeSJed Brown   PetscFunctionReturn(0);
10651411c6eeSJed Brown }
10661411c6eeSJed Brown 
106747c6ae99SBarry Smith /*@
10688472ad0fSDave May     DMCreateInterpolation - Gets interpolation matrix between two DM objects
106947c6ae99SBarry Smith 
1070d083f849SBarry Smith     Collective on dm1
107147c6ae99SBarry Smith 
107247c6ae99SBarry Smith     Input Parameter:
107347c6ae99SBarry Smith +   dm1 - the DM object
107447c6ae99SBarry Smith -   dm2 - the second, finer DM object
107547c6ae99SBarry Smith 
107647c6ae99SBarry Smith     Output Parameter:
107747c6ae99SBarry Smith +  mat - the interpolation
107847c6ae99SBarry Smith -  vec - the scaling (optional)
107947c6ae99SBarry Smith 
108047c6ae99SBarry Smith     Level: developer
108147c6ae99SBarry Smith 
108295452b02SPatrick Sanan     Notes:
108395452b02SPatrick 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
108485afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
1085d52bd9f3SBarry Smith 
10861f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
1087d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
108885afcc9aSBarry Smith 
108985afcc9aSBarry Smith 
10903ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction()
109147c6ae99SBarry Smith 
109247c6ae99SBarry Smith @*/
1093e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
109447c6ae99SBarry Smith {
109547c6ae99SBarry Smith   PetscErrorCode ierr;
109647c6ae99SBarry Smith 
109747c6ae99SBarry Smith   PetscFunctionBegin;
1098171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
1099171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
1100c7d20fa0SStefano Zampini   PetscValidPointer(mat,3);
1101b9d85ea2SLisandro Dalcin   if (!dm1->ops->createinterpolation) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInterpolation",((PetscObject)dm1)->type_name);
1102cea54e9dSPatrick Farrell   ierr = PetscLogEventBegin(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
110325296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
1104cea54e9dSPatrick Farrell   ierr = PetscLogEventEnd(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
110547c6ae99SBarry Smith   PetscFunctionReturn(0);
110647c6ae99SBarry Smith }
110747c6ae99SBarry Smith 
11083ad4599aSBarry Smith /*@
11093ad4599aSBarry Smith     DMCreateRestriction - Gets restriction matrix between two DM objects
11103ad4599aSBarry Smith 
1111d083f849SBarry Smith     Collective on dm1
11123ad4599aSBarry Smith 
11133ad4599aSBarry Smith     Input Parameter:
11143ad4599aSBarry Smith +   dm1 - the DM object
11153ad4599aSBarry Smith -   dm2 - the second, finer DM object
11163ad4599aSBarry Smith 
11173ad4599aSBarry Smith     Output Parameter:
11183ad4599aSBarry Smith .  mat - the restriction
11193ad4599aSBarry Smith 
11203ad4599aSBarry Smith 
11213ad4599aSBarry Smith     Level: developer
11223ad4599aSBarry Smith 
112395452b02SPatrick Sanan     Notes:
112495452b02SPatrick 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
11253ad4599aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
11263ad4599aSBarry Smith 
11273ad4599aSBarry Smith 
11283ad4599aSBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateInterpolation()
11293ad4599aSBarry Smith 
11303ad4599aSBarry Smith @*/
11313ad4599aSBarry Smith PetscErrorCode  DMCreateRestriction(DM dm1,DM dm2,Mat *mat)
11323ad4599aSBarry Smith {
11333ad4599aSBarry Smith   PetscErrorCode ierr;
11343ad4599aSBarry Smith 
11353ad4599aSBarry Smith   PetscFunctionBegin;
11363ad4599aSBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
11373ad4599aSBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
11385a84ad33SLisandro Dalcin   PetscValidPointer(mat,3);
1139b9d85ea2SLisandro Dalcin   if (!dm1->ops->createrestriction) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateRestriction",((PetscObject)dm1)->type_name);
11403ad4599aSBarry Smith   ierr = PetscLogEventBegin(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr);
11413ad4599aSBarry Smith   ierr = (*dm1->ops->createrestriction)(dm1,dm2,mat);CHKERRQ(ierr);
11423ad4599aSBarry Smith   ierr = PetscLogEventEnd(DM_CreateRestriction,dm1,dm2,0,0);CHKERRQ(ierr);
11433ad4599aSBarry Smith   PetscFunctionReturn(0);
11443ad4599aSBarry Smith }
11453ad4599aSBarry Smith 
114647c6ae99SBarry Smith /*@
11478472ad0fSDave May     DMCreateInjection - Gets injection matrix between two DM objects
114847c6ae99SBarry Smith 
1149d083f849SBarry Smith     Collective on dm1
115047c6ae99SBarry Smith 
115147c6ae99SBarry Smith     Input Parameter:
115247c6ae99SBarry Smith +   dm1 - the DM object
115347c6ae99SBarry Smith -   dm2 - the second, finer DM object
115447c6ae99SBarry Smith 
115547c6ae99SBarry Smith     Output Parameter:
11566dbf9973SLawrence Mitchell .   mat - the injection
115747c6ae99SBarry Smith 
115847c6ae99SBarry Smith     Level: developer
115947c6ae99SBarry Smith 
116095452b02SPatrick Sanan    Notes:
116195452b02SPatrick 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
116285afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
116385afcc9aSBarry Smith 
1164e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
116547c6ae99SBarry Smith 
116647c6ae99SBarry Smith @*/
11676dbf9973SLawrence Mitchell PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,Mat *mat)
116847c6ae99SBarry Smith {
116947c6ae99SBarry Smith   PetscErrorCode ierr;
117047c6ae99SBarry Smith 
117147c6ae99SBarry Smith   PetscFunctionBegin;
1172171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
1173171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
11745a84ad33SLisandro Dalcin   PetscValidPointer(mat,3);
1175b9d85ea2SLisandro Dalcin   if (!dm1->ops->createinjection) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateInjection",((PetscObject)dm1)->type_name);
11765a84ad33SLisandro Dalcin   ierr = PetscLogEventBegin(DM_CreateInjection,dm1,dm2,0,0);CHKERRQ(ierr);
11775a84ad33SLisandro Dalcin   ierr = (*dm1->ops->createinjection)(dm1,dm2,mat);CHKERRQ(ierr);
11785a84ad33SLisandro Dalcin   ierr = PetscLogEventEnd(DM_CreateInjection,dm1,dm2,0,0);CHKERRQ(ierr);
117947c6ae99SBarry Smith   PetscFunctionReturn(0);
118047c6ae99SBarry Smith }
118147c6ae99SBarry Smith 
1182b412c318SBarry Smith /*@
1183bd041c0cSMatthew G. Knepley   DMCreateMassMatrix - Gets mass matrix between two DM objects, M_ij = \int \phi_i \psi_j
1184bd041c0cSMatthew G. Knepley 
1185d083f849SBarry Smith   Collective on dm1
1186bd041c0cSMatthew G. Knepley 
1187bd041c0cSMatthew G. Knepley   Input Parameter:
1188bd041c0cSMatthew G. Knepley + dm1 - the DM object
1189bd041c0cSMatthew G. Knepley - dm2 - the second, finer DM object
1190bd041c0cSMatthew G. Knepley 
1191bd041c0cSMatthew G. Knepley   Output Parameter:
1192bd041c0cSMatthew G. Knepley . mat - the interpolation
1193bd041c0cSMatthew G. Knepley 
1194bd041c0cSMatthew G. Knepley   Level: developer
1195bd041c0cSMatthew G. Knepley 
1196bd041c0cSMatthew G. Knepley .seealso DMCreateMatrix(), DMRefine(), DMCoarsen(), DMCreateRestriction(), DMCreateInterpolation(), DMCreateInjection()
1197bd041c0cSMatthew G. Knepley @*/
1198bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix(DM dm1, DM dm2, Mat *mat)
1199bd041c0cSMatthew G. Knepley {
1200bd041c0cSMatthew G. Knepley   PetscErrorCode ierr;
1201bd041c0cSMatthew G. Knepley 
1202bd041c0cSMatthew G. Knepley   PetscFunctionBegin;
1203bd041c0cSMatthew G. Knepley   PetscValidHeaderSpecific(dm1, DM_CLASSID, 1);
1204bd041c0cSMatthew G. Knepley   PetscValidHeaderSpecific(dm2, DM_CLASSID, 2);
12055a84ad33SLisandro Dalcin   PetscValidPointer(mat,3);
1206b9d85ea2SLisandro Dalcin   if (!dm1->ops->createmassmatrix) SETERRQ1(PetscObjectComm((PetscObject)dm1),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMassMatrix",((PetscObject)dm1)->type_name);
1207bd041c0cSMatthew G. Knepley   ierr = (*dm1->ops->createmassmatrix)(dm1, dm2, mat);CHKERRQ(ierr);
1208bd041c0cSMatthew G. Knepley   PetscFunctionReturn(0);
1209bd041c0cSMatthew G. Knepley }
1210bd041c0cSMatthew G. Knepley 
1211bd041c0cSMatthew G. Knepley /*@
1212b412c318SBarry Smith     DMCreateColoring - Gets coloring for a DM
121347c6ae99SBarry Smith 
1214d083f849SBarry Smith     Collective on dm
121547c6ae99SBarry Smith 
121647c6ae99SBarry Smith     Input Parameter:
121747c6ae99SBarry Smith +   dm - the DM object
12185bdb020cSBarry Smith -   ctype - IS_COLORING_LOCAL or IS_COLORING_GLOBAL
121947c6ae99SBarry Smith 
122047c6ae99SBarry Smith     Output Parameter:
122147c6ae99SBarry Smith .   coloring - the coloring
122247c6ae99SBarry Smith 
122347c6ae99SBarry Smith     Level: developer
122447c6ae99SBarry Smith 
1225b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType()
122647c6ae99SBarry Smith 
1227aab9d709SJed Brown @*/
1228b412c318SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring)
122947c6ae99SBarry Smith {
123047c6ae99SBarry Smith   PetscErrorCode ierr;
123147c6ae99SBarry Smith 
123247c6ae99SBarry Smith   PetscFunctionBegin;
1233171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12345a84ad33SLisandro Dalcin   PetscValidPointer(coloring,3);
1235b9d85ea2SLisandro Dalcin   if (!dm->ops->getcoloring) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateColoring",((PetscObject)dm)->type_name);
1236b412c318SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr);
123747c6ae99SBarry Smith   PetscFunctionReturn(0);
123847c6ae99SBarry Smith }
123947c6ae99SBarry Smith 
1240b412c318SBarry Smith /*@
12418472ad0fSDave May     DMCreateMatrix - Gets empty Jacobian for a DM
124247c6ae99SBarry Smith 
1243d083f849SBarry Smith     Collective on dm
124447c6ae99SBarry Smith 
124547c6ae99SBarry Smith     Input Parameter:
1246b412c318SBarry Smith .   dm - the DM object
124747c6ae99SBarry Smith 
124847c6ae99SBarry Smith     Output Parameter:
124947c6ae99SBarry Smith .   mat - the empty Jacobian
125047c6ae99SBarry Smith 
1251073dac72SJed Brown     Level: beginner
125247c6ae99SBarry Smith 
125395452b02SPatrick Sanan     Notes:
125495452b02SPatrick Sanan     This properly preallocates the number of nonzeros in the sparse matrix so you
125594013140SBarry Smith        do not need to do it yourself.
125694013140SBarry Smith 
125794013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
12587889ec69SBarry Smith        the nonzero pattern call DMSetMatrixPreallocateOnly()
125994013140SBarry Smith 
126094013140SBarry 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
126194013140SBarry Smith        internally by PETSc.
126294013140SBarry Smith 
126394013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
1264aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
126594013140SBarry Smith 
1266b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType()
126747c6ae99SBarry Smith 
1268aab9d709SJed Brown @*/
1269b412c318SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,Mat *mat)
127047c6ae99SBarry Smith {
127147c6ae99SBarry Smith   PetscErrorCode ierr;
127247c6ae99SBarry Smith 
127347c6ae99SBarry Smith   PetscFunctionBegin;
1274171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1275c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
1276b9d85ea2SLisandro Dalcin   if (!dm->ops->creatematrix) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateMatrix",((PetscObject)dm)->type_name);
12775a84ad33SLisandro Dalcin   ierr = MatInitializePackage();CHKERRQ(ierr);
1278fdc842d1SBarry Smith   ierr = PetscLogEventBegin(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr);
1279b412c318SBarry Smith   ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr);
1280e571a35bSMatthew G. Knepley   /* Handle nullspace and near nullspace */
1281e5e52638SMatthew G. Knepley   if (dm->Nf) {
1282e571a35bSMatthew G. Knepley     MatNullSpace nullSpace;
1283e571a35bSMatthew G. Knepley     PetscInt     Nf;
1284e571a35bSMatthew G. Knepley 
1285e5e52638SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
1286e571a35bSMatthew G. Knepley     if (Nf == 1) {
1287e571a35bSMatthew G. Knepley       if (dm->nullspaceConstructors[0]) {
1288e571a35bSMatthew G. Knepley         ierr = (*dm->nullspaceConstructors[0])(dm, 0, &nullSpace);CHKERRQ(ierr);
1289e571a35bSMatthew G. Knepley         ierr = MatSetNullSpace(*mat, nullSpace);CHKERRQ(ierr);
1290e571a35bSMatthew G. Knepley         ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);
1291e571a35bSMatthew G. Knepley       }
1292e571a35bSMatthew G. Knepley       if (dm->nearnullspaceConstructors[0]) {
1293e571a35bSMatthew G. Knepley         ierr = (*dm->nearnullspaceConstructors[0])(dm, 0, &nullSpace);CHKERRQ(ierr);
1294e571a35bSMatthew G. Knepley         ierr = MatSetNearNullSpace(*mat, nullSpace);CHKERRQ(ierr);
1295e571a35bSMatthew G. Knepley         ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);
1296e571a35bSMatthew G. Knepley       }
1297e571a35bSMatthew G. Knepley     }
1298e571a35bSMatthew G. Knepley   }
1299fdc842d1SBarry Smith   ierr = PetscLogEventEnd(DM_CreateMatrix,0,0,0,0);CHKERRQ(ierr);
130047c6ae99SBarry Smith   PetscFunctionReturn(0);
130147c6ae99SBarry Smith }
130247c6ae99SBarry Smith 
1303732e2eb9SMatthew G Knepley /*@
1304950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
1305732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
1306732e2eb9SMatthew G Knepley 
1307d083f849SBarry Smith   Logically Collective on dm
1308732e2eb9SMatthew G Knepley 
1309732e2eb9SMatthew G Knepley   Input Parameter:
1310732e2eb9SMatthew G Knepley + dm - the DM
1311732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
1312732e2eb9SMatthew G Knepley 
1313732e2eb9SMatthew G Knepley   Level: developer
1314b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixStructureOnly()
1315732e2eb9SMatthew G Knepley @*/
1316732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
1317732e2eb9SMatthew G Knepley {
1318732e2eb9SMatthew G Knepley   PetscFunctionBegin;
1319732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1320732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
1321732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
1322732e2eb9SMatthew G Knepley }
1323732e2eb9SMatthew G Knepley 
1324b06ff27eSHong Zhang /*@
1325b06ff27eSHong Zhang   DMSetMatrixStructureOnly - When DMCreateMatrix() is called, the matrix structure will be created
1326b06ff27eSHong Zhang     but the array for values will not be allocated.
1327b06ff27eSHong Zhang 
1328d083f849SBarry Smith   Logically Collective on dm
1329b06ff27eSHong Zhang 
1330b06ff27eSHong Zhang   Input Parameter:
1331b06ff27eSHong Zhang + dm - the DM
1332b06ff27eSHong Zhang - only - PETSC_TRUE if only want matrix stucture
1333b06ff27eSHong Zhang 
1334b06ff27eSHong Zhang   Level: developer
1335b06ff27eSHong Zhang .seealso DMCreateMatrix(), DMSetMatrixPreallocateOnly()
1336b06ff27eSHong Zhang @*/
1337b06ff27eSHong Zhang PetscErrorCode DMSetMatrixStructureOnly(DM dm, PetscBool only)
1338b06ff27eSHong Zhang {
1339b06ff27eSHong Zhang   PetscFunctionBegin;
1340b06ff27eSHong Zhang   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1341b06ff27eSHong Zhang   dm->structure_only = only;
1342b06ff27eSHong Zhang   PetscFunctionReturn(0);
1343b06ff27eSHong Zhang }
1344b06ff27eSHong Zhang 
1345a89ea682SMatthew G Knepley /*@C
1346aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1347a89ea682SMatthew G Knepley 
1348a89ea682SMatthew G Knepley   Not Collective
1349a89ea682SMatthew G Knepley 
1350a89ea682SMatthew G Knepley   Input Parameters:
1351a89ea682SMatthew G Knepley + dm - the DM object
1352aa1993deSMatthew G Knepley . count - The minium size
135369291d52SBarry Smith - dtype - MPI data type, often MPIU_REAL, MPIU_SCALAR, MPIU_INT)
1354a89ea682SMatthew G Knepley 
1355a89ea682SMatthew G Knepley   Output Parameter:
1356a89ea682SMatthew G Knepley . array - the work array
1357a89ea682SMatthew G Knepley 
1358a89ea682SMatthew G Knepley   Level: developer
1359a89ea682SMatthew G Knepley 
1360a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
1361a89ea682SMatthew G Knepley @*/
136269291d52SBarry Smith PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,MPI_Datatype dtype,void *mem)
1363a89ea682SMatthew G Knepley {
1364a89ea682SMatthew G Knepley   PetscErrorCode ierr;
1365aa1993deSMatthew G Knepley   DMWorkLink     link;
136669291d52SBarry Smith   PetscMPIInt    dsize;
1367a89ea682SMatthew G Knepley 
1368a89ea682SMatthew G Knepley   PetscFunctionBegin;
1369a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1370aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1371aa1993deSMatthew G Knepley   if (dm->workin) {
1372aa1993deSMatthew G Knepley     link       = dm->workin;
1373aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
1374aa1993deSMatthew G Knepley   } else {
1375b00a9115SJed Brown     ierr = PetscNewLog(dm,&link);CHKERRQ(ierr);
1376a89ea682SMatthew G Knepley   }
137769291d52SBarry Smith   ierr = MPI_Type_size(dtype,&dsize);CHKERRQ(ierr);
13785056fcd2SBarry Smith   if (((size_t)dsize*count) > link->bytes) {
1379aa1993deSMatthew G Knepley     ierr        = PetscFree(link->mem);CHKERRQ(ierr);
1380854ce69bSBarry Smith     ierr        = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr);
1381abe1f95cSSatish Balay     ierr        = PetscMemzero(link->mem,dsize*count);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) {
1496534a8f05SLisandro Dalcin     PetscValidIntPointer(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   }
1507*92fd8e1eSJed Brown   ierr = DMGetLocalSection(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) {
1624534a8f05SLisandro Dalcin     PetscValidIntPointer(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 
1649*92fd8e1eSJed Brown     ierr = DMGetLocalSection(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);
1706b9d85ea2SLisandro Dalcin   if (!dm->ops->createsubdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSubDM",((PetscObject)dm)->type_name);
1707435a35e8SMatthew G Knepley   ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
1708435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1709435a35e8SMatthew G Knepley }
1710435a35e8SMatthew G Knepley 
17112adcc780SMatthew G. Knepley /*@C
17122adcc780SMatthew G. Knepley   DMCreateSuperDM - Returns an arrays of ISes and DM encapsulating a superproblem defined by the DMs passed in.
17132adcc780SMatthew G. Knepley 
17142adcc780SMatthew G. Knepley   Not collective
17152adcc780SMatthew G. Knepley 
17162adcc780SMatthew G. Knepley   Input Parameter:
17172adcc780SMatthew G. Knepley + dms - The DM objects
17182adcc780SMatthew G. Knepley - len - The number of DMs
17192adcc780SMatthew G. Knepley 
17202adcc780SMatthew G. Knepley   Output Parameters:
1721a42bd24dSMatthew G. Knepley + is - The global indices for the subproblem, or NULL
17222adcc780SMatthew G. Knepley - superdm - The DM for the superproblem
17232adcc780SMatthew G. Knepley 
17245d3b26e6SMatthew G. Knepley   Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed
17255d3b26e6SMatthew G. Knepley 
17262adcc780SMatthew G. Knepley   Level: intermediate
17272adcc780SMatthew G. Knepley 
17285d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
17292adcc780SMatthew G. Knepley @*/
17302adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM(DM dms[], PetscInt len, IS **is, DM *superdm)
17312adcc780SMatthew G. Knepley {
17322adcc780SMatthew G. Knepley   PetscInt       i;
17332adcc780SMatthew G. Knepley   PetscErrorCode ierr;
17342adcc780SMatthew G. Knepley 
17352adcc780SMatthew G. Knepley   PetscFunctionBegin;
17362adcc780SMatthew G. Knepley   PetscValidPointer(dms,1);
17372adcc780SMatthew G. Knepley   for (i = 0; i < len; ++i) {PetscValidHeaderSpecific(dms[i],DM_CLASSID,1);}
17382adcc780SMatthew G. Knepley   if (is) PetscValidPointer(is,3);
1739a42bd24dSMatthew G. Knepley   PetscValidPointer(superdm,4);
17402adcc780SMatthew G. Knepley   if (len < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of DMs must be nonnegative: %D", len);
17412adcc780SMatthew G. Knepley   if (len) {
1742b9d85ea2SLisandro Dalcin     DM dm = dms[0];
1743b9d85ea2SLisandro Dalcin     if (!dm->ops->createsuperdm) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateSuperDM",((PetscObject)dm)->type_name);
1744b9d85ea2SLisandro Dalcin     ierr = (*dm->ops->createsuperdm)(dms, len, is, superdm);CHKERRQ(ierr);
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);
1847b9d85ea2SLisandro Dalcin   if (!dm->ops->createddscatters) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCreateDomainDecompositionScatters",((PetscObject)dm)->type_name);
1848e30e807fSPeter Brune   ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr);
1849e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1850e7c4fc90SDmitry Karpeev }
1851e7c4fc90SDmitry Karpeev 
185247c6ae99SBarry Smith /*@
185347c6ae99SBarry Smith   DMRefine - Refines a DM object
185447c6ae99SBarry Smith 
1855d083f849SBarry Smith   Collective on dm
185647c6ae99SBarry Smith 
185747c6ae99SBarry Smith   Input Parameter:
185847c6ae99SBarry Smith + dm   - the DM object
185991d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
186047c6ae99SBarry Smith 
186147c6ae99SBarry Smith   Output Parameter:
18620298fd71SBarry Smith . dmf - the refined DM, or NULL
1863ae0a1c52SMatthew G Knepley 
18640298fd71SBarry Smith   Note: If no refinement was done, the return value is NULL
186547c6ae99SBarry Smith 
186647c6ae99SBarry Smith   Level: developer
186747c6ae99SBarry Smith 
1868e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
186947c6ae99SBarry Smith @*/
18707087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
187147c6ae99SBarry Smith {
187247c6ae99SBarry Smith   PetscErrorCode   ierr;
1873c833c3b5SJed Brown   DMRefineHookLink link;
187447c6ae99SBarry Smith 
187547c6ae99SBarry Smith   PetscFunctionBegin;
1876732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1877b9d85ea2SLisandro Dalcin   if (!dm->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMRefine",((PetscObject)dm)->type_name);
18781ac00216SMatthew G. Knepley   ierr = PetscLogEventBegin(DM_Refine,dm,0,0,0);CHKERRQ(ierr);
187947c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
18804057135bSMatthew G Knepley   if (*dmf) {
188143842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
18828865f1eaSKarl Rupp 
18838cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
18848865f1eaSKarl Rupp 
1885644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
18860598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1887656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
18888865f1eaSKarl Rupp 
1889e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1890c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
18918865f1eaSKarl Rupp       if (link->refinehook) {
18928865f1eaSKarl Rupp         ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);
18938865f1eaSKarl Rupp       }
1894c833c3b5SJed Brown     }
1895c833c3b5SJed Brown   }
18961ac00216SMatthew G. Knepley   ierr = PetscLogEventEnd(DM_Refine,dm,0,0,0);CHKERRQ(ierr);
1897c833c3b5SJed Brown   PetscFunctionReturn(0);
1898c833c3b5SJed Brown }
1899c833c3b5SJed Brown 
1900bb9467b5SJed Brown /*@C
1901c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1902c833c3b5SJed Brown 
1903c833c3b5SJed Brown    Logically Collective
1904c833c3b5SJed Brown 
1905c833c3b5SJed Brown    Input Arguments:
1906c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1907c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1908c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
19090298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1910c833c3b5SJed Brown 
1911c833c3b5SJed Brown    Calling sequence of refinehook:
1912c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1913c833c3b5SJed Brown 
1914c833c3b5SJed Brown +  coarse - coarse level DM
1915c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1916c833c3b5SJed Brown -  ctx - optional user-defined function context
1917c833c3b5SJed Brown 
1918c833c3b5SJed Brown    Calling sequence for interphook:
1919c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1920c833c3b5SJed Brown 
1921c833c3b5SJed Brown +  coarse - coarse level DM
1922c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1923c833c3b5SJed Brown .  fine - fine level DM to update
1924c833c3b5SJed Brown -  ctx - optional user-defined function context
1925c833c3b5SJed Brown 
1926c833c3b5SJed Brown    Level: advanced
1927c833c3b5SJed Brown 
1928c833c3b5SJed Brown    Notes:
1929c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1930c833c3b5SJed Brown 
1931c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1932c833c3b5SJed Brown 
1933bb9467b5SJed Brown    This function is currently not available from Fortran.
1934bb9467b5SJed Brown 
1935c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1936c833c3b5SJed Brown @*/
1937c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1938c833c3b5SJed Brown {
1939c833c3b5SJed Brown   PetscErrorCode   ierr;
1940c833c3b5SJed Brown   DMRefineHookLink link,*p;
1941c833c3b5SJed Brown 
1942c833c3b5SJed Brown   PetscFunctionBegin;
1943c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
19443d8e3701SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
19453d8e3701SJed Brown     if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) PetscFunctionReturn(0);
19463d8e3701SJed Brown   }
194795dccacaSBarry Smith   ierr             = PetscNew(&link);CHKERRQ(ierr);
1948c833c3b5SJed Brown   link->refinehook = refinehook;
1949c833c3b5SJed Brown   link->interphook = interphook;
1950c833c3b5SJed Brown   link->ctx        = ctx;
19510298fd71SBarry Smith   link->next       = NULL;
1952c833c3b5SJed Brown   *p               = link;
1953c833c3b5SJed Brown   PetscFunctionReturn(0);
1954c833c3b5SJed Brown }
1955c833c3b5SJed Brown 
19563d8e3701SJed Brown /*@C
19573d8e3701SJed Brown    DMRefineHookRemove - remove a callback from the list of hooks to be run when interpolating a nonlinear problem to a finer grid
19583d8e3701SJed Brown 
19593d8e3701SJed Brown    Logically Collective
19603d8e3701SJed Brown 
19613d8e3701SJed Brown    Input Arguments:
19623d8e3701SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
19633d8e3701SJed Brown .  refinehook - function to run when setting up a coarser level
19643d8e3701SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
19653d8e3701SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
19663d8e3701SJed Brown 
19673d8e3701SJed Brown    Level: advanced
19683d8e3701SJed Brown 
19693d8e3701SJed Brown    Notes:
19703d8e3701SJed Brown    This function does nothing if the hook is not in the list.
19713d8e3701SJed Brown 
19723d8e3701SJed Brown    This function is currently not available from Fortran.
19733d8e3701SJed Brown 
19743d8e3701SJed Brown .seealso: DMCoarsenHookRemove(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
19753d8e3701SJed Brown @*/
19763d8e3701SJed Brown PetscErrorCode DMRefineHookRemove(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
19773d8e3701SJed Brown {
19783d8e3701SJed Brown   PetscErrorCode   ierr;
19793d8e3701SJed Brown   DMRefineHookLink link,*p;
19803d8e3701SJed Brown 
19813d8e3701SJed Brown   PetscFunctionBegin;
19823d8e3701SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
19833d8e3701SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) { /* Search the list of current hooks */
19843d8e3701SJed Brown     if ((*p)->refinehook == refinehook && (*p)->interphook == interphook && (*p)->ctx == ctx) {
19853d8e3701SJed Brown       link = *p;
19863d8e3701SJed Brown       *p = link->next;
19873d8e3701SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
19883d8e3701SJed Brown       break;
19893d8e3701SJed Brown     }
19903d8e3701SJed Brown   }
19913d8e3701SJed Brown   PetscFunctionReturn(0);
19923d8e3701SJed Brown }
19933d8e3701SJed Brown 
1994c833c3b5SJed Brown /*@
1995c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1996c833c3b5SJed Brown 
1997c833c3b5SJed Brown    Collective if any hooks are
1998c833c3b5SJed Brown 
1999c833c3b5SJed Brown    Input Arguments:
2000c833c3b5SJed Brown +  coarse - coarser DM to use as a base
2001e91eccc2SStefano Zampini .  interp - interpolation matrix, apply using MatInterpolate()
2002c833c3b5SJed Brown -  fine - finer DM to update
2003c833c3b5SJed Brown 
2004c833c3b5SJed Brown    Level: developer
2005c833c3b5SJed Brown 
2006c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
2007c833c3b5SJed Brown @*/
2008c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
2009c833c3b5SJed Brown {
2010c833c3b5SJed Brown   PetscErrorCode   ierr;
2011c833c3b5SJed Brown   DMRefineHookLink link;
2012c833c3b5SJed Brown 
2013c833c3b5SJed Brown   PetscFunctionBegin;
2014c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
20158865f1eaSKarl Rupp     if (link->interphook) {
20168865f1eaSKarl Rupp       ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);
20178865f1eaSKarl Rupp     }
20184057135bSMatthew G Knepley   }
201947c6ae99SBarry Smith   PetscFunctionReturn(0);
202047c6ae99SBarry Smith }
202147c6ae99SBarry Smith 
2022eb3f98d2SBarry Smith /*@
2023eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
2024eb3f98d2SBarry Smith 
2025eb3f98d2SBarry Smith     Not Collective
2026eb3f98d2SBarry Smith 
2027eb3f98d2SBarry Smith     Input Parameter:
2028eb3f98d2SBarry Smith .   dm - the DM object
2029eb3f98d2SBarry Smith 
2030eb3f98d2SBarry Smith     Output Parameter:
2031eb3f98d2SBarry Smith .   level - number of refinements
2032eb3f98d2SBarry Smith 
2033eb3f98d2SBarry Smith     Level: developer
2034eb3f98d2SBarry Smith 
20356a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
2036eb3f98d2SBarry Smith 
2037eb3f98d2SBarry Smith @*/
2038eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
2039eb3f98d2SBarry Smith {
2040eb3f98d2SBarry Smith   PetscFunctionBegin;
2041eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2042eb3f98d2SBarry Smith   *level = dm->levelup;
2043eb3f98d2SBarry Smith   PetscFunctionReturn(0);
2044eb3f98d2SBarry Smith }
2045eb3f98d2SBarry Smith 
2046fef3a512SBarry Smith /*@
2047fef3a512SBarry Smith     DMSetRefineLevel - Set's the number of refinements that have generated this DM.
2048fef3a512SBarry Smith 
2049fef3a512SBarry Smith     Not Collective
2050fef3a512SBarry Smith 
2051fef3a512SBarry Smith     Input Parameter:
2052fef3a512SBarry Smith +   dm - the DM object
2053fef3a512SBarry Smith -   level - number of refinements
2054fef3a512SBarry Smith 
2055fef3a512SBarry Smith     Level: advanced
2056fef3a512SBarry Smith 
205795452b02SPatrick Sanan     Notes:
205895452b02SPatrick Sanan     This value is used by PCMG to determine how many multigrid levels to use
2059fef3a512SBarry Smith 
2060fef3a512SBarry Smith .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
2061fef3a512SBarry Smith 
2062fef3a512SBarry Smith @*/
2063fef3a512SBarry Smith PetscErrorCode  DMSetRefineLevel(DM dm,PetscInt level)
2064fef3a512SBarry Smith {
2065fef3a512SBarry Smith   PetscFunctionBegin;
2066fef3a512SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2067fef3a512SBarry Smith   dm->levelup = level;
2068fef3a512SBarry Smith   PetscFunctionReturn(0);
2069fef3a512SBarry Smith }
2070fef3a512SBarry Smith 
2071ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformDM_Internal(DM dm, DM *tdm)
2072ca3d3a14SMatthew G. Knepley {
2073ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2074ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2075ca3d3a14SMatthew G. Knepley   PetscValidPointer(tdm, 2);
2076ca3d3a14SMatthew G. Knepley   *tdm = dm->transformDM;
2077ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2078ca3d3a14SMatthew G. Knepley }
2079ca3d3a14SMatthew G. Knepley 
2080ca3d3a14SMatthew G. Knepley PetscErrorCode DMGetBasisTransformVec_Internal(DM dm, Vec *tv)
2081ca3d3a14SMatthew G. Knepley {
2082ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2083ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2084ca3d3a14SMatthew G. Knepley   PetscValidPointer(tv, 2);
2085ca3d3a14SMatthew G. Knepley   *tv = dm->transform;
2086ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2087ca3d3a14SMatthew G. Knepley }
2088ca3d3a14SMatthew G. Knepley 
2089ca3d3a14SMatthew G. Knepley /*@
2090c0f8e1fdSMatthew G. Knepley   DMHasBasisTransform - Whether we employ a basis transformation from functions in global vectors to functions in local vectors
2091ca3d3a14SMatthew G. Knepley 
2092ca3d3a14SMatthew G. Knepley   Input Parameter:
2093ca3d3a14SMatthew G. Knepley . dm - The DM
2094ca3d3a14SMatthew G. Knepley 
2095ca3d3a14SMatthew G. Knepley   Output Parameter:
2096ca3d3a14SMatthew G. Knepley . flg - PETSC_TRUE if a basis transformation should be done
2097ca3d3a14SMatthew G. Knepley 
2098ca3d3a14SMatthew G. Knepley   Level: developer
2099ca3d3a14SMatthew G. Knepley 
2100ca3d3a14SMatthew G. Knepley .seealso: DMPlexGlobalToLocalBasis(), DMPlexLocalToGlobalBasis()()
2101ca3d3a14SMatthew G. Knepley @*/
2102ca3d3a14SMatthew G. Knepley PetscErrorCode DMHasBasisTransform(DM dm, PetscBool *flg)
2103ca3d3a14SMatthew G. Knepley {
2104ca3d3a14SMatthew G. Knepley   Vec            tv;
2105ca3d3a14SMatthew G. Knepley   PetscErrorCode ierr;
2106ca3d3a14SMatthew G. Knepley 
2107ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2108ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2109534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg, 2);
2110ca3d3a14SMatthew G. Knepley   ierr = DMGetBasisTransformVec_Internal(dm, &tv);CHKERRQ(ierr);
2111ca3d3a14SMatthew G. Knepley   *flg = tv ? PETSC_TRUE : PETSC_FALSE;
2112ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2113ca3d3a14SMatthew G. Knepley }
2114ca3d3a14SMatthew G. Knepley 
2115ca3d3a14SMatthew G. Knepley PetscErrorCode DMConstructBasisTransform_Internal(DM dm)
2116ca3d3a14SMatthew G. Knepley {
2117ca3d3a14SMatthew G. Knepley   PetscSection   s, ts;
2118ca3d3a14SMatthew G. Knepley   PetscScalar   *ta;
2119ca3d3a14SMatthew G. Knepley   PetscInt       cdim, pStart, pEnd, p, Nf, f, Nc, dof;
2120ca3d3a14SMatthew G. Knepley   PetscErrorCode ierr;
2121ca3d3a14SMatthew G. Knepley 
2122ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2123ca3d3a14SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
2124*92fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
2125ca3d3a14SMatthew G. Knepley   ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
2126ca3d3a14SMatthew G. Knepley   ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
2127ca3d3a14SMatthew G. Knepley   ierr = DMClone(dm, &dm->transformDM);CHKERRQ(ierr);
2128*92fd8e1eSJed Brown   ierr = DMGetLocalSection(dm->transformDM, &ts);CHKERRQ(ierr);
2129ca3d3a14SMatthew G. Knepley   ierr = PetscSectionSetNumFields(ts, Nf);CHKERRQ(ierr);
2130ca3d3a14SMatthew G. Knepley   ierr = PetscSectionSetChart(ts, pStart, pEnd);CHKERRQ(ierr);
2131ca3d3a14SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2132ca3d3a14SMatthew G. Knepley     ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr);
2133ca3d3a14SMatthew G. Knepley     /* We could start to label fields by their transformation properties */
2134ca3d3a14SMatthew G. Knepley     if (Nc != cdim) continue;
2135ca3d3a14SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
2136ca3d3a14SMatthew G. Knepley       ierr = PetscSectionGetFieldDof(s, p, f, &dof);CHKERRQ(ierr);
2137ca3d3a14SMatthew G. Knepley       if (!dof) continue;
2138ca3d3a14SMatthew G. Knepley       ierr = PetscSectionSetFieldDof(ts, p, f, PetscSqr(cdim));CHKERRQ(ierr);
2139ca3d3a14SMatthew G. Knepley       ierr = PetscSectionAddDof(ts, p, PetscSqr(cdim));CHKERRQ(ierr);
2140ca3d3a14SMatthew G. Knepley     }
2141ca3d3a14SMatthew G. Knepley   }
2142ca3d3a14SMatthew G. Knepley   ierr = PetscSectionSetUp(ts);CHKERRQ(ierr);
2143ca3d3a14SMatthew G. Knepley   ierr = DMCreateLocalVector(dm->transformDM, &dm->transform);CHKERRQ(ierr);
2144ca3d3a14SMatthew G. Knepley   ierr = VecGetArray(dm->transform, &ta);CHKERRQ(ierr);
2145ca3d3a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2146ca3d3a14SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
2147ca3d3a14SMatthew G. Knepley       ierr = PetscSectionGetFieldDof(ts, p, f, &dof);CHKERRQ(ierr);
2148ca3d3a14SMatthew G. Knepley       if (dof) {
2149ca3d3a14SMatthew G. Knepley         PetscReal          x[3] = {0.0, 0.0, 0.0};
2150ca3d3a14SMatthew G. Knepley         PetscScalar       *tva;
2151ca3d3a14SMatthew G. Knepley         const PetscScalar *A;
2152ca3d3a14SMatthew G. Knepley 
2153ca3d3a14SMatthew G. Knepley         /* TODO Get quadrature point for this dual basis vector for coordinate */
2154ca3d3a14SMatthew G. Knepley         ierr = (*dm->transformGetMatrix)(dm, x, PETSC_TRUE, &A, dm->transformCtx);CHKERRQ(ierr);
2155ca3d3a14SMatthew G. Knepley         ierr = DMPlexPointLocalFieldRef(dm->transformDM, p, f, ta, (void *) &tva);CHKERRQ(ierr);
2156580bdb30SBarry Smith         ierr = PetscArraycpy(tva, A, PetscSqr(cdim));CHKERRQ(ierr);
2157ca3d3a14SMatthew G. Knepley       }
2158ca3d3a14SMatthew G. Knepley     }
2159ca3d3a14SMatthew G. Knepley   }
2160ca3d3a14SMatthew G. Knepley   ierr = VecRestoreArray(dm->transform, &ta);CHKERRQ(ierr);
2161ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2162ca3d3a14SMatthew G. Knepley }
2163ca3d3a14SMatthew G. Knepley 
2164ca3d3a14SMatthew G. Knepley PetscErrorCode DMCopyTransform(DM dm, DM newdm)
2165ca3d3a14SMatthew G. Knepley {
2166ca3d3a14SMatthew G. Knepley   PetscErrorCode ierr;
2167ca3d3a14SMatthew G. Knepley 
2168ca3d3a14SMatthew G. Knepley   PetscFunctionBegin;
2169ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2170ca3d3a14SMatthew G. Knepley   PetscValidHeaderSpecific(newdm, DM_CLASSID, 2);
2171ca3d3a14SMatthew G. Knepley   newdm->transformCtx       = dm->transformCtx;
2172ca3d3a14SMatthew G. Knepley   newdm->transformSetUp     = dm->transformSetUp;
2173ca3d3a14SMatthew G. Knepley   newdm->transformDestroy   = NULL;
2174ca3d3a14SMatthew G. Knepley   newdm->transformGetMatrix = dm->transformGetMatrix;
2175ca3d3a14SMatthew G. Knepley   if (newdm->transformSetUp) {ierr = DMConstructBasisTransform_Internal(newdm);CHKERRQ(ierr);}
2176ca3d3a14SMatthew G. Knepley   PetscFunctionReturn(0);
2177ca3d3a14SMatthew G. Knepley }
2178ca3d3a14SMatthew G. Knepley 
2179bb9467b5SJed Brown /*@C
2180baf369e7SPeter Brune    DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called
2181baf369e7SPeter Brune 
2182baf369e7SPeter Brune    Logically Collective
2183baf369e7SPeter Brune 
2184baf369e7SPeter Brune    Input Arguments:
2185baf369e7SPeter Brune +  dm - the DM
2186baf369e7SPeter Brune .  beginhook - function to run at the beginning of DMGlobalToLocalBegin()
2187baf369e7SPeter Brune .  endhook - function to run after DMGlobalToLocalEnd() has completed
21880298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2189baf369e7SPeter Brune 
2190baf369e7SPeter Brune    Calling sequence for beginhook:
2191baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
2192baf369e7SPeter Brune 
2193baf369e7SPeter Brune +  dm - global DM
2194baf369e7SPeter Brune .  g - global vector
2195baf369e7SPeter Brune .  mode - mode
2196baf369e7SPeter Brune .  l - local vector
2197baf369e7SPeter Brune -  ctx - optional user-defined function context
2198baf369e7SPeter Brune 
2199baf369e7SPeter Brune 
2200baf369e7SPeter Brune    Calling sequence for endhook:
2201ec4806b8SPeter Brune $    endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
2202baf369e7SPeter Brune 
2203baf369e7SPeter Brune +  global - global DM
2204baf369e7SPeter Brune -  ctx - optional user-defined function context
2205baf369e7SPeter Brune 
2206baf369e7SPeter Brune    Level: advanced
2207baf369e7SPeter Brune 
2208baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2209baf369e7SPeter Brune @*/
2210baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
2211baf369e7SPeter Brune {
2212baf369e7SPeter Brune   PetscErrorCode          ierr;
2213baf369e7SPeter Brune   DMGlobalToLocalHookLink link,*p;
2214baf369e7SPeter Brune 
2215baf369e7SPeter Brune   PetscFunctionBegin;
2216baf369e7SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2217baf369e7SPeter Brune   for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
221895dccacaSBarry Smith   ierr            = PetscNew(&link);CHKERRQ(ierr);
2219baf369e7SPeter Brune   link->beginhook = beginhook;
2220baf369e7SPeter Brune   link->endhook   = endhook;
2221baf369e7SPeter Brune   link->ctx       = ctx;
22220298fd71SBarry Smith   link->next      = NULL;
2223baf369e7SPeter Brune   *p              = link;
2224baf369e7SPeter Brune   PetscFunctionReturn(0);
2225baf369e7SPeter Brune }
2226baf369e7SPeter Brune 
22274c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx)
22284c274da1SToby Isaac {
22294c274da1SToby Isaac   Mat cMat;
22304c274da1SToby Isaac   Vec cVec;
22314c274da1SToby Isaac   PetscSection section, cSec;
22324c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
22334c274da1SToby Isaac   PetscErrorCode ierr;
22344c274da1SToby Isaac 
22354c274da1SToby Isaac   PetscFunctionBegin;
22364c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
22374c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
22384c274da1SToby Isaac   if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) {
22395db9a05bSToby Isaac     PetscInt nRows;
22405db9a05bSToby Isaac 
22415db9a05bSToby Isaac     ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr);
22425db9a05bSToby Isaac     if (nRows <= 0) PetscFunctionReturn(0);
2243*92fd8e1eSJed Brown     ierr = DMGetLocalSection(dm,&section);CHKERRQ(ierr);
22447711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
22454c274da1SToby Isaac     ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr);
22464c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
22474c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
22484c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
22494c274da1SToby Isaac       if (dof) {
22504c274da1SToby Isaac         PetscScalar *vals;
22514c274da1SToby Isaac         ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr);
22524c274da1SToby Isaac         ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr);
22534c274da1SToby Isaac       }
22544c274da1SToby Isaac     }
22554c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
22564c274da1SToby Isaac   }
22574c274da1SToby Isaac   PetscFunctionReturn(0);
22584c274da1SToby Isaac }
22594c274da1SToby Isaac 
226047c6ae99SBarry Smith /*@
226101729b5cSPatrick Sanan     DMGlobalToLocal - update local vectors from global vector
226201729b5cSPatrick Sanan 
2263d083f849SBarry Smith     Neighbor-wise Collective on dm
226401729b5cSPatrick Sanan 
226501729b5cSPatrick Sanan     Input Parameters:
226601729b5cSPatrick Sanan +   dm - the DM object
226701729b5cSPatrick Sanan .   g - the global vector
226801729b5cSPatrick Sanan .   mode - INSERT_VALUES or ADD_VALUES
226901729b5cSPatrick Sanan -   l - the local vector
227001729b5cSPatrick Sanan 
227101729b5cSPatrick Sanan     Notes:
227201729b5cSPatrick Sanan     The communication involved in this update can be overlapped with computation by using
227301729b5cSPatrick Sanan     DMGlobalToLocalBegin() and DMGlobalToLocalEnd().
227401729b5cSPatrick Sanan 
227501729b5cSPatrick Sanan     Level: beginner
227601729b5cSPatrick Sanan 
227701729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
227801729b5cSPatrick Sanan 
227901729b5cSPatrick Sanan @*/
228001729b5cSPatrick Sanan PetscErrorCode DMGlobalToLocal(DM dm,Vec g,InsertMode mode,Vec l)
228101729b5cSPatrick Sanan {
228201729b5cSPatrick Sanan   PetscErrorCode ierr;
228301729b5cSPatrick Sanan 
228401729b5cSPatrick Sanan   PetscFunctionBegin;
228501729b5cSPatrick Sanan   ierr = DMGlobalToLocalBegin(dm,g,mode,l);CHKERRQ(ierr);
228601729b5cSPatrick Sanan   ierr = DMGlobalToLocalEnd(dm,g,mode,l);CHKERRQ(ierr);
228701729b5cSPatrick Sanan   PetscFunctionReturn(0);
228801729b5cSPatrick Sanan }
228901729b5cSPatrick Sanan 
229001729b5cSPatrick Sanan /*@
229147c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
229247c6ae99SBarry Smith 
2293d083f849SBarry Smith     Neighbor-wise Collective on dm
229447c6ae99SBarry Smith 
229547c6ae99SBarry Smith     Input Parameters:
229647c6ae99SBarry Smith +   dm - the DM object
229747c6ae99SBarry Smith .   g - the global vector
229847c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
229947c6ae99SBarry Smith -   l - the local vector
230047c6ae99SBarry Smith 
230101729b5cSPatrick Sanan     Level: intermediate
230247c6ae99SBarry Smith 
230301729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
230447c6ae99SBarry Smith 
230547c6ae99SBarry Smith @*/
23067087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
230747c6ae99SBarry Smith {
23087128ae9fSMatthew G Knepley   PetscSF                 sf;
230947c6ae99SBarry Smith   PetscErrorCode          ierr;
2310baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
231147c6ae99SBarry Smith 
231247c6ae99SBarry Smith   PetscFunctionBegin;
2313171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2314baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
23158865f1eaSKarl Rupp     if (link->beginhook) {
23168865f1eaSKarl Rupp       ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);
23178865f1eaSKarl Rupp     }
2318baf369e7SPeter Brune   }
23197128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
23207128ae9fSMatthew G Knepley   if (sf) {
2321ae5cfb4aSMatthew G. Knepley     const PetscScalar *gArray;
2322ae5cfb4aSMatthew G. Knepley     PetscScalar       *lArray;
23237128ae9fSMatthew G Knepley 
232482f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
23257128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
2326ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
23277128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
23287128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
2329ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
23307128ae9fSMatthew G Knepley   } else {
233133907cc2SStefano Zampini     if (!dm->ops->globaltolocalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalBegin() for type %s",((PetscObject)dm)->type_name);
2332843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
23337128ae9fSMatthew G Knepley   }
233447c6ae99SBarry Smith   PetscFunctionReturn(0);
233547c6ae99SBarry Smith }
233647c6ae99SBarry Smith 
233747c6ae99SBarry Smith /*@
233847c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
233947c6ae99SBarry Smith 
2340d083f849SBarry Smith     Neighbor-wise Collective on dm
234147c6ae99SBarry Smith 
234247c6ae99SBarry Smith     Input Parameters:
234347c6ae99SBarry Smith +   dm - the DM object
234447c6ae99SBarry Smith .   g - the global vector
234547c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
234647c6ae99SBarry Smith -   l - the local vector
234747c6ae99SBarry Smith 
234801729b5cSPatrick Sanan     Level: intermediate
234947c6ae99SBarry Smith 
235001729b5cSPatrick Sanan .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMLocalToGlobalBegin(), DMLocalToGlobal(), DMLocalToGlobalBegin(), DMLocalToGlobalEnd()
235147c6ae99SBarry Smith 
235247c6ae99SBarry Smith @*/
23537087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
235447c6ae99SBarry Smith {
23557128ae9fSMatthew G Knepley   PetscSF                 sf;
235647c6ae99SBarry Smith   PetscErrorCode          ierr;
2357ae5cfb4aSMatthew G. Knepley   const PetscScalar      *gArray;
2358ae5cfb4aSMatthew G. Knepley   PetscScalar            *lArray;
2359ca3d3a14SMatthew G. Knepley   PetscBool               transform;
2360baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
236147c6ae99SBarry Smith 
236247c6ae99SBarry Smith   PetscFunctionBegin;
2363171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
23647128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
2365ca3d3a14SMatthew G. Knepley   ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr);
23667128ae9fSMatthew G Knepley   if (sf) {
236782f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
23687128ae9fSMatthew G Knepley 
23697128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
2370ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
23717128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
23727128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
2373ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
2374ca3d3a14SMatthew G. Knepley     if (transform) {ierr = DMPlexGlobalToLocalBasis(dm, l);CHKERRQ(ierr);}
23757128ae9fSMatthew G Knepley   } else {
237633907cc2SStefano Zampini     if (!dm->ops->globaltolocalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMGlobalToLocalEnd() for type %s",((PetscObject)dm)->type_name);
2377843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
23787128ae9fSMatthew G Knepley   }
23794c274da1SToby Isaac   ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr);
2380baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
2381baf369e7SPeter Brune     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
2382baf369e7SPeter Brune   }
238347c6ae99SBarry Smith   PetscFunctionReturn(0);
238447c6ae99SBarry Smith }
238547c6ae99SBarry Smith 
2386d4d07f1eSToby Isaac /*@C
2387d4d07f1eSToby Isaac    DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called
2388d4d07f1eSToby Isaac 
2389d4d07f1eSToby Isaac    Logically Collective
2390d4d07f1eSToby Isaac 
2391d4d07f1eSToby Isaac    Input Arguments:
2392d4d07f1eSToby Isaac +  dm - the DM
2393d4d07f1eSToby Isaac .  beginhook - function to run at the beginning of DMLocalToGlobalBegin()
2394d4d07f1eSToby Isaac .  endhook - function to run after DMLocalToGlobalEnd() has completed
2395d4d07f1eSToby Isaac -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2396d4d07f1eSToby Isaac 
2397d4d07f1eSToby Isaac    Calling sequence for beginhook:
2398d4d07f1eSToby Isaac $    beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
2399d4d07f1eSToby Isaac 
2400d4d07f1eSToby Isaac +  dm - global DM
2401d4d07f1eSToby Isaac .  l - local vector
2402d4d07f1eSToby Isaac .  mode - mode
2403d4d07f1eSToby Isaac .  g - global vector
2404d4d07f1eSToby Isaac -  ctx - optional user-defined function context
2405d4d07f1eSToby Isaac 
2406d4d07f1eSToby Isaac 
2407d4d07f1eSToby Isaac    Calling sequence for endhook:
2408d4d07f1eSToby Isaac $    endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
2409d4d07f1eSToby Isaac 
2410d4d07f1eSToby Isaac +  global - global DM
2411d4d07f1eSToby Isaac .  l - local vector
2412d4d07f1eSToby Isaac .  mode - mode
2413d4d07f1eSToby Isaac .  g - global vector
2414d4d07f1eSToby Isaac -  ctx - optional user-defined function context
2415d4d07f1eSToby Isaac 
2416d4d07f1eSToby Isaac    Level: advanced
2417d4d07f1eSToby Isaac 
2418d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2419d4d07f1eSToby Isaac @*/
2420d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
2421d4d07f1eSToby Isaac {
2422d4d07f1eSToby Isaac   PetscErrorCode          ierr;
2423d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link,*p;
2424d4d07f1eSToby Isaac 
2425d4d07f1eSToby Isaac   PetscFunctionBegin;
2426d4d07f1eSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2427d4d07f1eSToby Isaac   for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
242895dccacaSBarry Smith   ierr            = PetscNew(&link);CHKERRQ(ierr);
2429d4d07f1eSToby Isaac   link->beginhook = beginhook;
2430d4d07f1eSToby Isaac   link->endhook   = endhook;
2431d4d07f1eSToby Isaac   link->ctx       = ctx;
2432d4d07f1eSToby Isaac   link->next      = NULL;
2433d4d07f1eSToby Isaac   *p              = link;
2434d4d07f1eSToby Isaac   PetscFunctionReturn(0);
2435d4d07f1eSToby Isaac }
2436d4d07f1eSToby Isaac 
24374c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx)
24384c274da1SToby Isaac {
24394c274da1SToby Isaac   Mat cMat;
24404c274da1SToby Isaac   Vec cVec;
24414c274da1SToby Isaac   PetscSection section, cSec;
24424c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
24434c274da1SToby Isaac   PetscErrorCode ierr;
24444c274da1SToby Isaac 
24454c274da1SToby Isaac   PetscFunctionBegin;
24464c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
24474c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
24484c274da1SToby Isaac   if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) {
24495db9a05bSToby Isaac     PetscInt nRows;
24505db9a05bSToby Isaac 
24515db9a05bSToby Isaac     ierr = MatGetSize(cMat,&nRows,NULL);CHKERRQ(ierr);
24525db9a05bSToby Isaac     if (nRows <= 0) PetscFunctionReturn(0);
2453*92fd8e1eSJed Brown     ierr = DMGetLocalSection(dm,&section);CHKERRQ(ierr);
24547711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
24554c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
24564c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
24574c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
24584c274da1SToby Isaac       if (dof) {
24594c274da1SToby Isaac         PetscInt d;
24604c274da1SToby Isaac         PetscScalar *vals;
24614c274da1SToby Isaac         ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr);
24624c274da1SToby Isaac         ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr);
24634c274da1SToby Isaac         /* for this to be the true transpose, we have to zero the values that
24644c274da1SToby Isaac          * we just extracted */
24654c274da1SToby Isaac         for (d = 0; d < dof; d++) {
24664c274da1SToby Isaac           vals[d] = 0.;
24674c274da1SToby Isaac         }
24684c274da1SToby Isaac       }
24694c274da1SToby Isaac     }
24704c274da1SToby Isaac     ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr);
24714c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
24724c274da1SToby Isaac   }
24734c274da1SToby Isaac   PetscFunctionReturn(0);
24744c274da1SToby Isaac }
247501729b5cSPatrick Sanan /*@
247601729b5cSPatrick Sanan     DMLocalToGlobal - updates global vectors from local vectors
247701729b5cSPatrick Sanan 
2478d083f849SBarry Smith     Neighbor-wise Collective on dm
247901729b5cSPatrick Sanan 
248001729b5cSPatrick Sanan     Input Parameters:
248101729b5cSPatrick Sanan +   dm - the DM object
248201729b5cSPatrick Sanan .   l - the local vector
248301729b5cSPatrick 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.
248401729b5cSPatrick Sanan -   g - the global vector
248501729b5cSPatrick Sanan 
248601729b5cSPatrick Sanan     Notes:
248701729b5cSPatrick Sanan     The communication involved in this update can be overlapped with computation by using
248801729b5cSPatrick Sanan     DMLocalToGlobalBegin() and DMLocalToGlobalEnd().
248901729b5cSPatrick Sanan 
249001729b5cSPatrick Sanan     In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation.
249101729b5cSPatrick 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.
249201729b5cSPatrick Sanan 
249301729b5cSPatrick Sanan     Level: beginner
249401729b5cSPatrick Sanan 
249501729b5cSPatrick Sanan .seealso DMLocalToGlobalBegin(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
249601729b5cSPatrick Sanan 
249701729b5cSPatrick Sanan @*/
249801729b5cSPatrick Sanan PetscErrorCode DMLocalToGlobal(DM dm,Vec l,InsertMode mode,Vec g)
249901729b5cSPatrick Sanan {
250001729b5cSPatrick Sanan   PetscErrorCode ierr;
250101729b5cSPatrick Sanan 
250201729b5cSPatrick Sanan   PetscFunctionBegin;
250301729b5cSPatrick Sanan   ierr = DMLocalToGlobalBegin(dm,l,mode,g);CHKERRQ(ierr);
250401729b5cSPatrick Sanan   ierr = DMLocalToGlobalEnd(dm,l,mode,g);CHKERRQ(ierr);
250501729b5cSPatrick Sanan   PetscFunctionReturn(0);
250601729b5cSPatrick Sanan }
25074c274da1SToby Isaac 
250847c6ae99SBarry Smith /*@
250901729b5cSPatrick Sanan     DMLocalToGlobalBegin - begins updating global vectors from local vectors
25109a42bb27SBarry Smith 
2511d083f849SBarry Smith     Neighbor-wise Collective on dm
25129a42bb27SBarry Smith 
25139a42bb27SBarry Smith     Input Parameters:
25149a42bb27SBarry Smith +   dm - the DM object
2515f6813fd5SJed Brown .   l - the local vector
25161eb28f2eSBarry 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.
25171eb28f2eSBarry Smith -   g - the global vector
25189a42bb27SBarry Smith 
251995452b02SPatrick Sanan     Notes:
252095452b02SPatrick Sanan     In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation.
252184330215SMatthew 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.
25229a42bb27SBarry Smith 
252301729b5cSPatrick Sanan     Level: intermediate
25249a42bb27SBarry Smith 
252501729b5cSPatrick Sanan .seealso DMLocalToGlobal(), DMLocalToGlobalEnd(), DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocal(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
25269a42bb27SBarry Smith 
25279a42bb27SBarry Smith @*/
25287087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
25299a42bb27SBarry Smith {
25307128ae9fSMatthew G Knepley   PetscSF                 sf;
253184330215SMatthew G. Knepley   PetscSection            s, gs;
2532d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
2533ca3d3a14SMatthew G. Knepley   Vec                     tmpl;
2534ae5cfb4aSMatthew G. Knepley   const PetscScalar      *lArray;
2535ae5cfb4aSMatthew G. Knepley   PetscScalar            *gArray;
2536ca3d3a14SMatthew G. Knepley   PetscBool               isInsert, transform;
253784330215SMatthew G. Knepley   PetscErrorCode          ierr;
25389a42bb27SBarry Smith 
25399a42bb27SBarry Smith   PetscFunctionBegin;
2540171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2541d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
2542d4d07f1eSToby Isaac     if (link->beginhook) {
2543d4d07f1eSToby Isaac       ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr);
2544d4d07f1eSToby Isaac     }
2545d4d07f1eSToby Isaac   }
25464c274da1SToby Isaac   ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr);
25477128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
2548*92fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
25497128ae9fSMatthew G Knepley   switch (mode) {
25507128ae9fSMatthew G Knepley   case INSERT_VALUES:
25517128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
2552304ab55fSMatthew G. Knepley   case INSERT_BC_VALUES:
255384330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
25547128ae9fSMatthew G Knepley   case ADD_VALUES:
25557128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
2556304ab55fSMatthew G. Knepley   case ADD_BC_VALUES:
255784330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
25587128ae9fSMatthew G Knepley   default:
255982f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
25607128ae9fSMatthew G Knepley   }
2561ca3d3a14SMatthew G. Knepley   if ((sf && !isInsert) || (s && isInsert)) {
2562ca3d3a14SMatthew G. Knepley     ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr);
2563ca3d3a14SMatthew G. Knepley     if (transform) {
2564ca3d3a14SMatthew G. Knepley       ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2565ca3d3a14SMatthew G. Knepley       ierr = VecCopy(l, tmpl);CHKERRQ(ierr);
2566ca3d3a14SMatthew G. Knepley       ierr = DMPlexLocalToGlobalBasis(dm, tmpl);CHKERRQ(ierr);
2567ca3d3a14SMatthew G. Knepley       ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2568ca3d3a14SMatthew G. Knepley     } else {
2569ae5cfb4aSMatthew G. Knepley       ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
2570ca3d3a14SMatthew G. Knepley     }
25717128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
2572ca3d3a14SMatthew G. Knepley     if (sf && !isInsert) {
2573a9b180a6SBarry Smith       ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
257484330215SMatthew G. Knepley     } else if (s && isInsert) {
257584330215SMatthew G. Knepley       PetscInt gStart, pStart, pEnd, p;
257684330215SMatthew G. Knepley 
2577e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr);
257884330215SMatthew G. Knepley       ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
257984330215SMatthew G. Knepley       ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr);
258084330215SMatthew G. Knepley       for (p = pStart; p < pEnd; ++p) {
2581b3b16f48SMatthew G. Knepley         PetscInt dof, gdof, cdof, gcdof, off, goff, d, e;
258284330215SMatthew G. Knepley 
258384330215SMatthew G. Knepley         ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr);
258403442857SMatthew G. Knepley         ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr);
258584330215SMatthew G. Knepley         ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr);
2586b3b16f48SMatthew G. Knepley         ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr);
258784330215SMatthew G. Knepley         ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr);
258884330215SMatthew G. Knepley         ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr);
2589b3b16f48SMatthew G. Knepley         /* Ignore off-process data and points with no global data */
259003442857SMatthew G. Knepley         if (!gdof || goff < 0) continue;
2591b3b16f48SMatthew 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);
2592b3b16f48SMatthew G. Knepley         /* If no constraints are enforced in the global vector */
2593b3b16f48SMatthew G. Knepley         if (!gcdof) {
259484330215SMatthew G. Knepley           for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d];
2595b3b16f48SMatthew G. Knepley           /* If constraints are enforced in the global vector */
2596b3b16f48SMatthew G. Knepley         } else if (cdof == gcdof) {
259784330215SMatthew G. Knepley           const PetscInt *cdofs;
259884330215SMatthew G. Knepley           PetscInt        cind = 0;
259984330215SMatthew G. Knepley 
260084330215SMatthew G. Knepley           ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr);
2601b3b16f48SMatthew G. Knepley           for (d = 0, e = 0; d < dof; ++d) {
260284330215SMatthew G. Knepley             if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;}
2603b3b16f48SMatthew G. Knepley             gArray[goff-gStart+e++] = lArray[off+d];
260484330215SMatthew G. Knepley           }
2605b3b16f48SMatthew 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);
260684330215SMatthew G. Knepley       }
2607ca3d3a14SMatthew G. Knepley     }
26087128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
2609ca3d3a14SMatthew G. Knepley     if (transform) {
2610ca3d3a14SMatthew G. Knepley       ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2611ca3d3a14SMatthew G. Knepley       ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2612ca3d3a14SMatthew G. Knepley     } else {
2613ca3d3a14SMatthew G. Knepley       ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
2614ca3d3a14SMatthew G. Knepley     }
26157128ae9fSMatthew G Knepley   } else {
2616b9d85ea2SLisandro Dalcin     if (!dm->ops->localtoglobalbegin) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalBegin() for type %s",((PetscObject)dm)->type_name);
2617843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
26187128ae9fSMatthew G Knepley   }
26199a42bb27SBarry Smith   PetscFunctionReturn(0);
26209a42bb27SBarry Smith }
26219a42bb27SBarry Smith 
26229a42bb27SBarry Smith /*@
26239a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
262447c6ae99SBarry Smith 
2625d083f849SBarry Smith     Neighbor-wise Collective on dm
262647c6ae99SBarry Smith 
262747c6ae99SBarry Smith     Input Parameters:
262847c6ae99SBarry Smith +   dm - the DM object
2629f6813fd5SJed Brown .   l - the local vector
263047c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
2631f6813fd5SJed Brown -   g - the global vector
263247c6ae99SBarry Smith 
263301729b5cSPatrick Sanan     Level: intermediate
263447c6ae99SBarry Smith 
2635e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
263647c6ae99SBarry Smith 
263747c6ae99SBarry Smith @*/
26387087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
263947c6ae99SBarry Smith {
26407128ae9fSMatthew G Knepley   PetscSF                 sf;
264184330215SMatthew G. Knepley   PetscSection            s;
2642d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
2643ca3d3a14SMatthew G. Knepley   PetscBool               isInsert, transform;
264484330215SMatthew G. Knepley   PetscErrorCode          ierr;
264547c6ae99SBarry Smith 
264647c6ae99SBarry Smith   PetscFunctionBegin;
2647171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
26487128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
2649*92fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
26507128ae9fSMatthew G Knepley   switch (mode) {
26517128ae9fSMatthew G Knepley   case INSERT_VALUES:
26527128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
265384330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
26547128ae9fSMatthew G Knepley   case ADD_VALUES:
26557128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
265684330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
26577128ae9fSMatthew G Knepley   default:
265882f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
26597128ae9fSMatthew G Knepley   }
266084330215SMatthew G. Knepley   if (sf && !isInsert) {
2661ae5cfb4aSMatthew G. Knepley     const PetscScalar *lArray;
2662ae5cfb4aSMatthew G. Knepley     PetscScalar       *gArray;
2663ca3d3a14SMatthew G. Knepley     Vec                tmpl;
266484330215SMatthew G. Knepley 
2665ca3d3a14SMatthew G. Knepley     ierr = DMHasBasisTransform(dm, &transform);CHKERRQ(ierr);
2666ca3d3a14SMatthew G. Knepley     if (transform) {
2667ca3d3a14SMatthew G. Knepley       ierr = DMGetNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2668ca3d3a14SMatthew G. Knepley       ierr = VecGetArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2669ca3d3a14SMatthew G. Knepley     } else {
2670ae5cfb4aSMatthew G. Knepley       ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
2671ca3d3a14SMatthew G. Knepley     }
26727128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
2673a9b180a6SBarry Smith     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
2674ca3d3a14SMatthew G. Knepley     if (transform) {
2675ca3d3a14SMatthew G. Knepley       ierr = VecRestoreArrayRead(tmpl, &lArray);CHKERRQ(ierr);
2676ca3d3a14SMatthew G. Knepley       ierr = DMRestoreNamedLocalVector(dm, "__petsc_dm_transform_local_copy", &tmpl);CHKERRQ(ierr);
2677ca3d3a14SMatthew G. Knepley     } else {
2678ae5cfb4aSMatthew G. Knepley       ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
2679ca3d3a14SMatthew G. Knepley     }
26807128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
268184330215SMatthew G. Knepley   } else if (s && isInsert) {
26827128ae9fSMatthew G Knepley   } else {
2683b9d85ea2SLisandro Dalcin     if (!dm->ops->localtoglobalend) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Missing DMLocalToGlobalEnd() for type %s",((PetscObject)dm)->type_name);
2684843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
26857128ae9fSMatthew G Knepley   }
2686d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
2687d4d07f1eSToby Isaac     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
2688d4d07f1eSToby Isaac   }
268947c6ae99SBarry Smith   PetscFunctionReturn(0);
269047c6ae99SBarry Smith }
269147c6ae99SBarry Smith 
2692f089877aSRichard Tran Mills /*@
2693bc0a1609SRichard Tran Mills    DMLocalToLocalBegin - Maps from a local vector (including ghost points
2694bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2695d78e899eSRichard Tran Mills    points in the second are set correctly. Must be followed by DMLocalToLocalEnd().
2696f089877aSRichard Tran Mills 
2697d083f849SBarry Smith    Neighbor-wise Collective on dm
2698f089877aSRichard Tran Mills 
2699f089877aSRichard Tran Mills    Input Parameters:
2700f089877aSRichard Tran Mills +  dm - the DM object
2701bc0a1609SRichard Tran Mills .  g - the original local vector
2702bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2703f089877aSRichard Tran Mills 
2704bc0a1609SRichard Tran Mills    Output Parameter:
2705bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2706f089877aSRichard Tran Mills 
2707f089877aSRichard Tran Mills    Level: intermediate
2708f089877aSRichard Tran Mills 
2709bc0a1609SRichard Tran Mills    Notes:
2710bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2711bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2712bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2713bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2714bc0a1609SRichard Tran Mills 
2715bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2716f089877aSRichard Tran Mills 
2717f089877aSRichard Tran Mills @*/
2718f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
2719f089877aSRichard Tran Mills {
2720f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2721f089877aSRichard Tran Mills 
2722f089877aSRichard Tran Mills   PetscFunctionBegin;
2723f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2724bb358533SPatrick Sanan   if (!dm->ops->localtolocalbegin) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps");
2725f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2726f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2727f089877aSRichard Tran Mills }
2728f089877aSRichard Tran Mills 
2729f089877aSRichard Tran Mills /*@
2730bc0a1609SRichard Tran Mills    DMLocalToLocalEnd - Maps from a local vector (including ghost points
2731bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2732d78e899eSRichard Tran Mills    points in the second are set correctly. Must be preceded by DMLocalToLocalBegin().
2733f089877aSRichard Tran Mills 
2734d083f849SBarry Smith    Neighbor-wise Collective on dm
2735f089877aSRichard Tran Mills 
2736f089877aSRichard Tran Mills    Input Parameters:
2737bc0a1609SRichard Tran Mills +  da - the DM object
2738bc0a1609SRichard Tran Mills .  g - the original local vector
2739bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2740f089877aSRichard Tran Mills 
2741bc0a1609SRichard Tran Mills    Output Parameter:
2742bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2743f089877aSRichard Tran Mills 
2744f089877aSRichard Tran Mills    Level: intermediate
2745f089877aSRichard Tran Mills 
2746bc0a1609SRichard Tran Mills    Notes:
2747bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2748bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2749bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2750bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2751bc0a1609SRichard Tran Mills 
2752bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2753f089877aSRichard Tran Mills 
2754f089877aSRichard Tran Mills @*/
2755f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
2756f089877aSRichard Tran Mills {
2757f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2758f089877aSRichard Tran Mills 
2759f089877aSRichard Tran Mills   PetscFunctionBegin;
2760f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2761bb358533SPatrick Sanan   if (!dm->ops->localtolocalend) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"This DM does not support local to local maps");
2762f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2763f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2764f089877aSRichard Tran Mills }
2765f089877aSRichard Tran Mills 
2766f089877aSRichard Tran Mills 
276747c6ae99SBarry Smith /*@
276847c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
276947c6ae99SBarry Smith 
2770d083f849SBarry Smith     Collective on dm
277147c6ae99SBarry Smith 
277247c6ae99SBarry Smith     Input Parameter:
277347c6ae99SBarry Smith +   dm - the DM object
277491d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
277547c6ae99SBarry Smith 
277647c6ae99SBarry Smith     Output Parameter:
277747c6ae99SBarry Smith .   dmc - the coarsened DM
277847c6ae99SBarry Smith 
277947c6ae99SBarry Smith     Level: developer
278047c6ae99SBarry Smith 
2781e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
278247c6ae99SBarry Smith 
278347c6ae99SBarry Smith @*/
27847087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
278547c6ae99SBarry Smith {
278647c6ae99SBarry Smith   PetscErrorCode    ierr;
2787b17ce1afSJed Brown   DMCoarsenHookLink link;
278847c6ae99SBarry Smith 
278947c6ae99SBarry Smith   PetscFunctionBegin;
2790171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2791b9d85ea2SLisandro Dalcin   if (!dm->ops->coarsen) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMCoarsen",((PetscObject)dm)->type_name);
279247a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
279347c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
2794b9d85ea2SLisandro Dalcin   if (*dmc) {
2795a8fb8f29SToby Isaac     ierr = DMSetCoarseDM(dm,*dmc);CHKERRQ(ierr);
279643842a1eSJed Brown     (*dmc)->ops->creatematrix = dm->ops->creatematrix;
27978cd211a4SJed Brown     ierr                      = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
2798644e2e5bSBarry Smith     (*dmc)->ctx               = dm->ctx;
27990598a293SJed Brown     (*dmc)->levelup           = dm->levelup;
2800656b349aSBarry Smith     (*dmc)->leveldown         = dm->leveldown + 1;
2801e4b4b23bSJed Brown     ierr                      = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
2802b17ce1afSJed Brown     for (link=dm->coarsenhook; link; link=link->next) {
2803b17ce1afSJed Brown       if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
2804b17ce1afSJed Brown     }
2805b9d85ea2SLisandro Dalcin   }
280647a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
2807b9d85ea2SLisandro Dalcin   if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced");
2808b17ce1afSJed Brown   PetscFunctionReturn(0);
2809b17ce1afSJed Brown }
2810b17ce1afSJed Brown 
2811bb9467b5SJed Brown /*@C
2812b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
2813b17ce1afSJed Brown 
2814b17ce1afSJed Brown    Logically Collective
2815b17ce1afSJed Brown 
2816b17ce1afSJed Brown    Input Arguments:
2817b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
2818b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
2819b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
28200298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2821b17ce1afSJed Brown 
2822b17ce1afSJed Brown    Calling sequence of coarsenhook:
2823b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
2824b17ce1afSJed Brown 
2825b17ce1afSJed Brown +  fine - fine level DM
2826b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
2827b17ce1afSJed Brown -  ctx - optional user-defined function context
2828b17ce1afSJed Brown 
2829b17ce1afSJed Brown    Calling sequence for restricthook:
2830c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
2831b17ce1afSJed Brown 
2832b17ce1afSJed Brown +  fine - fine level DM
2833b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
2834c833c3b5SJed Brown .  rscale - scaling vector for restriction
2835c833c3b5SJed Brown .  inject - matrix restricting by injection
2836b17ce1afSJed Brown .  coarse - coarse level DM to update
2837b17ce1afSJed Brown -  ctx - optional user-defined function context
2838b17ce1afSJed Brown 
2839b17ce1afSJed Brown    Level: advanced
2840b17ce1afSJed Brown 
2841b17ce1afSJed Brown    Notes:
2842b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
2843b17ce1afSJed Brown 
2844b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
2845b17ce1afSJed Brown 
2846b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2847b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
2848b17ce1afSJed Brown 
2849bb9467b5SJed Brown    This function is currently not available from Fortran.
2850bb9467b5SJed Brown 
2851dc822a44SJed Brown .seealso: DMCoarsenHookRemove(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2852b17ce1afSJed Brown @*/
2853b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2854b17ce1afSJed Brown {
2855b17ce1afSJed Brown   PetscErrorCode    ierr;
2856b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
2857b17ce1afSJed Brown 
2858b17ce1afSJed Brown   PetscFunctionBegin;
2859b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
28601e3d8eccSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
28611e3d8eccSJed Brown     if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0);
28621e3d8eccSJed Brown   }
286395dccacaSBarry Smith   ierr               = PetscNew(&link);CHKERRQ(ierr);
2864b17ce1afSJed Brown   link->coarsenhook  = coarsenhook;
2865b17ce1afSJed Brown   link->restricthook = restricthook;
2866b17ce1afSJed Brown   link->ctx          = ctx;
28670298fd71SBarry Smith   link->next         = NULL;
2868b17ce1afSJed Brown   *p                 = link;
2869b17ce1afSJed Brown   PetscFunctionReturn(0);
2870b17ce1afSJed Brown }
2871b17ce1afSJed Brown 
2872dc822a44SJed Brown /*@C
2873dc822a44SJed Brown    DMCoarsenHookRemove - remove a callback from the list of hooks to be run when restricting a nonlinear problem to the coarse grid
2874dc822a44SJed Brown 
2875dc822a44SJed Brown    Logically Collective
2876dc822a44SJed Brown 
2877dc822a44SJed Brown    Input Arguments:
2878dc822a44SJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
2879dc822a44SJed Brown .  coarsenhook - function to run when setting up a coarser level
2880dc822a44SJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
2881dc822a44SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2882dc822a44SJed Brown 
2883dc822a44SJed Brown    Level: advanced
2884dc822a44SJed Brown 
2885dc822a44SJed Brown    Notes:
2886dc822a44SJed Brown    This function does nothing if the hook is not in the list.
2887dc822a44SJed Brown 
2888dc822a44SJed Brown    This function is currently not available from Fortran.
2889dc822a44SJed Brown 
2890dc822a44SJed Brown .seealso: DMCoarsenHookAdd(), DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2891dc822a44SJed Brown @*/
2892dc822a44SJed Brown PetscErrorCode DMCoarsenHookRemove(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2893dc822a44SJed Brown {
2894dc822a44SJed Brown   PetscErrorCode    ierr;
2895dc822a44SJed Brown   DMCoarsenHookLink link,*p;
2896dc822a44SJed Brown 
2897dc822a44SJed Brown   PetscFunctionBegin;
2898dc822a44SJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
2899dc822a44SJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) { /* Search the list of current hooks */
2900dc822a44SJed Brown     if ((*p)->coarsenhook == coarsenhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) {
2901dc822a44SJed Brown       link = *p;
2902dc822a44SJed Brown       *p = link->next;
2903dc822a44SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
2904dc822a44SJed Brown       break;
2905dc822a44SJed Brown     }
2906dc822a44SJed Brown   }
2907dc822a44SJed Brown   PetscFunctionReturn(0);
2908dc822a44SJed Brown }
2909dc822a44SJed Brown 
2910dc822a44SJed Brown 
2911b17ce1afSJed Brown /*@
2912b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
2913b17ce1afSJed Brown 
2914b17ce1afSJed Brown    Collective if any hooks are
2915b17ce1afSJed Brown 
2916b17ce1afSJed Brown    Input Arguments:
2917b17ce1afSJed Brown +  fine - finer DM to use as a base
2918b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
2919e91eccc2SStefano Zampini .  rscale - scaling vector for restriction
2920b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
2921e91eccc2SStefano Zampini -  coarse - coarser DM to update
2922b17ce1afSJed Brown 
2923b17ce1afSJed Brown    Level: developer
2924b17ce1afSJed Brown 
2925b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
2926b17ce1afSJed Brown @*/
2927b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
2928b17ce1afSJed Brown {
2929b17ce1afSJed Brown   PetscErrorCode    ierr;
2930b17ce1afSJed Brown   DMCoarsenHookLink link;
2931b17ce1afSJed Brown 
2932b17ce1afSJed Brown   PetscFunctionBegin;
2933b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
29348865f1eaSKarl Rupp     if (link->restricthook) {
29358865f1eaSKarl Rupp       ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);
29368865f1eaSKarl Rupp     }
2937b17ce1afSJed Brown   }
293847c6ae99SBarry Smith   PetscFunctionReturn(0);
293947c6ae99SBarry Smith }
294047c6ae99SBarry Smith 
2941bb9467b5SJed Brown /*@C
2942be081cd6SPeter Brune    DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid
29435dbd56e3SPeter Brune 
2944d083f849SBarry Smith    Logically Collective on global
29455dbd56e3SPeter Brune 
29465dbd56e3SPeter Brune    Input Arguments:
29475dbd56e3SPeter Brune +  global - global DM
2948ec4806b8SPeter Brune .  ddhook - function to run to pass data to the decomposition DM upon its creation
29495dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
29500298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
29515dbd56e3SPeter Brune 
2952ec4806b8SPeter Brune 
2953ec4806b8SPeter Brune    Calling sequence for ddhook:
2954ec4806b8SPeter Brune $    ddhook(DM global,DM block,void *ctx)
2955ec4806b8SPeter Brune 
2956ec4806b8SPeter Brune +  global - global DM
2957ec4806b8SPeter Brune .  block  - block DM
2958ec4806b8SPeter Brune -  ctx - optional user-defined function context
2959ec4806b8SPeter Brune 
29605dbd56e3SPeter Brune    Calling sequence for restricthook:
2961ec4806b8SPeter Brune $    restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx)
29625dbd56e3SPeter Brune 
29635dbd56e3SPeter Brune +  global - global DM
29645dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
29655dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
2966ec4806b8SPeter Brune .  block  - block DM
29675dbd56e3SPeter Brune -  ctx - optional user-defined function context
29685dbd56e3SPeter Brune 
29695dbd56e3SPeter Brune    Level: advanced
29705dbd56e3SPeter Brune 
29715dbd56e3SPeter Brune    Notes:
2972ec4806b8SPeter Brune    This function is only needed if auxiliary data needs to be set up on subdomain DMs.
29735dbd56e3SPeter Brune 
29745dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
29755dbd56e3SPeter Brune 
29765dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2977ec4806b8SPeter Brune    extract the global information from its context (instead of from the SNES).
29785dbd56e3SPeter Brune 
2979bb9467b5SJed Brown    This function is currently not available from Fortran.
2980bb9467b5SJed Brown 
29815dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
29825dbd56e3SPeter Brune @*/
2983be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
29845dbd56e3SPeter Brune {
29855dbd56e3SPeter Brune   PetscErrorCode      ierr;
2986be081cd6SPeter Brune   DMSubDomainHookLink link,*p;
29875dbd56e3SPeter Brune 
29885dbd56e3SPeter Brune   PetscFunctionBegin;
29895dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
2990b3a6b972SJed Brown   for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Scan to the end of the current list of hooks */
2991b3a6b972SJed Brown     if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) PetscFunctionReturn(0);
2992b3a6b972SJed Brown   }
299395dccacaSBarry Smith   ierr               = PetscNew(&link);CHKERRQ(ierr);
29945dbd56e3SPeter Brune   link->restricthook = restricthook;
2995be081cd6SPeter Brune   link->ddhook       = ddhook;
29965dbd56e3SPeter Brune   link->ctx          = ctx;
29970298fd71SBarry Smith   link->next         = NULL;
29985dbd56e3SPeter Brune   *p                 = link;
29995dbd56e3SPeter Brune   PetscFunctionReturn(0);
30005dbd56e3SPeter Brune }
30015dbd56e3SPeter Brune 
3002b3a6b972SJed Brown /*@C
3003b3a6b972SJed Brown    DMSubDomainHookRemove - remove a callback from the list to be run when restricting a problem to the coarse grid
3004b3a6b972SJed Brown 
3005b3a6b972SJed Brown    Logically Collective
3006b3a6b972SJed Brown 
3007b3a6b972SJed Brown    Input Arguments:
3008b3a6b972SJed Brown +  global - global DM
3009b3a6b972SJed Brown .  ddhook - function to run to pass data to the decomposition DM upon its creation
3010b3a6b972SJed Brown .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
3011b3a6b972SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
3012b3a6b972SJed Brown 
3013b3a6b972SJed Brown    Level: advanced
3014b3a6b972SJed Brown 
3015b3a6b972SJed Brown    Notes:
3016b3a6b972SJed Brown 
3017b3a6b972SJed Brown    This function is currently not available from Fortran.
3018b3a6b972SJed Brown 
3019b3a6b972SJed Brown .seealso: DMSubDomainHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
3020b3a6b972SJed Brown @*/
3021b3a6b972SJed Brown PetscErrorCode DMSubDomainHookRemove(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
3022b3a6b972SJed Brown {
3023b3a6b972SJed Brown   PetscErrorCode      ierr;
3024b3a6b972SJed Brown   DMSubDomainHookLink link,*p;
3025b3a6b972SJed Brown 
3026b3a6b972SJed Brown   PetscFunctionBegin;
3027b3a6b972SJed Brown   PetscValidHeaderSpecific(global,DM_CLASSID,1);
3028b3a6b972SJed Brown   for (p=&global->subdomainhook; *p; p=&(*p)->next) { /* Search the list of current hooks */
3029b3a6b972SJed Brown     if ((*p)->ddhook == ddhook && (*p)->restricthook == restricthook && (*p)->ctx == ctx) {
3030b3a6b972SJed Brown       link = *p;
3031b3a6b972SJed Brown       *p = link->next;
3032b3a6b972SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
3033b3a6b972SJed Brown       break;
3034b3a6b972SJed Brown     }
3035b3a6b972SJed Brown   }
3036b3a6b972SJed Brown   PetscFunctionReturn(0);
3037b3a6b972SJed Brown }
3038b3a6b972SJed Brown 
30395dbd56e3SPeter Brune /*@
3040be081cd6SPeter Brune    DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd()
30415dbd56e3SPeter Brune 
30425dbd56e3SPeter Brune    Collective if any hooks are
30435dbd56e3SPeter Brune 
30445dbd56e3SPeter Brune    Input Arguments:
30455dbd56e3SPeter Brune +  fine - finer DM to use as a base
3046be081cd6SPeter Brune .  oscatter - scatter from domain global vector filling subdomain global vector with overlap
3047be081cd6SPeter Brune .  gscatter - scatter from domain global vector filling subdomain local vector with ghosts
30485dbd56e3SPeter Brune -  coarse - coarer DM to update
30495dbd56e3SPeter Brune 
30505dbd56e3SPeter Brune    Level: developer
30515dbd56e3SPeter Brune 
30525dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
30535dbd56e3SPeter Brune @*/
3054be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm)
30555dbd56e3SPeter Brune {
30565dbd56e3SPeter Brune   PetscErrorCode      ierr;
3057be081cd6SPeter Brune   DMSubDomainHookLink link;
30585dbd56e3SPeter Brune 
30595dbd56e3SPeter Brune   PetscFunctionBegin;
3060be081cd6SPeter Brune   for (link=global->subdomainhook; link; link=link->next) {
30618865f1eaSKarl Rupp     if (link->restricthook) {
30628865f1eaSKarl Rupp       ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr);
30638865f1eaSKarl Rupp     }
30645dbd56e3SPeter Brune   }
30655dbd56e3SPeter Brune   PetscFunctionReturn(0);
30665dbd56e3SPeter Brune }
30675dbd56e3SPeter Brune 
30685fe1f584SPeter Brune /*@
30696a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
30705fe1f584SPeter Brune 
30715fe1f584SPeter Brune     Not Collective
30725fe1f584SPeter Brune 
30735fe1f584SPeter Brune     Input Parameter:
30745fe1f584SPeter Brune .   dm - the DM object
30755fe1f584SPeter Brune 
30765fe1f584SPeter Brune     Output Parameter:
30776a7d9d85SPeter Brune .   level - number of coarsenings
30785fe1f584SPeter Brune 
30795fe1f584SPeter Brune     Level: developer
30805fe1f584SPeter Brune 
30816a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
30825fe1f584SPeter Brune 
30835fe1f584SPeter Brune @*/
30845fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
30855fe1f584SPeter Brune {
30865fe1f584SPeter Brune   PetscFunctionBegin;
30875fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3088b9d85ea2SLisandro Dalcin   PetscValidIntPointer(level,2);
30895fe1f584SPeter Brune   *level = dm->leveldown;
30905fe1f584SPeter Brune   PetscFunctionReturn(0);
30915fe1f584SPeter Brune }
30925fe1f584SPeter Brune 
30939a64c4a8SMatthew G. Knepley /*@
30949a64c4a8SMatthew G. Knepley     DMSetCoarsenLevel - Sets the number of coarsenings that have generated this DM.
30959a64c4a8SMatthew G. Knepley 
30969a64c4a8SMatthew G. Knepley     Not Collective
30979a64c4a8SMatthew G. Knepley 
30989a64c4a8SMatthew G. Knepley     Input Parameters:
30999a64c4a8SMatthew G. Knepley +   dm - the DM object
31009a64c4a8SMatthew G. Knepley -   level - number of coarsenings
31019a64c4a8SMatthew G. Knepley 
31029a64c4a8SMatthew G. Knepley     Level: developer
31039a64c4a8SMatthew G. Knepley 
31049a64c4a8SMatthew G. Knepley .seealso DMCoarsen(), DMGetCoarsenLevel(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
31059a64c4a8SMatthew G. Knepley @*/
31069a64c4a8SMatthew G. Knepley PetscErrorCode DMSetCoarsenLevel(DM dm,PetscInt level)
31079a64c4a8SMatthew G. Knepley {
31089a64c4a8SMatthew G. Knepley   PetscFunctionBegin;
31099a64c4a8SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31109a64c4a8SMatthew G. Knepley   dm->leveldown = level;
31119a64c4a8SMatthew G. Knepley   PetscFunctionReturn(0);
31129a64c4a8SMatthew G. Knepley }
31139a64c4a8SMatthew G. Knepley 
31145fe1f584SPeter Brune 
31155fe1f584SPeter Brune 
311647c6ae99SBarry Smith /*@C
311747c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
311847c6ae99SBarry Smith 
3119d083f849SBarry Smith     Collective on dm
312047c6ae99SBarry Smith 
312147c6ae99SBarry Smith     Input Parameter:
312247c6ae99SBarry Smith +   dm - the DM object
312347c6ae99SBarry Smith -   nlevels - the number of levels of refinement
312447c6ae99SBarry Smith 
312547c6ae99SBarry Smith     Output Parameter:
312647c6ae99SBarry Smith .   dmf - the refined DM hierarchy
312747c6ae99SBarry Smith 
312847c6ae99SBarry Smith     Level: developer
312947c6ae99SBarry Smith 
3130e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
313147c6ae99SBarry Smith 
313247c6ae99SBarry Smith @*/
31337087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
313447c6ae99SBarry Smith {
313547c6ae99SBarry Smith   PetscErrorCode ierr;
313647c6ae99SBarry Smith 
313747c6ae99SBarry Smith   PetscFunctionBegin;
3138171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3139ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
314047c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
3141b9d85ea2SLisandro Dalcin   PetscValidPointer(dmf,3);
314247c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
314347c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
314447c6ae99SBarry Smith   } else if (dm->ops->refine) {
314547c6ae99SBarry Smith     PetscInt i;
314647c6ae99SBarry Smith 
3147ce94432eSBarry Smith     ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr);
314847c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
3149ce94432eSBarry Smith       ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr);
315047c6ae99SBarry Smith     }
3151ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
315247c6ae99SBarry Smith   PetscFunctionReturn(0);
315347c6ae99SBarry Smith }
315447c6ae99SBarry Smith 
315547c6ae99SBarry Smith /*@C
315647c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
315747c6ae99SBarry Smith 
3158d083f849SBarry Smith     Collective on dm
315947c6ae99SBarry Smith 
316047c6ae99SBarry Smith     Input Parameter:
316147c6ae99SBarry Smith +   dm - the DM object
316247c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
316347c6ae99SBarry Smith 
316447c6ae99SBarry Smith     Output Parameter:
316547c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
316647c6ae99SBarry Smith 
316747c6ae99SBarry Smith     Level: developer
316847c6ae99SBarry Smith 
3169e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
317047c6ae99SBarry Smith 
317147c6ae99SBarry Smith @*/
31727087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
317347c6ae99SBarry Smith {
317447c6ae99SBarry Smith   PetscErrorCode ierr;
317547c6ae99SBarry Smith 
317647c6ae99SBarry Smith   PetscFunctionBegin;
3177171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3178ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
317947c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
318047c6ae99SBarry Smith   PetscValidPointer(dmc,3);
318147c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
318247c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
318347c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
318447c6ae99SBarry Smith     PetscInt i;
318547c6ae99SBarry Smith 
3186ce94432eSBarry Smith     ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr);
318747c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
3188ce94432eSBarry Smith       ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr);
318947c6ae99SBarry Smith     }
3190ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
319147c6ae99SBarry Smith   PetscFunctionReturn(0);
319247c6ae99SBarry Smith }
319347c6ae99SBarry Smith 
31941a266240SBarry Smith /*@C
31951a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
31961a266240SBarry Smith 
31971a266240SBarry Smith     Not Collective
31981a266240SBarry Smith 
31991a266240SBarry Smith     Input Parameters:
32001a266240SBarry Smith +   dm - the DM object
32011a266240SBarry Smith -   destroy - the destroy function
32021a266240SBarry Smith 
32031a266240SBarry Smith     Level: intermediate
32041a266240SBarry Smith 
3205e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
32061a266240SBarry Smith 
3207f07f9ceaSJed Brown @*/
32081a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
32091a266240SBarry Smith {
32101a266240SBarry Smith   PetscFunctionBegin;
3211171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32121a266240SBarry Smith   dm->ctxdestroy = destroy;
32131a266240SBarry Smith   PetscFunctionReturn(0);
32141a266240SBarry Smith }
32151a266240SBarry Smith 
3216b07ff414SBarry Smith /*@
32171b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
321847c6ae99SBarry Smith 
321947c6ae99SBarry Smith     Not Collective
322047c6ae99SBarry Smith 
322147c6ae99SBarry Smith     Input Parameters:
322247c6ae99SBarry Smith +   dm - the DM object
322347c6ae99SBarry Smith -   ctx - the user context
322447c6ae99SBarry Smith 
322547c6ae99SBarry Smith     Level: intermediate
322647c6ae99SBarry Smith 
3227e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
322847c6ae99SBarry Smith 
322947c6ae99SBarry Smith @*/
32301b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
323147c6ae99SBarry Smith {
323247c6ae99SBarry Smith   PetscFunctionBegin;
3233171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
323447c6ae99SBarry Smith   dm->ctx = ctx;
323547c6ae99SBarry Smith   PetscFunctionReturn(0);
323647c6ae99SBarry Smith }
323747c6ae99SBarry Smith 
323847c6ae99SBarry Smith /*@
32391b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
324047c6ae99SBarry Smith 
324147c6ae99SBarry Smith     Not Collective
324247c6ae99SBarry Smith 
324347c6ae99SBarry Smith     Input Parameter:
324447c6ae99SBarry Smith .   dm - the DM object
324547c6ae99SBarry Smith 
324647c6ae99SBarry Smith     Output Parameter:
324747c6ae99SBarry Smith .   ctx - the user context
324847c6ae99SBarry Smith 
324947c6ae99SBarry Smith     Level: intermediate
325047c6ae99SBarry Smith 
3251e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
325247c6ae99SBarry Smith 
325347c6ae99SBarry Smith @*/
32541b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
325547c6ae99SBarry Smith {
325647c6ae99SBarry Smith   PetscFunctionBegin;
3257171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32581b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
325947c6ae99SBarry Smith   PetscFunctionReturn(0);
326047c6ae99SBarry Smith }
326147c6ae99SBarry Smith 
326208da532bSDmitry Karpeev /*@C
3263df3898eeSBarry Smith     DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI.
326408da532bSDmitry Karpeev 
3265d083f849SBarry Smith     Logically Collective on dm
326608da532bSDmitry Karpeev 
326708da532bSDmitry Karpeev     Input Parameter:
326808da532bSDmitry Karpeev +   dm - the DM object
32690298fd71SBarry Smith -   f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set)
327008da532bSDmitry Karpeev 
327108da532bSDmitry Karpeev     Level: intermediate
327208da532bSDmitry Karpeev 
3273835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(),
327408da532bSDmitry Karpeev          DMSetJacobian()
327508da532bSDmitry Karpeev 
327608da532bSDmitry Karpeev @*/
327708da532bSDmitry Karpeev PetscErrorCode DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
327808da532bSDmitry Karpeev {
327908da532bSDmitry Karpeev   PetscFunctionBegin;
32805a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
328108da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
328208da532bSDmitry Karpeev   PetscFunctionReturn(0);
328308da532bSDmitry Karpeev }
328408da532bSDmitry Karpeev 
328508da532bSDmitry Karpeev /*@
328608da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
328708da532bSDmitry Karpeev 
328808da532bSDmitry Karpeev     Not Collective
328908da532bSDmitry Karpeev 
329008da532bSDmitry Karpeev     Input Parameter:
329108da532bSDmitry Karpeev .   dm - the DM object to destroy
329208da532bSDmitry Karpeev 
329308da532bSDmitry Karpeev     Output Parameter:
329408da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
329508da532bSDmitry Karpeev 
329608da532bSDmitry Karpeev     Level: developer
329708da532bSDmitry Karpeev 
329874e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
329908da532bSDmitry Karpeev 
330008da532bSDmitry Karpeev @*/
330108da532bSDmitry Karpeev PetscErrorCode DMHasVariableBounds(DM dm,PetscBool *flg)
330208da532bSDmitry Karpeev {
330308da532bSDmitry Karpeev   PetscFunctionBegin;
33045a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3305534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
330608da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
330708da532bSDmitry Karpeev   PetscFunctionReturn(0);
330808da532bSDmitry Karpeev }
330908da532bSDmitry Karpeev 
331008da532bSDmitry Karpeev /*@C
331108da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
331208da532bSDmitry Karpeev 
3313d083f849SBarry Smith     Logically Collective on dm
331408da532bSDmitry Karpeev 
331508da532bSDmitry Karpeev     Input Parameters:
3316907376e6SBarry Smith .   dm - the DM object
331708da532bSDmitry Karpeev 
331808da532bSDmitry Karpeev     Output parameters:
331908da532bSDmitry Karpeev +   xl - lower bound
332008da532bSDmitry Karpeev -   xu - upper bound
332108da532bSDmitry Karpeev 
3322907376e6SBarry Smith     Level: advanced
3323907376e6SBarry Smith 
332495452b02SPatrick Sanan     Notes:
332595452b02SPatrick Sanan     This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds()
332608da532bSDmitry Karpeev 
332774e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
332808da532bSDmitry Karpeev 
332908da532bSDmitry Karpeev @*/
333008da532bSDmitry Karpeev PetscErrorCode DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
333108da532bSDmitry Karpeev {
333208da532bSDmitry Karpeev   PetscErrorCode ierr;
33335fd66863SKarl Rupp 
333408da532bSDmitry Karpeev   PetscFunctionBegin;
33355a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
333608da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
33375a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(xu,VEC_CLASSID,3);
3338b9d85ea2SLisandro Dalcin   if (!dm->ops->computevariablebounds) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeVariableBounds",((PetscObject)dm)->type_name);
333908da532bSDmitry Karpeev   ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr);
334008da532bSDmitry Karpeev   PetscFunctionReturn(0);
334108da532bSDmitry Karpeev }
334208da532bSDmitry Karpeev 
3343b0ae01b7SPeter Brune /*@
3344b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
3345b0ae01b7SPeter Brune 
3346b0ae01b7SPeter Brune     Not Collective
3347b0ae01b7SPeter Brune 
3348b0ae01b7SPeter Brune     Input Parameter:
3349b0ae01b7SPeter Brune .   dm - the DM object
3350b0ae01b7SPeter Brune 
3351b0ae01b7SPeter Brune     Output Parameter:
3352b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
3353b0ae01b7SPeter Brune 
3354b0ae01b7SPeter Brune     Level: developer
3355b0ae01b7SPeter Brune 
33561565f0a7SPatrick Sanan .seealso DMCreateColoring()
3357b0ae01b7SPeter Brune 
3358b0ae01b7SPeter Brune @*/
3359b0ae01b7SPeter Brune PetscErrorCode DMHasColoring(DM dm,PetscBool *flg)
3360b0ae01b7SPeter Brune {
3361b0ae01b7SPeter Brune   PetscFunctionBegin;
33625a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3363534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
3364b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
3365b0ae01b7SPeter Brune   PetscFunctionReturn(0);
3366b0ae01b7SPeter Brune }
3367b0ae01b7SPeter Brune 
33683ad4599aSBarry Smith /*@
33693ad4599aSBarry Smith     DMHasCreateRestriction - does the DM object have a method of providing a restriction?
33703ad4599aSBarry Smith 
33713ad4599aSBarry Smith     Not Collective
33723ad4599aSBarry Smith 
33733ad4599aSBarry Smith     Input Parameter:
33743ad4599aSBarry Smith .   dm - the DM object
33753ad4599aSBarry Smith 
33763ad4599aSBarry Smith     Output Parameter:
33773ad4599aSBarry Smith .   flg - PETSC_TRUE if the DM has facilities for DMCreateRestriction().
33783ad4599aSBarry Smith 
33793ad4599aSBarry Smith     Level: developer
33803ad4599aSBarry Smith 
33811565f0a7SPatrick Sanan .seealso DMCreateRestriction()
33823ad4599aSBarry Smith 
33833ad4599aSBarry Smith @*/
33843ad4599aSBarry Smith PetscErrorCode DMHasCreateRestriction(DM dm,PetscBool *flg)
33853ad4599aSBarry Smith {
33863ad4599aSBarry Smith   PetscFunctionBegin;
33875a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3388534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
33893ad4599aSBarry Smith   *flg =  (dm->ops->createrestriction) ? PETSC_TRUE : PETSC_FALSE;
33903ad4599aSBarry Smith   PetscFunctionReturn(0);
33913ad4599aSBarry Smith }
33923ad4599aSBarry Smith 
3393a7058e45SLawrence Mitchell 
3394a7058e45SLawrence Mitchell /*@
3395a7058e45SLawrence Mitchell     DMHasCreateInjection - does the DM object have a method of providing an injection?
3396a7058e45SLawrence Mitchell 
3397a7058e45SLawrence Mitchell     Not Collective
3398a7058e45SLawrence Mitchell 
3399a7058e45SLawrence Mitchell     Input Parameter:
3400a7058e45SLawrence Mitchell .   dm - the DM object
3401a7058e45SLawrence Mitchell 
3402a7058e45SLawrence Mitchell     Output Parameter:
3403a7058e45SLawrence Mitchell .   flg - PETSC_TRUE if the DM has facilities for DMCreateInjection().
3404a7058e45SLawrence Mitchell 
3405a7058e45SLawrence Mitchell     Level: developer
3406a7058e45SLawrence Mitchell 
34071565f0a7SPatrick Sanan .seealso DMCreateInjection()
3408a7058e45SLawrence Mitchell 
3409a7058e45SLawrence Mitchell @*/
3410a7058e45SLawrence Mitchell PetscErrorCode DMHasCreateInjection(DM dm,PetscBool *flg)
3411a7058e45SLawrence Mitchell {
34124a7a4c06SLawrence Mitchell   PetscErrorCode ierr;
34135a84ad33SLisandro Dalcin 
3414a7058e45SLawrence Mitchell   PetscFunctionBegin;
34155a84ad33SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3416534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
34175a84ad33SLisandro Dalcin   if (dm->ops->hascreateinjection) {
34184a7a4c06SLawrence Mitchell     ierr = (*dm->ops->hascreateinjection)(dm,flg);CHKERRQ(ierr);
34195a84ad33SLisandro Dalcin   } else {
34205a84ad33SLisandro Dalcin     *flg = (dm->ops->createinjection) ? PETSC_TRUE : PETSC_FALSE;
34215a84ad33SLisandro Dalcin   }
3422a7058e45SLawrence Mitchell   PetscFunctionReturn(0);
3423a7058e45SLawrence Mitchell }
3424a7058e45SLawrence Mitchell 
34255a84ad33SLisandro Dalcin 
3426748fac09SDmitry Karpeev /*@C
342708da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
342808da532bSDmitry Karpeev 
3429d083f849SBarry Smith     Collective on dm
343008da532bSDmitry Karpeev 
343108da532bSDmitry Karpeev     Input Parameter:
343208da532bSDmitry Karpeev +   dm - the DM object
34330298fd71SBarry Smith -   x - location to compute residual and Jacobian, if NULL is passed to those routines; will be NULL for linear problems.
343408da532bSDmitry Karpeev 
343508da532bSDmitry Karpeev     Level: developer
343608da532bSDmitry Karpeev 
343774e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
343808da532bSDmitry Karpeev 
343908da532bSDmitry Karpeev @*/
344008da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
344108da532bSDmitry Karpeev {
344208da532bSDmitry Karpeev   PetscErrorCode ierr;
34435fd66863SKarl Rupp 
344408da532bSDmitry Karpeev   PetscFunctionBegin;
3445b9d85ea2SLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
344608da532bSDmitry Karpeev   if (x) {
344708da532bSDmitry Karpeev     if (!dm->x) {
344808da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
344908da532bSDmitry Karpeev     }
345008da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
34518865f1eaSKarl Rupp   } else if (dm->x) {
345208da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);CHKERRQ(ierr);
345308da532bSDmitry Karpeev   }
345408da532bSDmitry Karpeev   PetscFunctionReturn(0);
345508da532bSDmitry Karpeev }
345608da532bSDmitry Karpeev 
34570298fd71SBarry Smith PetscFunctionList DMList              = NULL;
3458264ace61SBarry Smith PetscBool         DMRegisterAllCalled = PETSC_FALSE;
3459264ace61SBarry Smith 
3460264ace61SBarry Smith /*@C
3461264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
3462264ace61SBarry Smith 
3463d083f849SBarry Smith   Collective on dm
3464264ace61SBarry Smith 
3465264ace61SBarry Smith   Input Parameters:
3466264ace61SBarry Smith + dm     - The DM object
3467264ace61SBarry Smith - method - The name of the DM type
3468264ace61SBarry Smith 
3469264ace61SBarry Smith   Options Database Key:
3470264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
3471264ace61SBarry Smith 
3472264ace61SBarry Smith   Notes:
3473e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
3474264ace61SBarry Smith 
3475264ace61SBarry Smith   Level: intermediate
3476264ace61SBarry Smith 
3477264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
3478264ace61SBarry Smith @*/
347919fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
3480264ace61SBarry Smith {
3481264ace61SBarry Smith   PetscErrorCode (*r)(DM);
3482264ace61SBarry Smith   PetscBool      match;
3483264ace61SBarry Smith   PetscErrorCode ierr;
3484264ace61SBarry Smith 
3485264ace61SBarry Smith   PetscFunctionBegin;
3486264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
3487251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
3488264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
3489264ace61SBarry Smith 
34900f51fdf8SToby Isaac   ierr = DMRegisterAll();CHKERRQ(ierr);
34911c9cd337SJed Brown   ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr);
3492ce94432eSBarry Smith   if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
3493264ace61SBarry Smith 
3494264ace61SBarry Smith   if (dm->ops->destroy) {
3495264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
3496264ace61SBarry Smith   }
3497d57f96a3SLisandro Dalcin   ierr = PetscMemzero(dm->ops,sizeof(*dm->ops));CHKERRQ(ierr);
3498264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
3499d57f96a3SLisandro Dalcin   ierr = (*r)(dm);CHKERRQ(ierr);
3500264ace61SBarry Smith   PetscFunctionReturn(0);
3501264ace61SBarry Smith }
3502264ace61SBarry Smith 
3503264ace61SBarry Smith /*@C
3504264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
3505264ace61SBarry Smith 
3506264ace61SBarry Smith   Not Collective
3507264ace61SBarry Smith 
3508264ace61SBarry Smith   Input Parameter:
3509264ace61SBarry Smith . dm  - The DM
3510264ace61SBarry Smith 
3511264ace61SBarry Smith   Output Parameter:
3512264ace61SBarry Smith . type - The DM type name
3513264ace61SBarry Smith 
3514264ace61SBarry Smith   Level: intermediate
3515264ace61SBarry Smith 
3516264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
3517264ace61SBarry Smith @*/
351819fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
3519264ace61SBarry Smith {
3520264ace61SBarry Smith   PetscErrorCode ierr;
3521264ace61SBarry Smith 
3522264ace61SBarry Smith   PetscFunctionBegin;
3523264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
3524c959eef4SJed Brown   PetscValidPointer(type,2);
3525607a6623SBarry Smith   ierr = DMRegisterAll();CHKERRQ(ierr);
3526264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
3527264ace61SBarry Smith   PetscFunctionReturn(0);
3528264ace61SBarry Smith }
3529264ace61SBarry Smith 
353067a56275SMatthew G Knepley /*@C
353167a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
353267a56275SMatthew G Knepley 
3533d083f849SBarry Smith   Collective on dm
353467a56275SMatthew G Knepley 
353567a56275SMatthew G Knepley   Input Parameters:
353667a56275SMatthew G Knepley + dm - the DM
353767a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
353867a56275SMatthew G Knepley 
353967a56275SMatthew G Knepley   Output Parameter:
354067a56275SMatthew G Knepley . M - pointer to new DM
354167a56275SMatthew G Knepley 
354267a56275SMatthew G Knepley   Notes:
354367a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
354467a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
354567a56275SMatthew G Knepley   of the input DM.
354667a56275SMatthew G Knepley 
354767a56275SMatthew G Knepley   Level: intermediate
354867a56275SMatthew G Knepley 
354967a56275SMatthew G Knepley .seealso: DMCreate()
355067a56275SMatthew G Knepley @*/
355119fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
355267a56275SMatthew G Knepley {
355367a56275SMatthew G Knepley   DM             B;
355467a56275SMatthew G Knepley   char           convname[256];
3555c067b6caSMatthew G. Knepley   PetscBool      sametype/*, issame */;
355667a56275SMatthew G Knepley   PetscErrorCode ierr;
355767a56275SMatthew G Knepley 
355867a56275SMatthew G Knepley   PetscFunctionBegin;
355967a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
356067a56275SMatthew G Knepley   PetscValidType(dm,1);
356167a56275SMatthew G Knepley   PetscValidPointer(M,3);
3562251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
3563c067b6caSMatthew G. Knepley   /* ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr); */
3564c067b6caSMatthew G. Knepley   if (sametype) {
3565c067b6caSMatthew G. Knepley     *M   = dm;
3566c067b6caSMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr);
3567c067b6caSMatthew G. Knepley     PetscFunctionReturn(0);
3568c067b6caSMatthew G. Knepley   } else {
35690298fd71SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM*) = NULL;
357067a56275SMatthew G Knepley 
357167a56275SMatthew G Knepley     /*
357267a56275SMatthew G Knepley        Order of precedence:
357367a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
357467a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
357567a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
357667a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
357767a56275SMatthew G Knepley        5) Use a really basic converter.
357867a56275SMatthew G Knepley     */
357967a56275SMatthew G Knepley 
358067a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
3581a126751eSBarry Smith     ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr);
3582a126751eSBarry Smith     ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr);
3583a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
3584a126751eSBarry Smith     ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
3585a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
35860005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr);
358767a56275SMatthew G Knepley     if (conv) goto foundconv;
358867a56275SMatthew G Knepley 
358967a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
359082f516ccSBarry Smith     ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr);
359167a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
3592a126751eSBarry Smith     ierr = PetscStrncpy(convname,"DMConvert_",sizeof(convname));CHKERRQ(ierr);
3593a126751eSBarry Smith     ierr = PetscStrlcat(convname,((PetscObject) dm)->type_name,sizeof(convname));CHKERRQ(ierr);
3594a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
3595a126751eSBarry Smith     ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
3596a126751eSBarry Smith     ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
35970005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
359867a56275SMatthew G Knepley     if (conv) {
3599fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
360067a56275SMatthew G Knepley       goto foundconv;
360167a56275SMatthew G Knepley     }
360267a56275SMatthew G Knepley 
360367a56275SMatthew G Knepley #if 0
360467a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
360567a56275SMatthew G Knepley     conv = B->ops->convertfrom;
3606fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
360767a56275SMatthew G Knepley     if (conv) goto foundconv;
360867a56275SMatthew G Knepley 
360967a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
361067a56275SMatthew G Knepley     if (dm->ops->convert) {
361167a56275SMatthew G Knepley       conv = dm->ops->convert;
361267a56275SMatthew G Knepley     }
361367a56275SMatthew G Knepley     if (conv) goto foundconv;
361467a56275SMatthew G Knepley #endif
361567a56275SMatthew G Knepley 
361667a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
361782f516ccSBarry Smith     SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
361867a56275SMatthew G Knepley 
361967a56275SMatthew G Knepley foundconv:
362067a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
362167a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
362212fa691eSMatthew G. Knepley     /* Things that are independent of DM type: We should consult DMClone() here */
362390b157c4SStefano Zampini     {
362490b157c4SStefano Zampini       PetscBool             isper;
362512fa691eSMatthew G. Knepley       const PetscReal      *maxCell, *L;
362612fa691eSMatthew G. Knepley       const DMBoundaryType *bd;
362790b157c4SStefano Zampini       ierr = DMGetPeriodicity(dm, &isper, &maxCell, &L, &bd);CHKERRQ(ierr);
362890b157c4SStefano Zampini       ierr = DMSetPeriodicity(*M, isper, maxCell,  L,  bd);CHKERRQ(ierr);
362912fa691eSMatthew G. Knepley     }
363067a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
363167a56275SMatthew G Knepley   }
363267a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
363367a56275SMatthew G Knepley   PetscFunctionReturn(0);
363467a56275SMatthew G Knepley }
3635264ace61SBarry Smith 
3636264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
3637264ace61SBarry Smith 
3638264ace61SBarry Smith /*@C
36391c84c290SBarry Smith   DMRegister -  Adds a new DM component implementation
36401c84c290SBarry Smith 
36411c84c290SBarry Smith   Not Collective
36421c84c290SBarry Smith 
36431c84c290SBarry Smith   Input Parameters:
36441c84c290SBarry Smith + name        - The name of a new user-defined creation routine
36451c84c290SBarry Smith - create_func - The creation routine itself
36461c84c290SBarry Smith 
36471c84c290SBarry Smith   Notes:
36481c84c290SBarry Smith   DMRegister() may be called multiple times to add several user-defined DMs
36491c84c290SBarry Smith 
36501c84c290SBarry Smith 
36511c84c290SBarry Smith   Sample usage:
36521c84c290SBarry Smith .vb
3653bdf89e91SBarry Smith     DMRegister("my_da", MyDMCreate);
36541c84c290SBarry Smith .ve
36551c84c290SBarry Smith 
36561c84c290SBarry Smith   Then, your DM type can be chosen with the procedural interface via
36571c84c290SBarry Smith .vb
36581c84c290SBarry Smith     DMCreate(MPI_Comm, DM *);
36591c84c290SBarry Smith     DMSetType(DM,"my_da");
36601c84c290SBarry Smith .ve
36611c84c290SBarry Smith    or at runtime via the option
36621c84c290SBarry Smith .vb
36631c84c290SBarry Smith     -da_type my_da
36641c84c290SBarry Smith .ve
3665264ace61SBarry Smith 
3666264ace61SBarry Smith   Level: advanced
36671c84c290SBarry Smith 
3668bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy()
36691c84c290SBarry Smith 
3670264ace61SBarry Smith @*/
3671bdf89e91SBarry Smith PetscErrorCode  DMRegister(const char sname[],PetscErrorCode (*function)(DM))
3672264ace61SBarry Smith {
3673264ace61SBarry Smith   PetscErrorCode ierr;
3674264ace61SBarry Smith 
3675264ace61SBarry Smith   PetscFunctionBegin;
36761d36bdfdSBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
3677a240a19fSJed Brown   ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr);
3678264ace61SBarry Smith   PetscFunctionReturn(0);
3679264ace61SBarry Smith }
3680264ace61SBarry Smith 
3681b859378eSBarry Smith /*@C
368255849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
3683b859378eSBarry Smith 
3684d083f849SBarry Smith   Collective on viewer
3685b859378eSBarry Smith 
3686b859378eSBarry Smith   Input Parameters:
3687b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
3688b859378eSBarry Smith            some related function before a call to DMLoad().
3689b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
3690b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
3691b859378eSBarry Smith 
3692b859378eSBarry Smith    Level: intermediate
3693b859378eSBarry Smith 
3694b859378eSBarry Smith   Notes:
369555849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
3696b859378eSBarry Smith 
3697b859378eSBarry Smith   Notes for advanced users:
3698b859378eSBarry Smith   Most users should not need to know the details of the binary storage
3699b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
3700b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
3701b859378eSBarry Smith   format is
3702b859378eSBarry Smith .vb
3703b859378eSBarry Smith      has not yet been determined
3704b859378eSBarry Smith .ve
3705b859378eSBarry Smith 
3706b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
3707b859378eSBarry Smith @*/
3708b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
3709b859378eSBarry Smith {
37109331c7a4SMatthew G. Knepley   PetscBool      isbinary, ishdf5;
3711b859378eSBarry Smith   PetscErrorCode ierr;
3712b859378eSBarry Smith 
3713b859378eSBarry Smith   PetscFunctionBegin;
3714b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
3715b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
3716fb694a9eSVaclav Hapla   ierr = PetscViewerCheckReadable(viewer);CHKERRQ(ierr);
371732c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
37189331c7a4SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
37199331c7a4SMatthew G. Knepley   if (isbinary) {
37209331c7a4SMatthew G. Knepley     PetscInt classid;
37219331c7a4SMatthew G. Knepley     char     type[256];
3722b859378eSBarry Smith 
3723060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
37249200755eSBarry Smith     if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid);
3725060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
372632c0f0efSBarry Smith     ierr = DMSetType(newdm, type);CHKERRQ(ierr);
37279331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
37289331c7a4SMatthew G. Knepley   } else if (ishdf5) {
37299331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
37309331c7a4SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()");
3731b859378eSBarry Smith   PetscFunctionReturn(0);
3732b859378eSBarry Smith }
3733b859378eSBarry Smith 
37347da65231SMatthew G Knepley /******************************** FEM Support **********************************/
37357da65231SMatthew G Knepley 
3736a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[])
3737a6dfd86eSKarl Rupp {
37381d47ebbbSSatish Balay   PetscInt       f;
37391b30c384SMatthew G Knepley   PetscErrorCode ierr;
37401b30c384SMatthew G Knepley 
37417da65231SMatthew G Knepley   PetscFunctionBegin;
374274778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
37431d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
374457622a8eSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr);
37457da65231SMatthew G Knepley   }
37467da65231SMatthew G Knepley   PetscFunctionReturn(0);
37477da65231SMatthew G Knepley }
37487da65231SMatthew G Knepley 
3749a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[])
3750a6dfd86eSKarl Rupp {
37511b30c384SMatthew G Knepley   PetscInt       f, g;
37527da65231SMatthew G Knepley   PetscErrorCode ierr;
37537da65231SMatthew G Knepley 
37547da65231SMatthew G Knepley   PetscFunctionBegin;
375574778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
37561d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
375774778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
37581d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
3759e3556bceSMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
37607da65231SMatthew G Knepley     }
376174778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
37627da65231SMatthew G Knepley   }
37637da65231SMatthew G Knepley   PetscFunctionReturn(0);
37647da65231SMatthew G Knepley }
3765e7c4fc90SDmitry Karpeev 
37666113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X)
3767e759306cSMatthew G. Knepley {
37680c5b8624SToby Isaac   PetscInt          localSize, bs;
37690c5b8624SToby Isaac   PetscMPIInt       size;
37700c5b8624SToby Isaac   Vec               x, xglob;
37710c5b8624SToby Isaac   const PetscScalar *xarray;
3772e759306cSMatthew G. Knepley   PetscErrorCode    ierr;
3773e759306cSMatthew G. Knepley 
3774e759306cSMatthew G. Knepley   PetscFunctionBegin;
37759852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm),&size);CHKERRQ(ierr);
3776e759306cSMatthew G. Knepley   ierr = VecDuplicate(X, &x);CHKERRQ(ierr);
3777e759306cSMatthew G. Knepley   ierr = VecCopy(X, x);CHKERRQ(ierr);
37786113b454SMatthew G. Knepley   ierr = VecChop(x, tol);CHKERRQ(ierr);
37790c5b8624SToby Isaac   ierr = PetscPrintf(PetscObjectComm((PetscObject) dm),"%s:\n",name);CHKERRQ(ierr);
37800c5b8624SToby Isaac   if (size > 1) {
37810c5b8624SToby Isaac     ierr = VecGetLocalSize(x,&localSize);CHKERRQ(ierr);
37820c5b8624SToby Isaac     ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr);
37830c5b8624SToby Isaac     ierr = VecGetBlockSize(x,&bs);CHKERRQ(ierr);
37840c5b8624SToby Isaac     ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject) dm),bs,localSize,PETSC_DETERMINE,xarray,&xglob);CHKERRQ(ierr);
37850c5b8624SToby Isaac   } else {
37860c5b8624SToby Isaac     xglob = x;
37870c5b8624SToby Isaac   }
37880c5b8624SToby Isaac   ierr = VecView(xglob,PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) dm)));CHKERRQ(ierr);
37890c5b8624SToby Isaac   if (size > 1) {
37900c5b8624SToby Isaac     ierr = VecDestroy(&xglob);CHKERRQ(ierr);
37910c5b8624SToby Isaac     ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr);
37920c5b8624SToby Isaac   }
3793e759306cSMatthew G. Knepley   ierr = VecDestroy(&x);CHKERRQ(ierr);
3794e759306cSMatthew G. Knepley   PetscFunctionReturn(0);
3795e759306cSMatthew G. Knepley }
3796e759306cSMatthew G. Knepley 
379788ed4aceSMatthew G Knepley /*@
3798061576a5SJed Brown   DMGetSection - Get the PetscSection encoding the local data layout for the DM.  This is equivalent to DMGetLocalSection() and included only for compatibility.
3799061576a5SJed Brown 
3800061576a5SJed Brown   Input Parameter:
3801061576a5SJed Brown . dm - The DM
3802061576a5SJed Brown 
3803061576a5SJed Brown   Output Parameter:
3804061576a5SJed Brown . section - The PetscSection
3805061576a5SJed Brown 
3806061576a5SJed Brown   Options Database Keys:
3807061576a5SJed Brown . -dm_petscsection_view - View the Section created by the DM
3808061576a5SJed Brown 
3809061576a5SJed Brown   Level: advanced
3810061576a5SJed Brown 
3811061576a5SJed Brown   Notes:
3812061576a5SJed Brown   Use DMGetLocalSection() in new code.
3813061576a5SJed Brown 
3814061576a5SJed Brown   This gets a borrowed reference, so the user should not destroy this PetscSection.
3815061576a5SJed Brown 
3816061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetLocalSection(), DMGetGlobalSection()
3817061576a5SJed Brown @*/
3818061576a5SJed Brown PetscErrorCode DMGetSection(DM dm, PetscSection *section)
3819061576a5SJed Brown {
3820061576a5SJed Brown   PetscErrorCode ierr;
3821061576a5SJed Brown 
3822061576a5SJed Brown   PetscFunctionBegin;
3823061576a5SJed Brown   ierr = DMGetLocalSection(dm,section);CHKERRQ(ierr);
3824061576a5SJed Brown   PetscFunctionReturn(0);
3825061576a5SJed Brown }
3826061576a5SJed Brown 
3827061576a5SJed Brown /*@
3828061576a5SJed Brown   DMGetLocalSection - Get the PetscSection encoding the local data layout for the DM.
382988ed4aceSMatthew G Knepley 
383088ed4aceSMatthew G Knepley   Input Parameter:
383188ed4aceSMatthew G Knepley . dm - The DM
383288ed4aceSMatthew G Knepley 
383388ed4aceSMatthew G Knepley   Output Parameter:
383488ed4aceSMatthew G Knepley . section - The PetscSection
383588ed4aceSMatthew G Knepley 
3836e5893cccSMatthew G. Knepley   Options Database Keys:
3837e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM
3838e5893cccSMatthew G. Knepley 
383988ed4aceSMatthew G Knepley   Level: intermediate
384088ed4aceSMatthew G Knepley 
384188ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
384288ed4aceSMatthew G Knepley 
3843061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetGlobalSection()
384488ed4aceSMatthew G Knepley @*/
3845061576a5SJed Brown PetscErrorCode DMGetLocalSection(DM dm, PetscSection *section)
38460adebc6cSBarry Smith {
3847fd59a867SMatthew G. Knepley   PetscErrorCode ierr;
3848fd59a867SMatthew G. Knepley 
384988ed4aceSMatthew G Knepley   PetscFunctionBegin;
385088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
385188ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
38522f0f8703SMatthew G. Knepley   if (!dm->defaultSection && dm->ops->createdefaultsection) {
3853e5e52638SMatthew G. Knepley     PetscInt d;
3854e5e52638SMatthew G. Knepley 
3855e5e52638SMatthew G. Knepley     if (dm->setfromoptionscalled) for (d = 0; d < dm->Nds; ++d) {ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr);}
38562f0f8703SMatthew G. Knepley     ierr = (*dm->ops->createdefaultsection)(dm);CHKERRQ(ierr);
3857ae71db08SMatthew G. Knepley     if (dm->defaultSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->defaultSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);}
38582f0f8703SMatthew G. Knepley   }
385988ed4aceSMatthew G Knepley   *section = dm->defaultSection;
386088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
386188ed4aceSMatthew G Knepley }
386288ed4aceSMatthew G Knepley 
386388ed4aceSMatthew G Knepley /*@
3864061576a5SJed Brown   DMSetSection - Set the PetscSection encoding the local data layout for the DM.  This is equivalent to DMSetLocalSection() and included only for compatibility.
3865061576a5SJed Brown 
3866061576a5SJed Brown   Input Parameters:
3867061576a5SJed Brown + dm - The DM
3868061576a5SJed Brown - section - The PetscSection
3869061576a5SJed Brown 
3870061576a5SJed Brown   Level: advanced
3871061576a5SJed Brown 
3872061576a5SJed Brown   Notes:
3873061576a5SJed Brown   Use DMSetLocalSection() in new code.
3874061576a5SJed Brown 
3875061576a5SJed Brown   Any existing Section will be destroyed
3876061576a5SJed Brown 
3877061576a5SJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection(), DMSetGlobalSection()
3878061576a5SJed Brown @*/
3879061576a5SJed Brown PetscErrorCode DMSetSection(DM dm, PetscSection section)
3880061576a5SJed Brown {
3881061576a5SJed Brown   PetscErrorCode ierr;
3882061576a5SJed Brown 
3883061576a5SJed Brown   PetscFunctionBegin;
3884061576a5SJed Brown   ierr = DMSetLocalSection(dm,section);CHKERRQ(ierr);
3885061576a5SJed Brown   PetscFunctionReturn(0);
3886061576a5SJed Brown }
3887061576a5SJed Brown 
3888061576a5SJed Brown /*@
3889061576a5SJed Brown   DMSetLocalSection - Set the PetscSection encoding the local data layout for the DM.
389088ed4aceSMatthew G Knepley 
389188ed4aceSMatthew G Knepley   Input Parameters:
389288ed4aceSMatthew G Knepley + dm - The DM
389388ed4aceSMatthew G Knepley - section - The PetscSection
389488ed4aceSMatthew G Knepley 
389588ed4aceSMatthew G Knepley   Level: intermediate
389688ed4aceSMatthew G Knepley 
389788ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
389888ed4aceSMatthew G Knepley 
3899061576a5SJed Brown .seealso: DMGetLocalSection(), DMSetGlobalSection()
390088ed4aceSMatthew G Knepley @*/
3901061576a5SJed Brown PetscErrorCode DMSetLocalSection(DM dm, PetscSection section)
39020adebc6cSBarry Smith {
3903c473ab19SMatthew G. Knepley   PetscInt       numFields = 0;
3904af122d2aSMatthew G Knepley   PetscInt       f;
390588ed4aceSMatthew G Knepley   PetscErrorCode ierr;
390688ed4aceSMatthew G Knepley 
390788ed4aceSMatthew G Knepley   PetscFunctionBegin;
390888ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3909b9d85ea2SLisandro Dalcin   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
39101d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
391188ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
391288ed4aceSMatthew G Knepley   dm->defaultSection = section;
3913c473ab19SMatthew G. Knepley   if (section) {ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);}
3914af122d2aSMatthew G Knepley   if (numFields) {
3915af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
3916af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
39170f21e855SMatthew G. Knepley       PetscObject disc;
3918af122d2aSMatthew G Knepley       const char *name;
3919af122d2aSMatthew G Knepley 
3920af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
392144a7f3ddSMatthew G. Knepley       ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr);
39220f21e855SMatthew G. Knepley       ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr);
3923af122d2aSMatthew G Knepley     }
3924af122d2aSMatthew G Knepley   }
3925e87a4003SBarry Smith   /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */
39261d799100SJed Brown   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
392788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
392888ed4aceSMatthew G Knepley }
392988ed4aceSMatthew G Knepley 
39309435951eSToby Isaac /*@
39319435951eSToby Isaac   DMGetDefaultConstraints - Get the PetscSection and Mat the specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation.
39329435951eSToby Isaac 
3933e228b242SToby Isaac   not collective
3934e228b242SToby Isaac 
39359435951eSToby Isaac   Input Parameter:
39369435951eSToby Isaac . dm - The DM
39379435951eSToby Isaac 
39389435951eSToby Isaac   Output Parameter:
39399435951eSToby 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.
39409435951eSToby 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.
39419435951eSToby Isaac 
39429435951eSToby Isaac   Level: advanced
39439435951eSToby Isaac 
39449435951eSToby Isaac   Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat.
39459435951eSToby Isaac 
39469435951eSToby Isaac .seealso: DMSetDefaultConstraints()
39479435951eSToby Isaac @*/
39489435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat)
39499435951eSToby Isaac {
39509435951eSToby Isaac   PetscErrorCode ierr;
39519435951eSToby Isaac 
39529435951eSToby Isaac   PetscFunctionBegin;
39539435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
39549435951eSToby Isaac   if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);}
395545a75d81SToby Isaac   if (section) {*section = dm->defaultConstraintSection;}
395645a75d81SToby Isaac   if (mat) {*mat = dm->defaultConstraintMat;}
39579435951eSToby Isaac   PetscFunctionReturn(0);
39589435951eSToby Isaac }
39599435951eSToby Isaac 
39609435951eSToby Isaac /*@
39619435951eSToby Isaac   DMSetDefaultConstraints - Set the PetscSection and Mat the specify the local constraint interpolation.
39629435951eSToby Isaac 
39639435951eSToby 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().
39649435951eSToby Isaac 
39659435951eSToby 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.
39669435951eSToby Isaac 
3967e228b242SToby Isaac   collective on dm
3968e228b242SToby Isaac 
39699435951eSToby Isaac   Input Parameters:
39709435951eSToby Isaac + dm - The DM
3971e228b242SToby 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).
3972e228b242SToby 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).
39739435951eSToby Isaac 
39749435951eSToby Isaac   Level: advanced
39759435951eSToby Isaac 
39769435951eSToby Isaac   Note: This increments the references of the PetscSection and the Mat, so they user can destroy them
39779435951eSToby Isaac 
39789435951eSToby Isaac .seealso: DMGetDefaultConstraints()
39799435951eSToby Isaac @*/
39809435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat)
39819435951eSToby Isaac {
3982e228b242SToby Isaac   PetscMPIInt result;
39839435951eSToby Isaac   PetscErrorCode ierr;
39849435951eSToby Isaac 
39859435951eSToby Isaac   PetscFunctionBegin;
39869435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3987e228b242SToby Isaac   if (section) {
3988e228b242SToby Isaac     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
3989e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr);
3990f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator");
3991e228b242SToby Isaac   }
3992e228b242SToby Isaac   if (mat) {
3993e228b242SToby Isaac     PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
3994e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr);
3995f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator");
3996e228b242SToby Isaac   }
39979435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
39989435951eSToby Isaac   ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr);
39999435951eSToby Isaac   dm->defaultConstraintSection = section;
40009435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
40019435951eSToby Isaac   ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr);
40029435951eSToby Isaac   dm->defaultConstraintMat = mat;
40039435951eSToby Isaac   PetscFunctionReturn(0);
40049435951eSToby Isaac }
40059435951eSToby Isaac 
4006497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
4007507e4973SMatthew G. Knepley /*
4008507e4973SMatthew G. Knepley   DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections.
4009507e4973SMatthew G. Knepley 
4010507e4973SMatthew G. Knepley   Input Parameters:
4011507e4973SMatthew G. Knepley + dm - The DM
4012507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout
4013507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout
4014507e4973SMatthew G. Knepley 
4015507e4973SMatthew G. Knepley   Level: intermediate
4016507e4973SMatthew G. Knepley 
4017507e4973SMatthew G. Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
4018507e4973SMatthew G. Knepley */
4019f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection)
4020507e4973SMatthew G. Knepley {
4021507e4973SMatthew G. Knepley   MPI_Comm        comm;
4022507e4973SMatthew G. Knepley   PetscLayout     layout;
4023507e4973SMatthew G. Knepley   const PetscInt *ranges;
4024507e4973SMatthew G. Knepley   PetscInt        pStart, pEnd, p, nroots;
4025507e4973SMatthew G. Knepley   PetscMPIInt     size, rank;
4026507e4973SMatthew G. Knepley   PetscBool       valid = PETSC_TRUE, gvalid;
4027507e4973SMatthew G. Knepley   PetscErrorCode  ierr;
4028507e4973SMatthew G. Knepley 
4029507e4973SMatthew G. Knepley   PetscFunctionBegin;
4030507e4973SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
4031507e4973SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4032507e4973SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
4033507e4973SMatthew G. Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
4034507e4973SMatthew G. Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
4035507e4973SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
4036507e4973SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
4037507e4973SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
4038507e4973SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
4039507e4973SMatthew G. Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
4040507e4973SMatthew G. Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4041507e4973SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
4042f741bcd2SMatthew G. Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d;
4043507e4973SMatthew G. Knepley 
4044507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
4045507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
4046507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
4047507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
4048507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4049507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
4050507e4973SMatthew G. Knepley     if (!gdof) continue; /* Censored point */
4051507e4973SMatthew 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;}
4052507e4973SMatthew 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;}
4053507e4973SMatthew G. Knepley     if (gdof < 0) {
4054507e4973SMatthew G. Knepley       gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
4055507e4973SMatthew G. Knepley       for (d = 0; d < gsize; ++d) {
4056507e4973SMatthew G. Knepley         PetscInt offset = -(goff+1) + d, r;
4057507e4973SMatthew G. Knepley 
4058507e4973SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
4059507e4973SMatthew G. Knepley         if (r < 0) r = -(r+2);
4060507e4973SMatthew 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;}
4061507e4973SMatthew G. Knepley       }
4062507e4973SMatthew G. Knepley     }
4063507e4973SMatthew G. Knepley   }
4064507e4973SMatthew G. Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
4065507e4973SMatthew G. Knepley   ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);
4066b2566f29SBarry Smith   ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr);
4067507e4973SMatthew G. Knepley   if (!gvalid) {
4068507e4973SMatthew G. Knepley     ierr = DMView(dm, NULL);CHKERRQ(ierr);
4069507e4973SMatthew G. Knepley     SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections");
4070507e4973SMatthew G. Knepley   }
4071507e4973SMatthew G. Knepley   PetscFunctionReturn(0);
4072507e4973SMatthew G. Knepley }
4073f741bcd2SMatthew G. Knepley #endif
4074507e4973SMatthew G. Knepley 
407588ed4aceSMatthew G Knepley /*@
4076e87a4003SBarry Smith   DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM.
407788ed4aceSMatthew G Knepley 
4078d083f849SBarry Smith   Collective on dm
40798b1ab98fSJed Brown 
408088ed4aceSMatthew G Knepley   Input Parameter:
408188ed4aceSMatthew G Knepley . dm - The DM
408288ed4aceSMatthew G Knepley 
408388ed4aceSMatthew G Knepley   Output Parameter:
408488ed4aceSMatthew G Knepley . section - The PetscSection
408588ed4aceSMatthew G Knepley 
408688ed4aceSMatthew G Knepley   Level: intermediate
408788ed4aceSMatthew G Knepley 
408888ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
408988ed4aceSMatthew G Knepley 
4090*92fd8e1eSJed Brown .seealso: DMSetLocalSection(), DMGetLocalSection()
409188ed4aceSMatthew G Knepley @*/
4092e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section)
40930adebc6cSBarry Smith {
409488ed4aceSMatthew G Knepley   PetscErrorCode ierr;
409588ed4aceSMatthew G Knepley 
409688ed4aceSMatthew G Knepley   PetscFunctionBegin;
409788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
409888ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
409988ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
4100fd59a867SMatthew G. Knepley     PetscSection s;
4101fd59a867SMatthew G. Knepley 
4102*92fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
4103fd59a867SMatthew 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");
410433907cc2SStefano 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");
410515b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
4106cf06b437SMatthew G. Knepley     ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr);
4107ce94432eSBarry Smith     ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->defaultGlobalSection, &dm->map);CHKERRQ(ierr);
4108685405a1SBarry Smith     ierr = PetscSectionViewFromOptions(dm->defaultGlobalSection, NULL, "-global_section_view");CHKERRQ(ierr);
410988ed4aceSMatthew G Knepley   }
411088ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
411188ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
411288ed4aceSMatthew G Knepley }
411388ed4aceSMatthew G Knepley 
4114b21d0597SMatthew G Knepley /*@
4115e87a4003SBarry Smith   DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM.
4116b21d0597SMatthew G Knepley 
4117b21d0597SMatthew G Knepley   Input Parameters:
4118b21d0597SMatthew G Knepley + dm - The DM
41195080bbdbSMatthew G Knepley - section - The PetscSection, or NULL
4120b21d0597SMatthew G Knepley 
4121b21d0597SMatthew G Knepley   Level: intermediate
4122b21d0597SMatthew G Knepley 
4123b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
4124b21d0597SMatthew G Knepley 
4125*92fd8e1eSJed Brown .seealso: DMGetGlobalSection(), DMSetLocalSection()
4126b21d0597SMatthew G Knepley @*/
4127e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section)
41280adebc6cSBarry Smith {
4129b21d0597SMatthew G Knepley   PetscErrorCode ierr;
4130b21d0597SMatthew G Knepley 
4131b21d0597SMatthew G Knepley   PetscFunctionBegin;
4132b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
41335080bbdbSMatthew G Knepley   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
41341d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
4135b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
4136b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
4137497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
4138f741bcd2SMatthew G. Knepley   if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->defaultSection, section);CHKERRQ(ierr);}
4139507e4973SMatthew G. Knepley #endif
4140b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4141b21d0597SMatthew G Knepley }
4142b21d0597SMatthew G Knepley 
414388ed4aceSMatthew G Knepley /*@
414488ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
414588ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
414688ed4aceSMatthew G Knepley 
414788ed4aceSMatthew G Knepley   Input Parameter:
414888ed4aceSMatthew G Knepley . dm - The DM
414988ed4aceSMatthew G Knepley 
415088ed4aceSMatthew G Knepley   Output Parameter:
415188ed4aceSMatthew G Knepley . sf - The PetscSF
415288ed4aceSMatthew G Knepley 
415388ed4aceSMatthew G Knepley   Level: intermediate
415488ed4aceSMatthew G Knepley 
415588ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
415688ed4aceSMatthew G Knepley 
415788ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
415888ed4aceSMatthew G Knepley @*/
41590adebc6cSBarry Smith PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf)
41600adebc6cSBarry Smith {
416188ed4aceSMatthew G Knepley   PetscInt       nroots;
416288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
416388ed4aceSMatthew G Knepley 
416488ed4aceSMatthew G Knepley   PetscFunctionBegin;
416588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
416688ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
416733907cc2SStefano Zampini   if (!dm->defaultSF) {
416833907cc2SStefano Zampini     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->defaultSF);CHKERRQ(ierr);
416933907cc2SStefano Zampini   }
41700298fd71SBarry Smith   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
417188ed4aceSMatthew G Knepley   if (nroots < 0) {
417288ed4aceSMatthew G Knepley     PetscSection section, gSection;
417388ed4aceSMatthew G Knepley 
4174*92fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
417531ea6d37SMatthew G Knepley     if (section) {
4176e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr);
417788ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
417831ea6d37SMatthew G Knepley     } else {
41790298fd71SBarry Smith       *sf = NULL;
418031ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
418131ea6d37SMatthew G Knepley     }
418288ed4aceSMatthew G Knepley   }
418388ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
418488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
418588ed4aceSMatthew G Knepley }
418688ed4aceSMatthew G Knepley 
418788ed4aceSMatthew G Knepley /*@
418888ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
418988ed4aceSMatthew G Knepley 
419088ed4aceSMatthew G Knepley   Input Parameters:
419188ed4aceSMatthew G Knepley + dm - The DM
419288ed4aceSMatthew G Knepley - sf - The PetscSF
419388ed4aceSMatthew G Knepley 
419488ed4aceSMatthew G Knepley   Level: intermediate
419588ed4aceSMatthew G Knepley 
419688ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
419788ed4aceSMatthew G Knepley 
419888ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
419988ed4aceSMatthew G Knepley @*/
42000adebc6cSBarry Smith PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf)
42010adebc6cSBarry Smith {
420288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
420388ed4aceSMatthew G Knepley 
420488ed4aceSMatthew G Knepley   PetscFunctionBegin;
420588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4206b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
420733907cc2SStefano Zampini   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
420888ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
420988ed4aceSMatthew G Knepley   dm->defaultSF = sf;
421088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
421188ed4aceSMatthew G Knepley }
421288ed4aceSMatthew G Knepley 
421388ed4aceSMatthew G Knepley /*@C
421488ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
421588ed4aceSMatthew G Knepley   describing the data layout.
421688ed4aceSMatthew G Knepley 
421788ed4aceSMatthew G Knepley   Input Parameters:
421888ed4aceSMatthew G Knepley + dm - The DM
421988ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
422088ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
422188ed4aceSMatthew G Knepley 
422288ed4aceSMatthew G Knepley   Level: intermediate
422388ed4aceSMatthew G Knepley 
422488ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
422588ed4aceSMatthew G Knepley @*/
422688ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
422788ed4aceSMatthew G Knepley {
422882f516ccSBarry Smith   MPI_Comm       comm;
422988ed4aceSMatthew G Knepley   PetscLayout    layout;
423088ed4aceSMatthew G Knepley   const PetscInt *ranges;
423188ed4aceSMatthew G Knepley   PetscInt       *local;
423288ed4aceSMatthew G Knepley   PetscSFNode    *remote;
4233ecd73843SMatthew G. Knepley   PetscInt       pStart, pEnd, p, nroots, nleaves = 0, l;
423488ed4aceSMatthew G Knepley   PetscMPIInt    size, rank;
423588ed4aceSMatthew G Knepley   PetscErrorCode ierr;
423688ed4aceSMatthew G Knepley 
423788ed4aceSMatthew G Knepley   PetscFunctionBegin;
423888ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4239367003a6SStefano Zampini   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
424088ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
424188ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
424288ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
424388ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
424488ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
424588ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
424688ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
424788ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
424888ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4249ecd73843SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
42506636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
425188ed4aceSMatthew G Knepley 
42526636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
42536636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4254235fbf56SMatthew 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));
42556636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
425688ed4aceSMatthew G Knepley   }
4257785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr);
4258785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr);
425988ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
42601f588964SMatthew G Knepley     const PetscInt *cind;
42616636e97aSMatthew G Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
426288ed4aceSMatthew G Knepley 
426388ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
426488ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
426588ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
426688ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
426788ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
42686636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
426988ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
42706636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
42716636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
42726636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
4273057b4bcdSMatthew 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);
42746636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
42756636e97aSMatthew G Knepley     }
427688ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
427788ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
427888ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
427988ed4aceSMatthew G Knepley     }
428088ed4aceSMatthew G Knepley     if (gdof < 0) {
42816636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
428288ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
428388ed4aceSMatthew G Knepley 
428405376888SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
428531d3f06eSJed Brown         if (r < 0) r = -(r+2);
428605376888SMatthew 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);
428788ed4aceSMatthew G Knepley         remote[l].rank  = r;
428888ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
428988ed4aceSMatthew G Knepley       }
429088ed4aceSMatthew G Knepley     } else {
42916636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
429288ed4aceSMatthew G Knepley         remote[l].rank  = rank;
429388ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
429488ed4aceSMatthew G Knepley       }
429588ed4aceSMatthew G Knepley     }
429688ed4aceSMatthew G Knepley   }
42976636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
429888ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
429988ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
430088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
430188ed4aceSMatthew G Knepley }
4302af122d2aSMatthew G Knepley 
4303b21d0597SMatthew G Knepley /*@
4304b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
4305b21d0597SMatthew G Knepley 
4306b21d0597SMatthew G Knepley   Input Parameter:
4307b21d0597SMatthew G Knepley . dm - The DM
4308b21d0597SMatthew G Knepley 
4309b21d0597SMatthew G Knepley   Output Parameter:
4310b21d0597SMatthew G Knepley . sf - The PetscSF
4311b21d0597SMatthew G Knepley 
4312b21d0597SMatthew G Knepley   Level: intermediate
4313b21d0597SMatthew G Knepley 
4314b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
4315b21d0597SMatthew G Knepley 
4316057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
4317b21d0597SMatthew G Knepley @*/
43180adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf)
43190adebc6cSBarry Smith {
4320b21d0597SMatthew G Knepley   PetscFunctionBegin;
4321b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4322b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
4323b21d0597SMatthew G Knepley   *sf = dm->sf;
4324b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4325b21d0597SMatthew G Knepley }
4326b21d0597SMatthew G Knepley 
4327057b4bcdSMatthew G Knepley /*@
4328057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
4329057b4bcdSMatthew G Knepley 
4330057b4bcdSMatthew G Knepley   Input Parameters:
4331057b4bcdSMatthew G Knepley + dm - The DM
4332057b4bcdSMatthew G Knepley - sf - The PetscSF
4333057b4bcdSMatthew G Knepley 
4334057b4bcdSMatthew G Knepley   Level: intermediate
4335057b4bcdSMatthew G Knepley 
4336057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
4337057b4bcdSMatthew G Knepley @*/
43380adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf)
43390adebc6cSBarry Smith {
4340057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
4341057b4bcdSMatthew G Knepley 
4342057b4bcdSMatthew G Knepley   PetscFunctionBegin;
4343057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4344b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
4345057b4bcdSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
434633907cc2SStefano Zampini   ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
4347057b4bcdSMatthew G Knepley   dm->sf = sf;
4348057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
4349057b4bcdSMatthew G Knepley }
4350057b4bcdSMatthew G Knepley 
435134aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc)
435234aa8a36SMatthew G. Knepley {
435334aa8a36SMatthew G. Knepley   PetscClassId   id;
435434aa8a36SMatthew G. Knepley   PetscErrorCode ierr;
435534aa8a36SMatthew G. Knepley 
435634aa8a36SMatthew G. Knepley   PetscFunctionBegin;
435734aa8a36SMatthew G. Knepley   ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
435834aa8a36SMatthew G. Knepley   if (id == PETSCFE_CLASSID) {
435934aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
436034aa8a36SMatthew G. Knepley   } else if (id == PETSCFV_CLASSID) {
436134aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr);
436217c1d62eSMatthew G. Knepley   } else {
436317c1d62eSMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
436434aa8a36SMatthew G. Knepley   }
436534aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
436634aa8a36SMatthew G. Knepley }
436734aa8a36SMatthew G. Knepley 
436844a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew)
436944a7f3ddSMatthew G. Knepley {
437044a7f3ddSMatthew G. Knepley   RegionField   *tmpr;
437144a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf, f;
437244a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
437344a7f3ddSMatthew G. Knepley 
437444a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
437544a7f3ddSMatthew G. Knepley   if (Nf >= NfNew) PetscFunctionReturn(0);
437644a7f3ddSMatthew G. Knepley   ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr);
437744a7f3ddSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f];
437844a7f3ddSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL;}
437944a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
438044a7f3ddSMatthew G. Knepley   dm->Nf     = NfNew;
438144a7f3ddSMatthew G. Knepley   dm->fields = tmpr;
438244a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
438344a7f3ddSMatthew G. Knepley }
438444a7f3ddSMatthew G. Knepley 
438544a7f3ddSMatthew G. Knepley /*@
438644a7f3ddSMatthew G. Knepley   DMClearFields - Remove all fields from the DM
438744a7f3ddSMatthew G. Knepley 
4388d083f849SBarry Smith   Logically collective on dm
438944a7f3ddSMatthew G. Knepley 
439044a7f3ddSMatthew G. Knepley   Input Parameter:
439144a7f3ddSMatthew G. Knepley . dm - The DM
439244a7f3ddSMatthew G. Knepley 
439344a7f3ddSMatthew G. Knepley   Level: intermediate
439444a7f3ddSMatthew G. Knepley 
439544a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField()
439644a7f3ddSMatthew G. Knepley @*/
439744a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm)
439844a7f3ddSMatthew G. Knepley {
439944a7f3ddSMatthew G. Knepley   PetscInt       f;
440044a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
440144a7f3ddSMatthew G. Knepley 
440244a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
440344a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
440444a7f3ddSMatthew G. Knepley   for (f = 0; f < dm->Nf; ++f) {
440544a7f3ddSMatthew G. Knepley     ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
440644a7f3ddSMatthew G. Knepley     ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
440744a7f3ddSMatthew G. Knepley   }
440844a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
440944a7f3ddSMatthew G. Knepley   dm->fields = NULL;
441044a7f3ddSMatthew G. Knepley   dm->Nf     = 0;
441144a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
441244a7f3ddSMatthew G. Knepley }
441344a7f3ddSMatthew G. Knepley 
4414689b5837SMatthew G. Knepley /*@
4415689b5837SMatthew G. Knepley   DMGetNumFields - Get the number of fields in the DM
4416689b5837SMatthew G. Knepley 
4417689b5837SMatthew G. Knepley   Not collective
4418689b5837SMatthew G. Knepley 
4419689b5837SMatthew G. Knepley   Input Parameter:
4420689b5837SMatthew G. Knepley . dm - The DM
4421689b5837SMatthew G. Knepley 
4422689b5837SMatthew G. Knepley   Output Parameter:
4423689b5837SMatthew G. Knepley . Nf - The number of fields
4424689b5837SMatthew G. Knepley 
4425689b5837SMatthew G. Knepley   Level: intermediate
4426689b5837SMatthew G. Knepley 
4427689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField()
4428689b5837SMatthew G. Knepley @*/
44290f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
44300f21e855SMatthew G. Knepley {
44310f21e855SMatthew G. Knepley   PetscFunctionBegin;
44320f21e855SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4433534a8f05SLisandro Dalcin   PetscValidIntPointer(numFields, 2);
443444a7f3ddSMatthew G. Knepley   *numFields = dm->Nf;
4435af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4436af122d2aSMatthew G Knepley }
4437af122d2aSMatthew G Knepley 
4438689b5837SMatthew G. Knepley /*@
4439689b5837SMatthew G. Knepley   DMSetNumFields - Set the number of fields in the DM
4440689b5837SMatthew G. Knepley 
4441d083f849SBarry Smith   Logically collective on dm
4442689b5837SMatthew G. Knepley 
4443689b5837SMatthew G. Knepley   Input Parameters:
4444689b5837SMatthew G. Knepley + dm - The DM
4445689b5837SMatthew G. Knepley - Nf - The number of fields
4446689b5837SMatthew G. Knepley 
4447689b5837SMatthew G. Knepley   Level: intermediate
4448689b5837SMatthew G. Knepley 
4449689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField()
4450689b5837SMatthew G. Knepley @*/
4451af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
4452af122d2aSMatthew G Knepley {
44530f21e855SMatthew G. Knepley   PetscInt       Nf, f;
4454af122d2aSMatthew G Knepley   PetscErrorCode ierr;
4455af122d2aSMatthew G Knepley 
4456af122d2aSMatthew G Knepley   PetscFunctionBegin;
4457af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
445844a7f3ddSMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
44590f21e855SMatthew G. Knepley   for (f = Nf; f < numFields; ++f) {
44600f21e855SMatthew G. Knepley     PetscContainer obj;
44610f21e855SMatthew G. Knepley 
44620f21e855SMatthew G. Knepley     ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr);
446344a7f3ddSMatthew G. Knepley     ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr);
44640f21e855SMatthew G. Knepley     ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr);
4465af122d2aSMatthew G Knepley   }
4466af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4467af122d2aSMatthew G Knepley }
4468af122d2aSMatthew G Knepley 
4469c1929be8SMatthew G. Knepley /*@
4470c1929be8SMatthew G. Knepley   DMGetField - Return the discretization object for a given DM field
4471c1929be8SMatthew G. Knepley 
4472c1929be8SMatthew G. Knepley   Not collective
4473c1929be8SMatthew G. Knepley 
4474c1929be8SMatthew G. Knepley   Input Parameters:
4475c1929be8SMatthew G. Knepley + dm - The DM
4476c1929be8SMatthew G. Knepley - f  - The field number
4477c1929be8SMatthew G. Knepley 
447844a7f3ddSMatthew G. Knepley   Output Parameters:
447944a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh
448044a7f3ddSMatthew G. Knepley - field - The discretization object
4481c1929be8SMatthew G. Knepley 
448244a7f3ddSMatthew G. Knepley   Level: intermediate
4483c1929be8SMatthew G. Knepley 
448444a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField()
4485c1929be8SMatthew G. Knepley @*/
448644a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field)
4487af122d2aSMatthew G Knepley {
4488af122d2aSMatthew G Knepley   PetscFunctionBegin;
4489af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
449044a7f3ddSMatthew G. Knepley   PetscValidPointer(field, 3);
449144a7f3ddSMatthew 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);
449244a7f3ddSMatthew G. Knepley   if (label) *label = dm->fields[f].label;
449344a7f3ddSMatthew G. Knepley   if (field) *field = dm->fields[f].disc;
4494decb47aaSMatthew G. Knepley   PetscFunctionReturn(0);
4495decb47aaSMatthew G. Knepley }
4496decb47aaSMatthew G. Knepley 
4497c1929be8SMatthew G. Knepley /*@
4498c1929be8SMatthew G. Knepley   DMSetField - Set the discretization object for a given DM field
4499c1929be8SMatthew G. Knepley 
4500d083f849SBarry Smith   Logically collective on dm
4501c1929be8SMatthew G. Knepley 
4502c1929be8SMatthew G. Knepley   Input Parameters:
4503c1929be8SMatthew G. Knepley + dm    - The DM
4504c1929be8SMatthew G. Knepley . f     - The field number
450544a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
4506c1929be8SMatthew G. Knepley - field - The discretization object
4507c1929be8SMatthew G. Knepley 
450844a7f3ddSMatthew G. Knepley   Level: intermediate
4509c1929be8SMatthew G. Knepley 
451044a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField()
4511c1929be8SMatthew G. Knepley @*/
451244a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field)
4513decb47aaSMatthew G. Knepley {
4514decb47aaSMatthew G. Knepley   PetscErrorCode ierr;
4515decb47aaSMatthew G. Knepley 
4516decb47aaSMatthew G. Knepley   PetscFunctionBegin;
4517decb47aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4518e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
451944a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 4);
4520e5e52638SMatthew G. Knepley   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
452144a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr);
452244a7f3ddSMatthew G. Knepley   ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
452344a7f3ddSMatthew G. Knepley   ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
452444a7f3ddSMatthew G. Knepley   dm->fields[f].label = label;
452544a7f3ddSMatthew G. Knepley   dm->fields[f].disc  = field;
452644a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
452744a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
452834aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr);
45292df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
453044a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
453144a7f3ddSMatthew G. Knepley }
453244a7f3ddSMatthew G. Knepley 
453344a7f3ddSMatthew G. Knepley /*@
453444a7f3ddSMatthew G. Knepley   DMAddField - Add the discretization object for the given DM field
453544a7f3ddSMatthew G. Knepley 
4536d083f849SBarry Smith   Logically collective on dm
453744a7f3ddSMatthew G. Knepley 
453844a7f3ddSMatthew G. Knepley   Input Parameters:
453944a7f3ddSMatthew G. Knepley + dm    - The DM
454044a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
454144a7f3ddSMatthew G. Knepley - field - The discretization object
454244a7f3ddSMatthew G. Knepley 
454344a7f3ddSMatthew G. Knepley   Level: intermediate
454444a7f3ddSMatthew G. Knepley 
454544a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField()
454644a7f3ddSMatthew G. Knepley @*/
454744a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field)
454844a7f3ddSMatthew G. Knepley {
454944a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf;
455044a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
455144a7f3ddSMatthew G. Knepley 
455244a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
455344a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
455444a7f3ddSMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
455544a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 3);
455644a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr);
455744a7f3ddSMatthew G. Knepley   dm->fields[Nf].label = label;
455844a7f3ddSMatthew G. Knepley   dm->fields[Nf].disc  = field;
455944a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
456044a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
456134aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr);
45622df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
4563af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4564af122d2aSMatthew G Knepley }
45656636e97aSMatthew G Knepley 
4566e5e52638SMatthew G. Knepley /*@
4567e5e52638SMatthew G. Knepley   DMCopyFields - Copy the discretizations for the DM into another DM
4568e5e52638SMatthew G. Knepley 
4569d083f849SBarry Smith   Collective on dm
4570e5e52638SMatthew G. Knepley 
4571e5e52638SMatthew G. Knepley   Input Parameter:
4572e5e52638SMatthew G. Knepley . dm - The DM
4573e5e52638SMatthew G. Knepley 
4574e5e52638SMatthew G. Knepley   Output Parameter:
4575e5e52638SMatthew G. Knepley . newdm - The DM
4576e5e52638SMatthew G. Knepley 
4577e5e52638SMatthew G. Knepley   Level: advanced
4578e5e52638SMatthew G. Knepley 
4579e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS()
4580e5e52638SMatthew G. Knepley @*/
4581e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm)
4582e5e52638SMatthew G. Knepley {
4583e5e52638SMatthew G. Knepley   PetscInt       Nf, f;
4584e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4585e5e52638SMatthew G. Knepley 
4586e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4587e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
4588e5e52638SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4589e5e52638SMatthew G. Knepley   ierr = DMClearFields(newdm);CHKERRQ(ierr);
4590e5e52638SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4591e5e52638SMatthew G. Knepley     DMLabel     label;
4592e5e52638SMatthew G. Knepley     PetscObject field;
459334aa8a36SMatthew G. Knepley     PetscBool   useCone, useClosure;
4594e5e52638SMatthew G. Knepley 
4595e5e52638SMatthew G. Knepley     ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr);
4596e5e52638SMatthew G. Knepley     ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr);
459734aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr);
459834aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr);
459934aa8a36SMatthew G. Knepley   }
460034aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
460134aa8a36SMatthew G. Knepley }
460234aa8a36SMatthew G. Knepley 
460334aa8a36SMatthew G. Knepley /*@
460434aa8a36SMatthew G. Knepley   DMGetAdjacency - Returns the flags for determining variable influence
460534aa8a36SMatthew G. Knepley 
460634aa8a36SMatthew G. Knepley   Not collective
460734aa8a36SMatthew G. Knepley 
460834aa8a36SMatthew G. Knepley   Input Parameters:
460934aa8a36SMatthew G. Knepley + dm - The DM object
461034aa8a36SMatthew G. Knepley - f  - The field number, or PETSC_DEFAULT for the default adjacency
461134aa8a36SMatthew G. Knepley 
461234aa8a36SMatthew G. Knepley   Output Parameter:
461334aa8a36SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
461434aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
461534aa8a36SMatthew G. Knepley 
461634aa8a36SMatthew G. Knepley   Notes:
461734aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
461834aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
461934aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4620979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
462134aa8a36SMatthew G. Knepley 
462234aa8a36SMatthew G. Knepley   Level: developer
462334aa8a36SMatthew G. Knepley 
462434aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField()
462534aa8a36SMatthew G. Knepley @*/
462634aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure)
462734aa8a36SMatthew G. Knepley {
462834aa8a36SMatthew G. Knepley   PetscFunctionBegin;
462934aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4630534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4631534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
463234aa8a36SMatthew G. Knepley   if (f < 0) {
463334aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->adjacency[0];
463434aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->adjacency[1];
463534aa8a36SMatthew G. Knepley   } else {
463634aa8a36SMatthew G. Knepley     PetscInt       Nf;
463734aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
463834aa8a36SMatthew G. Knepley 
463934aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
464034aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
464134aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->fields[f].adjacency[0];
464234aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->fields[f].adjacency[1];
464334aa8a36SMatthew G. Knepley   }
464434aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
464534aa8a36SMatthew G. Knepley }
464634aa8a36SMatthew G. Knepley 
464734aa8a36SMatthew G. Knepley /*@
464834aa8a36SMatthew G. Knepley   DMSetAdjacency - Set the flags for determining variable influence
464934aa8a36SMatthew G. Knepley 
465034aa8a36SMatthew G. Knepley   Not collective
465134aa8a36SMatthew G. Knepley 
465234aa8a36SMatthew G. Knepley   Input Parameters:
465334aa8a36SMatthew G. Knepley + dm         - The DM object
465434aa8a36SMatthew G. Knepley . f          - The field number
465534aa8a36SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
465634aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
465734aa8a36SMatthew G. Knepley 
465834aa8a36SMatthew G. Knepley   Notes:
465934aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
466034aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
466134aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4662979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
466334aa8a36SMatthew G. Knepley 
466434aa8a36SMatthew G. Knepley   Level: developer
466534aa8a36SMatthew G. Knepley 
466634aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField()
466734aa8a36SMatthew G. Knepley @*/
466834aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure)
466934aa8a36SMatthew G. Knepley {
467034aa8a36SMatthew G. Knepley   PetscFunctionBegin;
467134aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
467234aa8a36SMatthew G. Knepley   if (f < 0) {
467334aa8a36SMatthew G. Knepley     dm->adjacency[0] = useCone;
467434aa8a36SMatthew G. Knepley     dm->adjacency[1] = useClosure;
467534aa8a36SMatthew G. Knepley   } else {
467634aa8a36SMatthew G. Knepley     PetscInt       Nf;
467734aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
467834aa8a36SMatthew G. Knepley 
467934aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
468034aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
468134aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[0] = useCone;
468234aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[1] = useClosure;
4683e5e52638SMatthew G. Knepley   }
4684e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4685e5e52638SMatthew G. Knepley }
4686e5e52638SMatthew G. Knepley 
4687b0441da4SMatthew G. Knepley /*@
4688b0441da4SMatthew G. Knepley   DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined
4689b0441da4SMatthew G. Knepley 
4690b0441da4SMatthew G. Knepley   Not collective
4691b0441da4SMatthew G. Knepley 
4692b0441da4SMatthew G. Knepley   Input Parameters:
4693b0441da4SMatthew G. Knepley . dm - The DM object
4694b0441da4SMatthew G. Knepley 
4695b0441da4SMatthew G. Knepley   Output Parameter:
4696b0441da4SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
4697b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4698b0441da4SMatthew G. Knepley 
4699b0441da4SMatthew G. Knepley   Notes:
4700b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4701b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4702b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4703b0441da4SMatthew G. Knepley 
4704b0441da4SMatthew G. Knepley   Level: developer
4705b0441da4SMatthew G. Knepley 
4706b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField()
4707b0441da4SMatthew G. Knepley @*/
4708b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure)
4709b0441da4SMatthew G. Knepley {
4710b0441da4SMatthew G. Knepley   PetscInt       Nf;
4711b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4712b0441da4SMatthew G. Knepley 
4713b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4714b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4715534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4716534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
4717b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4718b0441da4SMatthew G. Knepley   if (!Nf) {
4719b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4720b0441da4SMatthew G. Knepley   } else {
4721b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4722b0441da4SMatthew G. Knepley   }
4723b0441da4SMatthew G. Knepley   PetscFunctionReturn(0);
4724b0441da4SMatthew G. Knepley }
4725b0441da4SMatthew G. Knepley 
4726b0441da4SMatthew G. Knepley /*@
4727b0441da4SMatthew G. Knepley   DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined
4728b0441da4SMatthew G. Knepley 
4729b0441da4SMatthew G. Knepley   Not collective
4730b0441da4SMatthew G. Knepley 
4731b0441da4SMatthew G. Knepley   Input Parameters:
4732b0441da4SMatthew G. Knepley + dm         - The DM object
4733b0441da4SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
4734b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4735b0441da4SMatthew G. Knepley 
4736b0441da4SMatthew G. Knepley   Notes:
4737b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4738b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4739b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4740b0441da4SMatthew G. Knepley 
4741b0441da4SMatthew G. Knepley   Level: developer
4742b0441da4SMatthew G. Knepley 
4743b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField()
4744b0441da4SMatthew G. Knepley @*/
4745b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure)
4746b0441da4SMatthew G. Knepley {
4747b0441da4SMatthew G. Knepley   PetscInt       Nf;
4748b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4749b0441da4SMatthew G. Knepley 
4750b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4751b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4752b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4753b0441da4SMatthew G. Knepley   if (!Nf) {
4754b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4755b0441da4SMatthew G. Knepley   } else {
4756b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4757e5e52638SMatthew G. Knepley   }
4758e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4759e5e52638SMatthew G. Knepley }
4760e5e52638SMatthew G. Knepley 
4761e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew)
4762e5e52638SMatthew G. Knepley {
4763e5e52638SMatthew G. Knepley   DMSpace       *tmpd;
4764e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
4765e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4766e5e52638SMatthew G. Knepley 
4767e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4768e5e52638SMatthew G. Knepley   if (Nds >= NdsNew) PetscFunctionReturn(0);
4769e5e52638SMatthew G. Knepley   ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr);
4770e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s];
4771b3cf3223SMatthew G. Knepley   for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;}
4772e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4773e5e52638SMatthew G. Knepley   dm->Nds   = NdsNew;
4774e5e52638SMatthew G. Knepley   dm->probs = tmpd;
4775e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4776e5e52638SMatthew G. Knepley }
4777e5e52638SMatthew G. Knepley 
4778e5e52638SMatthew G. Knepley /*@
4779e5e52638SMatthew G. Knepley   DMGetNumDS - Get the number of discrete systems in the DM
4780e5e52638SMatthew G. Knepley 
4781e5e52638SMatthew G. Knepley   Not collective
4782e5e52638SMatthew G. Knepley 
4783e5e52638SMatthew G. Knepley   Input Parameter:
4784e5e52638SMatthew G. Knepley . dm - The DM
4785e5e52638SMatthew G. Knepley 
4786e5e52638SMatthew G. Knepley   Output Parameter:
4787e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects
4788e5e52638SMatthew G. Knepley 
4789e5e52638SMatthew G. Knepley   Level: intermediate
4790e5e52638SMatthew G. Knepley 
4791e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS()
4792e5e52638SMatthew G. Knepley @*/
4793e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds)
4794e5e52638SMatthew G. Knepley {
4795e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4796e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4797534a8f05SLisandro Dalcin   PetscValidIntPointer(Nds, 2);
4798e5e52638SMatthew G. Knepley   *Nds = dm->Nds;
4799e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4800e5e52638SMatthew G. Knepley }
4801e5e52638SMatthew G. Knepley 
4802e5e52638SMatthew G. Knepley /*@
4803e5e52638SMatthew G. Knepley   DMClearDS - Remove all discrete systems from the DM
4804e5e52638SMatthew G. Knepley 
4805d083f849SBarry Smith   Logically collective on dm
4806e5e52638SMatthew G. Knepley 
4807e5e52638SMatthew G. Knepley   Input Parameter:
4808e5e52638SMatthew G. Knepley . dm - The DM
4809e5e52638SMatthew G. Knepley 
4810e5e52638SMatthew G. Knepley   Level: intermediate
4811e5e52638SMatthew G. Knepley 
4812e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField()
4813e5e52638SMatthew G. Knepley @*/
4814e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm)
4815e5e52638SMatthew G. Knepley {
4816e5e52638SMatthew G. Knepley   PetscInt       s;
4817e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4818e5e52638SMatthew G. Knepley 
4819e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4820e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4821e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4822e5e52638SMatthew G. Knepley     ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
4823e5e52638SMatthew G. Knepley     ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr);
4824b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr);
4825e5e52638SMatthew G. Knepley   }
4826e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4827e5e52638SMatthew G. Knepley   dm->probs = NULL;
4828e5e52638SMatthew G. Knepley   dm->Nds   = 0;
4829e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4830e5e52638SMatthew G. Knepley }
4831e5e52638SMatthew G. Knepley 
4832e5e52638SMatthew G. Knepley /*@
4833e5e52638SMatthew G. Knepley   DMGetDS - Get the default PetscDS
4834e5e52638SMatthew G. Knepley 
4835e5e52638SMatthew G. Knepley   Not collective
4836e5e52638SMatthew G. Knepley 
4837e5e52638SMatthew G. Knepley   Input Parameter:
4838e5e52638SMatthew G. Knepley . dm    - The DM
4839e5e52638SMatthew G. Knepley 
4840e5e52638SMatthew G. Knepley   Output Parameter:
4841e5e52638SMatthew G. Knepley . prob - The default PetscDS
4842e5e52638SMatthew G. Knepley 
4843e5e52638SMatthew G. Knepley   Level: intermediate
4844e5e52638SMatthew G. Knepley 
4845e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS()
4846e5e52638SMatthew G. Knepley @*/
4847e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob)
4848e5e52638SMatthew G. Knepley {
4849b0143b4dSMatthew G. Knepley   PetscErrorCode ierr;
4850b0143b4dSMatthew G. Knepley 
4851e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4852e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4853e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 2);
4854b0143b4dSMatthew G. Knepley   if (dm->Nds <= 0) {
4855b0143b4dSMatthew G. Knepley     PetscDS ds;
4856b0143b4dSMatthew G. Knepley 
4857b0143b4dSMatthew G. Knepley     ierr = PetscDSCreate(PetscObjectComm((PetscObject) dm), &ds);CHKERRQ(ierr);
4858b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr);
4859b0143b4dSMatthew G. Knepley     ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
4860b0143b4dSMatthew G. Knepley   }
4861b0143b4dSMatthew G. Knepley   *prob = dm->probs[0].ds;
4862e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4863e5e52638SMatthew G. Knepley }
4864e5e52638SMatthew G. Knepley 
4865e5e52638SMatthew G. Knepley /*@
4866e5e52638SMatthew G. Knepley   DMGetCellDS - Get the PetscDS defined on a given cell
4867e5e52638SMatthew G. Knepley 
4868e5e52638SMatthew G. Knepley   Not collective
4869e5e52638SMatthew G. Knepley 
4870e5e52638SMatthew G. Knepley   Input Parameters:
4871e5e52638SMatthew G. Knepley + dm    - The DM
4872e5e52638SMatthew G. Knepley - point - Cell for the DS
4873e5e52638SMatthew G. Knepley 
4874e5e52638SMatthew G. Knepley   Output Parameter:
4875e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell
4876e5e52638SMatthew G. Knepley 
4877e5e52638SMatthew G. Knepley   Level: developer
4878e5e52638SMatthew G. Knepley 
4879b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS()
4880e5e52638SMatthew G. Knepley @*/
4881e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob)
4882e5e52638SMatthew G. Knepley {
4883e5e52638SMatthew G. Knepley   PetscDS        probDef = NULL;
4884e5e52638SMatthew G. Knepley   PetscInt       s;
4885e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4886e5e52638SMatthew G. Knepley 
4887e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4888e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4889e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 3);
4890e5e52638SMatthew G. Knepley   *prob = NULL;
4891e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4892e5e52638SMatthew G. Knepley     PetscInt val;
4893e5e52638SMatthew G. Knepley 
4894e5e52638SMatthew G. Knepley     if (!dm->probs[s].label) {probDef = dm->probs[s].ds;}
4895e5e52638SMatthew G. Knepley     else {
4896e5e52638SMatthew G. Knepley       ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr);
4897e5e52638SMatthew G. Knepley       if (val >= 0) {*prob = dm->probs[s].ds; break;}
4898e5e52638SMatthew G. Knepley     }
4899e5e52638SMatthew G. Knepley   }
4900e5e52638SMatthew G. Knepley   if (!*prob) *prob = probDef;
4901e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4902e5e52638SMatthew G. Knepley }
4903e5e52638SMatthew G. Knepley 
4904e5e52638SMatthew G. Knepley /*@
4905e5e52638SMatthew G. Knepley   DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel
4906e5e52638SMatthew G. Knepley 
4907e5e52638SMatthew G. Knepley   Not collective
4908e5e52638SMatthew G. Knepley 
4909e5e52638SMatthew G. Knepley   Input Parameters:
4910e5e52638SMatthew G. Knepley + dm    - The DM
4911e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh
4912e5e52638SMatthew G. Knepley 
4913b3cf3223SMatthew G. Knepley   Output Parameters:
4914b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL
4915b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL
4916e5e52638SMatthew G. Knepley 
4917e5e52638SMatthew G. Knepley   Note: If the label is missing, this function returns an error
4918e5e52638SMatthew G. Knepley 
4919e5e52638SMatthew G. Knepley   Level: advanced
4920e5e52638SMatthew G. Knepley 
4921e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
4922e5e52638SMatthew G. Knepley @*/
4923b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds)
4924e5e52638SMatthew G. Knepley {
4925e5e52638SMatthew G. Knepley   PetscInt Nds = dm->Nds, s;
4926e5e52638SMatthew G. Knepley 
4927e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4928e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4929e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
4930b3cf3223SMatthew G. Knepley   if (fields) {PetscValidPointer(fields, 3); *fields = NULL;}
4931b3cf3223SMatthew G. Knepley   if (ds)     {PetscValidPointer(ds, 4);     *ds     = NULL;}
4932e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
4933b3cf3223SMatthew G. Knepley     if (dm->probs[s].label == label) {
4934b3cf3223SMatthew G. Knepley       if (fields) *fields = dm->probs[s].fields;
4935b3cf3223SMatthew G. Knepley       if (ds)     *ds     = dm->probs[s].ds;
4936b3cf3223SMatthew G. Knepley       PetscFunctionReturn(0);
4937b3cf3223SMatthew G. Knepley     }
4938e5e52638SMatthew G. Knepley   }
49392df9ee95SMatthew G. Knepley   PetscFunctionReturn(0);
4940e5e52638SMatthew G. Knepley }
4941e5e52638SMatthew G. Knepley 
4942e5e52638SMatthew G. Knepley /*@
4943e5e52638SMatthew G. Knepley   DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number
4944e5e52638SMatthew G. Knepley 
4945e5e52638SMatthew G. Knepley   Not collective
4946e5e52638SMatthew G. Knepley 
4947e5e52638SMatthew G. Knepley   Input Parameters:
4948e5e52638SMatthew G. Knepley + dm  - The DM
4949e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds)
4950e5e52638SMatthew G. Knepley 
4951e5e52638SMatthew G. Knepley   Output Parameters:
4952b3cf3223SMatthew G. Knepley + label  - The region label, or NULL
4953b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL
4954b3cf3223SMatthew G. Knepley - prob   - The PetscDS defined on the given region, or NULL
4955e5e52638SMatthew G. Knepley 
4956e5e52638SMatthew G. Knepley   Level: advanced
4957e5e52638SMatthew G. Knepley 
4958e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
4959e5e52638SMatthew G. Knepley @*/
4960b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds)
4961e5e52638SMatthew G. Knepley {
4962e5e52638SMatthew G. Knepley   PetscInt       Nds;
4963e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4964e5e52638SMatthew G. Knepley 
4965e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4966e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4967e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
4968e5e52638SMatthew 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);
4969e5e52638SMatthew G. Knepley   if (label) {
4970e5e52638SMatthew G. Knepley     PetscValidPointer(label, 3);
4971e5e52638SMatthew G. Knepley     *label = dm->probs[num].label;
4972e5e52638SMatthew G. Knepley   }
4973b3cf3223SMatthew G. Knepley   if (fields) {
4974b3cf3223SMatthew G. Knepley     PetscValidPointer(fields, 4);
4975b3cf3223SMatthew G. Knepley     *fields = dm->probs[num].fields;
4976b3cf3223SMatthew G. Knepley   }
4977e5e52638SMatthew G. Knepley   if (ds) {
4978b3cf3223SMatthew G. Knepley     PetscValidPointer(ds, 5);
4979e5e52638SMatthew G. Knepley     *ds = dm->probs[num].ds;
4980e5e52638SMatthew G. Knepley   }
4981e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4982e5e52638SMatthew G. Knepley }
4983e5e52638SMatthew G. Knepley 
4984e5e52638SMatthew G. Knepley /*@
4985e5e52638SMatthew G. Knepley   DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel
4986e5e52638SMatthew G. Knepley 
4987d083f849SBarry Smith   Collective on dm
4988e5e52638SMatthew G. Knepley 
4989e5e52638SMatthew G. Knepley   Input Parameters:
4990e5e52638SMatthew G. Knepley + dm     - The DM
4991e5e52638SMatthew G. Knepley . label  - The DMLabel defining the mesh region, or NULL for the entire mesh
4992b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields
4993e5e52638SMatthew G. Knepley - prob   - The PetscDS defined on the given cell
4994e5e52638SMatthew G. Knepley 
4995b3cf3223SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM. If DS is replaced,
4996b3cf3223SMatthew G. Knepley   the fields argument is ignored.
4997e5e52638SMatthew G. Knepley 
4998e5e52638SMatthew G. Knepley   Level: advanced
4999e5e52638SMatthew G. Knepley 
5000e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMGetDS(), DMGetCellDS()
5001e5e52638SMatthew G. Knepley @*/
5002b3cf3223SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds)
5003e5e52638SMatthew G. Knepley {
5004e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
5005e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5006e5e52638SMatthew G. Knepley 
5007e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5008e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5009e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
5010e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3);
5011e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5012e5e52638SMatthew G. Knepley     if (dm->probs[s].label == label) {
5013b3cf3223SMatthew G. Knepley       ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
5014e5e52638SMatthew G. Knepley       dm->probs[s].ds = ds;
5015e5e52638SMatthew G. Knepley       PetscFunctionReturn(0);
5016e5e52638SMatthew G. Knepley     }
5017e5e52638SMatthew G. Knepley   }
50181b5e6740SSatish Balay   ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr);
5019e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
5020b3cf3223SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr);
5021e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr);
5022e5e52638SMatthew G. Knepley   if (!label) {
5023e5e52638SMatthew G. Knepley     /* Put the NULL label at the front, so it is returned as the default */
5024e5e52638SMatthew G. Knepley     for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s];
5025e5e52638SMatthew G. Knepley     Nds = 0;
5026e5e52638SMatthew G. Knepley   }
5027e5e52638SMatthew G. Knepley   dm->probs[Nds].label  = label;
5028b3cf3223SMatthew G. Knepley   dm->probs[Nds].fields = fields;
5029e5e52638SMatthew G. Knepley   dm->probs[Nds].ds     = ds;
5030e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5031e5e52638SMatthew G. Knepley }
5032e5e52638SMatthew G. Knepley 
5033e5e52638SMatthew G. Knepley /*@
5034e5e52638SMatthew G. Knepley   DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM
5035e5e52638SMatthew G. Knepley 
5036d083f849SBarry Smith   Collective on dm
5037e5e52638SMatthew G. Knepley 
5038e5e52638SMatthew G. Knepley   Input Parameter:
5039e5e52638SMatthew G. Knepley . dm - The DM
5040e5e52638SMatthew G. Knepley 
5041e5e52638SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM.
5042e5e52638SMatthew G. Knepley 
5043e5e52638SMatthew G. Knepley   Level: intermediate
5044e5e52638SMatthew G. Knepley 
5045e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
5046e5e52638SMatthew G. Knepley @*/
5047e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm)
5048e5e52638SMatthew G. Knepley {
5049e5e52638SMatthew G. Knepley   MPI_Comm       comm;
5050e5e52638SMatthew G. Knepley   PetscDS        prob, probh = NULL;
5051b3cf3223SMatthew G. Knepley   PetscInt       dimEmbed, Nf = dm->Nf, f, s, field = 0, fieldh = 0;
5052e5e52638SMatthew G. Knepley   PetscBool      doSetup = PETSC_TRUE;
5053e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5054e5e52638SMatthew G. Knepley 
5055e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5056e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5057e5e52638SMatthew G. Knepley   if (!dm->fields) PetscFunctionReturn(0);
5058e5e52638SMatthew G. Knepley   /* Can only handle two label cases right now:
5059e5e52638SMatthew G. Knepley    1) NULL
5060e5e52638SMatthew G. Knepley    2) Hybrid cells
5061e5e52638SMatthew G. Knepley   */
5062e5e52638SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr);
5063e5e52638SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr);
5064e5e52638SMatthew G. Knepley   /* Create default DS */
5065b3cf3223SMatthew G. Knepley   ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
50662df9ee95SMatthew G. Knepley   if (!prob) {
5067b3cf3223SMatthew G. Knepley     IS        fields;
5068b3cf3223SMatthew G. Knepley     PetscInt *fld, nf;
5069b3cf3223SMatthew G. Knepley 
5070b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf;
5071b3cf3223SMatthew G. Knepley     ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr);
5072b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f;
507388f0c812SMatthew G. Knepley     ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
507488f0c812SMatthew G. Knepley     ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
507588f0c812SMatthew G. Knepley     ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
507688f0c812SMatthew G. Knepley     ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
507788f0c812SMatthew G. Knepley 
50782df9ee95SMatthew G. Knepley     ierr = PetscDSCreate(comm, &prob);CHKERRQ(ierr);
5079b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, fields, prob);CHKERRQ(ierr);
50802df9ee95SMatthew G. Knepley     ierr = PetscDSDestroy(&prob);CHKERRQ(ierr);
5081b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&fields);CHKERRQ(ierr);
5082b3cf3223SMatthew G. Knepley     ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
50832df9ee95SMatthew G. Knepley   }
5084e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(prob, dimEmbed);CHKERRQ(ierr);
5085e5e52638SMatthew G. Knepley   /* Optionally create hybrid DS */
5086b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5087e5e52638SMatthew G. Knepley     DMLabel  label = dm->fields[f].label;
5088e5e52638SMatthew G. Knepley     PetscInt lStart, lEnd;
5089e5e52638SMatthew G. Knepley 
5090e5e52638SMatthew G. Knepley     if (label) {
50910122748bSMatthew G. Knepley       DM        plex;
5092a2d47024SMatthew G. Knepley       IS        fields;
5093a2d47024SMatthew G. Knepley       PetscInt *fld;
50940122748bSMatthew G. Knepley       PetscInt  depth, pMax[4];
50950122748bSMatthew G. Knepley 
50960122748bSMatthew G. Knepley       ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr);
50970122748bSMatthew G. Knepley       ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr);
50980122748bSMatthew 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);
50990122748bSMatthew G. Knepley       ierr = DMDestroy(&plex);CHKERRQ(ierr);
51000122748bSMatthew G. Knepley 
5101e5e52638SMatthew G. Knepley       ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr);
5102e5e52638SMatthew G. Knepley       if (lStart < pMax[depth]) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only support labels over hybrid cells right now");
5103e5e52638SMatthew G. Knepley       ierr = PetscDSCreate(comm, &probh);CHKERRQ(ierr);
5104a2d47024SMatthew G. Knepley       ierr = PetscMalloc1(1, &fld);CHKERRQ(ierr);
5105a2d47024SMatthew G. Knepley       fld[0] = f;
5106a2d47024SMatthew G. Knepley       ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
5107a2d47024SMatthew G. Knepley       ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
5108a2d47024SMatthew G. Knepley       ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
5109a2d47024SMatthew G. Knepley       ierr = ISGeneralSetIndices(fields, 1, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
5110a2d47024SMatthew G. Knepley       ierr = DMSetRegionDS(dm, label, fields, probh);CHKERRQ(ierr);
5111a2d47024SMatthew G. Knepley       ierr = ISDestroy(&fields);CHKERRQ(ierr);
5112e5e52638SMatthew G. Knepley       ierr = PetscDSSetHybrid(probh, PETSC_TRUE);CHKERRQ(ierr);
5113e5e52638SMatthew G. Knepley       ierr = PetscDSSetCoordinateDimension(probh, dimEmbed);CHKERRQ(ierr);
5114e5e52638SMatthew G. Knepley       break;
5115e5e52638SMatthew G. Knepley     }
5116e5e52638SMatthew G. Knepley   }
5117e5e52638SMatthew G. Knepley   /* Set fields in DSes */
5118b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5119e5e52638SMatthew G. Knepley     DMLabel     label = dm->fields[f].label;
5120e5e52638SMatthew G. Knepley     PetscObject disc  = dm->fields[f].disc;
5121e5e52638SMatthew G. Knepley 
5122e5e52638SMatthew G. Knepley     if (!label) {
5123e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(prob,  field++,  disc);CHKERRQ(ierr);
5124e5e52638SMatthew G. Knepley       if (probh) {
5125e5e52638SMatthew G. Knepley         PetscFE subfe;
5126e5e52638SMatthew G. Knepley 
5127e5e52638SMatthew G. Knepley         ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, &subfe);CHKERRQ(ierr);
5128e5e52638SMatthew G. Knepley         ierr = PetscDSSetDiscretization(probh, fieldh++, (PetscObject) subfe);CHKERRQ(ierr);
5129e5e52638SMatthew G. Knepley       }
5130e5e52638SMatthew G. Knepley     } else {
5131e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(probh, fieldh++, disc);CHKERRQ(ierr);
5132e5e52638SMatthew G. Knepley     }
5133e5e52638SMatthew G. Knepley     /* We allow people to have placeholder fields and construct the Section by hand */
5134e5e52638SMatthew G. Knepley     {
5135e5e52638SMatthew G. Knepley       PetscClassId id;
5136e5e52638SMatthew G. Knepley 
5137e5e52638SMatthew G. Knepley       ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
5138e5e52638SMatthew G. Knepley       if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE;
5139e5e52638SMatthew G. Knepley     }
5140e5e52638SMatthew G. Knepley   }
5141e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&probh);CHKERRQ(ierr);
5142e5e52638SMatthew G. Knepley   /* Setup DSes */
5143e5e52638SMatthew G. Knepley   if (doSetup) {
5144e5e52638SMatthew G. Knepley     for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);}
5145e5e52638SMatthew G. Knepley   }
5146e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5147e5e52638SMatthew G. Knepley }
5148e5e52638SMatthew G. Knepley 
5149e5e52638SMatthew G. Knepley /*@
5150e5e52638SMatthew G. Knepley   DMCopyDS - Copy the discrete systems for the DM into another DM
5151e5e52638SMatthew G. Knepley 
5152d083f849SBarry Smith   Collective on dm
5153e5e52638SMatthew G. Knepley 
5154e5e52638SMatthew G. Knepley   Input Parameter:
5155e5e52638SMatthew G. Knepley . dm - The DM
5156e5e52638SMatthew G. Knepley 
5157e5e52638SMatthew G. Knepley   Output Parameter:
5158e5e52638SMatthew G. Knepley . newdm - The DM
5159e5e52638SMatthew G. Knepley 
5160e5e52638SMatthew G. Knepley   Level: advanced
5161e5e52638SMatthew G. Knepley 
5162e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
5163e5e52638SMatthew G. Knepley @*/
5164e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm)
5165e5e52638SMatthew G. Knepley {
5166e5e52638SMatthew G. Knepley   PetscInt       Nds, s;
5167e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5168e5e52638SMatthew G. Knepley 
5169e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5170e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5171e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
5172e5e52638SMatthew G. Knepley   ierr = DMClearDS(newdm);CHKERRQ(ierr);
5173e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5174e5e52638SMatthew G. Knepley     DMLabel label;
5175b3cf3223SMatthew G. Knepley     IS      fields;
5176e5e52638SMatthew G. Knepley     PetscDS ds;
5177e5e52638SMatthew G. Knepley 
5178b3cf3223SMatthew G. Knepley     ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr);
5179b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(newdm, label, fields, ds);CHKERRQ(ierr);
5180e5e52638SMatthew G. Knepley   }
5181e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5182e5e52638SMatthew G. Knepley }
5183e5e52638SMatthew G. Knepley 
5184e5e52638SMatthew G. Knepley /*@
5185e5e52638SMatthew G. Knepley   DMCopyDisc - Copy the fields and discrete systems for the DM into another DM
5186e5e52638SMatthew G. Knepley 
5187d083f849SBarry Smith   Collective on dm
5188e5e52638SMatthew G. Knepley 
5189e5e52638SMatthew G. Knepley   Input Parameter:
5190e5e52638SMatthew G. Knepley . dm - The DM
5191e5e52638SMatthew G. Knepley 
5192e5e52638SMatthew G. Knepley   Output Parameter:
5193e5e52638SMatthew G. Knepley . newdm - The DM
5194e5e52638SMatthew G. Knepley 
5195e5e52638SMatthew G. Knepley   Level: advanced
5196e5e52638SMatthew G. Knepley 
5197e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS()
5198e5e52638SMatthew G. Knepley @*/
5199e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm)
5200e5e52638SMatthew G. Knepley {
5201e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5202e5e52638SMatthew G. Knepley 
5203e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5204e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5205e5e52638SMatthew G. Knepley   ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr);
5206e5e52638SMatthew G. Knepley   ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr);
5207e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5208e5e52638SMatthew G. Knepley }
5209e5e52638SMatthew G. Knepley 
5210b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx)
5211b64e0483SPeter Brune {
5212b64e0483SPeter Brune   DM dm_coord,dmc_coord;
5213b64e0483SPeter Brune   PetscErrorCode ierr;
5214b64e0483SPeter Brune   Vec coords,ccoords;
52156dbf9973SLawrence Mitchell   Mat inject;
5216b64e0483SPeter Brune   PetscFunctionBegin;
5217b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
5218b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr);
5219b64e0483SPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
5220b64e0483SPeter Brune   ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr);
5221b64e0483SPeter Brune   if (coords && !ccoords) {
5222b64e0483SPeter Brune     ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr);
52236668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
52246dbf9973SLawrence Mitchell     ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr);
52252adcf181SLawrence Mitchell     ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr);
52266dbf9973SLawrence Mitchell     ierr = MatDestroy(&inject);CHKERRQ(ierr);
5227b64e0483SPeter Brune     ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr);
5228b64e0483SPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
5229b64e0483SPeter Brune   }
5230b64e0483SPeter Brune   PetscFunctionReturn(0);
5231b64e0483SPeter Brune }
5232b64e0483SPeter Brune 
523303dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx)
523403dadc2fSPeter Brune {
523503dadc2fSPeter Brune   DM dm_coord,subdm_coord;
523603dadc2fSPeter Brune   PetscErrorCode ierr;
523703dadc2fSPeter Brune   Vec coords,ccoords,clcoords;
523803dadc2fSPeter Brune   VecScatter *scat_i,*scat_g;
523903dadc2fSPeter Brune   PetscFunctionBegin;
524003dadc2fSPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
524103dadc2fSPeter Brune   ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr);
524203dadc2fSPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
524303dadc2fSPeter Brune   ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr);
524403dadc2fSPeter Brune   if (coords && !ccoords) {
524503dadc2fSPeter Brune     ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr);
52466668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
524703dadc2fSPeter Brune     ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr);
524824640c55SToby Isaac     ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr);
524903dadc2fSPeter Brune     ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr);
525003dadc2fSPeter Brune     ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
525103dadc2fSPeter Brune     ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
52521ed9ada7SJunchao Zhang     ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
525303dadc2fSPeter Brune     ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
525403dadc2fSPeter Brune     ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr);
525503dadc2fSPeter Brune     ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr);
525603dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr);
525703dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr);
525803dadc2fSPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
525903dadc2fSPeter Brune     ierr = VecDestroy(&clcoords);CHKERRQ(ierr);
526003dadc2fSPeter Brune     ierr = PetscFree(scat_i);CHKERRQ(ierr);
526103dadc2fSPeter Brune     ierr = PetscFree(scat_g);CHKERRQ(ierr);
526203dadc2fSPeter Brune   }
526303dadc2fSPeter Brune   PetscFunctionReturn(0);
526403dadc2fSPeter Brune }
526503dadc2fSPeter Brune 
5266c73cfb54SMatthew G. Knepley /*@
5267c73cfb54SMatthew G. Knepley   DMGetDimension - Return the topological dimension of the DM
5268c73cfb54SMatthew G. Knepley 
5269c73cfb54SMatthew G. Knepley   Not collective
5270c73cfb54SMatthew G. Knepley 
5271c73cfb54SMatthew G. Knepley   Input Parameter:
5272c73cfb54SMatthew G. Knepley . dm - The DM
5273c73cfb54SMatthew G. Knepley 
5274c73cfb54SMatthew G. Knepley   Output Parameter:
5275c73cfb54SMatthew G. Knepley . dim - The topological dimension
5276c73cfb54SMatthew G. Knepley 
5277c73cfb54SMatthew G. Knepley   Level: beginner
5278c73cfb54SMatthew G. Knepley 
5279c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate()
5280c73cfb54SMatthew G. Knepley @*/
5281c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim)
5282c73cfb54SMatthew G. Knepley {
5283c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5284c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5285534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
5286c73cfb54SMatthew G. Knepley   *dim = dm->dim;
5287c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5288c73cfb54SMatthew G. Knepley }
5289c73cfb54SMatthew G. Knepley 
5290c73cfb54SMatthew G. Knepley /*@
5291c73cfb54SMatthew G. Knepley   DMSetDimension - Set the topological dimension of the DM
5292c73cfb54SMatthew G. Knepley 
5293c73cfb54SMatthew G. Knepley   Collective on dm
5294c73cfb54SMatthew G. Knepley 
5295c73cfb54SMatthew G. Knepley   Input Parameters:
5296c73cfb54SMatthew G. Knepley + dm - The DM
5297c73cfb54SMatthew G. Knepley - dim - The topological dimension
5298c73cfb54SMatthew G. Knepley 
5299c73cfb54SMatthew G. Knepley   Level: beginner
5300c73cfb54SMatthew G. Knepley 
5301c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate()
5302c73cfb54SMatthew G. Knepley @*/
5303c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim)
5304c73cfb54SMatthew G. Knepley {
5305e5e52638SMatthew G. Knepley   PetscDS        ds;
5306f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5307f17e8794SMatthew G. Knepley 
5308c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5309c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5310c73cfb54SMatthew G. Knepley   PetscValidLogicalCollectiveInt(dm, dim, 2);
5311c73cfb54SMatthew G. Knepley   dm->dim = dim;
5312e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5313e5e52638SMatthew G. Knepley   if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);}
5314c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5315c73cfb54SMatthew G. Knepley }
5316c73cfb54SMatthew G. Knepley 
5317793f3fe5SMatthew G. Knepley /*@
5318793f3fe5SMatthew G. Knepley   DMGetDimPoints - Get the half-open interval for all points of a given dimension
5319793f3fe5SMatthew G. Knepley 
5320d083f849SBarry Smith   Collective on dm
5321793f3fe5SMatthew G. Knepley 
5322793f3fe5SMatthew G. Knepley   Input Parameters:
5323793f3fe5SMatthew G. Knepley + dm - the DM
5324793f3fe5SMatthew G. Knepley - dim - the dimension
5325793f3fe5SMatthew G. Knepley 
5326793f3fe5SMatthew G. Knepley   Output Parameters:
5327793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension
5328aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension
5329793f3fe5SMatthew G. Knepley 
5330793f3fe5SMatthew G. Knepley   Note:
5331793f3fe5SMatthew G. Knepley   The points are vertices in the Hasse diagram encoding the topology. This is explained in
5332a8d69d7bSBarry Smith   https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme,
5333793f3fe5SMatthew G. Knepley   then the interval is empty.
5334793f3fe5SMatthew G. Knepley 
5335793f3fe5SMatthew G. Knepley   Level: intermediate
5336793f3fe5SMatthew G. Knepley 
5337793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum()
5338793f3fe5SMatthew G. Knepley @*/
5339793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
5340793f3fe5SMatthew G. Knepley {
5341793f3fe5SMatthew G. Knepley   PetscInt       d;
5342793f3fe5SMatthew G. Knepley   PetscErrorCode ierr;
5343793f3fe5SMatthew G. Knepley 
5344793f3fe5SMatthew G. Knepley   PetscFunctionBegin;
5345793f3fe5SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5346793f3fe5SMatthew G. Knepley   ierr = DMGetDimension(dm, &d);CHKERRQ(ierr);
5347793f3fe5SMatthew G. Knepley   if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d);
5348b9d85ea2SLisandro Dalcin   if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name);
5349793f3fe5SMatthew G. Knepley   ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr);
5350793f3fe5SMatthew G. Knepley   PetscFunctionReturn(0);
5351793f3fe5SMatthew G. Knepley }
5352793f3fe5SMatthew G. Knepley 
53536636e97aSMatthew G Knepley /*@
53546636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
53556636e97aSMatthew G Knepley 
5356d083f849SBarry Smith   Collective on dm
53576636e97aSMatthew G Knepley 
53586636e97aSMatthew G Knepley   Input Parameters:
53596636e97aSMatthew G Knepley + dm - the DM
53606636e97aSMatthew G Knepley - c - coordinate vector
53616636e97aSMatthew G Knepley 
53622dd40e9bSPatrick Sanan   Notes:
53632dd40e9bSPatrick Sanan   The coordinates do include those for ghost points, which are in the local vector.
53642dd40e9bSPatrick Sanan 
53652dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
53666636e97aSMatthew G Knepley 
53676636e97aSMatthew G Knepley   Level: intermediate
53686636e97aSMatthew G Knepley 
53692dd40e9bSPatrick Sanan .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
53706636e97aSMatthew G Knepley @*/
53716636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
53726636e97aSMatthew G Knepley {
53736636e97aSMatthew G Knepley   PetscErrorCode ierr;
53746636e97aSMatthew G Knepley 
53756636e97aSMatthew G Knepley   PetscFunctionBegin;
53766636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
53776636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
53786636e97aSMatthew G Knepley   ierr            = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
53796636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
53806636e97aSMatthew G Knepley   dm->coordinates = c;
53816636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
5382b64e0483SPeter Brune   ierr            = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
538303dadc2fSPeter Brune   ierr            = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
53846636e97aSMatthew G Knepley   PetscFunctionReturn(0);
53856636e97aSMatthew G Knepley }
53866636e97aSMatthew G Knepley 
53876636e97aSMatthew G Knepley /*@
53886636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
53896636e97aSMatthew G Knepley 
53907058e716SVaclav Hapla   Not collective
53916636e97aSMatthew G Knepley 
53926636e97aSMatthew G Knepley    Input Parameters:
53936636e97aSMatthew G Knepley +  dm - the DM
53946636e97aSMatthew G Knepley -  c - coordinate vector
53956636e97aSMatthew G Knepley 
53962dd40e9bSPatrick Sanan   Notes:
53976636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
53986636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
53996636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
54006636e97aSMatthew G Knepley 
54012dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
54022dd40e9bSPatrick Sanan 
54036636e97aSMatthew G Knepley   Level: intermediate
54046636e97aSMatthew G Knepley 
54056636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
54066636e97aSMatthew G Knepley @*/
54076636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
54086636e97aSMatthew G Knepley {
54096636e97aSMatthew G Knepley   PetscErrorCode ierr;
54106636e97aSMatthew G Knepley 
54116636e97aSMatthew G Knepley   PetscFunctionBegin;
54126636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
54136636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
54146636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
54156636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
54168865f1eaSKarl Rupp 
54176636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
54188865f1eaSKarl Rupp 
54196636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
54206636e97aSMatthew G Knepley   PetscFunctionReturn(0);
54216636e97aSMatthew G Knepley }
54226636e97aSMatthew G Knepley 
54236636e97aSMatthew G Knepley /*@
54246636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
54256636e97aSMatthew G Knepley 
5426d083f849SBarry Smith   Collective on dm
54276636e97aSMatthew G Knepley 
54286636e97aSMatthew G Knepley   Input Parameter:
54296636e97aSMatthew G Knepley . dm - the DM
54306636e97aSMatthew G Knepley 
54316636e97aSMatthew G Knepley   Output Parameter:
54326636e97aSMatthew G Knepley . c - global coordinate vector
54336636e97aSMatthew G Knepley 
54346636e97aSMatthew G Knepley   Note:
54356636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
54366636e97aSMatthew G Knepley 
54376636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
54386636e97aSMatthew G Knepley 
54396636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
54406636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
54416636e97aSMatthew G Knepley 
54426636e97aSMatthew G Knepley   Level: intermediate
54436636e97aSMatthew G Knepley 
54446636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
54456636e97aSMatthew G Knepley @*/
54466636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
54476636e97aSMatthew G Knepley {
54486636e97aSMatthew G Knepley   PetscErrorCode ierr;
54496636e97aSMatthew G Knepley 
54506636e97aSMatthew G Knepley   PetscFunctionBegin;
54516636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
54526636e97aSMatthew G Knepley   PetscValidPointer(c,2);
54531f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
54540298fd71SBarry Smith     DM        cdm = NULL;
54551970a576SMatthew G. Knepley     PetscBool localized;
54566636e97aSMatthew G Knepley 
54576636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
54586636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
54591970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
54601970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */
54611970a576SMatthew G. Knepley     if (localized) {
54621970a576SMatthew G. Knepley       PetscInt cdim;
54631970a576SMatthew G. Knepley 
54641970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
54651970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
54661970a576SMatthew G. Knepley     }
54676636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
54686636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
54696636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
54706636e97aSMatthew G Knepley   }
54716636e97aSMatthew G Knepley   *c = dm->coordinates;
54726636e97aSMatthew G Knepley   PetscFunctionReturn(0);
54736636e97aSMatthew G Knepley }
54746636e97aSMatthew G Knepley 
54756636e97aSMatthew G Knepley /*@
547681e9a530SVaclav Hapla   DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards.
547781e9a530SVaclav Hapla 
5478d083f849SBarry Smith   Collective on dm
547981e9a530SVaclav Hapla 
548081e9a530SVaclav Hapla   Input Parameter:
548181e9a530SVaclav Hapla . dm - the DM
548281e9a530SVaclav Hapla 
548381e9a530SVaclav Hapla   Level: advanced
548481e9a530SVaclav Hapla 
548581e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective()
548681e9a530SVaclav Hapla @*/
548781e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm)
548881e9a530SVaclav Hapla {
548981e9a530SVaclav Hapla   PetscErrorCode ierr;
549081e9a530SVaclav Hapla 
549181e9a530SVaclav Hapla   PetscFunctionBegin;
549281e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
549381e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) {
54941970a576SMatthew G. Knepley     DM        cdm = NULL;
54951970a576SMatthew G. Knepley     PetscBool localized;
54961970a576SMatthew G. Knepley 
549781e9a530SVaclav Hapla     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
549881e9a530SVaclav Hapla     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
54991970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
55001970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */
55011970a576SMatthew G. Knepley     if (localized) {
55021970a576SMatthew G. Knepley       PetscInt cdim;
55031970a576SMatthew G. Knepley 
55041970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
55051970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
55061970a576SMatthew G. Knepley     }
550781e9a530SVaclav Hapla     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
550881e9a530SVaclav Hapla     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
550981e9a530SVaclav Hapla     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
551081e9a530SVaclav Hapla   }
551181e9a530SVaclav Hapla   PetscFunctionReturn(0);
551281e9a530SVaclav Hapla }
551381e9a530SVaclav Hapla 
551481e9a530SVaclav Hapla /*@
55156636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
55166636e97aSMatthew G Knepley 
5517d083f849SBarry Smith   Collective on dm
55186636e97aSMatthew G Knepley 
55196636e97aSMatthew G Knepley   Input Parameter:
55206636e97aSMatthew G Knepley . dm - the DM
55216636e97aSMatthew G Knepley 
55226636e97aSMatthew G Knepley   Output Parameter:
55236636e97aSMatthew G Knepley . c - coordinate vector
55246636e97aSMatthew G Knepley 
55256636e97aSMatthew G Knepley   Note:
55266636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
55276636e97aSMatthew G Knepley 
55286636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
55296636e97aSMatthew G Knepley 
55306636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
55316636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
55326636e97aSMatthew G Knepley 
55336636e97aSMatthew G Knepley   Level: intermediate
55346636e97aSMatthew G Knepley 
553581e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective()
55366636e97aSMatthew G Knepley @*/
55376636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
55386636e97aSMatthew G Knepley {
55396636e97aSMatthew G Knepley   PetscErrorCode ierr;
55406636e97aSMatthew G Knepley 
55416636e97aSMatthew G Knepley   PetscFunctionBegin;
55426636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
55436636e97aSMatthew G Knepley   PetscValidPointer(c,2);
554481e9a530SVaclav Hapla   ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr);
55456636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
55466636e97aSMatthew G Knepley   PetscFunctionReturn(0);
55476636e97aSMatthew G Knepley }
55486636e97aSMatthew G Knepley 
554981e9a530SVaclav Hapla /*@
555081e9a530SVaclav Hapla   DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called.
555181e9a530SVaclav Hapla 
555281e9a530SVaclav Hapla   Not collective
555381e9a530SVaclav Hapla 
555481e9a530SVaclav Hapla   Input Parameter:
555581e9a530SVaclav Hapla . dm - the DM
555681e9a530SVaclav Hapla 
555781e9a530SVaclav Hapla   Output Parameter:
555881e9a530SVaclav Hapla . c - coordinate vector
555981e9a530SVaclav Hapla 
556081e9a530SVaclav Hapla   Level: advanced
556181e9a530SVaclav Hapla 
556281e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
556381e9a530SVaclav Hapla @*/
556481e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c)
556581e9a530SVaclav Hapla {
556681e9a530SVaclav Hapla   PetscFunctionBegin;
556781e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
556881e9a530SVaclav Hapla   PetscValidPointer(c,2);
556981e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called");
55706636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
55716636e97aSMatthew G Knepley   PetscFunctionReturn(0);
55726636e97aSMatthew G Knepley }
55736636e97aSMatthew G Knepley 
55742db98f8dSVaclav Hapla /*@
55752db98f8dSVaclav Hapla   DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout.
55762db98f8dSVaclav Hapla 
55772db98f8dSVaclav Hapla   Not collective
55782db98f8dSVaclav Hapla 
55792db98f8dSVaclav Hapla   Input Parameter:
55802db98f8dSVaclav Hapla + dm - the DM
55812db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned
55822db98f8dSVaclav Hapla 
55832db98f8dSVaclav Hapla   Output Parameter:
55842db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates
55852db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p
55862db98f8dSVaclav Hapla 
55872db98f8dSVaclav Hapla   Note:
55882db98f8dSVaclav Hapla   DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective.
55892db98f8dSVaclav Hapla 
55902db98f8dSVaclav Hapla   This creates a new vector, so the user SHOULD destroy this vector
55912db98f8dSVaclav Hapla 
55922db98f8dSVaclav Hapla   Each process has the local and ghost coordinates
55932db98f8dSVaclav Hapla 
55942db98f8dSVaclav Hapla   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
55952db98f8dSVaclav Hapla   and (x_0,y_0,z_0,x_1,y_1,z_1...)
55962db98f8dSVaclav Hapla 
55972db98f8dSVaclav Hapla   Level: advanced
55982db98f8dSVaclav Hapla 
55992db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
56002db98f8dSVaclav Hapla @*/
56012db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord)
56022db98f8dSVaclav Hapla {
56032db98f8dSVaclav Hapla   PetscSection        cs, newcs;
56042db98f8dSVaclav Hapla   Vec                 coords;
56052db98f8dSVaclav Hapla   const PetscScalar   *arr;
56062db98f8dSVaclav Hapla   PetscScalar         *newarr=NULL;
56072db98f8dSVaclav Hapla   PetscInt            n;
56082db98f8dSVaclav Hapla   PetscErrorCode      ierr;
56092db98f8dSVaclav Hapla 
56102db98f8dSVaclav Hapla   PetscFunctionBegin;
56112db98f8dSVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
56122db98f8dSVaclav Hapla   PetscValidHeaderSpecific(p, IS_CLASSID, 2);
56132db98f8dSVaclav Hapla   if (pCoordSection) PetscValidPointer(pCoordSection, 3);
56142db98f8dSVaclav Hapla   if (pCoord) PetscValidPointer(pCoord, 4);
56152db98f8dSVaclav Hapla   if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set");
56162db98f8dSVaclav Hapla   if (!dm->coordinateDM || !dm->coordinateDM->defaultSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported");
56172db98f8dSVaclav Hapla   cs = dm->coordinateDM->defaultSection;
56182db98f8dSVaclav Hapla   coords = dm->coordinatesLocal;
56192db98f8dSVaclav Hapla   ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr);
56202db98f8dSVaclav Hapla   ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr);
56212db98f8dSVaclav Hapla   ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr);
56222db98f8dSVaclav Hapla   if (pCoord) {
56232db98f8dSVaclav Hapla     ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr);
56242db98f8dSVaclav Hapla     /* set array in two steps to mimic PETSC_OWN_POINTER */
56252db98f8dSVaclav Hapla     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr);
56262db98f8dSVaclav Hapla     ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr);
5627ad9ac99dSVaclav Hapla   } else {
5628ad9ac99dSVaclav Hapla     ierr = PetscFree(newarr);CHKERRQ(ierr);
56292db98f8dSVaclav Hapla   }
5630ad9ac99dSVaclav Hapla   if (pCoordSection) {*pCoordSection = newcs;}
5631ad9ac99dSVaclav Hapla   else               {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);}
56322db98f8dSVaclav Hapla   PetscFunctionReturn(0);
56332db98f8dSVaclav Hapla }
56342db98f8dSVaclav Hapla 
5635f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field)
5636f19dbd58SToby Isaac {
5637f19dbd58SToby Isaac   PetscErrorCode ierr;
5638f19dbd58SToby Isaac 
5639f19dbd58SToby Isaac   PetscFunctionBegin;
5640f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5641f19dbd58SToby Isaac   PetscValidPointer(field,2);
5642f19dbd58SToby Isaac   if (!dm->coordinateField) {
5643f19dbd58SToby Isaac     if (dm->ops->createcoordinatefield) {
5644f19dbd58SToby Isaac       ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr);
5645f19dbd58SToby Isaac     }
5646f19dbd58SToby Isaac   }
5647f19dbd58SToby Isaac   *field = dm->coordinateField;
5648f19dbd58SToby Isaac   PetscFunctionReturn(0);
5649f19dbd58SToby Isaac }
5650f19dbd58SToby Isaac 
5651f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field)
5652f19dbd58SToby Isaac {
5653f19dbd58SToby Isaac   PetscErrorCode ierr;
5654f19dbd58SToby Isaac 
5655f19dbd58SToby Isaac   PetscFunctionBegin;
5656f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5657f19dbd58SToby Isaac   if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2);
5658c4e6da2cSBarry Smith   ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr);
5659f19dbd58SToby Isaac   ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr);
5660f19dbd58SToby Isaac   dm->coordinateField = field;
5661f19dbd58SToby Isaac   PetscFunctionReturn(0);
5662f19dbd58SToby Isaac }
5663f19dbd58SToby Isaac 
56646636e97aSMatthew G Knepley /*@
56651cfe2091SMatthew G. Knepley   DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates
56666636e97aSMatthew G Knepley 
5667d083f849SBarry Smith   Collective on dm
56686636e97aSMatthew G Knepley 
56696636e97aSMatthew G Knepley   Input Parameter:
56706636e97aSMatthew G Knepley . dm - the DM
56716636e97aSMatthew G Knepley 
56726636e97aSMatthew G Knepley   Output Parameter:
56736636e97aSMatthew G Knepley . cdm - coordinate DM
56746636e97aSMatthew G Knepley 
56756636e97aSMatthew G Knepley   Level: intermediate
56766636e97aSMatthew G Knepley 
56771cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
56786636e97aSMatthew G Knepley @*/
56796636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
56806636e97aSMatthew G Knepley {
56816636e97aSMatthew G Knepley   PetscErrorCode ierr;
56826636e97aSMatthew G Knepley 
56836636e97aSMatthew G Knepley   PetscFunctionBegin;
56846636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
56856636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
56866636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
5687308f8a94SToby Isaac     DM cdm;
5688308f8a94SToby Isaac 
568982f516ccSBarry Smith     if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM");
5690308f8a94SToby Isaac     ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr);
5691308f8a94SToby Isaac     /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup
5692308f8a94SToby Isaac      * until the call to CreateCoordinateDM) */
5693308f8a94SToby Isaac     ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
5694308f8a94SToby Isaac     dm->coordinateDM = cdm;
56956636e97aSMatthew G Knepley   }
56966636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
56976636e97aSMatthew G Knepley   PetscFunctionReturn(0);
56986636e97aSMatthew G Knepley }
5699e87bb0d3SMatthew G Knepley 
57001cfe2091SMatthew G. Knepley /*@
57011cfe2091SMatthew G. Knepley   DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates
57021cfe2091SMatthew G. Knepley 
5703d083f849SBarry Smith   Logically Collective on dm
57041cfe2091SMatthew G. Knepley 
57051cfe2091SMatthew G. Knepley   Input Parameters:
57061cfe2091SMatthew G. Knepley + dm - the DM
57071cfe2091SMatthew G. Knepley - cdm - coordinate DM
57081cfe2091SMatthew G. Knepley 
57091cfe2091SMatthew G. Knepley   Level: intermediate
57101cfe2091SMatthew G. Knepley 
57111cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
57121cfe2091SMatthew G. Knepley @*/
57131cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm)
57141cfe2091SMatthew G. Knepley {
57151cfe2091SMatthew G. Knepley   PetscErrorCode ierr;
57161cfe2091SMatthew G. Knepley 
57171cfe2091SMatthew G. Knepley   PetscFunctionBegin;
57181cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
57191cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(cdm,DM_CLASSID,2);
5720f26b38b9SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
57211cfe2091SMatthew G. Knepley   ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
57221cfe2091SMatthew G. Knepley   dm->coordinateDM = cdm;
57231cfe2091SMatthew G. Knepley   PetscFunctionReturn(0);
57241cfe2091SMatthew G. Knepley }
57251cfe2091SMatthew G. Knepley 
572646e270d4SMatthew G. Knepley /*@
572746e270d4SMatthew G. Knepley   DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values.
572846e270d4SMatthew G. Knepley 
572946e270d4SMatthew G. Knepley   Not Collective
573046e270d4SMatthew G. Knepley 
573146e270d4SMatthew G. Knepley   Input Parameter:
573246e270d4SMatthew G. Knepley . dm - The DM object
573346e270d4SMatthew G. Knepley 
573446e270d4SMatthew G. Knepley   Output Parameter:
573546e270d4SMatthew G. Knepley . dim - The embedding dimension
573646e270d4SMatthew G. Knepley 
573746e270d4SMatthew G. Knepley   Level: intermediate
573846e270d4SMatthew G. Knepley 
5739*92fd8e1eSJed Brown .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection()
574046e270d4SMatthew G. Knepley @*/
574146e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim)
574246e270d4SMatthew G. Knepley {
574346e270d4SMatthew G. Knepley   PetscFunctionBegin;
574446e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5745534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
57469a9a41abSToby Isaac   if (dm->dimEmbed == PETSC_DEFAULT) {
57479a9a41abSToby Isaac     dm->dimEmbed = dm->dim;
57489a9a41abSToby Isaac   }
574946e270d4SMatthew G. Knepley   *dim = dm->dimEmbed;
575046e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
575146e270d4SMatthew G. Knepley }
575246e270d4SMatthew G. Knepley 
575346e270d4SMatthew G. Knepley /*@
575446e270d4SMatthew G. Knepley   DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values.
575546e270d4SMatthew G. Knepley 
575646e270d4SMatthew G. Knepley   Not Collective
575746e270d4SMatthew G. Knepley 
575846e270d4SMatthew G. Knepley   Input Parameters:
575946e270d4SMatthew G. Knepley + dm  - The DM object
576046e270d4SMatthew G. Knepley - dim - The embedding dimension
576146e270d4SMatthew G. Knepley 
576246e270d4SMatthew G. Knepley   Level: intermediate
576346e270d4SMatthew G. Knepley 
5764*92fd8e1eSJed Brown .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection()
576546e270d4SMatthew G. Knepley @*/
576646e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim)
576746e270d4SMatthew G. Knepley {
5768e5e52638SMatthew G. Knepley   PetscDS        ds;
5769f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5770f17e8794SMatthew G. Knepley 
577146e270d4SMatthew G. Knepley   PetscFunctionBegin;
577246e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
577346e270d4SMatthew G. Knepley   dm->dimEmbed = dim;
5774e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5775e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr);
577646e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
577746e270d4SMatthew G. Knepley }
577846e270d4SMatthew G. Knepley 
5779e8abe2deSMatthew G. Knepley /*@
5780e8abe2deSMatthew G. Knepley   DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh.
5781e8abe2deSMatthew G. Knepley 
5782d083f849SBarry Smith   Collective on dm
5783e8abe2deSMatthew G. Knepley 
5784e8abe2deSMatthew G. Knepley   Input Parameter:
5785e8abe2deSMatthew G. Knepley . dm - The DM object
5786e8abe2deSMatthew G. Knepley 
5787e8abe2deSMatthew G. Knepley   Output Parameter:
5788e8abe2deSMatthew G. Knepley . section - The PetscSection object
5789e8abe2deSMatthew G. Knepley 
5790e8abe2deSMatthew G. Knepley   Level: intermediate
5791e8abe2deSMatthew G. Knepley 
5792*92fd8e1eSJed Brown .seealso: DMGetCoordinateDM(), DMGetLocalSection(), DMSetLocalSection()
5793e8abe2deSMatthew G. Knepley @*/
5794e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section)
5795e8abe2deSMatthew G. Knepley {
5796e8abe2deSMatthew G. Knepley   DM             cdm;
5797e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5798e8abe2deSMatthew G. Knepley 
5799e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5800e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5801e8abe2deSMatthew G. Knepley   PetscValidPointer(section, 2);
5802e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
5803*92fd8e1eSJed Brown   ierr = DMGetLocalSection(cdm, section);CHKERRQ(ierr);
5804e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5805e8abe2deSMatthew G. Knepley }
5806e8abe2deSMatthew G. Knepley 
5807e8abe2deSMatthew G. Knepley /*@
5808e8abe2deSMatthew G. Knepley   DMSetCoordinateSection - Set the layout of coordinate values over the mesh.
5809e8abe2deSMatthew G. Knepley 
5810e8abe2deSMatthew G. Knepley   Not Collective
5811e8abe2deSMatthew G. Knepley 
5812e8abe2deSMatthew G. Knepley   Input Parameters:
5813e8abe2deSMatthew G. Knepley + dm      - The DM object
581446e270d4SMatthew G. Knepley . dim     - The embedding dimension, or PETSC_DETERMINE
5815e8abe2deSMatthew G. Knepley - section - The PetscSection object
5816e8abe2deSMatthew G. Knepley 
5817e8abe2deSMatthew G. Knepley   Level: intermediate
5818e8abe2deSMatthew G. Knepley 
5819*92fd8e1eSJed Brown .seealso: DMGetCoordinateSection(), DMGetLocalSection(), DMSetLocalSection()
5820e8abe2deSMatthew G. Knepley @*/
582146e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section)
5822e8abe2deSMatthew G. Knepley {
5823e8abe2deSMatthew G. Knepley   DM             cdm;
5824e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5825e8abe2deSMatthew G. Knepley 
5826e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5827e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
582846e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3);
5829e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
5830*92fd8e1eSJed Brown   ierr = DMSetLocalSection(cdm, section);CHKERRQ(ierr);
583146e270d4SMatthew G. Knepley   if (dim == PETSC_DETERMINE) {
58324c1069a6SMatthew G. Knepley     PetscInt d = PETSC_DEFAULT;
583346e270d4SMatthew G. Knepley     PetscInt pStart, pEnd, vStart, vEnd, v, dd;
583446e270d4SMatthew G. Knepley 
583546e270d4SMatthew G. Knepley     ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
583646e270d4SMatthew G. Knepley     ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
583746e270d4SMatthew G. Knepley     pStart = PetscMax(vStart, pStart);
583846e270d4SMatthew G. Knepley     pEnd   = PetscMin(vEnd, pEnd);
583946e270d4SMatthew G. Knepley     for (v = pStart; v < pEnd; ++v) {
584046e270d4SMatthew G. Knepley       ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr);
584146e270d4SMatthew G. Knepley       if (dd) {d = dd; break;}
584246e270d4SMatthew G. Knepley     }
5843ebfe4b0dSMatthew G. Knepley     if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);}
584446e270d4SMatthew G. Knepley   }
5845e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5846e8abe2deSMatthew G. Knepley }
5847e8abe2deSMatthew G. Knepley 
58485dc8c3f7SMatthew G. Knepley /*@C
584990b157c4SStefano Zampini   DMGetPeriodicity - Get the description of mesh periodicity
58505dc8c3f7SMatthew G. Knepley 
58515dc8c3f7SMatthew G. Knepley   Input Parameters:
585290b157c4SStefano Zampini . dm      - The DM object
585390b157c4SStefano Zampini 
585490b157c4SStefano Zampini   Output Parameters:
585590b157c4SStefano Zampini + per     - Whether the DM is periodic or not
58565dc8c3f7SMatthew 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
58575dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
58585dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
58595dc8c3f7SMatthew G. Knepley 
58605dc8c3f7SMatthew G. Knepley   Level: developer
58615dc8c3f7SMatthew G. Knepley 
58625dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
58635dc8c3f7SMatthew G. Knepley @*/
586490b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd)
5865c6b900c6SMatthew G. Knepley {
5866c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
5867c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
586890b157c4SStefano Zampini   if (per)     *per     = dm->periodic;
5869c6b900c6SMatthew G. Knepley   if (L)       *L       = dm->L;
5870c6b900c6SMatthew G. Knepley   if (maxCell) *maxCell = dm->maxCell;
58715dc8c3f7SMatthew G. Knepley   if (bd)      *bd      = dm->bdtype;
5872c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
5873c6b900c6SMatthew G. Knepley }
5874c6b900c6SMatthew G. Knepley 
58755dc8c3f7SMatthew G. Knepley /*@C
58765dc8c3f7SMatthew G. Knepley   DMSetPeriodicity - Set the description of mesh periodicity
58775dc8c3f7SMatthew G. Knepley 
58785dc8c3f7SMatthew G. Knepley   Input Parameters:
58795dc8c3f7SMatthew G. Knepley + dm      - The DM object
588090b157c4SStefano Zampini . per     - Whether the DM is periodic or not. If maxCell is not provided, coordinates need to be localized
58815dc8c3f7SMatthew 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
58825dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
58835dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
58845dc8c3f7SMatthew G. Knepley 
58855dc8c3f7SMatthew G. Knepley   Level: developer
58865dc8c3f7SMatthew G. Knepley 
58875dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
58885dc8c3f7SMatthew G. Knepley @*/
588990b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[])
5890c6b900c6SMatthew G. Knepley {
5891c6b900c6SMatthew G. Knepley   PetscInt       dim, d;
5892c6b900c6SMatthew G. Knepley   PetscErrorCode ierr;
5893c6b900c6SMatthew G. Knepley 
5894c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
5895c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
589690b157c4SStefano Zampini   PetscValidLogicalCollectiveBool(dm,per,2);
589790b157c4SStefano Zampini   if (maxCell) {
5898534a8f05SLisandro Dalcin     PetscValidRealPointer(maxCell,3);
5899534a8f05SLisandro Dalcin     PetscValidRealPointer(L,4);
590090b157c4SStefano Zampini     PetscValidPointer(bd,5);
590190b157c4SStefano Zampini   }
59025dc8c3f7SMatthew G. Knepley   ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr);
59035dc8c3f7SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
590490b157c4SStefano Zampini   if (maxCell) {
59055dc8c3f7SMatthew G. Knepley     ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr);
59065dc8c3f7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];}
590790b157c4SStefano Zampini   }
5908072d7d67SStefano Zampini   dm->periodic = per;
5909c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
5910c6b900c6SMatthew G. Knepley }
5911c6b900c6SMatthew G. Knepley 
59122e17dfb7SMatthew G. Knepley /*@
59132e17dfb7SMatthew 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.
59142e17dfb7SMatthew G. Knepley 
59152e17dfb7SMatthew G. Knepley   Input Parameters:
59162e17dfb7SMatthew G. Knepley + dm     - The DM
591765da65dcSMatthew G. Knepley . in     - The input coordinate point (dim numbers)
591865da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i
59192e17dfb7SMatthew G. Knepley 
59202e17dfb7SMatthew G. Knepley   Output Parameter:
59212e17dfb7SMatthew G. Knepley . out - The localized coordinate point
59222e17dfb7SMatthew G. Knepley 
59232e17dfb7SMatthew G. Knepley   Level: developer
59242e17dfb7SMatthew G. Knepley 
59252e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
59262e17dfb7SMatthew G. Knepley @*/
592765da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[])
59282e17dfb7SMatthew G. Knepley {
59292e17dfb7SMatthew G. Knepley   PetscInt       dim, d;
59302e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
59312e17dfb7SMatthew G. Knepley 
59322e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
59332e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr);
59342e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
59352e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
59362e17dfb7SMatthew G. Knepley   } else {
593765da65dcSMatthew G. Knepley     if (endpoint) {
593865da65dcSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
5939da3333bfSMatthew 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)) {
5940da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1);
594165da65dcSMatthew G. Knepley         } else {
5942da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
594365da65dcSMatthew G. Knepley         }
594465da65dcSMatthew G. Knepley       }
594565da65dcSMatthew G. Knepley     } else {
59462e17dfb7SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
59471118d4bcSLisandro Dalcin         out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
59482e17dfb7SMatthew G. Knepley       }
59492e17dfb7SMatthew G. Knepley     }
595065da65dcSMatthew G. Knepley   }
59512e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
59522e17dfb7SMatthew G. Knepley }
59532e17dfb7SMatthew G. Knepley 
59542e17dfb7SMatthew G. Knepley /*
59552e17dfb7SMatthew 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.
59562e17dfb7SMatthew G. Knepley 
59572e17dfb7SMatthew G. Knepley   Input Parameters:
59582e17dfb7SMatthew G. Knepley + dm     - The DM
59592e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
59602e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
59612e17dfb7SMatthew G. Knepley - in     - The input coordinate point (dim numbers)
59622e17dfb7SMatthew G. Knepley 
59632e17dfb7SMatthew G. Knepley   Output Parameter:
59642e17dfb7SMatthew G. Knepley . out - The localized coordinate point
59652e17dfb7SMatthew G. Knepley 
59662e17dfb7SMatthew G. Knepley   Level: developer
59672e17dfb7SMatthew G. Knepley 
59682e17dfb7SMatthew 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
59692e17dfb7SMatthew G. Knepley 
59702e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
59712e17dfb7SMatthew G. Knepley */
59722e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
59732e17dfb7SMatthew G. Knepley {
59742e17dfb7SMatthew G. Knepley   PetscInt d;
59752e17dfb7SMatthew G. Knepley 
59762e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
59772e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
59782e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
59792e17dfb7SMatthew G. Knepley   } else {
59802e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5981908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
59822e17dfb7SMatthew G. Knepley         out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
59832e17dfb7SMatthew G. Knepley       } else {
59842e17dfb7SMatthew G. Knepley         out[d] = in[d];
59852e17dfb7SMatthew G. Knepley       }
59862e17dfb7SMatthew G. Knepley     }
59872e17dfb7SMatthew G. Knepley   }
59882e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
59892e17dfb7SMatthew G. Knepley }
59902e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[])
59912e17dfb7SMatthew G. Knepley {
59922e17dfb7SMatthew G. Knepley   PetscInt d;
59932e17dfb7SMatthew G. Knepley 
59942e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
59952e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
59962e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
59972e17dfb7SMatthew G. Knepley   } else {
59982e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5999908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) {
60002e17dfb7SMatthew G. Knepley         out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d];
60012e17dfb7SMatthew G. Knepley       } else {
60022e17dfb7SMatthew G. Knepley         out[d] = in[d];
60032e17dfb7SMatthew G. Knepley       }
60042e17dfb7SMatthew G. Knepley     }
60052e17dfb7SMatthew G. Knepley   }
60062e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
60072e17dfb7SMatthew G. Knepley }
60082e17dfb7SMatthew G. Knepley 
60092e17dfb7SMatthew G. Knepley /*
60102e17dfb7SMatthew 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.
60112e17dfb7SMatthew G. Knepley 
60122e17dfb7SMatthew G. Knepley   Input Parameters:
60132e17dfb7SMatthew G. Knepley + dm     - The DM
60142e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
60152e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
60162e17dfb7SMatthew G. Knepley . in     - The input coordinate delta (dim numbers)
60172e17dfb7SMatthew G. Knepley - out    - The input coordinate point (dim numbers)
60182e17dfb7SMatthew G. Knepley 
60192e17dfb7SMatthew G. Knepley   Output Parameter:
60202e17dfb7SMatthew G. Knepley . out    - The localized coordinate in + out
60212e17dfb7SMatthew G. Knepley 
60222e17dfb7SMatthew G. Knepley   Level: developer
60232e17dfb7SMatthew G. Knepley 
60242e17dfb7SMatthew 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
60252e17dfb7SMatthew G. Knepley 
60262e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate()
60272e17dfb7SMatthew G. Knepley */
60282e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
60292e17dfb7SMatthew G. Knepley {
60302e17dfb7SMatthew G. Knepley   PetscInt d;
60312e17dfb7SMatthew G. Knepley 
60322e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
60332e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
60342e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] += in[d];
60352e17dfb7SMatthew G. Knepley   } else {
60362e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
6037908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
60382e17dfb7SMatthew G. Knepley         out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
60392e17dfb7SMatthew G. Knepley       } else {
60402e17dfb7SMatthew G. Knepley         out[d] += in[d];
60412e17dfb7SMatthew G. Knepley       }
60422e17dfb7SMatthew G. Knepley     }
60432e17dfb7SMatthew G. Knepley   }
60442e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
60452e17dfb7SMatthew G. Knepley }
60462e17dfb7SMatthew G. Knepley 
604736447a5eSToby Isaac /*@
60488f700142SStefano Zampini   DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process
60498f700142SStefano Zampini 
60508f700142SStefano Zampini   Not collective
605136447a5eSToby Isaac 
605236447a5eSToby Isaac   Input Parameter:
605336447a5eSToby Isaac . dm - The DM
605436447a5eSToby Isaac 
605536447a5eSToby Isaac   Output Parameter:
605636447a5eSToby Isaac   areLocalized - True if localized
605736447a5eSToby Isaac 
605836447a5eSToby Isaac   Level: developer
605936447a5eSToby Isaac 
60608f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity()
606136447a5eSToby Isaac @*/
60628f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized)
606336447a5eSToby Isaac {
606436447a5eSToby Isaac   DM             cdm;
606536447a5eSToby Isaac   PetscSection   coordSection;
606646a3a80fSLisandro Dalcin   PetscInt       cStart, cEnd, sStart, sEnd, c, dof;
606746a3a80fSLisandro Dalcin   PetscBool      isPlex, alreadyLocalized;
606836447a5eSToby Isaac   PetscErrorCode ierr;
606936447a5eSToby Isaac 
607036447a5eSToby Isaac   PetscFunctionBegin;
607136447a5eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6072534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
60738b09590cSToby Isaac   *areLocalized = PETSC_FALSE;
607446a3a80fSLisandro Dalcin 
607536447a5eSToby Isaac   /* We need some generic way of refering to cells/vertices */
607636447a5eSToby Isaac   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
607746a3a80fSLisandro Dalcin   ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr);
60789f7230bfSMatthew G. Knepley   if (!isPlex) PetscFunctionReturn(0);
607946a3a80fSLisandro Dalcin 
60809f7230bfSMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
608146a3a80fSLisandro Dalcin   ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr);
608236447a5eSToby Isaac   ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr);
608336447a5eSToby Isaac   alreadyLocalized = PETSC_FALSE;
608446a3a80fSLisandro Dalcin   for (c = cStart; c < cEnd; ++c) {
608546a3a80fSLisandro Dalcin     if (c < sStart || c >= sEnd) continue;
608636447a5eSToby Isaac     ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr);
608746a3a80fSLisandro Dalcin     if (dof) { alreadyLocalized = PETSC_TRUE; break; }
608836447a5eSToby Isaac   }
60898f700142SStefano Zampini   *areLocalized = alreadyLocalized;
609036447a5eSToby Isaac   PetscFunctionReturn(0);
609136447a5eSToby Isaac }
609236447a5eSToby Isaac 
60938f700142SStefano Zampini /*@
60948f700142SStefano Zampini   DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells
60958f700142SStefano Zampini 
60968f700142SStefano Zampini   Collective on dm
60978f700142SStefano Zampini 
60988f700142SStefano Zampini   Input Parameter:
60998f700142SStefano Zampini . dm - The DM
61008f700142SStefano Zampini 
61018f700142SStefano Zampini   Output Parameter:
61028f700142SStefano Zampini   areLocalized - True if localized
61038f700142SStefano Zampini 
61048f700142SStefano Zampini   Level: developer
61058f700142SStefano Zampini 
61068f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal()
61078f700142SStefano Zampini @*/
61088f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized)
61098f700142SStefano Zampini {
61108f700142SStefano Zampini   PetscBool      localized;
61118f700142SStefano Zampini   PetscErrorCode ierr;
61128f700142SStefano Zampini 
61138f700142SStefano Zampini   PetscFunctionBegin;
61148f700142SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6115534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
61168f700142SStefano Zampini   ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr);
61178f700142SStefano Zampini   ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
61188f700142SStefano Zampini   PetscFunctionReturn(0);
61198f700142SStefano Zampini }
612036447a5eSToby Isaac 
61212e17dfb7SMatthew G. Knepley /*@
6122492b8470SStefano Zampini   DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces
61232e17dfb7SMatthew G. Knepley 
61248f700142SStefano Zampini   Collective on dm
61258f700142SStefano Zampini 
61262e17dfb7SMatthew G. Knepley   Input Parameter:
61272e17dfb7SMatthew G. Knepley . dm - The DM
61282e17dfb7SMatthew G. Knepley 
61292e17dfb7SMatthew G. Knepley   Level: developer
61302e17dfb7SMatthew G. Knepley 
61318f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate()
61322e17dfb7SMatthew G. Knepley @*/
61332e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm)
61342e17dfb7SMatthew G. Knepley {
61352e17dfb7SMatthew G. Knepley   DM             cdm;
61362e17dfb7SMatthew G. Knepley   PetscSection   coordSection, cSection;
61372e17dfb7SMatthew G. Knepley   Vec            coordinates,  cVec;
61383e922f36SToby Isaac   PetscScalar   *coords, *coords2, *anchor, *localized;
61393e922f36SToby Isaac   PetscInt       Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize;
6140e0ae35bbSToby Isaac   PetscBool      alreadyLocalized, alreadyLocalizedGlobal;
61413e922f36SToby Isaac   PetscInt       maxHeight = 0, h;
61423e922f36SToby Isaac   PetscInt       *pStart = NULL, *pEnd = NULL;
61432e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
61442e17dfb7SMatthew G. Knepley 
61452e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
61462e17dfb7SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
614792c9c85fSStefano Zampini   if (!dm->periodic) PetscFunctionReturn(0);
6148f7cbd40bSStefano Zampini   ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr);
6149f7cbd40bSStefano Zampini   if (alreadyLocalized) PetscFunctionReturn(0);
6150f7cbd40bSStefano Zampini 
61512e17dfb7SMatthew G. Knepley   /* We need some generic way of refering to cells/vertices */
61522e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
61532e17dfb7SMatthew G. Knepley   {
61542e17dfb7SMatthew G. Knepley     PetscBool isplex;
61552e17dfb7SMatthew G. Knepley 
61562e17dfb7SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr);
61572e17dfb7SMatthew G. Knepley     if (isplex) {
61582e17dfb7SMatthew G. Knepley       ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr);
61593e922f36SToby Isaac       ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr);
616069291d52SBarry Smith       ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
61613e922f36SToby Isaac       pEnd = &pStart[maxHeight + 1];
61623e922f36SToby Isaac       newStart = vStart;
61633e922f36SToby Isaac       newEnd   = vEnd;
61643e922f36SToby Isaac       for (h = 0; h <= maxHeight; h++) {
61653e922f36SToby Isaac         ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr);
61663e922f36SToby Isaac         newStart = PetscMin(newStart,pStart[h]);
61673e922f36SToby Isaac         newEnd   = PetscMax(newEnd,pEnd[h]);
61683e922f36SToby Isaac       }
61692e17dfb7SMatthew G. Knepley     } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM");
61702e17dfb7SMatthew G. Knepley   }
61712e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
617243eeeb2dSStefano Zampini   if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector");
61732e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
61743e922f36SToby Isaac   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
6175e0ae35bbSToby Isaac   ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr);
61763e922f36SToby Isaac 
61772e17dfb7SMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr);
61782e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr);
61792e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr);
61802e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr);
61813e922f36SToby Isaac   ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr);
61823e922f36SToby Isaac 
618369291d52SBarry Smith   ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
61843e922f36SToby Isaac   localized = &anchor[bs];
61853e922f36SToby Isaac   alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE;
61863e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
61873e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
61883e922f36SToby Isaac 
61893e922f36SToby Isaac     for (c = cStart; c < cEnd; ++c) {
61903e922f36SToby Isaac       PetscScalar *cellCoords = NULL;
61913e922f36SToby Isaac       PetscInt     b;
61923e922f36SToby Isaac 
61933e922f36SToby Isaac       if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE;
61943e922f36SToby Isaac       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
61953e922f36SToby Isaac       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
61963e922f36SToby Isaac       for (d = 0; d < dof/bs; ++d) {
61973e922f36SToby Isaac         ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr);
61983e922f36SToby Isaac         for (b = 0; b < bs; b++) {
61993e922f36SToby Isaac           if (cellCoords[d*bs + b] != localized[b]) break;
62003e922f36SToby Isaac         }
62013e922f36SToby Isaac         if (b < bs) break;
62023e922f36SToby Isaac       }
62033e922f36SToby Isaac       if (d < dof/bs) {
62043e922f36SToby Isaac         if (c >= sStart && c < sEnd) {
62053e922f36SToby Isaac           PetscInt cdof;
62063e922f36SToby Isaac 
62073e922f36SToby Isaac           ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
62083e922f36SToby Isaac           if (cdof != dof) alreadyLocalized = PETSC_FALSE;
62093e922f36SToby Isaac         }
62103e922f36SToby Isaac         ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr);
62113e922f36SToby Isaac         ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr);
62123e922f36SToby Isaac       }
62133e922f36SToby Isaac       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
62143e922f36SToby Isaac     }
62153e922f36SToby Isaac   }
62163e922f36SToby Isaac   ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
62173e922f36SToby Isaac   if (alreadyLocalizedGlobal) {
621869291d52SBarry Smith     ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
62193e922f36SToby Isaac     ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
622069291d52SBarry Smith     ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
62213e922f36SToby Isaac     PetscFunctionReturn(0);
62223e922f36SToby Isaac   }
62232e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
62242e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
62252e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr);
62262e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr);
62272e17dfb7SMatthew G. Knepley   }
62282e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr);
62292e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr);
6230c2be7e5eSLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr);
62312e17dfb7SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr);
62322e17dfb7SMatthew G. Knepley   ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr);
62332e17dfb7SMatthew G. Knepley   ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr);
62342e17dfb7SMatthew G. Knepley   ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr);
6235c2be7e5eSLisandro Dalcin   ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
62362e17dfb7SMatthew G. Knepley   ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr);
62372e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
62382e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
62392e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
62402e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(cSection,     v, &off2);CHKERRQ(ierr);
62412e17dfb7SMatthew G. Knepley     for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d];
62422e17dfb7SMatthew G. Knepley   }
62433e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
62443e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
62453e922f36SToby Isaac 
62462e17dfb7SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
62472e17dfb7SMatthew G. Knepley       PetscScalar *cellCoords = NULL;
62483e922f36SToby Isaac       PetscInt     b, cdof;
62492e17dfb7SMatthew G. Knepley 
62503e922f36SToby Isaac       ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr);
62513e922f36SToby Isaac       if (!cdof) continue;
62522e17dfb7SMatthew G. Knepley       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
62532e17dfb7SMatthew G. Knepley       ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr);
62542e17dfb7SMatthew G. Knepley       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
62552e17dfb7SMatthew G. Knepley       for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);}
62562e17dfb7SMatthew G. Knepley       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
62572e17dfb7SMatthew G. Knepley     }
62583e922f36SToby Isaac   }
625969291d52SBarry Smith   ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
626069291d52SBarry Smith   ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
6261c2be7e5eSLisandro Dalcin   ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
62622e17dfb7SMatthew G. Knepley   ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr);
62632e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr);
62642e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr);
62652e17dfb7SMatthew G. Knepley   ierr = VecDestroy(&cVec);CHKERRQ(ierr);
62662e17dfb7SMatthew G. Knepley   ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
62672e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
62682e17dfb7SMatthew G. Knepley }
62692e17dfb7SMatthew G. Knepley 
6270e87bb0d3SMatthew G Knepley /*@
62713a93e3b7SToby Isaac   DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells
6272e87bb0d3SMatthew G Knepley 
6273d083f849SBarry Smith   Collective on v (see explanation below)
6274e87bb0d3SMatthew G Knepley 
6275e87bb0d3SMatthew G Knepley   Input Parameters:
6276e87bb0d3SMatthew G Knepley + dm - The DM
62773a93e3b7SToby Isaac . v - The Vec of points
627862a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST
62793a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point.
6280e87bb0d3SMatthew G Knepley 
628161e3bb9bSMatthew G Knepley   Output Parameter:
628262a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used
628362a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points.
62843a93e3b7SToby Isaac 
6285e87bb0d3SMatthew G Knepley 
6286e87bb0d3SMatthew G Knepley   Level: developer
628761e3bb9bSMatthew G Knepley 
628862a38674SMatthew G. Knepley   Notes:
62893a93e3b7SToby Isaac   To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator.
629062a38674SMatthew G. Knepley   To do a search of all the cells in the distributed mesh, v should have the same communicator as dm.
62913a93e3b7SToby Isaac 
62923a93e3b7SToby Isaac   If *cellSF is NULL on input, a PetscSF will be created.
629362a38674SMatthew G. Knepley   If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses.
62943a93e3b7SToby Isaac 
62953a93e3b7SToby Isaac   An array that maps each point to its containing cell can be obtained with
62963a93e3b7SToby Isaac 
629762a38674SMatthew G. Knepley $    const PetscSFNode *cells;
629862a38674SMatthew G. Knepley $    PetscInt           nFound;
6299a6216909SToby Isaac $    const PetscInt    *found;
630062a38674SMatthew G. Knepley $
6301a6216909SToby Isaac $    PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells);
63023a93e3b7SToby Isaac 
63033a93e3b7SToby 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
63043a93e3b7SToby Isaac   the index of the cell in its rank's local numbering.
63053a93e3b7SToby Isaac 
630662a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType
630761e3bb9bSMatthew G Knepley @*/
630862a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF)
6309e87bb0d3SMatthew G Knepley {
6310735aa83eSMatthew G Knepley   PetscErrorCode ierr;
6311735aa83eSMatthew G Knepley 
6312e87bb0d3SMatthew G Knepley   PetscFunctionBegin;
6313e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6314e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
6315e0fc9d1bSMatthew G. Knepley   PetscValidPointer(cellSF,4);
63163a93e3b7SToby Isaac   if (*cellSF) {
63173a93e3b7SToby Isaac     PetscMPIInt result;
63183a93e3b7SToby Isaac 
6319e0fc9d1bSMatthew G. Knepley     PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4);
6320a4f09dd6SDave May     ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRQ(ierr);
63213a93e3b7SToby 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");
6322e0fc9d1bSMatthew G. Knepley   } else {
63233a93e3b7SToby Isaac     ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr);
63243a93e3b7SToby Isaac   }
6325b9d85ea2SLisandro Dalcin   if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM");
632647a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
632762a38674SMatthew G. Knepley   ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr);
632847a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
6329e87bb0d3SMatthew G Knepley   PetscFunctionReturn(0);
6330e87bb0d3SMatthew G Knepley }
633114f150ffSMatthew G. Knepley 
6332f4d763aaSMatthew G. Knepley /*@
6333f4d763aaSMatthew G. Knepley   DMGetOutputDM - Retrieve the DM associated with the layout for output
6334f4d763aaSMatthew G. Knepley 
63358f700142SStefano Zampini   Collective on dm
63368f700142SStefano Zampini 
6337f4d763aaSMatthew G. Knepley   Input Parameter:
6338f4d763aaSMatthew G. Knepley . dm - The original DM
6339f4d763aaSMatthew G. Knepley 
6340f4d763aaSMatthew G. Knepley   Output Parameter:
6341f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output
6342f4d763aaSMatthew G. Knepley 
6343f4d763aaSMatthew G. Knepley   Level: intermediate
6344f4d763aaSMatthew G. Knepley 
6345e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection()
6346f4d763aaSMatthew G. Knepley @*/
634714f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm)
634814f150ffSMatthew G. Knepley {
6349c26acbdeSMatthew G. Knepley   PetscSection   section;
63502d4e4a49SMatthew G. Knepley   PetscBool      hasConstraints, ghasConstraints;
635114f150ffSMatthew G. Knepley   PetscErrorCode ierr;
635214f150ffSMatthew G. Knepley 
635314f150ffSMatthew G. Knepley   PetscFunctionBegin;
635414f150ffSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
635514f150ffSMatthew G. Knepley   PetscValidPointer(odm,2);
6356*92fd8e1eSJed Brown   ierr = DMGetLocalSection(dm, &section);CHKERRQ(ierr);
6357c26acbdeSMatthew G. Knepley   ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr);
6358127fe6b9SMatthew G. Knepley   ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
63592d4e4a49SMatthew G. Knepley   if (!ghasConstraints) {
6360c26acbdeSMatthew G. Knepley     *odm = dm;
6361c26acbdeSMatthew G. Knepley     PetscFunctionReturn(0);
6362c26acbdeSMatthew G. Knepley   }
636314f150ffSMatthew G. Knepley   if (!dm->dmBC) {
6364c26acbdeSMatthew G. Knepley     PetscSection newSection, gsection;
636514f150ffSMatthew G. Knepley     PetscSF      sf;
636614f150ffSMatthew G. Knepley 
636714f150ffSMatthew G. Knepley     ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr);
6368e5e52638SMatthew G. Knepley     ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr);
636914f150ffSMatthew G. Knepley     ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr);
6370*92fd8e1eSJed Brown     ierr = DMSetLocalSection(dm->dmBC, newSection);CHKERRQ(ierr);
637114f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);
637214f150ffSMatthew G. Knepley     ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr);
637315b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr);
6374e87a4003SBarry Smith     ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr);
637514f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr);
637614f150ffSMatthew G. Knepley   }
637714f150ffSMatthew G. Knepley   *odm = dm->dmBC;
637814f150ffSMatthew G. Knepley   PetscFunctionReturn(0);
637914f150ffSMatthew G. Knepley }
6380f4d763aaSMatthew G. Knepley 
6381f4d763aaSMatthew G. Knepley /*@
6382cdb7a50dSMatthew G. Knepley   DMGetOutputSequenceNumber - Retrieve the sequence number/value for output
6383f4d763aaSMatthew G. Knepley 
6384f4d763aaSMatthew G. Knepley   Input Parameter:
6385f4d763aaSMatthew G. Knepley . dm - The original DM
6386f4d763aaSMatthew G. Knepley 
6387cdb7a50dSMatthew G. Knepley   Output Parameters:
6388cdb7a50dSMatthew G. Knepley + num - The output sequence number
6389cdb7a50dSMatthew G. Knepley - val - The output sequence value
6390f4d763aaSMatthew G. Knepley 
6391f4d763aaSMatthew G. Knepley   Level: intermediate
6392f4d763aaSMatthew G. Knepley 
6393f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6394f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6395f4d763aaSMatthew G. Knepley 
6396f4d763aaSMatthew G. Knepley .seealso: VecView()
6397f4d763aaSMatthew G. Knepley @*/
6398cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val)
6399f4d763aaSMatthew G. Knepley {
6400f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6401f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6402534a8f05SLisandro Dalcin   if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;}
6403534a8f05SLisandro Dalcin   if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;}
6404f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6405f4d763aaSMatthew G. Knepley }
6406f4d763aaSMatthew G. Knepley 
6407f4d763aaSMatthew G. Knepley /*@
6408cdb7a50dSMatthew G. Knepley   DMSetOutputSequenceNumber - Set the sequence number/value for output
6409f4d763aaSMatthew G. Knepley 
6410f4d763aaSMatthew G. Knepley   Input Parameters:
6411f4d763aaSMatthew G. Knepley + dm - The original DM
6412cdb7a50dSMatthew G. Knepley . num - The output sequence number
6413cdb7a50dSMatthew G. Knepley - val - The output sequence value
6414f4d763aaSMatthew G. Knepley 
6415f4d763aaSMatthew G. Knepley   Level: intermediate
6416f4d763aaSMatthew G. Knepley 
6417f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6418f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6419f4d763aaSMatthew G. Knepley 
6420f4d763aaSMatthew G. Knepley .seealso: VecView()
6421f4d763aaSMatthew G. Knepley @*/
6422cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val)
6423f4d763aaSMatthew G. Knepley {
6424f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6425f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6426f4d763aaSMatthew G. Knepley   dm->outputSequenceNum = num;
6427cdb7a50dSMatthew G. Knepley   dm->outputSequenceVal = val;
6428cdb7a50dSMatthew G. Knepley   PetscFunctionReturn(0);
6429cdb7a50dSMatthew G. Knepley }
6430cdb7a50dSMatthew G. Knepley 
6431cdb7a50dSMatthew G. Knepley /*@C
6432cdb7a50dSMatthew G. Knepley   DMOutputSequenceLoad - Retrieve the sequence value from a Viewer
6433cdb7a50dSMatthew G. Knepley 
6434cdb7a50dSMatthew G. Knepley   Input Parameters:
6435cdb7a50dSMatthew G. Knepley + dm   - The original DM
6436cdb7a50dSMatthew G. Knepley . name - The sequence name
6437cdb7a50dSMatthew G. Knepley - num  - The output sequence number
6438cdb7a50dSMatthew G. Knepley 
6439cdb7a50dSMatthew G. Knepley   Output Parameter:
6440cdb7a50dSMatthew G. Knepley . val  - The output sequence value
6441cdb7a50dSMatthew G. Knepley 
6442cdb7a50dSMatthew G. Knepley   Level: intermediate
6443cdb7a50dSMatthew G. Knepley 
6444cdb7a50dSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6445cdb7a50dSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6446cdb7a50dSMatthew G. Knepley 
6447cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView()
6448cdb7a50dSMatthew G. Knepley @*/
6449cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val)
6450cdb7a50dSMatthew G. Knepley {
6451cdb7a50dSMatthew G. Knepley   PetscBool      ishdf5;
6452cdb7a50dSMatthew G. Knepley   PetscErrorCode ierr;
6453cdb7a50dSMatthew G. Knepley 
6454cdb7a50dSMatthew G. Knepley   PetscFunctionBegin;
6455cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6456cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
6457534a8f05SLisandro Dalcin   PetscValidRealPointer(val,4);
6458cdb7a50dSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr);
6459cdb7a50dSMatthew G. Knepley   if (ishdf5) {
6460cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
6461cdb7a50dSMatthew G. Knepley     PetscScalar value;
6462cdb7a50dSMatthew G. Knepley 
646339d25373SMatthew G. Knepley     ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr);
64644aeb217fSMatthew G. Knepley     *val = PetscRealPart(value);
6465cdb7a50dSMatthew G. Knepley #endif
6466cdb7a50dSMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()");
6467f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6468f4d763aaSMatthew G. Knepley }
64698e4ac7eaSMatthew G. Knepley 
64708e4ac7eaSMatthew G. Knepley /*@
64718e4ac7eaSMatthew G. Knepley   DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution
64728e4ac7eaSMatthew G. Knepley 
64738e4ac7eaSMatthew G. Knepley   Not collective
64748e4ac7eaSMatthew G. Knepley 
64758e4ac7eaSMatthew G. Knepley   Input Parameter:
64768e4ac7eaSMatthew G. Knepley . dm - The DM
64778e4ac7eaSMatthew G. Knepley 
64788e4ac7eaSMatthew G. Knepley   Output Parameter:
64798e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution
64808e4ac7eaSMatthew G. Knepley 
64818e4ac7eaSMatthew G. Knepley   Level: beginner
64828e4ac7eaSMatthew G. Knepley 
64838e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate()
64848e4ac7eaSMatthew G. Knepley @*/
64858e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural)
64868e4ac7eaSMatthew G. Knepley {
64878e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
64888e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6489534a8f05SLisandro Dalcin   PetscValidBoolPointer(useNatural, 2);
64908e4ac7eaSMatthew G. Knepley   *useNatural = dm->useNatural;
64918e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
64928e4ac7eaSMatthew G. Knepley }
64938e4ac7eaSMatthew G. Knepley 
64948e4ac7eaSMatthew G. Knepley /*@
64955d3b26e6SMatthew G. Knepley   DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution
64968e4ac7eaSMatthew G. Knepley 
64978e4ac7eaSMatthew G. Knepley   Collective on dm
64988e4ac7eaSMatthew G. Knepley 
64998e4ac7eaSMatthew G. Knepley   Input Parameters:
65008e4ac7eaSMatthew G. Knepley + dm - The DM
65018e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution
65028e4ac7eaSMatthew G. Knepley 
65035d3b26e6SMatthew G. Knepley   Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM()
65045d3b26e6SMatthew G. Knepley 
65058e4ac7eaSMatthew G. Knepley   Level: beginner
65068e4ac7eaSMatthew G. Knepley 
65075d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM()
65088e4ac7eaSMatthew G. Knepley @*/
65098e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural)
65108e4ac7eaSMatthew G. Knepley {
65118e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
65128e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
65138833efb5SBlaise Bourdin   PetscValidLogicalCollectiveBool(dm, useNatural, 2);
65148e4ac7eaSMatthew G. Knepley   dm->useNatural = useNatural;
65158e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
65168e4ac7eaSMatthew G. Knepley }
6517c58f1c22SToby Isaac 
6518c58f1c22SToby Isaac 
6519c58f1c22SToby Isaac /*@C
6520c58f1c22SToby Isaac   DMCreateLabel - Create a label of the given name if it does not already exist
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 
6528c58f1c22SToby Isaac   Level: intermediate
6529c58f1c22SToby Isaac 
6530c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6531c58f1c22SToby Isaac @*/
6532c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[])
6533c58f1c22SToby Isaac {
6534c58f1c22SToby Isaac   DMLabelLink    next  = dm->labels->next;
6535c58f1c22SToby Isaac   PetscBool      flg   = PETSC_FALSE;
6536d67d17b1SMatthew G. Knepley   const char    *lname;
6537c58f1c22SToby Isaac   PetscErrorCode ierr;
6538c58f1c22SToby Isaac 
6539c58f1c22SToby Isaac   PetscFunctionBegin;
6540c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6541c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6542c58f1c22SToby Isaac   while (next) {
6543d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6544d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
6545c58f1c22SToby Isaac     if (flg) break;
6546c58f1c22SToby Isaac     next = next->next;
6547c58f1c22SToby Isaac   }
6548c58f1c22SToby Isaac   if (!flg) {
6549c58f1c22SToby Isaac     DMLabelLink tmpLabel;
6550c58f1c22SToby Isaac 
6551c58f1c22SToby Isaac     ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
6552d67d17b1SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, name, &tmpLabel->label);CHKERRQ(ierr);
6553c58f1c22SToby Isaac     tmpLabel->output = PETSC_TRUE;
6554c58f1c22SToby Isaac     tmpLabel->next   = dm->labels->next;
6555c58f1c22SToby Isaac     dm->labels->next = tmpLabel;
6556c58f1c22SToby Isaac   }
6557c58f1c22SToby Isaac   PetscFunctionReturn(0);
6558c58f1c22SToby Isaac }
6559c58f1c22SToby Isaac 
6560c58f1c22SToby Isaac /*@C
6561c58f1c22SToby Isaac   DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default
6562c58f1c22SToby Isaac 
6563c58f1c22SToby Isaac   Not Collective
6564c58f1c22SToby Isaac 
6565c58f1c22SToby Isaac   Input Parameters:
6566c58f1c22SToby Isaac + dm   - The DM object
6567c58f1c22SToby Isaac . name - The label name
6568c58f1c22SToby Isaac - point - The mesh point
6569c58f1c22SToby Isaac 
6570c58f1c22SToby Isaac   Output Parameter:
6571c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label
6572c58f1c22SToby Isaac 
6573c58f1c22SToby Isaac   Level: beginner
6574c58f1c22SToby Isaac 
6575c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS()
6576c58f1c22SToby Isaac @*/
6577c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value)
6578c58f1c22SToby Isaac {
6579c58f1c22SToby Isaac   DMLabel        label;
6580c58f1c22SToby Isaac   PetscErrorCode ierr;
6581c58f1c22SToby Isaac 
6582c58f1c22SToby Isaac   PetscFunctionBegin;
6583c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6584c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6585c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
658613903a91SSatish Balay   if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name);
6587c58f1c22SToby Isaac   ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr);
6588c58f1c22SToby Isaac   PetscFunctionReturn(0);
6589c58f1c22SToby Isaac }
6590c58f1c22SToby Isaac 
6591c58f1c22SToby Isaac /*@C
6592c58f1c22SToby Isaac   DMSetLabelValue - Add a point to a Sieve Label with given value
6593c58f1c22SToby Isaac 
6594c58f1c22SToby Isaac   Not Collective
6595c58f1c22SToby Isaac 
6596c58f1c22SToby Isaac   Input Parameters:
6597c58f1c22SToby Isaac + dm   - The DM object
6598c58f1c22SToby Isaac . name - The label name
6599c58f1c22SToby Isaac . point - The mesh point
6600c58f1c22SToby Isaac - value - The label value for this point
6601c58f1c22SToby Isaac 
6602c58f1c22SToby Isaac   Output Parameter:
6603c58f1c22SToby Isaac 
6604c58f1c22SToby Isaac   Level: beginner
6605c58f1c22SToby Isaac 
6606c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue()
6607c58f1c22SToby Isaac @*/
6608c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6609c58f1c22SToby Isaac {
6610c58f1c22SToby Isaac   DMLabel        label;
6611c58f1c22SToby Isaac   PetscErrorCode ierr;
6612c58f1c22SToby Isaac 
6613c58f1c22SToby Isaac   PetscFunctionBegin;
6614c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6615c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6616c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6617c58f1c22SToby Isaac   if (!label) {
6618c58f1c22SToby Isaac     ierr = DMCreateLabel(dm, name);CHKERRQ(ierr);
6619c58f1c22SToby Isaac     ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6620c58f1c22SToby Isaac   }
6621c58f1c22SToby Isaac   ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr);
6622c58f1c22SToby Isaac   PetscFunctionReturn(0);
6623c58f1c22SToby Isaac }
6624c58f1c22SToby Isaac 
6625c58f1c22SToby Isaac /*@C
6626c58f1c22SToby Isaac   DMClearLabelValue - Remove a point from a Sieve Label with given value
6627c58f1c22SToby Isaac 
6628c58f1c22SToby Isaac   Not Collective
6629c58f1c22SToby Isaac 
6630c58f1c22SToby Isaac   Input Parameters:
6631c58f1c22SToby Isaac + dm   - The DM object
6632c58f1c22SToby Isaac . name - The label name
6633c58f1c22SToby Isaac . point - The mesh point
6634c58f1c22SToby Isaac - value - The label value for this point
6635c58f1c22SToby Isaac 
6636c58f1c22SToby Isaac   Output Parameter:
6637c58f1c22SToby Isaac 
6638c58f1c22SToby Isaac   Level: beginner
6639c58f1c22SToby Isaac 
6640c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS()
6641c58f1c22SToby Isaac @*/
6642c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6643c58f1c22SToby Isaac {
6644c58f1c22SToby Isaac   DMLabel        label;
6645c58f1c22SToby Isaac   PetscErrorCode ierr;
6646c58f1c22SToby Isaac 
6647c58f1c22SToby Isaac   PetscFunctionBegin;
6648c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6649c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6650c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6651c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6652c58f1c22SToby Isaac   ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr);
6653c58f1c22SToby Isaac   PetscFunctionReturn(0);
6654c58f1c22SToby Isaac }
6655c58f1c22SToby Isaac 
6656c58f1c22SToby Isaac /*@C
6657c58f1c22SToby Isaac   DMGetLabelSize - Get the number of different integer ids in a Label
6658c58f1c22SToby Isaac 
6659c58f1c22SToby Isaac   Not Collective
6660c58f1c22SToby Isaac 
6661c58f1c22SToby Isaac   Input Parameters:
6662c58f1c22SToby Isaac + dm   - The DM object
6663c58f1c22SToby Isaac - name - The label name
6664c58f1c22SToby Isaac 
6665c58f1c22SToby Isaac   Output Parameter:
6666c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist
6667c58f1c22SToby Isaac 
6668c58f1c22SToby Isaac   Level: beginner
6669c58f1c22SToby Isaac 
6670df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue()
6671c58f1c22SToby Isaac @*/
6672c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size)
6673c58f1c22SToby Isaac {
6674c58f1c22SToby Isaac   DMLabel        label;
6675c58f1c22SToby Isaac   PetscErrorCode ierr;
6676c58f1c22SToby Isaac 
6677c58f1c22SToby Isaac   PetscFunctionBegin;
6678c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6679c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6680534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 3);
6681c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6682c58f1c22SToby Isaac   *size = 0;
6683c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6684c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr);
6685c58f1c22SToby Isaac   PetscFunctionReturn(0);
6686c58f1c22SToby Isaac }
6687c58f1c22SToby Isaac 
6688c58f1c22SToby Isaac /*@C
6689c58f1c22SToby Isaac   DMGetLabelIdIS - Get the integer ids in a label
6690c58f1c22SToby Isaac 
6691c58f1c22SToby Isaac   Not Collective
6692c58f1c22SToby Isaac 
6693c58f1c22SToby Isaac   Input Parameters:
6694c58f1c22SToby Isaac + mesh - The DM object
6695c58f1c22SToby Isaac - name - The label name
6696c58f1c22SToby Isaac 
6697c58f1c22SToby Isaac   Output Parameter:
6698c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist
6699c58f1c22SToby Isaac 
6700c58f1c22SToby Isaac   Level: beginner
6701c58f1c22SToby Isaac 
6702c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize()
6703c58f1c22SToby Isaac @*/
6704c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids)
6705c58f1c22SToby Isaac {
6706c58f1c22SToby Isaac   DMLabel        label;
6707c58f1c22SToby Isaac   PetscErrorCode ierr;
6708c58f1c22SToby Isaac 
6709c58f1c22SToby Isaac   PetscFunctionBegin;
6710c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6711c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6712c58f1c22SToby Isaac   PetscValidPointer(ids, 3);
6713c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6714c58f1c22SToby Isaac   *ids = NULL;
6715dab2e251SBlaise Bourdin  if (label) {
6716c58f1c22SToby Isaac     ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr);
6717dab2e251SBlaise Bourdin   } else {
6718dab2e251SBlaise Bourdin     /* returning an empty IS */
6719dab2e251SBlaise Bourdin     ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr);
6720dab2e251SBlaise Bourdin   }
6721c58f1c22SToby Isaac   PetscFunctionReturn(0);
6722c58f1c22SToby Isaac }
6723c58f1c22SToby Isaac 
6724c58f1c22SToby Isaac /*@C
6725c58f1c22SToby Isaac   DMGetStratumSize - Get the number of points in a label stratum
6726c58f1c22SToby Isaac 
6727c58f1c22SToby Isaac   Not Collective
6728c58f1c22SToby Isaac 
6729c58f1c22SToby Isaac   Input Parameters:
6730c58f1c22SToby Isaac + dm - The DM object
6731c58f1c22SToby Isaac . name - The label name
6732c58f1c22SToby Isaac - value - The stratum value
6733c58f1c22SToby Isaac 
6734c58f1c22SToby Isaac   Output Parameter:
6735c58f1c22SToby Isaac . size - The stratum size
6736c58f1c22SToby Isaac 
6737c58f1c22SToby Isaac   Level: beginner
6738c58f1c22SToby Isaac 
6739c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds()
6740c58f1c22SToby Isaac @*/
6741c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size)
6742c58f1c22SToby Isaac {
6743c58f1c22SToby Isaac   DMLabel        label;
6744c58f1c22SToby Isaac   PetscErrorCode ierr;
6745c58f1c22SToby Isaac 
6746c58f1c22SToby Isaac   PetscFunctionBegin;
6747c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6748c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6749534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 4);
6750c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6751c58f1c22SToby Isaac   *size = 0;
6752c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6753c58f1c22SToby Isaac   ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr);
6754c58f1c22SToby Isaac   PetscFunctionReturn(0);
6755c58f1c22SToby Isaac }
6756c58f1c22SToby Isaac 
6757c58f1c22SToby Isaac /*@C
6758c58f1c22SToby Isaac   DMGetStratumIS - Get the points in a label stratum
6759c58f1c22SToby Isaac 
6760c58f1c22SToby Isaac   Not Collective
6761c58f1c22SToby Isaac 
6762c58f1c22SToby Isaac   Input Parameters:
6763c58f1c22SToby Isaac + dm - The DM object
6764c58f1c22SToby Isaac . name - The label name
6765c58f1c22SToby Isaac - value - The stratum value
6766c58f1c22SToby Isaac 
6767c58f1c22SToby Isaac   Output Parameter:
6768c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value
6769c58f1c22SToby Isaac 
6770c58f1c22SToby Isaac   Level: beginner
6771c58f1c22SToby Isaac 
6772c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize()
6773c58f1c22SToby Isaac @*/
6774c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points)
6775c58f1c22SToby Isaac {
6776c58f1c22SToby Isaac   DMLabel        label;
6777c58f1c22SToby Isaac   PetscErrorCode ierr;
6778c58f1c22SToby Isaac 
6779c58f1c22SToby Isaac   PetscFunctionBegin;
6780c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6781c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6782c58f1c22SToby Isaac   PetscValidPointer(points, 4);
6783c58f1c22SToby Isaac   ierr    = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6784c58f1c22SToby Isaac   *points = NULL;
6785c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6786c58f1c22SToby Isaac   ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr);
6787c58f1c22SToby Isaac   PetscFunctionReturn(0);
6788c58f1c22SToby Isaac }
6789c58f1c22SToby Isaac 
67904de306b1SToby Isaac /*@C
67919044fa66SMatthew G. Knepley   DMSetStratumIS - Set the points in a label stratum
67924de306b1SToby Isaac 
67934de306b1SToby Isaac   Not Collective
67944de306b1SToby Isaac 
67954de306b1SToby Isaac   Input Parameters:
67964de306b1SToby Isaac + dm - The DM object
67974de306b1SToby Isaac . name - The label name
67984de306b1SToby Isaac . value - The stratum value
67994de306b1SToby Isaac - points - The stratum points
68004de306b1SToby Isaac 
68014de306b1SToby Isaac   Level: beginner
68024de306b1SToby Isaac 
68034de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize()
68044de306b1SToby Isaac @*/
68054de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points)
68064de306b1SToby Isaac {
68074de306b1SToby Isaac   DMLabel        label;
68084de306b1SToby Isaac   PetscErrorCode ierr;
68094de306b1SToby Isaac 
68104de306b1SToby Isaac   PetscFunctionBegin;
68114de306b1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
68124de306b1SToby Isaac   PetscValidCharPointer(name, 2);
68134de306b1SToby Isaac   PetscValidPointer(points, 4);
68144de306b1SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
68154de306b1SToby Isaac   if (!label) PetscFunctionReturn(0);
68164de306b1SToby Isaac   ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr);
68174de306b1SToby Isaac   PetscFunctionReturn(0);
68184de306b1SToby Isaac }
68194de306b1SToby Isaac 
6820c58f1c22SToby Isaac /*@C
6821c58f1c22SToby Isaac   DMClearLabelStratum - Remove all points from a stratum from a Sieve Label
6822c58f1c22SToby Isaac 
6823c58f1c22SToby Isaac   Not Collective
6824c58f1c22SToby Isaac 
6825c58f1c22SToby Isaac   Input Parameters:
6826c58f1c22SToby Isaac + dm   - The DM object
6827c58f1c22SToby Isaac . name - The label name
6828c58f1c22SToby Isaac - value - The label value for this point
6829c58f1c22SToby Isaac 
6830c58f1c22SToby Isaac   Output Parameter:
6831c58f1c22SToby Isaac 
6832c58f1c22SToby Isaac   Level: beginner
6833c58f1c22SToby Isaac 
6834c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue()
6835c58f1c22SToby Isaac @*/
6836c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value)
6837c58f1c22SToby Isaac {
6838c58f1c22SToby Isaac   DMLabel        label;
6839c58f1c22SToby Isaac   PetscErrorCode ierr;
6840c58f1c22SToby Isaac 
6841c58f1c22SToby Isaac   PetscFunctionBegin;
6842c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6843c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6844c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6845c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6846c58f1c22SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
6847c58f1c22SToby Isaac   PetscFunctionReturn(0);
6848c58f1c22SToby Isaac }
6849c58f1c22SToby Isaac 
6850c58f1c22SToby Isaac /*@
6851c58f1c22SToby Isaac   DMGetNumLabels - Return the number of labels defined by the mesh
6852c58f1c22SToby Isaac 
6853c58f1c22SToby Isaac   Not Collective
6854c58f1c22SToby Isaac 
6855c58f1c22SToby Isaac   Input Parameter:
6856c58f1c22SToby Isaac . dm   - The DM object
6857c58f1c22SToby Isaac 
6858c58f1c22SToby Isaac   Output Parameter:
6859c58f1c22SToby Isaac . numLabels - the number of Labels
6860c58f1c22SToby Isaac 
6861c58f1c22SToby Isaac   Level: intermediate
6862c58f1c22SToby Isaac 
6863c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6864c58f1c22SToby Isaac @*/
6865c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels)
6866c58f1c22SToby Isaac {
6867c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
6868c58f1c22SToby Isaac   PetscInt  n    = 0;
6869c58f1c22SToby Isaac 
6870c58f1c22SToby Isaac   PetscFunctionBegin;
6871c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6872534a8f05SLisandro Dalcin   PetscValidIntPointer(numLabels, 2);
6873c58f1c22SToby Isaac   while (next) {++n; next = next->next;}
6874c58f1c22SToby Isaac   *numLabels = n;
6875c58f1c22SToby Isaac   PetscFunctionReturn(0);
6876c58f1c22SToby Isaac }
6877c58f1c22SToby Isaac 
6878c58f1c22SToby Isaac /*@C
6879c58f1c22SToby Isaac   DMGetLabelName - Return the name of nth label
6880c58f1c22SToby Isaac 
6881c58f1c22SToby Isaac   Not Collective
6882c58f1c22SToby Isaac 
6883c58f1c22SToby Isaac   Input Parameters:
6884c58f1c22SToby Isaac + dm - The DM object
6885c58f1c22SToby Isaac - n  - the label number
6886c58f1c22SToby Isaac 
6887c58f1c22SToby Isaac   Output Parameter:
6888c58f1c22SToby Isaac . name - the label name
6889c58f1c22SToby Isaac 
6890c58f1c22SToby Isaac   Level: intermediate
6891c58f1c22SToby Isaac 
6892c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6893c58f1c22SToby Isaac @*/
6894c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name)
6895c58f1c22SToby Isaac {
6896c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6897c58f1c22SToby Isaac   PetscInt       l    = 0;
6898d67d17b1SMatthew G. Knepley   PetscErrorCode ierr;
6899c58f1c22SToby Isaac 
6900c58f1c22SToby Isaac   PetscFunctionBegin;
6901c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6902c58f1c22SToby Isaac   PetscValidPointer(name, 3);
6903c58f1c22SToby Isaac   while (next) {
6904c58f1c22SToby Isaac     if (l == n) {
6905d67d17b1SMatthew G. Knepley       ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr);
6906c58f1c22SToby Isaac       PetscFunctionReturn(0);
6907c58f1c22SToby Isaac     }
6908c58f1c22SToby Isaac     ++l;
6909c58f1c22SToby Isaac     next = next->next;
6910c58f1c22SToby Isaac   }
6911c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
6912c58f1c22SToby Isaac }
6913c58f1c22SToby Isaac 
6914c58f1c22SToby Isaac /*@C
6915c58f1c22SToby Isaac   DMHasLabel - Determine whether the mesh has a label of a given name
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 . hasLabel - PETSC_TRUE if the label is present
6925c58f1c22SToby Isaac 
6926c58f1c22SToby Isaac   Level: intermediate
6927c58f1c22SToby Isaac 
6928c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6929c58f1c22SToby Isaac @*/
6930c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel)
6931c58f1c22SToby Isaac {
6932c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6933d67d17b1SMatthew G. Knepley   const char    *lname;
6934c58f1c22SToby Isaac   PetscErrorCode ierr;
6935c58f1c22SToby Isaac 
6936c58f1c22SToby Isaac   PetscFunctionBegin;
6937c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6938c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6939534a8f05SLisandro Dalcin   PetscValidBoolPointer(hasLabel, 3);
6940c58f1c22SToby Isaac   *hasLabel = PETSC_FALSE;
6941c58f1c22SToby Isaac   while (next) {
6942d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6943d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr);
6944c58f1c22SToby Isaac     if (*hasLabel) break;
6945c58f1c22SToby Isaac     next = next->next;
6946c58f1c22SToby Isaac   }
6947c58f1c22SToby Isaac   PetscFunctionReturn(0);
6948c58f1c22SToby Isaac }
6949c58f1c22SToby Isaac 
6950c58f1c22SToby Isaac /*@C
6951c58f1c22SToby Isaac   DMGetLabel - Return the label of a given name, or NULL
6952c58f1c22SToby Isaac 
6953c58f1c22SToby Isaac   Not Collective
6954c58f1c22SToby Isaac 
6955c58f1c22SToby Isaac   Input Parameters:
6956c58f1c22SToby Isaac + dm   - The DM object
6957c58f1c22SToby Isaac - name - The label name
6958c58f1c22SToby Isaac 
6959c58f1c22SToby Isaac   Output Parameter:
6960c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
6961c58f1c22SToby Isaac 
6962c58f1c22SToby Isaac   Level: intermediate
6963c58f1c22SToby Isaac 
6964c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6965c58f1c22SToby Isaac @*/
6966c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label)
6967c58f1c22SToby Isaac {
6968c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6969c58f1c22SToby Isaac   PetscBool      hasLabel;
6970d67d17b1SMatthew G. Knepley   const char    *lname;
6971c58f1c22SToby Isaac   PetscErrorCode ierr;
6972c58f1c22SToby Isaac 
6973c58f1c22SToby Isaac   PetscFunctionBegin;
6974c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6975c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6976c58f1c22SToby Isaac   PetscValidPointer(label, 3);
6977c58f1c22SToby Isaac   *label = NULL;
6978c58f1c22SToby Isaac   while (next) {
6979d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6980d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
6981c58f1c22SToby Isaac     if (hasLabel) {
6982c58f1c22SToby Isaac       *label = next->label;
6983c58f1c22SToby Isaac       break;
6984c58f1c22SToby Isaac     }
6985c58f1c22SToby Isaac     next = next->next;
6986c58f1c22SToby Isaac   }
6987c58f1c22SToby Isaac   PetscFunctionReturn(0);
6988c58f1c22SToby Isaac }
6989c58f1c22SToby Isaac 
6990c58f1c22SToby Isaac /*@C
6991c58f1c22SToby Isaac   DMGetLabelByNum - Return the nth label
6992c58f1c22SToby Isaac 
6993c58f1c22SToby Isaac   Not Collective
6994c58f1c22SToby Isaac 
6995c58f1c22SToby Isaac   Input Parameters:
6996c58f1c22SToby Isaac + dm - The DM object
6997c58f1c22SToby Isaac - n  - the label number
6998c58f1c22SToby Isaac 
6999c58f1c22SToby Isaac   Output Parameter:
7000c58f1c22SToby Isaac . label - the label
7001c58f1c22SToby Isaac 
7002c58f1c22SToby Isaac   Level: intermediate
7003c58f1c22SToby Isaac 
7004c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7005c58f1c22SToby Isaac @*/
7006c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label)
7007c58f1c22SToby Isaac {
7008c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
7009c58f1c22SToby Isaac   PetscInt    l    = 0;
7010c58f1c22SToby Isaac 
7011c58f1c22SToby Isaac   PetscFunctionBegin;
7012c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7013c58f1c22SToby Isaac   PetscValidPointer(label, 3);
7014c58f1c22SToby Isaac   while (next) {
7015c58f1c22SToby Isaac     if (l == n) {
7016c58f1c22SToby Isaac       *label = next->label;
7017c58f1c22SToby Isaac       PetscFunctionReturn(0);
7018c58f1c22SToby Isaac     }
7019c58f1c22SToby Isaac     ++l;
7020c58f1c22SToby Isaac     next = next->next;
7021c58f1c22SToby Isaac   }
7022c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
7023c58f1c22SToby Isaac }
7024c58f1c22SToby Isaac 
7025c58f1c22SToby Isaac /*@C
7026c58f1c22SToby Isaac   DMAddLabel - Add the label to this mesh
7027c58f1c22SToby Isaac 
7028c58f1c22SToby Isaac   Not Collective
7029c58f1c22SToby Isaac 
7030c58f1c22SToby Isaac   Input Parameters:
7031c58f1c22SToby Isaac + dm   - The DM object
7032c58f1c22SToby Isaac - label - The DMLabel
7033c58f1c22SToby Isaac 
7034c58f1c22SToby Isaac   Level: developer
7035c58f1c22SToby Isaac 
7036c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7037c58f1c22SToby Isaac @*/
7038c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label)
7039c58f1c22SToby Isaac {
7040c58f1c22SToby Isaac   DMLabelLink    tmpLabel;
7041c58f1c22SToby Isaac   PetscBool      hasLabel;
7042d67d17b1SMatthew G. Knepley   const char    *lname;
7043c58f1c22SToby Isaac   PetscErrorCode ierr;
7044c58f1c22SToby Isaac 
7045c58f1c22SToby Isaac   PetscFunctionBegin;
7046c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7047d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
7048d67d17b1SMatthew G. Knepley   ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr);
7049d67d17b1SMatthew G. Knepley   if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname);
7050c58f1c22SToby Isaac   ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
7051c58f1c22SToby Isaac   tmpLabel->label  = label;
7052c58f1c22SToby Isaac   tmpLabel->output = PETSC_TRUE;
7053c58f1c22SToby Isaac   tmpLabel->next   = dm->labels->next;
7054c58f1c22SToby Isaac   dm->labels->next = tmpLabel;
7055c58f1c22SToby Isaac   PetscFunctionReturn(0);
7056c58f1c22SToby Isaac }
7057c58f1c22SToby Isaac 
7058c58f1c22SToby Isaac /*@C
7059c58f1c22SToby Isaac   DMRemoveLabel - Remove the label from this mesh
7060c58f1c22SToby Isaac 
7061c58f1c22SToby Isaac   Not Collective
7062c58f1c22SToby Isaac 
7063c58f1c22SToby Isaac   Input Parameters:
7064c58f1c22SToby Isaac + dm   - The DM object
7065c58f1c22SToby Isaac - name - The label name
7066c58f1c22SToby Isaac 
7067c58f1c22SToby Isaac   Output Parameter:
7068c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
7069c58f1c22SToby Isaac 
7070c58f1c22SToby Isaac   Level: developer
7071c58f1c22SToby Isaac 
7072c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7073c58f1c22SToby Isaac @*/
7074c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label)
7075c58f1c22SToby Isaac {
7076c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
7077c58f1c22SToby Isaac   DMLabelLink    last = NULL;
7078c58f1c22SToby Isaac   PetscBool      hasLabel;
7079d67d17b1SMatthew G. Knepley   const char    *lname;
7080c58f1c22SToby Isaac   PetscErrorCode ierr;
7081c58f1c22SToby Isaac 
7082c58f1c22SToby Isaac   PetscFunctionBegin;
7083c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7084c58f1c22SToby Isaac   ierr   = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr);
7085c58f1c22SToby Isaac   *label = NULL;
7086c58f1c22SToby Isaac   if (!hasLabel) PetscFunctionReturn(0);
7087c58f1c22SToby Isaac   while (next) {
7088d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7089d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
7090c58f1c22SToby Isaac     if (hasLabel) {
7091c58f1c22SToby Isaac       if (last) last->next       = next->next;
7092c58f1c22SToby Isaac       else      dm->labels->next = next->next;
7093c58f1c22SToby Isaac       next->next = NULL;
7094c58f1c22SToby Isaac       *label     = next->label;
7095c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr);
7096c58f1c22SToby Isaac       if (hasLabel) {
7097c58f1c22SToby Isaac         dm->depthLabel = NULL;
7098c58f1c22SToby Isaac       }
7099c58f1c22SToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
7100c58f1c22SToby Isaac       break;
7101c58f1c22SToby Isaac     }
7102c58f1c22SToby Isaac     last = next;
7103c58f1c22SToby Isaac     next = next->next;
7104c58f1c22SToby Isaac   }
7105c58f1c22SToby Isaac   PetscFunctionReturn(0);
7106c58f1c22SToby Isaac }
7107c58f1c22SToby Isaac 
7108c58f1c22SToby Isaac /*@C
7109c58f1c22SToby Isaac   DMGetLabelOutput - Get the output flag for a given label
7110c58f1c22SToby Isaac 
7111c58f1c22SToby Isaac   Not Collective
7112c58f1c22SToby Isaac 
7113c58f1c22SToby Isaac   Input Parameters:
7114c58f1c22SToby Isaac + dm   - The DM object
7115c58f1c22SToby Isaac - name - The label name
7116c58f1c22SToby Isaac 
7117c58f1c22SToby Isaac   Output Parameter:
7118c58f1c22SToby Isaac . output - The flag for output
7119c58f1c22SToby Isaac 
7120c58f1c22SToby Isaac   Level: developer
7121c58f1c22SToby Isaac 
7122c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7123c58f1c22SToby Isaac @*/
7124c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output)
7125c58f1c22SToby Isaac {
7126c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
7127d67d17b1SMatthew G. Knepley   const char    *lname;
7128c58f1c22SToby Isaac   PetscErrorCode ierr;
7129c58f1c22SToby Isaac 
7130c58f1c22SToby Isaac   PetscFunctionBegin;
7131c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7132c58f1c22SToby Isaac   PetscValidPointer(name, 2);
7133c58f1c22SToby Isaac   PetscValidPointer(output, 3);
7134c58f1c22SToby Isaac   while (next) {
7135c58f1c22SToby Isaac     PetscBool flg;
7136c58f1c22SToby Isaac 
7137d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7138d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7139c58f1c22SToby Isaac     if (flg) {*output = next->output; PetscFunctionReturn(0);}
7140c58f1c22SToby Isaac     next = next->next;
7141c58f1c22SToby Isaac   }
7142c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7143c58f1c22SToby Isaac }
7144c58f1c22SToby Isaac 
7145c58f1c22SToby Isaac /*@C
7146c58f1c22SToby Isaac   DMSetLabelOutput - Set the output flag for a given label
7147c58f1c22SToby Isaac 
7148c58f1c22SToby Isaac   Not Collective
7149c58f1c22SToby Isaac 
7150c58f1c22SToby Isaac   Input Parameters:
7151c58f1c22SToby Isaac + dm     - The DM object
7152c58f1c22SToby Isaac . name   - The label name
7153c58f1c22SToby Isaac - output - The flag for output
7154c58f1c22SToby Isaac 
7155c58f1c22SToby Isaac   Level: developer
7156c58f1c22SToby Isaac 
7157c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7158c58f1c22SToby Isaac @*/
7159c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output)
7160c58f1c22SToby Isaac {
7161c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
7162d67d17b1SMatthew G. Knepley   const char    *lname;
7163c58f1c22SToby Isaac   PetscErrorCode ierr;
7164c58f1c22SToby Isaac 
7165c58f1c22SToby Isaac   PetscFunctionBegin;
7166c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7167534a8f05SLisandro Dalcin   PetscValidCharPointer(name, 2);
7168c58f1c22SToby Isaac   while (next) {
7169c58f1c22SToby Isaac     PetscBool flg;
7170c58f1c22SToby Isaac 
7171d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7172d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7173c58f1c22SToby Isaac     if (flg) {next->output = output; PetscFunctionReturn(0);}
7174c58f1c22SToby Isaac     next = next->next;
7175c58f1c22SToby Isaac   }
7176c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7177c58f1c22SToby Isaac }
7178c58f1c22SToby Isaac 
7179c58f1c22SToby Isaac 
7180c58f1c22SToby Isaac /*@
7181c58f1c22SToby Isaac   DMCopyLabels - Copy labels from one mesh to another with a superset of the points
7182c58f1c22SToby Isaac 
7183d083f849SBarry Smith   Collective on dmA
7184c58f1c22SToby Isaac 
7185c58f1c22SToby Isaac   Input Parameter:
71862e17dfb7SMatthew G. Knepley . dmA - The DM object with initial labels
7187c58f1c22SToby Isaac 
7188c58f1c22SToby Isaac   Output Parameter:
71892e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels
7190c58f1c22SToby Isaac 
7191c58f1c22SToby Isaac   Level: intermediate
7192c58f1c22SToby Isaac 
7193c58f1c22SToby Isaac   Note: This is typically used when interpolating or otherwise adding to a mesh
7194c58f1c22SToby Isaac 
7195367003a6SStefano Zampini .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection()
7196c58f1c22SToby Isaac @*/
7197c58f1c22SToby Isaac PetscErrorCode DMCopyLabels(DM dmA, DM dmB)
7198c58f1c22SToby Isaac {
7199c58f1c22SToby Isaac   PetscInt       numLabels, l;
7200c58f1c22SToby Isaac   PetscErrorCode ierr;
7201c58f1c22SToby Isaac 
7202c58f1c22SToby Isaac   PetscFunctionBegin;
7203c58f1c22SToby Isaac   if (dmA == dmB) PetscFunctionReturn(0);
7204c58f1c22SToby Isaac   ierr = DMGetNumLabels(dmA, &numLabels);CHKERRQ(ierr);
7205c58f1c22SToby Isaac   for (l = 0; l < numLabels; ++l) {
7206c58f1c22SToby Isaac     DMLabel     label, labelNew;
7207c58f1c22SToby Isaac     const char *name;
7208c58f1c22SToby Isaac     PetscBool   flg;
7209c58f1c22SToby Isaac 
7210c58f1c22SToby Isaac     ierr = DMGetLabelName(dmA, l, &name);CHKERRQ(ierr);
7211c58f1c22SToby Isaac     ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr);
7212c58f1c22SToby Isaac     if (flg) continue;
72137d5acc75SStefano Zampini     ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr);
72147d5acc75SStefano Zampini     if (flg) continue;
7215c58f1c22SToby Isaac     ierr = DMGetLabel(dmA, name, &label);CHKERRQ(ierr);
7216c58f1c22SToby Isaac     ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr);
7217c58f1c22SToby Isaac     ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr);
7218c58f1c22SToby Isaac   }
7219c58f1c22SToby Isaac   PetscFunctionReturn(0);
7220c58f1c22SToby Isaac }
7221a8fb8f29SToby Isaac 
7222a8fb8f29SToby Isaac /*@
7223a8fb8f29SToby Isaac   DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement
7224a8fb8f29SToby Isaac 
7225a8fb8f29SToby Isaac   Input Parameter:
7226a8fb8f29SToby Isaac . dm - The DM object
7227a8fb8f29SToby Isaac 
7228a8fb8f29SToby Isaac   Output Parameter:
7229a8fb8f29SToby Isaac . cdm - The coarse DM
7230a8fb8f29SToby Isaac 
7231a8fb8f29SToby Isaac   Level: intermediate
7232a8fb8f29SToby Isaac 
7233a8fb8f29SToby Isaac .seealso: DMSetCoarseDM()
7234a8fb8f29SToby Isaac @*/
7235a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm)
7236a8fb8f29SToby Isaac {
7237a8fb8f29SToby Isaac   PetscFunctionBegin;
7238a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7239a8fb8f29SToby Isaac   PetscValidPointer(cdm, 2);
7240a8fb8f29SToby Isaac   *cdm = dm->coarseMesh;
7241a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7242a8fb8f29SToby Isaac }
7243a8fb8f29SToby Isaac 
7244a8fb8f29SToby Isaac /*@
7245a8fb8f29SToby Isaac   DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement
7246a8fb8f29SToby Isaac 
7247a8fb8f29SToby Isaac   Input Parameters:
7248a8fb8f29SToby Isaac + dm - The DM object
7249a8fb8f29SToby Isaac - cdm - The coarse DM
7250a8fb8f29SToby Isaac 
7251a8fb8f29SToby Isaac   Level: intermediate
7252a8fb8f29SToby Isaac 
7253a8fb8f29SToby Isaac .seealso: DMGetCoarseDM()
7254a8fb8f29SToby Isaac @*/
7255a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm)
7256a8fb8f29SToby Isaac {
7257a8fb8f29SToby Isaac   PetscErrorCode ierr;
7258a8fb8f29SToby Isaac 
7259a8fb8f29SToby Isaac   PetscFunctionBegin;
7260a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7261a8fb8f29SToby Isaac   if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2);
7262a8fb8f29SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
7263a8fb8f29SToby Isaac   ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr);
7264a8fb8f29SToby Isaac   dm->coarseMesh = cdm;
7265a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7266a8fb8f29SToby Isaac }
7267a8fb8f29SToby Isaac 
726888bdff64SToby Isaac /*@
726988bdff64SToby Isaac   DMGetFineDM - Get the fine mesh from which this was obtained by refinement
727088bdff64SToby Isaac 
727188bdff64SToby Isaac   Input Parameter:
727288bdff64SToby Isaac . dm - The DM object
727388bdff64SToby Isaac 
727488bdff64SToby Isaac   Output Parameter:
727588bdff64SToby Isaac . fdm - The fine DM
727688bdff64SToby Isaac 
727788bdff64SToby Isaac   Level: intermediate
727888bdff64SToby Isaac 
727988bdff64SToby Isaac .seealso: DMSetFineDM()
728088bdff64SToby Isaac @*/
728188bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm)
728288bdff64SToby Isaac {
728388bdff64SToby Isaac   PetscFunctionBegin;
728488bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
728588bdff64SToby Isaac   PetscValidPointer(fdm, 2);
728688bdff64SToby Isaac   *fdm = dm->fineMesh;
728788bdff64SToby Isaac   PetscFunctionReturn(0);
728888bdff64SToby Isaac }
728988bdff64SToby Isaac 
729088bdff64SToby Isaac /*@
729188bdff64SToby Isaac   DMSetFineDM - Set the fine mesh from which this was obtained by refinement
729288bdff64SToby Isaac 
729388bdff64SToby Isaac   Input Parameters:
729488bdff64SToby Isaac + dm - The DM object
729588bdff64SToby Isaac - fdm - The fine DM
729688bdff64SToby Isaac 
729788bdff64SToby Isaac   Level: intermediate
729888bdff64SToby Isaac 
729988bdff64SToby Isaac .seealso: DMGetFineDM()
730088bdff64SToby Isaac @*/
730188bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm)
730288bdff64SToby Isaac {
730388bdff64SToby Isaac   PetscErrorCode ierr;
730488bdff64SToby Isaac 
730588bdff64SToby Isaac   PetscFunctionBegin;
730688bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
730788bdff64SToby Isaac   if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2);
730888bdff64SToby Isaac   ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr);
730988bdff64SToby Isaac   ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr);
731088bdff64SToby Isaac   dm->fineMesh = fdm;
731188bdff64SToby Isaac   PetscFunctionReturn(0);
731288bdff64SToby Isaac }
731388bdff64SToby Isaac 
7314a6ba4734SToby Isaac /*=== DMBoundary code ===*/
7315a6ba4734SToby Isaac 
7316a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew)
7317a6ba4734SToby Isaac {
7318e5e52638SMatthew G. Knepley   PetscInt       d;
7319a6ba4734SToby Isaac   PetscErrorCode ierr;
7320a6ba4734SToby Isaac 
7321a6ba4734SToby Isaac   PetscFunctionBegin;
7322e5e52638SMatthew G. Knepley   for (d = 0; d < dm->Nds; ++d) {
7323e5e52638SMatthew G. Knepley     ierr = PetscDSCopyBoundary(dm->probs[d].ds, dmNew->probs[d].ds);CHKERRQ(ierr);
7324e5e52638SMatthew G. Knepley   }
7325a6ba4734SToby Isaac   PetscFunctionReturn(0);
7326a6ba4734SToby Isaac }
7327a6ba4734SToby Isaac 
7328a6ba4734SToby Isaac /*@C
7329a6ba4734SToby Isaac   DMAddBoundary - Add a boundary condition to the model
7330a6ba4734SToby Isaac 
7331a6ba4734SToby Isaac   Input Parameters:
73324c258f51SMatthew G. Knepley + dm          - The DM, with a PetscDS that matches the problem being constrained
7333f971fd6bSMatthew G. Knepley . type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7334a6ba4734SToby Isaac . name        - The BC name
7335a6ba4734SToby Isaac . labelname   - The label defining constrained points
7336a6ba4734SToby Isaac . field       - The field to constrain
7337e8ecbf3fSStefano Zampini . numcomps    - The number of constrained field components (0 will constrain all fields)
7338a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7339a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7340a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7341a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7342a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7343a6ba4734SToby Isaac 
7344a6ba4734SToby Isaac   Options Database Keys:
7345a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7346a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7347a6ba4734SToby Isaac 
7348a6ba4734SToby Isaac   Level: developer
7349a6ba4734SToby Isaac 
7350a6ba4734SToby Isaac .seealso: DMGetBoundary()
7351a6ba4734SToby Isaac @*/
7352a30ec4eaSSatish 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)
7353a6ba4734SToby Isaac {
7354e5e52638SMatthew G. Knepley   PetscDS        ds;
7355a6ba4734SToby Isaac   PetscErrorCode ierr;
7356a6ba4734SToby Isaac 
7357a6ba4734SToby Isaac   PetscFunctionBegin;
7358a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7359e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7360e5e52638SMatthew G. Knepley   ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, numids, ids, ctx);CHKERRQ(ierr);
7361a6ba4734SToby Isaac   PetscFunctionReturn(0);
7362a6ba4734SToby Isaac }
7363a6ba4734SToby Isaac 
7364a6ba4734SToby Isaac /*@
7365a6ba4734SToby Isaac   DMGetNumBoundary - Get the number of registered BC
7366a6ba4734SToby Isaac 
7367a6ba4734SToby Isaac   Input Parameters:
7368a6ba4734SToby Isaac . dm - The mesh object
7369a6ba4734SToby Isaac 
7370a6ba4734SToby Isaac   Output Parameters:
7371a6ba4734SToby Isaac . numBd - The number of BC
7372a6ba4734SToby Isaac 
7373a6ba4734SToby Isaac   Level: intermediate
7374a6ba4734SToby Isaac 
7375a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary()
7376a6ba4734SToby Isaac @*/
7377a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd)
7378a6ba4734SToby Isaac {
7379e5e52638SMatthew G. Knepley   PetscDS        ds;
738058ebd649SToby Isaac   PetscErrorCode ierr;
7381a6ba4734SToby Isaac 
7382a6ba4734SToby Isaac   PetscFunctionBegin;
7383a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7384e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7385e5e52638SMatthew G. Knepley   ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr);
7386a6ba4734SToby Isaac   PetscFunctionReturn(0);
7387a6ba4734SToby Isaac }
7388a6ba4734SToby Isaac 
7389a6ba4734SToby Isaac /*@C
73901c531cf8SMatthew G. Knepley   DMGetBoundary - Get a model boundary condition
7391a6ba4734SToby Isaac 
7392a6ba4734SToby Isaac   Input Parameters:
7393a6ba4734SToby Isaac + dm          - The mesh object
7394a6ba4734SToby Isaac - bd          - The BC number
7395a6ba4734SToby Isaac 
7396a6ba4734SToby Isaac   Output Parameters:
7397f971fd6bSMatthew G. Knepley + type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7398a6ba4734SToby Isaac . name        - The BC name
7399a6ba4734SToby Isaac . labelname   - The label defining constrained points
7400a6ba4734SToby Isaac . field       - The field to constrain
7401a6ba4734SToby Isaac . numcomps    - The number of constrained field components
7402a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7403a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7404a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7405a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7406a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7407a6ba4734SToby Isaac 
7408a6ba4734SToby Isaac   Options Database Keys:
7409a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7410a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7411a6ba4734SToby Isaac 
7412a6ba4734SToby Isaac   Level: developer
7413a6ba4734SToby Isaac 
7414a6ba4734SToby Isaac .seealso: DMAddBoundary()
7415a6ba4734SToby Isaac @*/
7416a30ec4eaSSatish 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)
7417a6ba4734SToby Isaac {
7418e5e52638SMatthew G. Knepley   PetscDS        ds;
741958ebd649SToby Isaac   PetscErrorCode ierr;
7420a6ba4734SToby Isaac 
7421a6ba4734SToby Isaac   PetscFunctionBegin;
7422a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7423e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7424e5e52638SMatthew G. Knepley   ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, numids, ids, ctx);CHKERRQ(ierr);
7425a6ba4734SToby Isaac   PetscFunctionReturn(0);
7426a6ba4734SToby Isaac }
7427a6ba4734SToby Isaac 
7428e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm)
7429e6f8dbb6SToby Isaac {
7430e5e52638SMatthew G. Knepley   PetscDS        ds;
7431dff059c6SToby Isaac   DMBoundary    *lastnext;
7432e6f8dbb6SToby Isaac   DSBoundary     dsbound;
7433e6f8dbb6SToby Isaac   PetscErrorCode ierr;
7434e6f8dbb6SToby Isaac 
7435e6f8dbb6SToby Isaac   PetscFunctionBegin;
7436e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7437e5e52638SMatthew G. Knepley   dsbound = ds->boundary;
743847a1f5adSToby Isaac   if (dm->boundary) {
743947a1f5adSToby Isaac     DMBoundary next = dm->boundary;
744047a1f5adSToby Isaac 
744147a1f5adSToby Isaac     /* quick check to see if the PetscDS has changed */
744247a1f5adSToby Isaac     if (next->dsboundary == dsbound) PetscFunctionReturn(0);
744347a1f5adSToby Isaac     /* the PetscDS has changed: tear down and rebuild */
744447a1f5adSToby Isaac     while (next) {
744547a1f5adSToby Isaac       DMBoundary b = next;
744647a1f5adSToby Isaac 
744747a1f5adSToby Isaac       next = b->next;
744847a1f5adSToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
7449a6ba4734SToby Isaac     }
745047a1f5adSToby Isaac     dm->boundary = NULL;
7451a6ba4734SToby Isaac   }
745247a1f5adSToby Isaac 
7453dff059c6SToby Isaac   lastnext = &(dm->boundary);
7454e6f8dbb6SToby Isaac   while (dsbound) {
7455e6f8dbb6SToby Isaac     DMBoundary dmbound;
7456e6f8dbb6SToby Isaac 
7457e6f8dbb6SToby Isaac     ierr = PetscNew(&dmbound);CHKERRQ(ierr);
7458e6f8dbb6SToby Isaac     dmbound->dsboundary = dsbound;
7459e6f8dbb6SToby Isaac     ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr);
7460994fe344SLisandro 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);}
746147a1f5adSToby Isaac     /* push on the back instead of the front so that it is in the same order as in the PetscDS */
7462dff059c6SToby Isaac     *lastnext = dmbound;
7463dff059c6SToby Isaac     lastnext = &(dmbound->next);
7464dff059c6SToby Isaac     dsbound = dsbound->next;
7465a6ba4734SToby Isaac   }
7466a6ba4734SToby Isaac   PetscFunctionReturn(0);
7467a6ba4734SToby Isaac }
7468a6ba4734SToby Isaac 
7469a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd)
7470a6ba4734SToby Isaac {
7471b95f2879SToby Isaac   DMBoundary     b;
7472a6ba4734SToby Isaac   PetscErrorCode ierr;
7473a6ba4734SToby Isaac 
7474a6ba4734SToby Isaac   PetscFunctionBegin;
7475a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7476534a8f05SLisandro Dalcin   PetscValidBoolPointer(isBd, 3);
7477a6ba4734SToby Isaac   *isBd = PETSC_FALSE;
7478e6f8dbb6SToby Isaac   ierr = DMPopulateBoundary(dm);CHKERRQ(ierr);
7479b95f2879SToby Isaac   b = dm->boundary;
7480a6ba4734SToby Isaac   while (b && !(*isBd)) {
7481e6f8dbb6SToby Isaac     DMLabel    label = b->label;
7482e6f8dbb6SToby Isaac     DSBoundary dsb = b->dsboundary;
74833424c85cSToby Isaac 
74843424c85cSToby Isaac     if (label) {
7485a6ba4734SToby Isaac       PetscInt i;
7486a6ba4734SToby Isaac 
7487e6f8dbb6SToby Isaac       for (i = 0; i < dsb->numids && !(*isBd); ++i) {
7488e6f8dbb6SToby Isaac         ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr);
7489a6ba4734SToby Isaac       }
7490a6ba4734SToby Isaac     }
7491a6ba4734SToby Isaac     b = b->next;
7492a6ba4734SToby Isaac   }
7493a6ba4734SToby Isaac   PetscFunctionReturn(0);
7494a6ba4734SToby Isaac }
74954d6f44ffSToby Isaac 
74964d6f44ffSToby Isaac /*@C
74974d6f44ffSToby Isaac   DMProjectFunction - This projects the given function into the function space provided.
74984d6f44ffSToby Isaac 
74994d6f44ffSToby Isaac   Input Parameters:
75004d6f44ffSToby Isaac + dm      - The DM
75010709b2feSToby Isaac . time    - The time
75024d6f44ffSToby Isaac . funcs   - The coordinate functions to evaluate, one per field
75034d6f44ffSToby Isaac . ctxs    - Optional array of contexts to pass to each coordinate function.  ctxs itself may be null.
75044d6f44ffSToby Isaac - mode    - The insertion mode for values
75054d6f44ffSToby Isaac 
75064d6f44ffSToby Isaac   Output Parameter:
75074d6f44ffSToby Isaac . X - vector
75084d6f44ffSToby Isaac 
75094d6f44ffSToby Isaac    Calling sequence of func:
75100709b2feSToby Isaac $    func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx);
75114d6f44ffSToby Isaac 
75124d6f44ffSToby Isaac +  dim - The spatial dimension
75134d6f44ffSToby Isaac .  x   - The coordinates
75144d6f44ffSToby Isaac .  Nf  - The number of fields
75154d6f44ffSToby Isaac .  u   - The output field values
75164d6f44ffSToby Isaac -  ctx - optional user-defined function context
75174d6f44ffSToby Isaac 
75184d6f44ffSToby Isaac   Level: developer
75194d6f44ffSToby Isaac 
75202716604bSToby Isaac .seealso: DMComputeL2Diff()
75214d6f44ffSToby Isaac @*/
75220709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X)
75234d6f44ffSToby Isaac {
75244d6f44ffSToby Isaac   Vec            localX;
75254d6f44ffSToby Isaac   PetscErrorCode ierr;
75264d6f44ffSToby Isaac 
75274d6f44ffSToby Isaac   PetscFunctionBegin;
75284d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
75294d6f44ffSToby Isaac   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
75300709b2feSToby Isaac   ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
75314d6f44ffSToby Isaac   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
75324d6f44ffSToby Isaac   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
75334d6f44ffSToby Isaac   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
75344d6f44ffSToby Isaac   PetscFunctionReturn(0);
75354d6f44ffSToby Isaac }
75364d6f44ffSToby Isaac 
75370709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
75384d6f44ffSToby Isaac {
75394d6f44ffSToby Isaac   PetscErrorCode ierr;
75404d6f44ffSToby Isaac 
75414d6f44ffSToby Isaac   PetscFunctionBegin;
75424d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75434d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
75440918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name);
75450709b2feSToby Isaac   ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
75464d6f44ffSToby Isaac   PetscFunctionReturn(0);
75474d6f44ffSToby Isaac }
75484d6f44ffSToby Isaac 
75492c53366bSMatthew 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)
75502c53366bSMatthew G. Knepley {
75512c53366bSMatthew G. Knepley   Vec            localX;
75522c53366bSMatthew G. Knepley   PetscErrorCode ierr;
75532c53366bSMatthew G. Knepley 
75542c53366bSMatthew G. Knepley   PetscFunctionBegin;
75552c53366bSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
75562c53366bSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
75572c53366bSMatthew G. Knepley   ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
75582c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
75592c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
75602c53366bSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
75612c53366bSMatthew G. Knepley   PetscFunctionReturn(0);
75622c53366bSMatthew G. Knepley }
75632c53366bSMatthew G. Knepley 
75641c531cf8SMatthew 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)
75654d6f44ffSToby Isaac {
75664d6f44ffSToby Isaac   PetscErrorCode ierr;
75674d6f44ffSToby Isaac 
75684d6f44ffSToby Isaac   PetscFunctionBegin;
75694d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75704d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
75710918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name);
75721c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
75734d6f44ffSToby Isaac   PetscFunctionReturn(0);
75744d6f44ffSToby Isaac }
75752716604bSToby Isaac 
75768c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU,
75778c6c5593SMatthew G. Knepley                                    void (**funcs)(PetscInt, PetscInt, PetscInt,
75788c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
75798c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7580191494d9SMatthew G. Knepley                                                   PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
75818c6c5593SMatthew G. Knepley                                    InsertMode mode, Vec localX)
75828c6c5593SMatthew G. Knepley {
75838c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
75848c6c5593SMatthew G. Knepley 
75858c6c5593SMatthew G. Knepley   PetscFunctionBegin;
75868c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75878c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,3);
75888c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,6);
75890918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
75908c6c5593SMatthew G. Knepley   ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr);
75918c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
75928c6c5593SMatthew G. Knepley }
75938c6c5593SMatthew G. Knepley 
75941c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU,
75958c6c5593SMatthew G. Knepley                                         void (**funcs)(PetscInt, PetscInt, PetscInt,
75968c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
75978c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7598191494d9SMatthew G. Knepley                                                        PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
75998c6c5593SMatthew G. Knepley                                         InsertMode mode, Vec localX)
76008c6c5593SMatthew G. Knepley {
76018c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
76028c6c5593SMatthew G. Knepley 
76038c6c5593SMatthew G. Knepley   PetscFunctionBegin;
76048c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
76058c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,6);
76068c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,9);
76070918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
76081c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr);
76098c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
76108c6c5593SMatthew G. Knepley }
76118c6c5593SMatthew G. Knepley 
76122716604bSToby Isaac /*@C
76132716604bSToby Isaac   DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h.
76142716604bSToby Isaac 
76152716604bSToby Isaac   Input Parameters:
76162716604bSToby Isaac + dm    - The DM
76170709b2feSToby Isaac . time  - The time
76182716604bSToby Isaac . funcs - The functions to evaluate for each field component
76192716604bSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7620574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
76212716604bSToby Isaac 
76222716604bSToby Isaac   Output Parameter:
76232716604bSToby Isaac . diff - The diff ||u - u_h||_2
76242716604bSToby Isaac 
76252716604bSToby Isaac   Level: developer
76262716604bSToby Isaac 
76271189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
76282716604bSToby Isaac @*/
76290709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff)
76302716604bSToby Isaac {
76312716604bSToby Isaac   PetscErrorCode ierr;
76322716604bSToby Isaac 
76332716604bSToby Isaac   PetscFunctionBegin;
76342716604bSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7635b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
76360918c465SMatthew G. Knepley   if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name);
76370709b2feSToby Isaac   ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
76382716604bSToby Isaac   PetscFunctionReturn(0);
76392716604bSToby Isaac }
7640b698f381SToby Isaac 
7641b698f381SToby Isaac /*@C
7642b698f381SToby Isaac   DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h.
7643b698f381SToby Isaac 
7644d083f849SBarry Smith   Collective on dm
7645d083f849SBarry Smith 
7646b698f381SToby Isaac   Input Parameters:
7647b698f381SToby Isaac + dm    - The DM
7648b698f381SToby Isaac , time  - The time
7649b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component
7650b698f381SToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7651574a98acSMatthew G. Knepley . X     - The coefficient vector u_h, a global vector
7652b698f381SToby Isaac - n     - The vector to project along
7653b698f381SToby Isaac 
7654b698f381SToby Isaac   Output Parameter:
7655b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2
7656b698f381SToby Isaac 
7657b698f381SToby Isaac   Level: developer
7658b698f381SToby Isaac 
7659b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff()
7660b698f381SToby Isaac @*/
7661b698f381SToby 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)
7662b698f381SToby Isaac {
7663b698f381SToby Isaac   PetscErrorCode ierr;
7664b698f381SToby Isaac 
7665b698f381SToby Isaac   PetscFunctionBegin;
7666b698f381SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7667b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
7668b698f381SToby Isaac   if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name);
7669b698f381SToby Isaac   ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr);
7670b698f381SToby Isaac   PetscFunctionReturn(0);
7671b698f381SToby Isaac }
7672b698f381SToby Isaac 
76732a16baeaSToby Isaac /*@C
76742a16baeaSToby Isaac   DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components.
76752a16baeaSToby Isaac 
7676d083f849SBarry Smith   Collective on dm
7677d083f849SBarry Smith 
76782a16baeaSToby Isaac   Input Parameters:
76792a16baeaSToby Isaac + dm    - The DM
76802a16baeaSToby Isaac . time  - The time
76812a16baeaSToby Isaac . funcs - The functions to evaluate for each field component
76822a16baeaSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7683574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
76842a16baeaSToby Isaac 
76852a16baeaSToby Isaac   Output Parameter:
76862a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2
76872a16baeaSToby Isaac 
76882a16baeaSToby Isaac   Level: developer
76892a16baeaSToby Isaac 
76901189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
76912a16baeaSToby Isaac @*/
76921189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[])
76932a16baeaSToby Isaac {
76942a16baeaSToby Isaac   PetscErrorCode ierr;
76952a16baeaSToby Isaac 
76962a16baeaSToby Isaac   PetscFunctionBegin;
76972a16baeaSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
76982a16baeaSToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
76990918c465SMatthew G. Knepley   if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name);
77002a16baeaSToby Isaac   ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
77012a16baeaSToby Isaac   PetscFunctionReturn(0);
77022a16baeaSToby Isaac }
77032a16baeaSToby Isaac 
7704df0b854cSToby Isaac /*@C
7705df0b854cSToby Isaac   DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags.  Specific implementations of DM maybe have
7706cd3c525cSToby Isaac                  specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN.
7707df0b854cSToby Isaac 
7708df0b854cSToby Isaac   Collective on dm
7709df0b854cSToby Isaac 
7710df0b854cSToby Isaac   Input parameters:
7711df0b854cSToby Isaac + dm - the pre-adaptation DM object
7712a1b0c543SToby Isaac - label - label with the flags
7713df0b854cSToby Isaac 
7714df0b854cSToby Isaac   Output parameters:
77150d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced.
7716df0b854cSToby Isaac 
7717df0b854cSToby Isaac   Level: intermediate
77180d1cd5e0SMatthew G. Knepley 
77190d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine()
7720df0b854cSToby Isaac @*/
77210d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt)
7722df0b854cSToby Isaac {
7723df0b854cSToby Isaac   PetscErrorCode ierr;
7724df0b854cSToby Isaac 
7725df0b854cSToby Isaac   PetscFunctionBegin;
7726df0b854cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7727a1b0c543SToby Isaac   PetscValidPointer(label,2);
77280d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt,3);
77290d1cd5e0SMatthew G. Knepley   *dmAdapt = NULL;
77306f25b0d8SLisandro Dalcin   if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name);
77310d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr);
77320d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
77330d1cd5e0SMatthew G. Knepley }
77340d1cd5e0SMatthew G. Knepley 
77350d1cd5e0SMatthew G. Knepley /*@C
77360d1cd5e0SMatthew G. Knepley   DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library.
77370d1cd5e0SMatthew G. Knepley 
77380d1cd5e0SMatthew G. Knepley   Input Parameters:
77390d1cd5e0SMatthew G. Knepley + dm - The DM object
77400d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise.
77416f25b0d8SLisandro 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_".
77420d1cd5e0SMatthew G. Knepley 
77430d1cd5e0SMatthew G. Knepley   Output Parameter:
77440d1cd5e0SMatthew G. Knepley . dmAdapt  - Pointer to the DM object containing the adapted mesh
77450d1cd5e0SMatthew G. Knepley 
77460d1cd5e0SMatthew G. Knepley   Note: The label in the adapted mesh will be registered under the name of the input DMLabel object
77470d1cd5e0SMatthew G. Knepley 
77480d1cd5e0SMatthew G. Knepley   Level: advanced
77490d1cd5e0SMatthew G. Knepley 
77500d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine()
77510d1cd5e0SMatthew G. Knepley @*/
77520d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt)
77530d1cd5e0SMatthew G. Knepley {
77540d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
77550d1cd5e0SMatthew G. Knepley 
77560d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
77570d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77580d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(metric, VEC_CLASSID, 2);
77590d1cd5e0SMatthew G. Knepley   if (bdLabel) PetscValidPointer(bdLabel, 3);
77600d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt, 4);
77616f25b0d8SLisandro Dalcin   *dmAdapt = NULL;
77626f25b0d8SLisandro Dalcin   if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name);
77630d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr);
7764df0b854cSToby Isaac   PetscFunctionReturn(0);
7765df0b854cSToby Isaac }
7766c4088d22SMatthew G. Knepley 
7767502a2867SDave May /*@C
7768502a2867SDave May  DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors
7769502a2867SDave May 
7770502a2867SDave May  Not Collective
7771502a2867SDave May 
7772502a2867SDave May  Input Parameter:
7773502a2867SDave May  . dm    - The DM
7774502a2867SDave May 
7775502a2867SDave May  Output Parameter:
7776502a2867SDave May  . nranks - the number of neighbours
7777502a2867SDave May  . ranks - the neighbors ranks
7778502a2867SDave May 
7779502a2867SDave May  Notes:
7780502a2867SDave May  Do not free the array, it is freed when the DM is destroyed.
7781502a2867SDave May 
7782502a2867SDave May  Level: beginner
7783502a2867SDave May 
7784dec1416fSJunchao Zhang  .seealso: DMDAGetNeighbors(), PetscSFGetRootRanks()
7785502a2867SDave May @*/
7786502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[])
7787502a2867SDave May {
7788502a2867SDave May   PetscErrorCode ierr;
7789502a2867SDave May 
7790502a2867SDave May   PetscFunctionBegin;
7791502a2867SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77920918c465SMatthew G. Knepley   if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name);
7793502a2867SDave May   ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr);
7794502a2867SDave May   PetscFunctionReturn(0);
7795502a2867SDave May }
7796502a2867SDave May 
7797531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */
7798531c7667SBarry Smith 
7799531c7667SBarry Smith /*
7800531c7667SBarry Smith     Converts the input vector to a ghosted vector and then calls the standard coloring code.
7801531c7667SBarry Smith     This has be a different function because it requires DM which is not defined in the Mat library
7802531c7667SBarry Smith */
7803531c7667SBarry Smith PetscErrorCode  MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx)
7804531c7667SBarry Smith {
7805531c7667SBarry Smith   PetscErrorCode ierr;
7806531c7667SBarry Smith 
7807531c7667SBarry Smith   PetscFunctionBegin;
7808531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7809531c7667SBarry Smith     Vec x1local;
7810531c7667SBarry Smith     DM  dm;
7811531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
7812531c7667SBarry Smith     if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM");
7813531c7667SBarry Smith     ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr);
7814531c7667SBarry Smith     ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
7815531c7667SBarry Smith     ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
7816531c7667SBarry Smith     x1   = x1local;
7817531c7667SBarry Smith   }
7818531c7667SBarry Smith   ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr);
7819531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7820531c7667SBarry Smith     DM  dm;
7821531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
7822531c7667SBarry Smith     ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr);
7823531c7667SBarry Smith   }
7824531c7667SBarry Smith   PetscFunctionReturn(0);
7825531c7667SBarry Smith }
7826531c7667SBarry Smith 
7827531c7667SBarry Smith /*@
7828531c7667SBarry Smith     MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring
7829531c7667SBarry Smith 
7830531c7667SBarry Smith     Input Parameter:
7831531c7667SBarry Smith .    coloring - the MatFDColoring object
7832531c7667SBarry Smith 
783395452b02SPatrick Sanan     Developer Notes:
783495452b02SPatrick Sanan     this routine exists because the PETSc Mat library does not know about the DM objects
7835531c7667SBarry Smith 
78361b266c99SBarry Smith     Level: advanced
78371b266c99SBarry Smith 
7838531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType
7839531c7667SBarry Smith @*/
7840531c7667SBarry Smith PetscErrorCode  MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring)
7841531c7667SBarry Smith {
7842531c7667SBarry Smith   PetscFunctionBegin;
7843531c7667SBarry Smith   coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM;
7844531c7667SBarry Smith   PetscFunctionReturn(0);
7845531c7667SBarry Smith }
78468320bc6fSPatrick Sanan 
78478320bc6fSPatrick Sanan /*@
78488320bc6fSPatrick Sanan     DMGetCompatibility - determine if two DMs are compatible
78498320bc6fSPatrick Sanan 
78508320bc6fSPatrick Sanan     Collective
78518320bc6fSPatrick Sanan 
78528320bc6fSPatrick Sanan     Input Parameters:
78538320bc6fSPatrick Sanan +    dm - the first DM
78548320bc6fSPatrick Sanan -    dm2 - the second DM
78558320bc6fSPatrick Sanan 
78568320bc6fSPatrick Sanan     Output Parameters:
78578320bc6fSPatrick Sanan +    compatible - whether or not the two DMs are compatible
78588320bc6fSPatrick Sanan -    set - whether or not the compatible value was set
78598320bc6fSPatrick Sanan 
78608320bc6fSPatrick Sanan     Notes:
78618320bc6fSPatrick Sanan     Two DMs are deemed compatible if they represent the same parallel decomposition
78623d862458SPatrick Sanan     of the same topology. This implies that the section (field data) on one
78638320bc6fSPatrick Sanan     "makes sense" with respect to the topology and parallel decomposition of the other.
78643d862458SPatrick Sanan     Loosely speaking, compatible DMs represent the same domain and parallel
78653d862458SPatrick Sanan     decomposition, but hold different data.
78668320bc6fSPatrick Sanan 
78678320bc6fSPatrick Sanan     Typically, one would confirm compatibility if intending to simultaneously iterate
78688320bc6fSPatrick Sanan     over a pair of vectors obtained from different DMs.
78698320bc6fSPatrick Sanan 
78708320bc6fSPatrick Sanan     For example, two DMDA objects are compatible if they have the same local
78718320bc6fSPatrick Sanan     and global sizes and the same stencil width. They can have different numbers
78728320bc6fSPatrick Sanan     of degrees of freedom per node. Thus, one could use the node numbering from
78738320bc6fSPatrick Sanan     either DM in bounds for a loop over vectors derived from either DM.
78748320bc6fSPatrick Sanan 
78758320bc6fSPatrick Sanan     Consider the operation of summing data living on a 2-dof DMDA to data living
78768320bc6fSPatrick Sanan     on a 1-dof DMDA, which should be compatible, as in the following snippet.
78778320bc6fSPatrick Sanan .vb
78788320bc6fSPatrick Sanan   ...
78798320bc6fSPatrick Sanan   ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr);
78808320bc6fSPatrick Sanan   if (set && compatible)  {
78818320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
78828320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
78833d862458SPatrick Sanan     ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr);
78848320bc6fSPatrick Sanan     for (j=y; j<y+n; ++j) {
78858320bc6fSPatrick Sanan       for (i=x; i<x+m, ++i) {
78868320bc6fSPatrick Sanan         arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1];
78878320bc6fSPatrick Sanan       }
78888320bc6fSPatrick Sanan     }
78898320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
78908320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
78918320bc6fSPatrick Sanan   } else {
78928320bc6fSPatrick Sanan     SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible");
78938320bc6fSPatrick Sanan   }
78948320bc6fSPatrick Sanan   ...
78958320bc6fSPatrick Sanan .ve
78968320bc6fSPatrick Sanan 
78978320bc6fSPatrick Sanan     Checking compatibility might be expensive for a given implementation of DM,
78988320bc6fSPatrick Sanan     or might be impossible to unambiguously confirm or deny. For this reason,
78998320bc6fSPatrick Sanan     this function may decline to determine compatibility, and hence users should
79008320bc6fSPatrick Sanan     always check the "set" output parameter.
79018320bc6fSPatrick Sanan 
79028320bc6fSPatrick Sanan     A DM is always compatible with itself.
79038320bc6fSPatrick Sanan 
79048320bc6fSPatrick Sanan     In the current implementation, DMs which live on "unequal" communicators
79058320bc6fSPatrick Sanan     (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed
79068320bc6fSPatrick Sanan     incompatible.
79078320bc6fSPatrick Sanan 
79088320bc6fSPatrick Sanan     This function is labeled "Collective," as information about all subdomains
79098320bc6fSPatrick Sanan     is required on each rank. However, in DM implementations which store all this
79108320bc6fSPatrick Sanan     information locally, this function may be merely "Logically Collective".
79118320bc6fSPatrick Sanan 
79128320bc6fSPatrick Sanan     Developer Notes:
79133d862458SPatrick Sanan     Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B
79143d862458SPatrick Sanan     iff B is compatible with A. Thus, this function checks the implementations
79158320bc6fSPatrick Sanan     of both dm and dm2 (if they are of different types), attempting to determine
79168320bc6fSPatrick Sanan     compatibility. It is left to DM implementers to ensure that symmetry is
79178320bc6fSPatrick Sanan     preserved. The simplest way to do this is, when implementing type-specific
79183d862458SPatrick Sanan     logic for this function, is to check for existing logic in the implementation
79193d862458SPatrick Sanan     of other DM types and let *set = PETSC_FALSE if found.
79208320bc6fSPatrick Sanan 
79218320bc6fSPatrick Sanan     Level: advanced
79228320bc6fSPatrick Sanan 
79233d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag()
79248320bc6fSPatrick Sanan @*/
79258320bc6fSPatrick Sanan 
79268320bc6fSPatrick Sanan PetscErrorCode DMGetCompatibility(DM dm,DM dm2,PetscBool *compatible,PetscBool *set)
79278320bc6fSPatrick Sanan {
79288320bc6fSPatrick Sanan   PetscErrorCode ierr;
79298320bc6fSPatrick Sanan   PetscMPIInt    compareResult;
79308320bc6fSPatrick Sanan   DMType         type,type2;
79318320bc6fSPatrick Sanan   PetscBool      sameType;
79328320bc6fSPatrick Sanan 
79338320bc6fSPatrick Sanan   PetscFunctionBegin;
79348320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
79358320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
79368320bc6fSPatrick Sanan 
79378320bc6fSPatrick Sanan   /* Declare a DM compatible with itself */
79388320bc6fSPatrick Sanan   if (dm == dm2) {
79398320bc6fSPatrick Sanan     *set = PETSC_TRUE;
79408320bc6fSPatrick Sanan     *compatible = PETSC_TRUE;
79418320bc6fSPatrick Sanan     PetscFunctionReturn(0);
79428320bc6fSPatrick Sanan   }
79438320bc6fSPatrick Sanan 
79448320bc6fSPatrick Sanan   /* Declare a DM incompatible with a DM that lives on an "unequal"
79458320bc6fSPatrick Sanan      communicator. Note that this does not preclude compatibility with
79468320bc6fSPatrick Sanan      DMs living on "congruent" or "similar" communicators, but this must be
79478320bc6fSPatrick Sanan      determined by the implementation-specific logic */
79488320bc6fSPatrick Sanan   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRQ(ierr);
79498320bc6fSPatrick Sanan   if (compareResult == MPI_UNEQUAL) {
79508320bc6fSPatrick Sanan     *set = PETSC_TRUE;
79518320bc6fSPatrick Sanan     *compatible = PETSC_FALSE;
79528320bc6fSPatrick Sanan     PetscFunctionReturn(0);
79538320bc6fSPatrick Sanan   }
79548320bc6fSPatrick Sanan 
79558320bc6fSPatrick Sanan   /* Pass to the implementation-specific routine, if one exists. */
79568320bc6fSPatrick Sanan   if (dm->ops->getcompatibility) {
79578320bc6fSPatrick Sanan     ierr = (*dm->ops->getcompatibility)(dm,dm2,compatible,set);CHKERRQ(ierr);
7958b9d85ea2SLisandro Dalcin     if (*set) PetscFunctionReturn(0);
79598320bc6fSPatrick Sanan   }
79608320bc6fSPatrick Sanan 
79618320bc6fSPatrick Sanan   /* If dm and dm2 are of different types, then attempt to check compatibility
79628320bc6fSPatrick Sanan      with an implementation of this function from dm2 */
79638320bc6fSPatrick Sanan   ierr = DMGetType(dm,&type);CHKERRQ(ierr);
79648320bc6fSPatrick Sanan   ierr = DMGetType(dm2,&type2);CHKERRQ(ierr);
79658320bc6fSPatrick Sanan   ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr);
79668320bc6fSPatrick Sanan   if (!sameType && dm2->ops->getcompatibility) {
79678320bc6fSPatrick Sanan     ierr = (*dm2->ops->getcompatibility)(dm2,dm,compatible,set);CHKERRQ(ierr); /* Note argument order */
79688320bc6fSPatrick Sanan   } else {
79698320bc6fSPatrick Sanan     *set = PETSC_FALSE;
79708320bc6fSPatrick Sanan   }
79718320bc6fSPatrick Sanan   PetscFunctionReturn(0);
79728320bc6fSPatrick Sanan }
7973