xref: /petsc/src/dm/interface/dm.c (revision 534a8f05a7a8aff70dd8cfd53d9cd834400a8dbf)
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 
137e87a4003SBarry Smith     ierr = DMGetSection(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);
143e87a4003SBarry Smith       ierr = DMSetSection(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 
991e87a4003SBarry Smith     ierr = DMGetSection(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);
1061*534a8f05SLisandro 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) {
1496*534a8f05SLisandro 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   }
1507e87a4003SBarry Smith   ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
150837d0c07bSMatthew G Knepley   if (section) {
15093a544194SStefano Zampini     PetscInt *fieldSizes, *fieldNc, **fieldIndices;
151037d0c07bSMatthew G Knepley     PetscInt nF, f, pStart, pEnd, p;
151137d0c07bSMatthew G Knepley 
1512e87a4003SBarry Smith     ierr = DMGetGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
151337d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
15143a544194SStefano Zampini     ierr = PetscMalloc3(nF,&fieldSizes,nF,&fieldNc,nF,&fieldIndices);CHKERRQ(ierr);
151537d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
151637d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
151737d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
15183a544194SStefano Zampini       ierr          = PetscSectionGetFieldComponents(section, f, &fieldNc[f]);CHKERRQ(ierr);
151937d0c07bSMatthew G Knepley     }
152037d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
152137d0c07bSMatthew G Knepley       PetscInt gdof;
152237d0c07bSMatthew G Knepley 
152337d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
152437d0c07bSMatthew G Knepley       if (gdof > 0) {
152537d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
15263a544194SStefano Zampini           PetscInt fdof, fcdof, fpdof;
152737d0c07bSMatthew G Knepley 
152837d0c07bSMatthew G Knepley           ierr  = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
152937d0c07bSMatthew G Knepley           ierr  = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
15303a544194SStefano Zampini           fpdof = fdof-fcdof;
15313a544194SStefano Zampini           if (fpdof && fpdof != fieldNc[f]) {
15323a544194SStefano Zampini             /* Layout does not admit a pointwise block size */
15333a544194SStefano Zampini             fieldNc[f] = 1;
15343a544194SStefano Zampini           }
15353a544194SStefano Zampini           fieldSizes[f] += fpdof;
153637d0c07bSMatthew G Knepley         }
153737d0c07bSMatthew G Knepley       }
153837d0c07bSMatthew G Knepley     }
153937d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
1540785e854fSJed Brown       ierr          = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr);
154137d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
154237d0c07bSMatthew G Knepley     }
154337d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
154437d0c07bSMatthew G Knepley       PetscInt gdof, goff;
154537d0c07bSMatthew G Knepley 
154637d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
154737d0c07bSMatthew G Knepley       if (gdof > 0) {
154837d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
154937d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
155037d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
155137d0c07bSMatthew G Knepley 
155237d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
155337d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
155437d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
155537d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
155637d0c07bSMatthew G Knepley           }
155737d0c07bSMatthew G Knepley         }
155837d0c07bSMatthew G Knepley       }
155937d0c07bSMatthew G Knepley     }
15608865f1eaSKarl Rupp     if (numFields) *numFields = nF;
156137d0c07bSMatthew G Knepley     if (fieldNames) {
1562785e854fSJed Brown       ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr);
156337d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
156437d0c07bSMatthew G Knepley         const char *fieldName;
156537d0c07bSMatthew G Knepley 
156637d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
156737d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr);
156837d0c07bSMatthew G Knepley       }
156937d0c07bSMatthew G Knepley     }
157037d0c07bSMatthew G Knepley     if (fields) {
1571785e854fSJed Brown       ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr);
157237d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
15733a544194SStefano Zampini         PetscInt bs, in[2], out[2];
15743a544194SStefano Zampini 
157582f516ccSBarry Smith         ierr  = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
15763a544194SStefano Zampini         in[0] = -fieldNc[f];
15773a544194SStefano Zampini         in[1] = fieldNc[f];
15783a544194SStefano Zampini         ierr  = MPIU_Allreduce(in, out, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
15793a544194SStefano Zampini         bs    = (-out[0] == out[1]) ? out[1] : 1;
15803a544194SStefano Zampini         ierr  = ISSetBlockSize((*fields)[f], bs);CHKERRQ(ierr);
158137d0c07bSMatthew G Knepley       }
158237d0c07bSMatthew G Knepley     }
15833a544194SStefano Zampini     ierr = PetscFree3(fieldSizes,fieldNc,fieldIndices);CHKERRQ(ierr);
15848865f1eaSKarl Rupp   } else if (dm->ops->createfieldis) {
15858865f1eaSKarl Rupp     ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);
158669ca1f37SDmitry Karpeev   }
15874d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
15884d343eeaSMatthew G Knepley }
15894d343eeaSMatthew G Knepley 
159016621825SDmitry Karpeev 
159116621825SDmitry Karpeev /*@C
159216621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
159316621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
159416621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1595e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1596e7c4fc90SDmitry Karpeev 
1597e7c4fc90SDmitry Karpeev   Not collective
1598e7c4fc90SDmitry Karpeev 
1599e7c4fc90SDmitry Karpeev   Input Parameter:
1600e7c4fc90SDmitry Karpeev . dm - the DM object
1601e7c4fc90SDmitry Karpeev 
1602e7c4fc90SDmitry Karpeev   Output Parameters:
16030298fd71SBarry Smith + len       - The number of subproblems in the field decomposition (or NULL if not requested)
16040298fd71SBarry Smith . namelist  - The name for each field (or NULL if not requested)
16050298fd71SBarry Smith . islist    - The global indices for each field (or NULL if not requested)
16060298fd71SBarry Smith - dmlist    - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
1607e7c4fc90SDmitry Karpeev 
1608e7c4fc90SDmitry Karpeev   Level: intermediate
1609e7c4fc90SDmitry Karpeev 
1610e7c4fc90SDmitry Karpeev   Notes:
1611e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1612e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1613e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1614e7c4fc90SDmitry Karpeev 
1615e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1616e7c4fc90SDmitry Karpeev @*/
161716621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1618e7c4fc90SDmitry Karpeev {
1619e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1620e7c4fc90SDmitry Karpeev 
1621e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1622e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
16238865f1eaSKarl Rupp   if (len) {
1624*534a8f05SLisandro 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 
1649e87a4003SBarry Smith     ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
1650435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1651435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1652f25d98f1SMatthew G. Knepley       if (len) *len = numFields;
165303dc3394SMatthew G. Knepley       if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);}
165403dc3394SMatthew G. Knepley       if (islist)   {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);}
165503dc3394SMatthew G. Knepley       if (dmlist)   {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);}
1656435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1657435a35e8SMatthew G Knepley         const char *fieldName;
1658435a35e8SMatthew G Knepley 
165903dc3394SMatthew G. Knepley         ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr);
166003dc3394SMatthew G. Knepley         if (namelist) {
1661435a35e8SMatthew G Knepley           ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1662435a35e8SMatthew G Knepley           ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr);
1663435a35e8SMatthew G Knepley         }
166403dc3394SMatthew G. Knepley       }
1665435a35e8SMatthew G Knepley     } else {
166669ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1667e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
16680298fd71SBarry Smith       if (dmlist) *dmlist = NULL;
1669e7c4fc90SDmitry Karpeev     }
16708865f1eaSKarl Rupp   } else {
167116621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr);
167216621825SDmitry Karpeev   }
167316621825SDmitry Karpeev   PetscFunctionReturn(0);
167416621825SDmitry Karpeev }
167516621825SDmitry Karpeev 
1676564cec59SMatthew G. Knepley /*@
1677435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1678435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1679435a35e8SMatthew G Knepley 
1680435a35e8SMatthew G Knepley   Not collective
1681435a35e8SMatthew G Knepley 
1682435a35e8SMatthew G Knepley   Input Parameters:
16832adcc780SMatthew G. Knepley + dm        - The DM object
16842adcc780SMatthew G. Knepley . numFields - The number of fields in this subproblem
16852adcc780SMatthew G. Knepley - fields    - The field numbers of the selected fields
1686435a35e8SMatthew G Knepley 
1687435a35e8SMatthew G Knepley   Output Parameters:
16882adcc780SMatthew G. Knepley + is - The global indices for the subproblem
16892adcc780SMatthew G. Knepley - subdm - The DM for the subproblem
1690435a35e8SMatthew G Knepley 
16915d3b26e6SMatthew G. Knepley   Note: You need to call DMPlexSetMigrationSF() on the original DM if you want the Global-To-Natural map to be automatically constructed
16925d3b26e6SMatthew G. Knepley 
1693435a35e8SMatthew G Knepley   Level: intermediate
1694435a35e8SMatthew G Knepley 
16955d3b26e6SMatthew G. Knepley .seealso DMPlexSetMigrationSF(), DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1696435a35e8SMatthew G Knepley @*/
169737bc7515SMatthew G. Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1698435a35e8SMatthew G Knepley {
1699435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1700435a35e8SMatthew G Knepley 
1701435a35e8SMatthew G Knepley   PetscFunctionBegin;
1702435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1703435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
17048865f1eaSKarl Rupp   if (is) PetscValidPointer(is,4);
17058865f1eaSKarl Rupp   if (subdm) PetscValidPointer(subdm,5);
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);
2109*534a8f05SLisandro 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);
2124ca3d3a14SMatthew G. Knepley   ierr = DMGetSection(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);
2128ca3d3a14SMatthew G. Knepley   ierr = DMGetSection(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);
2243e87a4003SBarry Smith     ierr = DMGetSection(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);
2453e87a4003SBarry Smith     ierr = DMGetSection(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);
2548e87a4003SBarry Smith   ierr = DMGetSection(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);
2649e87a4003SBarry Smith   ierr = DMGetSection(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);
3305*534a8f05SLisandro 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);
3363*534a8f05SLisandro 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);
3388*534a8f05SLisandro 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);
3416*534a8f05SLisandro 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 /*@
3798e87a4003SBarry Smith   DMGetSection - Get the PetscSection encoding the local data layout for the DM.
379988ed4aceSMatthew G Knepley 
380088ed4aceSMatthew G Knepley   Input Parameter:
380188ed4aceSMatthew G Knepley . dm - The DM
380288ed4aceSMatthew G Knepley 
380388ed4aceSMatthew G Knepley   Output Parameter:
380488ed4aceSMatthew G Knepley . section - The PetscSection
380588ed4aceSMatthew G Knepley 
3806e5893cccSMatthew G. Knepley   Options Database Keys:
3807e5893cccSMatthew G. Knepley . -dm_petscsection_view - View the Section created by the DM
3808e5893cccSMatthew G. Knepley 
380988ed4aceSMatthew G Knepley   Level: intermediate
381088ed4aceSMatthew G Knepley 
381188ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
381288ed4aceSMatthew G Knepley 
3813e87a4003SBarry Smith .seealso: DMSetSection(), DMGetGlobalSection()
381488ed4aceSMatthew G Knepley @*/
3815e87a4003SBarry Smith PetscErrorCode DMGetSection(DM dm, PetscSection *section)
38160adebc6cSBarry Smith {
3817fd59a867SMatthew G. Knepley   PetscErrorCode ierr;
3818fd59a867SMatthew G. Knepley 
381988ed4aceSMatthew G Knepley   PetscFunctionBegin;
382088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
382188ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
38222f0f8703SMatthew G. Knepley   if (!dm->defaultSection && dm->ops->createdefaultsection) {
3823e5e52638SMatthew G. Knepley     PetscInt d;
3824e5e52638SMatthew G. Knepley 
3825e5e52638SMatthew G. Knepley     if (dm->setfromoptionscalled) for (d = 0; d < dm->Nds; ++d) {ierr = PetscDSSetFromOptions(dm->probs[d].ds);CHKERRQ(ierr);}
38262f0f8703SMatthew G. Knepley     ierr = (*dm->ops->createdefaultsection)(dm);CHKERRQ(ierr);
3827ae71db08SMatthew G. Knepley     if (dm->defaultSection) {ierr = PetscObjectViewFromOptions((PetscObject) dm->defaultSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);}
38282f0f8703SMatthew G. Knepley   }
382988ed4aceSMatthew G Knepley   *section = dm->defaultSection;
383088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
383188ed4aceSMatthew G Knepley }
383288ed4aceSMatthew G Knepley 
383388ed4aceSMatthew G Knepley /*@
3834e87a4003SBarry Smith   DMSetSection - Set the PetscSection encoding the local data layout for the DM.
383588ed4aceSMatthew G Knepley 
383688ed4aceSMatthew G Knepley   Input Parameters:
383788ed4aceSMatthew G Knepley + dm - The DM
383888ed4aceSMatthew G Knepley - section - The PetscSection
383988ed4aceSMatthew G Knepley 
384088ed4aceSMatthew G Knepley   Level: intermediate
384188ed4aceSMatthew G Knepley 
384288ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
384388ed4aceSMatthew G Knepley 
3844e87a4003SBarry Smith .seealso: DMSetSection(), DMGetGlobalSection()
384588ed4aceSMatthew G Knepley @*/
3846e87a4003SBarry Smith PetscErrorCode DMSetSection(DM dm, PetscSection section)
38470adebc6cSBarry Smith {
3848c473ab19SMatthew G. Knepley   PetscInt       numFields = 0;
3849af122d2aSMatthew G Knepley   PetscInt       f;
385088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
385188ed4aceSMatthew G Knepley 
385288ed4aceSMatthew G Knepley   PetscFunctionBegin;
385388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3854b9d85ea2SLisandro Dalcin   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
38551d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
385688ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
385788ed4aceSMatthew G Knepley   dm->defaultSection = section;
3858c473ab19SMatthew G. Knepley   if (section) {ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);}
3859af122d2aSMatthew G Knepley   if (numFields) {
3860af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
3861af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
38620f21e855SMatthew G. Knepley       PetscObject disc;
3863af122d2aSMatthew G Knepley       const char *name;
3864af122d2aSMatthew G Knepley 
3865af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
386644a7f3ddSMatthew G. Knepley       ierr = DMGetField(dm, f, NULL, &disc);CHKERRQ(ierr);
38670f21e855SMatthew G. Knepley       ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr);
3868af122d2aSMatthew G Knepley     }
3869af122d2aSMatthew G Knepley   }
3870e87a4003SBarry Smith   /* The global section will be rebuilt in the next call to DMGetGlobalSection(). */
38711d799100SJed Brown   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
387288ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
387388ed4aceSMatthew G Knepley }
387488ed4aceSMatthew G Knepley 
38759435951eSToby Isaac /*@
38769435951eSToby Isaac   DMGetDefaultConstraints - Get the PetscSection and Mat the specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation.
38779435951eSToby Isaac 
3878e228b242SToby Isaac   not collective
3879e228b242SToby Isaac 
38809435951eSToby Isaac   Input Parameter:
38819435951eSToby Isaac . dm - The DM
38829435951eSToby Isaac 
38839435951eSToby Isaac   Output Parameter:
38849435951eSToby 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.
38859435951eSToby 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.
38869435951eSToby Isaac 
38879435951eSToby Isaac   Level: advanced
38889435951eSToby Isaac 
38899435951eSToby Isaac   Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat.
38909435951eSToby Isaac 
38919435951eSToby Isaac .seealso: DMSetDefaultConstraints()
38929435951eSToby Isaac @*/
38939435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat)
38949435951eSToby Isaac {
38959435951eSToby Isaac   PetscErrorCode ierr;
38969435951eSToby Isaac 
38979435951eSToby Isaac   PetscFunctionBegin;
38989435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
38999435951eSToby Isaac   if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);}
390045a75d81SToby Isaac   if (section) {*section = dm->defaultConstraintSection;}
390145a75d81SToby Isaac   if (mat) {*mat = dm->defaultConstraintMat;}
39029435951eSToby Isaac   PetscFunctionReturn(0);
39039435951eSToby Isaac }
39049435951eSToby Isaac 
39059435951eSToby Isaac /*@
39069435951eSToby Isaac   DMSetDefaultConstraints - Set the PetscSection and Mat the specify the local constraint interpolation.
39079435951eSToby Isaac 
39089435951eSToby 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().
39099435951eSToby Isaac 
39109435951eSToby 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.
39119435951eSToby Isaac 
3912e228b242SToby Isaac   collective on dm
3913e228b242SToby Isaac 
39149435951eSToby Isaac   Input Parameters:
39159435951eSToby Isaac + dm - The DM
3916e228b242SToby 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).
3917e228b242SToby 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).
39189435951eSToby Isaac 
39199435951eSToby Isaac   Level: advanced
39209435951eSToby Isaac 
39219435951eSToby Isaac   Note: This increments the references of the PetscSection and the Mat, so they user can destroy them
39229435951eSToby Isaac 
39239435951eSToby Isaac .seealso: DMGetDefaultConstraints()
39249435951eSToby Isaac @*/
39259435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat)
39269435951eSToby Isaac {
3927e228b242SToby Isaac   PetscMPIInt result;
39289435951eSToby Isaac   PetscErrorCode ierr;
39299435951eSToby Isaac 
39309435951eSToby Isaac   PetscFunctionBegin;
39319435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3932e228b242SToby Isaac   if (section) {
3933e228b242SToby Isaac     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
3934e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr);
3935f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator");
3936e228b242SToby Isaac   }
3937e228b242SToby Isaac   if (mat) {
3938e228b242SToby Isaac     PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
3939e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr);
3940f60917d2SBarry Smith     if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator");
3941e228b242SToby Isaac   }
39429435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
39439435951eSToby Isaac   ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr);
39449435951eSToby Isaac   dm->defaultConstraintSection = section;
39459435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
39469435951eSToby Isaac   ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr);
39479435951eSToby Isaac   dm->defaultConstraintMat = mat;
39489435951eSToby Isaac   PetscFunctionReturn(0);
39499435951eSToby Isaac }
39509435951eSToby Isaac 
3951497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
3952507e4973SMatthew G. Knepley /*
3953507e4973SMatthew G. Knepley   DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections.
3954507e4973SMatthew G. Knepley 
3955507e4973SMatthew G. Knepley   Input Parameters:
3956507e4973SMatthew G. Knepley + dm - The DM
3957507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout
3958507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout
3959507e4973SMatthew G. Knepley 
3960507e4973SMatthew G. Knepley   Level: intermediate
3961507e4973SMatthew G. Knepley 
3962507e4973SMatthew G. Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
3963507e4973SMatthew G. Knepley */
3964f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection)
3965507e4973SMatthew G. Knepley {
3966507e4973SMatthew G. Knepley   MPI_Comm        comm;
3967507e4973SMatthew G. Knepley   PetscLayout     layout;
3968507e4973SMatthew G. Knepley   const PetscInt *ranges;
3969507e4973SMatthew G. Knepley   PetscInt        pStart, pEnd, p, nroots;
3970507e4973SMatthew G. Knepley   PetscMPIInt     size, rank;
3971507e4973SMatthew G. Knepley   PetscBool       valid = PETSC_TRUE, gvalid;
3972507e4973SMatthew G. Knepley   PetscErrorCode  ierr;
3973507e4973SMatthew G. Knepley 
3974507e4973SMatthew G. Knepley   PetscFunctionBegin;
3975507e4973SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
3976507e4973SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3977507e4973SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
3978507e4973SMatthew G. Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
3979507e4973SMatthew G. Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
3980507e4973SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
3981507e4973SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
3982507e4973SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
3983507e4973SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
3984507e4973SMatthew G. Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
3985507e4973SMatthew G. Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
3986507e4973SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
3987f741bcd2SMatthew G. Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d;
3988507e4973SMatthew G. Knepley 
3989507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
3990507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
3991507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
3992507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
3993507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
3994507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
3995507e4973SMatthew G. Knepley     if (!gdof) continue; /* Censored point */
3996507e4973SMatthew 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;}
3997507e4973SMatthew 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;}
3998507e4973SMatthew G. Knepley     if (gdof < 0) {
3999507e4973SMatthew G. Knepley       gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
4000507e4973SMatthew G. Knepley       for (d = 0; d < gsize; ++d) {
4001507e4973SMatthew G. Knepley         PetscInt offset = -(goff+1) + d, r;
4002507e4973SMatthew G. Knepley 
4003507e4973SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
4004507e4973SMatthew G. Knepley         if (r < 0) r = -(r+2);
4005507e4973SMatthew 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;}
4006507e4973SMatthew G. Knepley       }
4007507e4973SMatthew G. Knepley     }
4008507e4973SMatthew G. Knepley   }
4009507e4973SMatthew G. Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
4010507e4973SMatthew G. Knepley   ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);
4011b2566f29SBarry Smith   ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr);
4012507e4973SMatthew G. Knepley   if (!gvalid) {
4013507e4973SMatthew G. Knepley     ierr = DMView(dm, NULL);CHKERRQ(ierr);
4014507e4973SMatthew G. Knepley     SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections");
4015507e4973SMatthew G. Knepley   }
4016507e4973SMatthew G. Knepley   PetscFunctionReturn(0);
4017507e4973SMatthew G. Knepley }
4018f741bcd2SMatthew G. Knepley #endif
4019507e4973SMatthew G. Knepley 
402088ed4aceSMatthew G Knepley /*@
4021e87a4003SBarry Smith   DMGetGlobalSection - Get the PetscSection encoding the global data layout for the DM.
402288ed4aceSMatthew G Knepley 
4023d083f849SBarry Smith   Collective on dm
40248b1ab98fSJed Brown 
402588ed4aceSMatthew G Knepley   Input Parameter:
402688ed4aceSMatthew G Knepley . dm - The DM
402788ed4aceSMatthew G Knepley 
402888ed4aceSMatthew G Knepley   Output Parameter:
402988ed4aceSMatthew G Knepley . section - The PetscSection
403088ed4aceSMatthew G Knepley 
403188ed4aceSMatthew G Knepley   Level: intermediate
403288ed4aceSMatthew G Knepley 
403388ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
403488ed4aceSMatthew G Knepley 
4035e87a4003SBarry Smith .seealso: DMSetSection(), DMGetSection()
403688ed4aceSMatthew G Knepley @*/
4037e87a4003SBarry Smith PetscErrorCode DMGetGlobalSection(DM dm, PetscSection *section)
40380adebc6cSBarry Smith {
403988ed4aceSMatthew G Knepley   PetscErrorCode ierr;
404088ed4aceSMatthew G Knepley 
404188ed4aceSMatthew G Knepley   PetscFunctionBegin;
404288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
404388ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
404488ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
4045fd59a867SMatthew G. Knepley     PetscSection s;
4046fd59a867SMatthew G. Knepley 
4047e87a4003SBarry Smith     ierr = DMGetSection(dm, &s);CHKERRQ(ierr);
4048fd59a867SMatthew 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");
404933907cc2SStefano 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");
405015b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
4051cf06b437SMatthew G. Knepley     ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr);
4052ce94432eSBarry Smith     ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->defaultGlobalSection, &dm->map);CHKERRQ(ierr);
4053685405a1SBarry Smith     ierr = PetscSectionViewFromOptions(dm->defaultGlobalSection, NULL, "-global_section_view");CHKERRQ(ierr);
405488ed4aceSMatthew G Knepley   }
405588ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
405688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
405788ed4aceSMatthew G Knepley }
405888ed4aceSMatthew G Knepley 
4059b21d0597SMatthew G Knepley /*@
4060e87a4003SBarry Smith   DMSetGlobalSection - Set the PetscSection encoding the global data layout for the DM.
4061b21d0597SMatthew G Knepley 
4062b21d0597SMatthew G Knepley   Input Parameters:
4063b21d0597SMatthew G Knepley + dm - The DM
40645080bbdbSMatthew G Knepley - section - The PetscSection, or NULL
4065b21d0597SMatthew G Knepley 
4066b21d0597SMatthew G Knepley   Level: intermediate
4067b21d0597SMatthew G Knepley 
4068b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
4069b21d0597SMatthew G Knepley 
4070e87a4003SBarry Smith .seealso: DMGetGlobalSection(), DMSetSection()
4071b21d0597SMatthew G Knepley @*/
4072e87a4003SBarry Smith PetscErrorCode DMSetGlobalSection(DM dm, PetscSection section)
40730adebc6cSBarry Smith {
4074b21d0597SMatthew G Knepley   PetscErrorCode ierr;
4075b21d0597SMatthew G Knepley 
4076b21d0597SMatthew G Knepley   PetscFunctionBegin;
4077b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
40785080bbdbSMatthew G Knepley   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
40791d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
4080b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
4081b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
4082497880caSRichard Tran Mills #if defined(PETSC_USE_DEBUG)
4083f741bcd2SMatthew G. Knepley   if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->defaultSection, section);CHKERRQ(ierr);}
4084507e4973SMatthew G. Knepley #endif
4085b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4086b21d0597SMatthew G Knepley }
4087b21d0597SMatthew G Knepley 
408888ed4aceSMatthew G Knepley /*@
408988ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
409088ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
409188ed4aceSMatthew G Knepley 
409288ed4aceSMatthew G Knepley   Input Parameter:
409388ed4aceSMatthew G Knepley . dm - The DM
409488ed4aceSMatthew G Knepley 
409588ed4aceSMatthew G Knepley   Output Parameter:
409688ed4aceSMatthew G Knepley . sf - The PetscSF
409788ed4aceSMatthew G Knepley 
409888ed4aceSMatthew G Knepley   Level: intermediate
409988ed4aceSMatthew G Knepley 
410088ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
410188ed4aceSMatthew G Knepley 
410288ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
410388ed4aceSMatthew G Knepley @*/
41040adebc6cSBarry Smith PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf)
41050adebc6cSBarry Smith {
410688ed4aceSMatthew G Knepley   PetscInt       nroots;
410788ed4aceSMatthew G Knepley   PetscErrorCode ierr;
410888ed4aceSMatthew G Knepley 
410988ed4aceSMatthew G Knepley   PetscFunctionBegin;
411088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
411188ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
411233907cc2SStefano Zampini   if (!dm->defaultSF) {
411333907cc2SStefano Zampini     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm),&dm->defaultSF);CHKERRQ(ierr);
411433907cc2SStefano Zampini   }
41150298fd71SBarry Smith   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
411688ed4aceSMatthew G Knepley   if (nroots < 0) {
411788ed4aceSMatthew G Knepley     PetscSection section, gSection;
411888ed4aceSMatthew G Knepley 
4119e87a4003SBarry Smith     ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
412031ea6d37SMatthew G Knepley     if (section) {
4121e87a4003SBarry Smith       ierr = DMGetGlobalSection(dm, &gSection);CHKERRQ(ierr);
412288ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
412331ea6d37SMatthew G Knepley     } else {
41240298fd71SBarry Smith       *sf = NULL;
412531ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
412631ea6d37SMatthew G Knepley     }
412788ed4aceSMatthew G Knepley   }
412888ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
412988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
413088ed4aceSMatthew G Knepley }
413188ed4aceSMatthew G Knepley 
413288ed4aceSMatthew G Knepley /*@
413388ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
413488ed4aceSMatthew G Knepley 
413588ed4aceSMatthew G Knepley   Input Parameters:
413688ed4aceSMatthew G Knepley + dm - The DM
413788ed4aceSMatthew G Knepley - sf - The PetscSF
413888ed4aceSMatthew G Knepley 
413988ed4aceSMatthew G Knepley   Level: intermediate
414088ed4aceSMatthew G Knepley 
414188ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
414288ed4aceSMatthew G Knepley 
414388ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
414488ed4aceSMatthew G Knepley @*/
41450adebc6cSBarry Smith PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf)
41460adebc6cSBarry Smith {
414788ed4aceSMatthew G Knepley   PetscErrorCode ierr;
414888ed4aceSMatthew G Knepley 
414988ed4aceSMatthew G Knepley   PetscFunctionBegin;
415088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4151b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
415233907cc2SStefano Zampini   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
415388ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
415488ed4aceSMatthew G Knepley   dm->defaultSF = sf;
415588ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
415688ed4aceSMatthew G Knepley }
415788ed4aceSMatthew G Knepley 
415888ed4aceSMatthew G Knepley /*@C
415988ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
416088ed4aceSMatthew G Knepley   describing the data layout.
416188ed4aceSMatthew G Knepley 
416288ed4aceSMatthew G Knepley   Input Parameters:
416388ed4aceSMatthew G Knepley + dm - The DM
416488ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
416588ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
416688ed4aceSMatthew G Knepley 
416788ed4aceSMatthew G Knepley   Level: intermediate
416888ed4aceSMatthew G Knepley 
416988ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
417088ed4aceSMatthew G Knepley @*/
417188ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
417288ed4aceSMatthew G Knepley {
417382f516ccSBarry Smith   MPI_Comm       comm;
417488ed4aceSMatthew G Knepley   PetscLayout    layout;
417588ed4aceSMatthew G Knepley   const PetscInt *ranges;
417688ed4aceSMatthew G Knepley   PetscInt       *local;
417788ed4aceSMatthew G Knepley   PetscSFNode    *remote;
4178ecd73843SMatthew G. Knepley   PetscInt       pStart, pEnd, p, nroots, nleaves = 0, l;
417988ed4aceSMatthew G Knepley   PetscMPIInt    size, rank;
418088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
418188ed4aceSMatthew G Knepley 
418288ed4aceSMatthew G Knepley   PetscFunctionBegin;
418388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4184367003a6SStefano Zampini   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
418588ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
418688ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
418788ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
418888ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
418988ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
419088ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
419188ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
419288ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
419388ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
4194ecd73843SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
41956636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
419688ed4aceSMatthew G Knepley 
41976636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
41986636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
4199235fbf56SMatthew 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));
42006636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
420188ed4aceSMatthew G Knepley   }
4202785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr);
4203785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr);
420488ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
42051f588964SMatthew G Knepley     const PetscInt *cind;
42066636e97aSMatthew G Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
420788ed4aceSMatthew G Knepley 
420888ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
420988ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
421088ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
421188ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
421288ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
42136636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
421488ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
42156636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
42166636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
42176636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
4218057b4bcdSMatthew 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);
42196636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
42206636e97aSMatthew G Knepley     }
422188ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
422288ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
422388ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
422488ed4aceSMatthew G Knepley     }
422588ed4aceSMatthew G Knepley     if (gdof < 0) {
42266636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
422788ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
422888ed4aceSMatthew G Knepley 
422905376888SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
423031d3f06eSJed Brown         if (r < 0) r = -(r+2);
423105376888SMatthew 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);
423288ed4aceSMatthew G Knepley         remote[l].rank  = r;
423388ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
423488ed4aceSMatthew G Knepley       }
423588ed4aceSMatthew G Knepley     } else {
42366636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
423788ed4aceSMatthew G Knepley         remote[l].rank  = rank;
423888ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
423988ed4aceSMatthew G Knepley       }
424088ed4aceSMatthew G Knepley     }
424188ed4aceSMatthew G Knepley   }
42426636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
424388ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
424488ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
424588ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
424688ed4aceSMatthew G Knepley }
4247af122d2aSMatthew G Knepley 
4248b21d0597SMatthew G Knepley /*@
4249b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
4250b21d0597SMatthew G Knepley 
4251b21d0597SMatthew G Knepley   Input Parameter:
4252b21d0597SMatthew G Knepley . dm - The DM
4253b21d0597SMatthew G Knepley 
4254b21d0597SMatthew G Knepley   Output Parameter:
4255b21d0597SMatthew G Knepley . sf - The PetscSF
4256b21d0597SMatthew G Knepley 
4257b21d0597SMatthew G Knepley   Level: intermediate
4258b21d0597SMatthew G Knepley 
4259b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
4260b21d0597SMatthew G Knepley 
4261057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
4262b21d0597SMatthew G Knepley @*/
42630adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf)
42640adebc6cSBarry Smith {
4265b21d0597SMatthew G Knepley   PetscFunctionBegin;
4266b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4267b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
4268b21d0597SMatthew G Knepley   *sf = dm->sf;
4269b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
4270b21d0597SMatthew G Knepley }
4271b21d0597SMatthew G Knepley 
4272057b4bcdSMatthew G Knepley /*@
4273057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
4274057b4bcdSMatthew G Knepley 
4275057b4bcdSMatthew G Knepley   Input Parameters:
4276057b4bcdSMatthew G Knepley + dm - The DM
4277057b4bcdSMatthew G Knepley - sf - The PetscSF
4278057b4bcdSMatthew G Knepley 
4279057b4bcdSMatthew G Knepley   Level: intermediate
4280057b4bcdSMatthew G Knepley 
4281057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
4282057b4bcdSMatthew G Knepley @*/
42830adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf)
42840adebc6cSBarry Smith {
4285057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
4286057b4bcdSMatthew G Knepley 
4287057b4bcdSMatthew G Knepley   PetscFunctionBegin;
4288057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4289b9d85ea2SLisandro Dalcin   if (sf) PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
4290057b4bcdSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
429133907cc2SStefano Zampini   ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
4292057b4bcdSMatthew G Knepley   dm->sf = sf;
4293057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
4294057b4bcdSMatthew G Knepley }
4295057b4bcdSMatthew G Knepley 
429634aa8a36SMatthew G. Knepley static PetscErrorCode DMSetDefaultAdjacency_Private(DM dm, PetscInt f, PetscObject disc)
429734aa8a36SMatthew G. Knepley {
429834aa8a36SMatthew G. Knepley   PetscClassId   id;
429934aa8a36SMatthew G. Knepley   PetscErrorCode ierr;
430034aa8a36SMatthew G. Knepley 
430134aa8a36SMatthew G. Knepley   PetscFunctionBegin;
430234aa8a36SMatthew G. Knepley   ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
430334aa8a36SMatthew G. Knepley   if (id == PETSCFE_CLASSID) {
430434aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
430534aa8a36SMatthew G. Knepley   } else if (id == PETSCFV_CLASSID) {
430634aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr);
430717c1d62eSMatthew G. Knepley   } else {
430817c1d62eSMatthew G. Knepley     ierr = DMSetAdjacency(dm, f, PETSC_FALSE, PETSC_TRUE);CHKERRQ(ierr);
430934aa8a36SMatthew G. Knepley   }
431034aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
431134aa8a36SMatthew G. Knepley }
431234aa8a36SMatthew G. Knepley 
431344a7f3ddSMatthew G. Knepley static PetscErrorCode DMFieldEnlarge_Static(DM dm, PetscInt NfNew)
431444a7f3ddSMatthew G. Knepley {
431544a7f3ddSMatthew G. Knepley   RegionField   *tmpr;
431644a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf, f;
431744a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
431844a7f3ddSMatthew G. Knepley 
431944a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
432044a7f3ddSMatthew G. Knepley   if (Nf >= NfNew) PetscFunctionReturn(0);
432144a7f3ddSMatthew G. Knepley   ierr = PetscMalloc1(NfNew, &tmpr);CHKERRQ(ierr);
432244a7f3ddSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpr[f] = dm->fields[f];
432344a7f3ddSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) {tmpr[f].disc = NULL; tmpr[f].label = NULL;}
432444a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
432544a7f3ddSMatthew G. Knepley   dm->Nf     = NfNew;
432644a7f3ddSMatthew G. Knepley   dm->fields = tmpr;
432744a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
432844a7f3ddSMatthew G. Knepley }
432944a7f3ddSMatthew G. Knepley 
433044a7f3ddSMatthew G. Knepley /*@
433144a7f3ddSMatthew G. Knepley   DMClearFields - Remove all fields from the DM
433244a7f3ddSMatthew G. Knepley 
4333d083f849SBarry Smith   Logically collective on dm
433444a7f3ddSMatthew G. Knepley 
433544a7f3ddSMatthew G. Knepley   Input Parameter:
433644a7f3ddSMatthew G. Knepley . dm - The DM
433744a7f3ddSMatthew G. Knepley 
433844a7f3ddSMatthew G. Knepley   Level: intermediate
433944a7f3ddSMatthew G. Knepley 
434044a7f3ddSMatthew G. Knepley .seealso: DMGetNumFields(), DMSetNumFields(), DMSetField()
434144a7f3ddSMatthew G. Knepley @*/
434244a7f3ddSMatthew G. Knepley PetscErrorCode DMClearFields(DM dm)
434344a7f3ddSMatthew G. Knepley {
434444a7f3ddSMatthew G. Knepley   PetscInt       f;
434544a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
434644a7f3ddSMatthew G. Knepley 
434744a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
434844a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
434944a7f3ddSMatthew G. Knepley   for (f = 0; f < dm->Nf; ++f) {
435044a7f3ddSMatthew G. Knepley     ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
435144a7f3ddSMatthew G. Knepley     ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
435244a7f3ddSMatthew G. Knepley   }
435344a7f3ddSMatthew G. Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
435444a7f3ddSMatthew G. Knepley   dm->fields = NULL;
435544a7f3ddSMatthew G. Knepley   dm->Nf     = 0;
435644a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
435744a7f3ddSMatthew G. Knepley }
435844a7f3ddSMatthew G. Knepley 
4359689b5837SMatthew G. Knepley /*@
4360689b5837SMatthew G. Knepley   DMGetNumFields - Get the number of fields in the DM
4361689b5837SMatthew G. Knepley 
4362689b5837SMatthew G. Knepley   Not collective
4363689b5837SMatthew G. Knepley 
4364689b5837SMatthew G. Knepley   Input Parameter:
4365689b5837SMatthew G. Knepley . dm - The DM
4366689b5837SMatthew G. Knepley 
4367689b5837SMatthew G. Knepley   Output Parameter:
4368689b5837SMatthew G. Knepley . Nf - The number of fields
4369689b5837SMatthew G. Knepley 
4370689b5837SMatthew G. Knepley   Level: intermediate
4371689b5837SMatthew G. Knepley 
4372689b5837SMatthew G. Knepley .seealso: DMSetNumFields(), DMSetField()
4373689b5837SMatthew G. Knepley @*/
43740f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
43750f21e855SMatthew G. Knepley {
43760f21e855SMatthew G. Knepley   PetscFunctionBegin;
43770f21e855SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4378*534a8f05SLisandro Dalcin   PetscValidIntPointer(numFields, 2);
437944a7f3ddSMatthew G. Knepley   *numFields = dm->Nf;
4380af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4381af122d2aSMatthew G Knepley }
4382af122d2aSMatthew G Knepley 
4383689b5837SMatthew G. Knepley /*@
4384689b5837SMatthew G. Knepley   DMSetNumFields - Set the number of fields in the DM
4385689b5837SMatthew G. Knepley 
4386d083f849SBarry Smith   Logically collective on dm
4387689b5837SMatthew G. Knepley 
4388689b5837SMatthew G. Knepley   Input Parameters:
4389689b5837SMatthew G. Knepley + dm - The DM
4390689b5837SMatthew G. Knepley - Nf - The number of fields
4391689b5837SMatthew G. Knepley 
4392689b5837SMatthew G. Knepley   Level: intermediate
4393689b5837SMatthew G. Knepley 
4394689b5837SMatthew G. Knepley .seealso: DMGetNumFields(), DMSetField()
4395689b5837SMatthew G. Knepley @*/
4396af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
4397af122d2aSMatthew G Knepley {
43980f21e855SMatthew G. Knepley   PetscInt       Nf, f;
4399af122d2aSMatthew G Knepley   PetscErrorCode ierr;
4400af122d2aSMatthew G Knepley 
4401af122d2aSMatthew G Knepley   PetscFunctionBegin;
4402af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
440344a7f3ddSMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
44040f21e855SMatthew G. Knepley   for (f = Nf; f < numFields; ++f) {
44050f21e855SMatthew G. Knepley     PetscContainer obj;
44060f21e855SMatthew G. Knepley 
44070f21e855SMatthew G. Knepley     ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr);
440844a7f3ddSMatthew G. Knepley     ierr = DMAddField(dm, NULL, (PetscObject) obj);CHKERRQ(ierr);
44090f21e855SMatthew G. Knepley     ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr);
4410af122d2aSMatthew G Knepley   }
4411af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4412af122d2aSMatthew G Knepley }
4413af122d2aSMatthew G Knepley 
4414c1929be8SMatthew G. Knepley /*@
4415c1929be8SMatthew G. Knepley   DMGetField - Return the discretization object for a given DM field
4416c1929be8SMatthew G. Knepley 
4417c1929be8SMatthew G. Knepley   Not collective
4418c1929be8SMatthew G. Knepley 
4419c1929be8SMatthew G. Knepley   Input Parameters:
4420c1929be8SMatthew G. Knepley + dm - The DM
4421c1929be8SMatthew G. Knepley - f  - The field number
4422c1929be8SMatthew G. Knepley 
442344a7f3ddSMatthew G. Knepley   Output Parameters:
442444a7f3ddSMatthew G. Knepley + label - The label indicating the support of the field, or NULL for the entire mesh
442544a7f3ddSMatthew G. Knepley - field - The discretization object
4426c1929be8SMatthew G. Knepley 
442744a7f3ddSMatthew G. Knepley   Level: intermediate
4428c1929be8SMatthew G. Knepley 
442944a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMSetField()
4430c1929be8SMatthew G. Knepley @*/
443144a7f3ddSMatthew G. Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, DMLabel *label, PetscObject *field)
4432af122d2aSMatthew G Knepley {
4433af122d2aSMatthew G Knepley   PetscFunctionBegin;
4434af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
443544a7f3ddSMatthew G. Knepley   PetscValidPointer(field, 3);
443644a7f3ddSMatthew 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);
443744a7f3ddSMatthew G. Knepley   if (label) *label = dm->fields[f].label;
443844a7f3ddSMatthew G. Knepley   if (field) *field = dm->fields[f].disc;
4439decb47aaSMatthew G. Knepley   PetscFunctionReturn(0);
4440decb47aaSMatthew G. Knepley }
4441decb47aaSMatthew G. Knepley 
4442c1929be8SMatthew G. Knepley /*@
4443c1929be8SMatthew G. Knepley   DMSetField - Set the discretization object for a given DM field
4444c1929be8SMatthew G. Knepley 
4445d083f849SBarry Smith   Logically collective on dm
4446c1929be8SMatthew G. Knepley 
4447c1929be8SMatthew G. Knepley   Input Parameters:
4448c1929be8SMatthew G. Knepley + dm    - The DM
4449c1929be8SMatthew G. Knepley . f     - The field number
445044a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
4451c1929be8SMatthew G. Knepley - field - The discretization object
4452c1929be8SMatthew G. Knepley 
445344a7f3ddSMatthew G. Knepley   Level: intermediate
4454c1929be8SMatthew G. Knepley 
445544a7f3ddSMatthew G. Knepley .seealso: DMAddField(), DMGetField()
4456c1929be8SMatthew G. Knepley @*/
445744a7f3ddSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, DMLabel label, PetscObject field)
4458decb47aaSMatthew G. Knepley {
4459decb47aaSMatthew G. Knepley   PetscErrorCode ierr;
4460decb47aaSMatthew G. Knepley 
4461decb47aaSMatthew G. Knepley   PetscFunctionBegin;
4462decb47aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4463e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
446444a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 4);
4465e5e52638SMatthew G. Knepley   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
446644a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, f+1);CHKERRQ(ierr);
446744a7f3ddSMatthew G. Knepley   ierr = DMLabelDestroy(&dm->fields[f].label);CHKERRQ(ierr);
446844a7f3ddSMatthew G. Knepley   ierr = PetscObjectDestroy(&dm->fields[f].disc);CHKERRQ(ierr);
446944a7f3ddSMatthew G. Knepley   dm->fields[f].label = label;
447044a7f3ddSMatthew G. Knepley   dm->fields[f].disc  = field;
447144a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
447244a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
447334aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, f, field);CHKERRQ(ierr);
44742df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
447544a7f3ddSMatthew G. Knepley   PetscFunctionReturn(0);
447644a7f3ddSMatthew G. Knepley }
447744a7f3ddSMatthew G. Knepley 
447844a7f3ddSMatthew G. Knepley /*@
447944a7f3ddSMatthew G. Knepley   DMAddField - Add the discretization object for the given DM field
448044a7f3ddSMatthew G. Knepley 
4481d083f849SBarry Smith   Logically collective on dm
448244a7f3ddSMatthew G. Knepley 
448344a7f3ddSMatthew G. Knepley   Input Parameters:
448444a7f3ddSMatthew G. Knepley + dm    - The DM
448544a7f3ddSMatthew G. Knepley . label - The label indicating the support of the field, or NULL for the entire mesh
448644a7f3ddSMatthew G. Knepley - field - The discretization object
448744a7f3ddSMatthew G. Knepley 
448844a7f3ddSMatthew G. Knepley   Level: intermediate
448944a7f3ddSMatthew G. Knepley 
449044a7f3ddSMatthew G. Knepley .seealso: DMSetField(), DMGetField()
449144a7f3ddSMatthew G. Knepley @*/
449244a7f3ddSMatthew G. Knepley PetscErrorCode DMAddField(DM dm, DMLabel label, PetscObject field)
449344a7f3ddSMatthew G. Knepley {
449444a7f3ddSMatthew G. Knepley   PetscInt       Nf = dm->Nf;
449544a7f3ddSMatthew G. Knepley   PetscErrorCode ierr;
449644a7f3ddSMatthew G. Knepley 
449744a7f3ddSMatthew G. Knepley   PetscFunctionBegin;
449844a7f3ddSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
449944a7f3ddSMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 3);
450044a7f3ddSMatthew G. Knepley   PetscValidHeader(field, 3);
450144a7f3ddSMatthew G. Knepley   ierr = DMFieldEnlarge_Static(dm, Nf+1);CHKERRQ(ierr);
450244a7f3ddSMatthew G. Knepley   dm->fields[Nf].label = label;
450344a7f3ddSMatthew G. Knepley   dm->fields[Nf].disc  = field;
450444a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
450544a7f3ddSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) field);CHKERRQ(ierr);
450634aa8a36SMatthew G. Knepley   ierr = DMSetDefaultAdjacency_Private(dm, Nf, field);CHKERRQ(ierr);
45072df9ee95SMatthew G. Knepley   ierr = DMClearDS(dm);CHKERRQ(ierr);
4508af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
4509af122d2aSMatthew G Knepley }
45106636e97aSMatthew G Knepley 
4511e5e52638SMatthew G. Knepley /*@
4512e5e52638SMatthew G. Knepley   DMCopyFields - Copy the discretizations for the DM into another DM
4513e5e52638SMatthew G. Knepley 
4514d083f849SBarry Smith   Collective on dm
4515e5e52638SMatthew G. Knepley 
4516e5e52638SMatthew G. Knepley   Input Parameter:
4517e5e52638SMatthew G. Knepley . dm - The DM
4518e5e52638SMatthew G. Knepley 
4519e5e52638SMatthew G. Knepley   Output Parameter:
4520e5e52638SMatthew G. Knepley . newdm - The DM
4521e5e52638SMatthew G. Knepley 
4522e5e52638SMatthew G. Knepley   Level: advanced
4523e5e52638SMatthew G. Knepley 
4524e5e52638SMatthew G. Knepley .seealso: DMGetField(), DMSetField(), DMAddField(), DMCopyDS(), DMGetDS(), DMGetCellDS()
4525e5e52638SMatthew G. Knepley @*/
4526e5e52638SMatthew G. Knepley PetscErrorCode DMCopyFields(DM dm, DM newdm)
4527e5e52638SMatthew G. Knepley {
4528e5e52638SMatthew G. Knepley   PetscInt       Nf, f;
4529e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4530e5e52638SMatthew G. Knepley 
4531e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4532e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
4533e5e52638SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4534e5e52638SMatthew G. Knepley   ierr = DMClearFields(newdm);CHKERRQ(ierr);
4535e5e52638SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4536e5e52638SMatthew G. Knepley     DMLabel     label;
4537e5e52638SMatthew G. Knepley     PetscObject field;
453834aa8a36SMatthew G. Knepley     PetscBool   useCone, useClosure;
4539e5e52638SMatthew G. Knepley 
4540e5e52638SMatthew G. Knepley     ierr = DMGetField(dm, f, &label, &field);CHKERRQ(ierr);
4541e5e52638SMatthew G. Knepley     ierr = DMSetField(newdm, f, label, field);CHKERRQ(ierr);
454234aa8a36SMatthew G. Knepley     ierr = DMGetAdjacency(dm, f, &useCone, &useClosure);CHKERRQ(ierr);
454334aa8a36SMatthew G. Knepley     ierr = DMSetAdjacency(newdm, f, useCone, useClosure);CHKERRQ(ierr);
454434aa8a36SMatthew G. Knepley   }
454534aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
454634aa8a36SMatthew G. Knepley }
454734aa8a36SMatthew G. Knepley 
454834aa8a36SMatthew G. Knepley /*@
454934aa8a36SMatthew G. Knepley   DMGetAdjacency - Returns the flags for determining variable influence
455034aa8a36SMatthew G. Knepley 
455134aa8a36SMatthew G. Knepley   Not collective
455234aa8a36SMatthew G. Knepley 
455334aa8a36SMatthew G. Knepley   Input Parameters:
455434aa8a36SMatthew G. Knepley + dm - The DM object
455534aa8a36SMatthew G. Knepley - f  - The field number, or PETSC_DEFAULT for the default adjacency
455634aa8a36SMatthew G. Knepley 
455734aa8a36SMatthew G. Knepley   Output Parameter:
455834aa8a36SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
455934aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
456034aa8a36SMatthew G. Knepley 
456134aa8a36SMatthew G. Knepley   Notes:
456234aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
456334aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
456434aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4565979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
456634aa8a36SMatthew G. Knepley 
456734aa8a36SMatthew G. Knepley   Level: developer
456834aa8a36SMatthew G. Knepley 
456934aa8a36SMatthew G. Knepley .seealso: DMSetAdjacency(), DMGetField(), DMSetField()
457034aa8a36SMatthew G. Knepley @*/
457134aa8a36SMatthew G. Knepley PetscErrorCode DMGetAdjacency(DM dm, PetscInt f, PetscBool *useCone, PetscBool *useClosure)
457234aa8a36SMatthew G. Knepley {
457334aa8a36SMatthew G. Knepley   PetscFunctionBegin;
457434aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4575*534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4576*534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
457734aa8a36SMatthew G. Knepley   if (f < 0) {
457834aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->adjacency[0];
457934aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->adjacency[1];
458034aa8a36SMatthew G. Knepley   } else {
458134aa8a36SMatthew G. Knepley     PetscInt       Nf;
458234aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
458334aa8a36SMatthew G. Knepley 
458434aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
458534aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
458634aa8a36SMatthew G. Knepley     if (useCone)    *useCone    = dm->fields[f].adjacency[0];
458734aa8a36SMatthew G. Knepley     if (useClosure) *useClosure = dm->fields[f].adjacency[1];
458834aa8a36SMatthew G. Knepley   }
458934aa8a36SMatthew G. Knepley   PetscFunctionReturn(0);
459034aa8a36SMatthew G. Knepley }
459134aa8a36SMatthew G. Knepley 
459234aa8a36SMatthew G. Knepley /*@
459334aa8a36SMatthew G. Knepley   DMSetAdjacency - Set the flags for determining variable influence
459434aa8a36SMatthew G. Knepley 
459534aa8a36SMatthew G. Knepley   Not collective
459634aa8a36SMatthew G. Knepley 
459734aa8a36SMatthew G. Knepley   Input Parameters:
459834aa8a36SMatthew G. Knepley + dm         - The DM object
459934aa8a36SMatthew G. Knepley . f          - The field number
460034aa8a36SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
460134aa8a36SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
460234aa8a36SMatthew G. Knepley 
460334aa8a36SMatthew G. Knepley   Notes:
460434aa8a36SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
460534aa8a36SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
460634aa8a36SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4607979e053dSMatthew G. Knepley   Further explanation can be found in the User's Manual Section on the Influence of Variables on One Another.
460834aa8a36SMatthew G. Knepley 
460934aa8a36SMatthew G. Knepley   Level: developer
461034aa8a36SMatthew G. Knepley 
461134aa8a36SMatthew G. Knepley .seealso: DMGetAdjacency(), DMGetField(), DMSetField()
461234aa8a36SMatthew G. Knepley @*/
461334aa8a36SMatthew G. Knepley PetscErrorCode DMSetAdjacency(DM dm, PetscInt f, PetscBool useCone, PetscBool useClosure)
461434aa8a36SMatthew G. Knepley {
461534aa8a36SMatthew G. Knepley   PetscFunctionBegin;
461634aa8a36SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
461734aa8a36SMatthew G. Knepley   if (f < 0) {
461834aa8a36SMatthew G. Knepley     dm->adjacency[0] = useCone;
461934aa8a36SMatthew G. Knepley     dm->adjacency[1] = useClosure;
462034aa8a36SMatthew G. Knepley   } else {
462134aa8a36SMatthew G. Knepley     PetscInt       Nf;
462234aa8a36SMatthew G. Knepley     PetscErrorCode ierr;
462334aa8a36SMatthew G. Knepley 
462434aa8a36SMatthew G. Knepley     ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
462534aa8a36SMatthew G. Knepley     if (f >= Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, Nf);
462634aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[0] = useCone;
462734aa8a36SMatthew G. Knepley     dm->fields[f].adjacency[1] = useClosure;
4628e5e52638SMatthew G. Knepley   }
4629e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4630e5e52638SMatthew G. Knepley }
4631e5e52638SMatthew G. Knepley 
4632b0441da4SMatthew G. Knepley /*@
4633b0441da4SMatthew G. Knepley   DMGetBasicAdjacency - Returns the flags for determining variable influence, using either the default or field 0 if it is defined
4634b0441da4SMatthew G. Knepley 
4635b0441da4SMatthew G. Knepley   Not collective
4636b0441da4SMatthew G. Knepley 
4637b0441da4SMatthew G. Knepley   Input Parameters:
4638b0441da4SMatthew G. Knepley . dm - The DM object
4639b0441da4SMatthew G. Knepley 
4640b0441da4SMatthew G. Knepley   Output Parameter:
4641b0441da4SMatthew G. Knepley + useCone    - Flag for variable influence starting with the cone operation
4642b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4643b0441da4SMatthew G. Knepley 
4644b0441da4SMatthew G. Knepley   Notes:
4645b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4646b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4647b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4648b0441da4SMatthew G. Knepley 
4649b0441da4SMatthew G. Knepley   Level: developer
4650b0441da4SMatthew G. Knepley 
4651b0441da4SMatthew G. Knepley .seealso: DMSetBasicAdjacency(), DMGetField(), DMSetField()
4652b0441da4SMatthew G. Knepley @*/
4653b0441da4SMatthew G. Knepley PetscErrorCode DMGetBasicAdjacency(DM dm, PetscBool *useCone, PetscBool *useClosure)
4654b0441da4SMatthew G. Knepley {
4655b0441da4SMatthew G. Knepley   PetscInt       Nf;
4656b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4657b0441da4SMatthew G. Knepley 
4658b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4659b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4660*534a8f05SLisandro Dalcin   if (useCone)    PetscValidBoolPointer(useCone, 3);
4661*534a8f05SLisandro Dalcin   if (useClosure) PetscValidBoolPointer(useClosure, 4);
4662b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4663b0441da4SMatthew G. Knepley   if (!Nf) {
4664b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4665b0441da4SMatthew G. Knepley   } else {
4666b0441da4SMatthew G. Knepley     ierr = DMGetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4667b0441da4SMatthew G. Knepley   }
4668b0441da4SMatthew G. Knepley   PetscFunctionReturn(0);
4669b0441da4SMatthew G. Knepley }
4670b0441da4SMatthew G. Knepley 
4671b0441da4SMatthew G. Knepley /*@
4672b0441da4SMatthew G. Knepley   DMSetBasicAdjacency - Set the flags for determining variable influence, using either the default or field 0 if it is defined
4673b0441da4SMatthew G. Knepley 
4674b0441da4SMatthew G. Knepley   Not collective
4675b0441da4SMatthew G. Knepley 
4676b0441da4SMatthew G. Knepley   Input Parameters:
4677b0441da4SMatthew G. Knepley + dm         - The DM object
4678b0441da4SMatthew G. Knepley . useCone    - Flag for variable influence starting with the cone operation
4679b0441da4SMatthew G. Knepley - useClosure - Flag for variable influence using transitive closure
4680b0441da4SMatthew G. Knepley 
4681b0441da4SMatthew G. Knepley   Notes:
4682b0441da4SMatthew G. Knepley $     FEM:   Two points p and q are adjacent if q \in closure(star(p)),   useCone = PETSC_FALSE, useClosure = PETSC_TRUE
4683b0441da4SMatthew G. Knepley $     FVM:   Two points p and q are adjacent if q \in support(p+cone(p)), useCone = PETSC_TRUE,  useClosure = PETSC_FALSE
4684b0441da4SMatthew G. Knepley $     FVM++: Two points p and q are adjacent if q \in star(closure(p)),   useCone = PETSC_TRUE,  useClosure = PETSC_TRUE
4685b0441da4SMatthew G. Knepley 
4686b0441da4SMatthew G. Knepley   Level: developer
4687b0441da4SMatthew G. Knepley 
4688b0441da4SMatthew G. Knepley .seealso: DMGetBasicAdjacency(), DMGetField(), DMSetField()
4689b0441da4SMatthew G. Knepley @*/
4690b0441da4SMatthew G. Knepley PetscErrorCode DMSetBasicAdjacency(DM dm, PetscBool useCone, PetscBool useClosure)
4691b0441da4SMatthew G. Knepley {
4692b0441da4SMatthew G. Knepley   PetscInt       Nf;
4693b0441da4SMatthew G. Knepley   PetscErrorCode ierr;
4694b0441da4SMatthew G. Knepley 
4695b0441da4SMatthew G. Knepley   PetscFunctionBegin;
4696b0441da4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4697b0441da4SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4698b0441da4SMatthew G. Knepley   if (!Nf) {
4699b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, PETSC_DEFAULT, useCone, useClosure);CHKERRQ(ierr);
4700b0441da4SMatthew G. Knepley   } else {
4701b0441da4SMatthew G. Knepley     ierr = DMSetAdjacency(dm, 0, useCone, useClosure);CHKERRQ(ierr);
4702e5e52638SMatthew G. Knepley   }
4703e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4704e5e52638SMatthew G. Knepley }
4705e5e52638SMatthew G. Knepley 
4706e5e52638SMatthew G. Knepley static PetscErrorCode DMDSEnlarge_Static(DM dm, PetscInt NdsNew)
4707e5e52638SMatthew G. Knepley {
4708e5e52638SMatthew G. Knepley   DMSpace       *tmpd;
4709e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
4710e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4711e5e52638SMatthew G. Knepley 
4712e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4713e5e52638SMatthew G. Knepley   if (Nds >= NdsNew) PetscFunctionReturn(0);
4714e5e52638SMatthew G. Knepley   ierr = PetscMalloc1(NdsNew, &tmpd);CHKERRQ(ierr);
4715e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) tmpd[s] = dm->probs[s];
4716b3cf3223SMatthew G. Knepley   for (s = Nds; s < NdsNew; ++s) {tmpd[s].ds = NULL; tmpd[s].label = NULL; tmpd[s].fields = NULL;}
4717e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4718e5e52638SMatthew G. Knepley   dm->Nds   = NdsNew;
4719e5e52638SMatthew G. Knepley   dm->probs = tmpd;
4720e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4721e5e52638SMatthew G. Knepley }
4722e5e52638SMatthew G. Knepley 
4723e5e52638SMatthew G. Knepley /*@
4724e5e52638SMatthew G. Knepley   DMGetNumDS - Get the number of discrete systems in the DM
4725e5e52638SMatthew G. Knepley 
4726e5e52638SMatthew G. Knepley   Not collective
4727e5e52638SMatthew G. Knepley 
4728e5e52638SMatthew G. Knepley   Input Parameter:
4729e5e52638SMatthew G. Knepley . dm - The DM
4730e5e52638SMatthew G. Knepley 
4731e5e52638SMatthew G. Knepley   Output Parameter:
4732e5e52638SMatthew G. Knepley . Nds - The number of PetscDS objects
4733e5e52638SMatthew G. Knepley 
4734e5e52638SMatthew G. Knepley   Level: intermediate
4735e5e52638SMatthew G. Knepley 
4736e5e52638SMatthew G. Knepley .seealso: DMGetDS(), DMGetCellDS()
4737e5e52638SMatthew G. Knepley @*/
4738e5e52638SMatthew G. Knepley PetscErrorCode DMGetNumDS(DM dm, PetscInt *Nds)
4739e5e52638SMatthew G. Knepley {
4740e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4741e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4742*534a8f05SLisandro Dalcin   PetscValidIntPointer(Nds, 2);
4743e5e52638SMatthew G. Knepley   *Nds = dm->Nds;
4744e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4745e5e52638SMatthew G. Knepley }
4746e5e52638SMatthew G. Knepley 
4747e5e52638SMatthew G. Knepley /*@
4748e5e52638SMatthew G. Knepley   DMClearDS - Remove all discrete systems from the DM
4749e5e52638SMatthew G. Knepley 
4750d083f849SBarry Smith   Logically collective on dm
4751e5e52638SMatthew G. Knepley 
4752e5e52638SMatthew G. Knepley   Input Parameter:
4753e5e52638SMatthew G. Knepley . dm - The DM
4754e5e52638SMatthew G. Knepley 
4755e5e52638SMatthew G. Knepley   Level: intermediate
4756e5e52638SMatthew G. Knepley 
4757e5e52638SMatthew G. Knepley .seealso: DMGetNumDS(), DMGetDS(), DMSetField()
4758e5e52638SMatthew G. Knepley @*/
4759e5e52638SMatthew G. Knepley PetscErrorCode DMClearDS(DM dm)
4760e5e52638SMatthew G. Knepley {
4761e5e52638SMatthew G. Knepley   PetscInt       s;
4762e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4763e5e52638SMatthew G. Knepley 
4764e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4765e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4766e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4767e5e52638SMatthew G. Knepley     ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
4768e5e52638SMatthew G. Knepley     ierr = DMLabelDestroy(&dm->probs[s].label);CHKERRQ(ierr);
4769b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&dm->probs[s].fields);CHKERRQ(ierr);
4770e5e52638SMatthew G. Knepley   }
4771e5e52638SMatthew G. Knepley   ierr = PetscFree(dm->probs);CHKERRQ(ierr);
4772e5e52638SMatthew G. Knepley   dm->probs = NULL;
4773e5e52638SMatthew G. Knepley   dm->Nds   = 0;
4774e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4775e5e52638SMatthew G. Knepley }
4776e5e52638SMatthew G. Knepley 
4777e5e52638SMatthew G. Knepley /*@
4778e5e52638SMatthew G. Knepley   DMGetDS - Get the default PetscDS
4779e5e52638SMatthew G. Knepley 
4780e5e52638SMatthew G. Knepley   Not collective
4781e5e52638SMatthew G. Knepley 
4782e5e52638SMatthew G. Knepley   Input Parameter:
4783e5e52638SMatthew G. Knepley . dm    - The DM
4784e5e52638SMatthew G. Knepley 
4785e5e52638SMatthew G. Knepley   Output Parameter:
4786e5e52638SMatthew G. Knepley . prob - The default PetscDS
4787e5e52638SMatthew G. Knepley 
4788e5e52638SMatthew G. Knepley   Level: intermediate
4789e5e52638SMatthew G. Knepley 
4790e5e52638SMatthew G. Knepley .seealso: DMGetCellDS(), DMGetRegionDS()
4791e5e52638SMatthew G. Knepley @*/
4792e5e52638SMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob)
4793e5e52638SMatthew G. Knepley {
4794b0143b4dSMatthew G. Knepley   PetscErrorCode ierr;
4795b0143b4dSMatthew G. Knepley 
4796e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4797e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4798e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 2);
4799b0143b4dSMatthew G. Knepley   if (dm->Nds <= 0) {
4800b0143b4dSMatthew G. Knepley     PetscDS ds;
4801b0143b4dSMatthew G. Knepley 
4802b0143b4dSMatthew G. Knepley     ierr = PetscDSCreate(PetscObjectComm((PetscObject) dm), &ds);CHKERRQ(ierr);
4803b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, NULL, ds);CHKERRQ(ierr);
4804b0143b4dSMatthew G. Knepley     ierr = PetscDSDestroy(&ds);CHKERRQ(ierr);
4805b0143b4dSMatthew G. Knepley   }
4806b0143b4dSMatthew G. Knepley   *prob = dm->probs[0].ds;
4807e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4808e5e52638SMatthew G. Knepley }
4809e5e52638SMatthew G. Knepley 
4810e5e52638SMatthew G. Knepley /*@
4811e5e52638SMatthew G. Knepley   DMGetCellDS - Get the PetscDS defined on a given cell
4812e5e52638SMatthew G. Knepley 
4813e5e52638SMatthew G. Knepley   Not collective
4814e5e52638SMatthew G. Knepley 
4815e5e52638SMatthew G. Knepley   Input Parameters:
4816e5e52638SMatthew G. Knepley + dm    - The DM
4817e5e52638SMatthew G. Knepley - point - Cell for the DS
4818e5e52638SMatthew G. Knepley 
4819e5e52638SMatthew G. Knepley   Output Parameter:
4820e5e52638SMatthew G. Knepley . prob - The PetscDS defined on the given cell
4821e5e52638SMatthew G. Knepley 
4822e5e52638SMatthew G. Knepley   Level: developer
4823e5e52638SMatthew G. Knepley 
4824b0143b4dSMatthew G. Knepley .seealso: DMGetDS(), DMSetRegionDS()
4825e5e52638SMatthew G. Knepley @*/
4826e5e52638SMatthew G. Knepley PetscErrorCode DMGetCellDS(DM dm, PetscInt point, PetscDS *prob)
4827e5e52638SMatthew G. Knepley {
4828e5e52638SMatthew G. Knepley   PetscDS        probDef = NULL;
4829e5e52638SMatthew G. Knepley   PetscInt       s;
4830e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4831e5e52638SMatthew G. Knepley 
4832e5e52638SMatthew G. Knepley   PetscFunctionBeginHot;
4833e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4834e5e52638SMatthew G. Knepley   PetscValidPointer(prob, 3);
4835e5e52638SMatthew G. Knepley   *prob = NULL;
4836e5e52638SMatthew G. Knepley   for (s = 0; s < dm->Nds; ++s) {
4837e5e52638SMatthew G. Knepley     PetscInt val;
4838e5e52638SMatthew G. Knepley 
4839e5e52638SMatthew G. Knepley     if (!dm->probs[s].label) {probDef = dm->probs[s].ds;}
4840e5e52638SMatthew G. Knepley     else {
4841e5e52638SMatthew G. Knepley       ierr = DMLabelGetValue(dm->probs[s].label, point, &val);CHKERRQ(ierr);
4842e5e52638SMatthew G. Knepley       if (val >= 0) {*prob = dm->probs[s].ds; break;}
4843e5e52638SMatthew G. Knepley     }
4844e5e52638SMatthew G. Knepley   }
4845e5e52638SMatthew G. Knepley   if (!*prob) *prob = probDef;
4846e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4847e5e52638SMatthew G. Knepley }
4848e5e52638SMatthew G. Knepley 
4849e5e52638SMatthew G. Knepley /*@
4850e5e52638SMatthew G. Knepley   DMGetRegionDS - Get the PetscDS for a given mesh region, defined by a DMLabel
4851e5e52638SMatthew G. Knepley 
4852e5e52638SMatthew G. Knepley   Not collective
4853e5e52638SMatthew G. Knepley 
4854e5e52638SMatthew G. Knepley   Input Parameters:
4855e5e52638SMatthew G. Knepley + dm    - The DM
4856e5e52638SMatthew G. Knepley - label - The DMLabel defining the mesh region, or NULL for the entire mesh
4857e5e52638SMatthew G. Knepley 
4858b3cf3223SMatthew G. Knepley   Output Parameters:
4859b3cf3223SMatthew G. Knepley + fields - The IS containing the DM field numbers for the fields in this DS, or NULL
4860b3cf3223SMatthew G. Knepley - prob - The PetscDS defined on the given region, or NULL
4861e5e52638SMatthew G. Knepley 
4862e5e52638SMatthew G. Knepley   Note: If the label is missing, this function returns an error
4863e5e52638SMatthew G. Knepley 
4864e5e52638SMatthew G. Knepley   Level: advanced
4865e5e52638SMatthew G. Knepley 
4866e5e52638SMatthew G. Knepley .seealso: DMGetRegionNumDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
4867e5e52638SMatthew G. Knepley @*/
4868b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionDS(DM dm, DMLabel label, IS *fields, PetscDS *ds)
4869e5e52638SMatthew G. Knepley {
4870e5e52638SMatthew G. Knepley   PetscInt Nds = dm->Nds, s;
4871e5e52638SMatthew G. Knepley 
4872e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4873e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4874e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
4875b3cf3223SMatthew G. Knepley   if (fields) {PetscValidPointer(fields, 3); *fields = NULL;}
4876b3cf3223SMatthew G. Knepley   if (ds)     {PetscValidPointer(ds, 4);     *ds     = NULL;}
4877e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
4878b3cf3223SMatthew G. Knepley     if (dm->probs[s].label == label) {
4879b3cf3223SMatthew G. Knepley       if (fields) *fields = dm->probs[s].fields;
4880b3cf3223SMatthew G. Knepley       if (ds)     *ds     = dm->probs[s].ds;
4881b3cf3223SMatthew G. Knepley       PetscFunctionReturn(0);
4882b3cf3223SMatthew G. Knepley     }
4883e5e52638SMatthew G. Knepley   }
48842df9ee95SMatthew G. Knepley   PetscFunctionReturn(0);
4885e5e52638SMatthew G. Knepley }
4886e5e52638SMatthew G. Knepley 
4887e5e52638SMatthew G. Knepley /*@
4888e5e52638SMatthew G. Knepley   DMGetRegionNumDS - Get the PetscDS for a given mesh region, defined by the region number
4889e5e52638SMatthew G. Knepley 
4890e5e52638SMatthew G. Knepley   Not collective
4891e5e52638SMatthew G. Knepley 
4892e5e52638SMatthew G. Knepley   Input Parameters:
4893e5e52638SMatthew G. Knepley + dm  - The DM
4894e5e52638SMatthew G. Knepley - num - The region number, in [0, Nds)
4895e5e52638SMatthew G. Knepley 
4896e5e52638SMatthew G. Knepley   Output Parameters:
4897b3cf3223SMatthew G. Knepley + label  - The region label, or NULL
4898b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL
4899b3cf3223SMatthew G. Knepley - prob   - The PetscDS defined on the given region, or NULL
4900e5e52638SMatthew G. Knepley 
4901e5e52638SMatthew G. Knepley   Level: advanced
4902e5e52638SMatthew G. Knepley 
4903e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMSetRegionDS(), DMGetDS(), DMGetCellDS()
4904e5e52638SMatthew G. Knepley @*/
4905b3cf3223SMatthew G. Knepley PetscErrorCode DMGetRegionNumDS(DM dm, PetscInt num, DMLabel *label, IS *fields, PetscDS *ds)
4906e5e52638SMatthew G. Knepley {
4907e5e52638SMatthew G. Knepley   PetscInt       Nds;
4908e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4909e5e52638SMatthew G. Knepley 
4910e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4911e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4912e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
4913e5e52638SMatthew 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);
4914e5e52638SMatthew G. Knepley   if (label) {
4915e5e52638SMatthew G. Knepley     PetscValidPointer(label, 3);
4916e5e52638SMatthew G. Knepley     *label = dm->probs[num].label;
4917e5e52638SMatthew G. Knepley   }
4918b3cf3223SMatthew G. Knepley   if (fields) {
4919b3cf3223SMatthew G. Knepley     PetscValidPointer(fields, 4);
4920b3cf3223SMatthew G. Knepley     *fields = dm->probs[num].fields;
4921b3cf3223SMatthew G. Knepley   }
4922e5e52638SMatthew G. Knepley   if (ds) {
4923b3cf3223SMatthew G. Knepley     PetscValidPointer(ds, 5);
4924e5e52638SMatthew G. Knepley     *ds = dm->probs[num].ds;
4925e5e52638SMatthew G. Knepley   }
4926e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4927e5e52638SMatthew G. Knepley }
4928e5e52638SMatthew G. Knepley 
4929e5e52638SMatthew G. Knepley /*@
4930e5e52638SMatthew G. Knepley   DMSetRegionDS - Set the PetscDS for a given mesh region, defined by a DMLabel
4931e5e52638SMatthew G. Knepley 
4932d083f849SBarry Smith   Collective on dm
4933e5e52638SMatthew G. Knepley 
4934e5e52638SMatthew G. Knepley   Input Parameters:
4935e5e52638SMatthew G. Knepley + dm     - The DM
4936e5e52638SMatthew G. Knepley . label  - The DMLabel defining the mesh region, or NULL for the entire mesh
4937b3cf3223SMatthew G. Knepley . fields - The IS containing the DM field numbers for the fields in this DS, or NULL for all fields
4938e5e52638SMatthew G. Knepley - prob   - The PetscDS defined on the given cell
4939e5e52638SMatthew G. Knepley 
4940b3cf3223SMatthew 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,
4941b3cf3223SMatthew G. Knepley   the fields argument is ignored.
4942e5e52638SMatthew G. Knepley 
4943e5e52638SMatthew G. Knepley   Level: advanced
4944e5e52638SMatthew G. Knepley 
4945e5e52638SMatthew G. Knepley .seealso: DMGetRegionDS(), DMGetDS(), DMGetCellDS()
4946e5e52638SMatthew G. Knepley @*/
4947b3cf3223SMatthew G. Knepley PetscErrorCode DMSetRegionDS(DM dm, DMLabel label, IS fields, PetscDS ds)
4948e5e52638SMatthew G. Knepley {
4949e5e52638SMatthew G. Knepley   PetscInt       Nds = dm->Nds, s;
4950e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4951e5e52638SMatthew G. Knepley 
4952e5e52638SMatthew G. Knepley   PetscFunctionBegin;
4953e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4954e5e52638SMatthew G. Knepley   if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
4955e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 3);
4956e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
4957e5e52638SMatthew G. Knepley     if (dm->probs[s].label == label) {
4958b3cf3223SMatthew G. Knepley       ierr = PetscDSDestroy(&dm->probs[s].ds);CHKERRQ(ierr);
4959e5e52638SMatthew G. Knepley       dm->probs[s].ds = ds;
4960e5e52638SMatthew G. Knepley       PetscFunctionReturn(0);
4961e5e52638SMatthew G. Knepley     }
4962e5e52638SMatthew G. Knepley   }
49631b5e6740SSatish Balay   ierr = DMDSEnlarge_Static(dm, Nds+1);CHKERRQ(ierr);
4964e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
4965b3cf3223SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) fields);CHKERRQ(ierr);
4966e5e52638SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) ds);CHKERRQ(ierr);
4967e5e52638SMatthew G. Knepley   if (!label) {
4968e5e52638SMatthew G. Knepley     /* Put the NULL label at the front, so it is returned as the default */
4969e5e52638SMatthew G. Knepley     for (s = Nds-1; s >=0; --s) dm->probs[s+1] = dm->probs[s];
4970e5e52638SMatthew G. Knepley     Nds = 0;
4971e5e52638SMatthew G. Knepley   }
4972e5e52638SMatthew G. Knepley   dm->probs[Nds].label  = label;
4973b3cf3223SMatthew G. Knepley   dm->probs[Nds].fields = fields;
4974e5e52638SMatthew G. Knepley   dm->probs[Nds].ds     = ds;
4975e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
4976e5e52638SMatthew G. Knepley }
4977e5e52638SMatthew G. Knepley 
4978e5e52638SMatthew G. Knepley /*@
4979e5e52638SMatthew G. Knepley   DMCreateDS - Create the discrete systems for the DM based upon the fields added to the DM
4980e5e52638SMatthew G. Knepley 
4981d083f849SBarry Smith   Collective on dm
4982e5e52638SMatthew G. Knepley 
4983e5e52638SMatthew G. Knepley   Input Parameter:
4984e5e52638SMatthew G. Knepley . dm - The DM
4985e5e52638SMatthew G. Knepley 
4986e5e52638SMatthew G. Knepley   Note: If the label has a DS defined, it will be replaced. Otherwise, it will be added to the DM.
4987e5e52638SMatthew G. Knepley 
4988e5e52638SMatthew G. Knepley   Level: intermediate
4989e5e52638SMatthew G. Knepley 
4990e5e52638SMatthew G. Knepley .seealso: DMSetField, DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
4991e5e52638SMatthew G. Knepley @*/
4992e5e52638SMatthew G. Knepley PetscErrorCode DMCreateDS(DM dm)
4993e5e52638SMatthew G. Knepley {
4994e5e52638SMatthew G. Knepley   MPI_Comm       comm;
4995e5e52638SMatthew G. Knepley   PetscDS        prob, probh = NULL;
4996b3cf3223SMatthew G. Knepley   PetscInt       dimEmbed, Nf = dm->Nf, f, s, field = 0, fieldh = 0;
4997e5e52638SMatthew G. Knepley   PetscBool      doSetup = PETSC_TRUE;
4998e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
4999e5e52638SMatthew G. Knepley 
5000e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5001e5e52638SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5002e5e52638SMatthew G. Knepley   if (!dm->fields) PetscFunctionReturn(0);
5003e5e52638SMatthew G. Knepley   /* Can only handle two label cases right now:
5004e5e52638SMatthew G. Knepley    1) NULL
5005e5e52638SMatthew G. Knepley    2) Hybrid cells
5006e5e52638SMatthew G. Knepley   */
5007e5e52638SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr);
5008e5e52638SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dimEmbed);CHKERRQ(ierr);
5009e5e52638SMatthew G. Knepley   /* Create default DS */
5010b3cf3223SMatthew G. Knepley   ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
50112df9ee95SMatthew G. Knepley   if (!prob) {
5012b3cf3223SMatthew G. Knepley     IS        fields;
5013b3cf3223SMatthew G. Knepley     PetscInt *fld, nf;
5014b3cf3223SMatthew G. Knepley 
5015b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) ++nf;
5016b3cf3223SMatthew G. Knepley     ierr = PetscMalloc1(nf, &fld);CHKERRQ(ierr);
5017b3cf3223SMatthew G. Knepley     for (f = 0, nf = 0; f < Nf; ++f) if (!dm->fields[f].label) fld[nf++] = f;
501888f0c812SMatthew G. Knepley     ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
501988f0c812SMatthew G. Knepley     ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
502088f0c812SMatthew G. Knepley     ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
502188f0c812SMatthew G. Knepley     ierr = ISGeneralSetIndices(fields, nf, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
502288f0c812SMatthew G. Knepley 
50232df9ee95SMatthew G. Knepley     ierr = PetscDSCreate(comm, &prob);CHKERRQ(ierr);
5024b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(dm, NULL, fields, prob);CHKERRQ(ierr);
50252df9ee95SMatthew G. Knepley     ierr = PetscDSDestroy(&prob);CHKERRQ(ierr);
5026b3cf3223SMatthew G. Knepley     ierr = ISDestroy(&fields);CHKERRQ(ierr);
5027b3cf3223SMatthew G. Knepley     ierr = DMGetRegionDS(dm, NULL, NULL, &prob);CHKERRQ(ierr);
50282df9ee95SMatthew G. Knepley   }
5029e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(prob, dimEmbed);CHKERRQ(ierr);
5030e5e52638SMatthew G. Knepley   /* Optionally create hybrid DS */
5031b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5032e5e52638SMatthew G. Knepley     DMLabel  label = dm->fields[f].label;
5033e5e52638SMatthew G. Knepley     PetscInt lStart, lEnd;
5034e5e52638SMatthew G. Knepley 
5035e5e52638SMatthew G. Knepley     if (label) {
50360122748bSMatthew G. Knepley       DM        plex;
5037a2d47024SMatthew G. Knepley       IS        fields;
5038a2d47024SMatthew G. Knepley       PetscInt *fld;
50390122748bSMatthew G. Knepley       PetscInt  depth, pMax[4];
50400122748bSMatthew G. Knepley 
50410122748bSMatthew G. Knepley       ierr = DMConvert(dm, DMPLEX, &plex);CHKERRQ(ierr);
50420122748bSMatthew G. Knepley       ierr = DMPlexGetDepth(plex, &depth);CHKERRQ(ierr);
50430122748bSMatthew 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);
50440122748bSMatthew G. Knepley       ierr = DMDestroy(&plex);CHKERRQ(ierr);
50450122748bSMatthew G. Knepley 
5046e5e52638SMatthew G. Knepley       ierr = DMLabelGetBounds(label, &lStart, &lEnd);CHKERRQ(ierr);
5047e5e52638SMatthew G. Knepley       if (lStart < pMax[depth]) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only support labels over hybrid cells right now");
5048e5e52638SMatthew G. Knepley       ierr = PetscDSCreate(comm, &probh);CHKERRQ(ierr);
5049a2d47024SMatthew G. Knepley       ierr = PetscMalloc1(1, &fld);CHKERRQ(ierr);
5050a2d47024SMatthew G. Knepley       fld[0] = f;
5051a2d47024SMatthew G. Knepley       ierr = ISCreate(PETSC_COMM_SELF, &fields);CHKERRQ(ierr);
5052a2d47024SMatthew G. Knepley       ierr = PetscObjectSetOptionsPrefix((PetscObject) fields, "dm_fields_");CHKERRQ(ierr);
5053a2d47024SMatthew G. Knepley       ierr = ISSetType(fields, ISGENERAL);CHKERRQ(ierr);
5054a2d47024SMatthew G. Knepley       ierr = ISGeneralSetIndices(fields, 1, fld, PETSC_OWN_POINTER);CHKERRQ(ierr);
5055a2d47024SMatthew G. Knepley       ierr = DMSetRegionDS(dm, label, fields, probh);CHKERRQ(ierr);
5056a2d47024SMatthew G. Knepley       ierr = ISDestroy(&fields);CHKERRQ(ierr);
5057e5e52638SMatthew G. Knepley       ierr = PetscDSSetHybrid(probh, PETSC_TRUE);CHKERRQ(ierr);
5058e5e52638SMatthew G. Knepley       ierr = PetscDSSetCoordinateDimension(probh, dimEmbed);CHKERRQ(ierr);
5059e5e52638SMatthew G. Knepley       break;
5060e5e52638SMatthew G. Knepley     }
5061e5e52638SMatthew G. Knepley   }
5062e5e52638SMatthew G. Knepley   /* Set fields in DSes */
5063b3cf3223SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
5064e5e52638SMatthew G. Knepley     DMLabel     label = dm->fields[f].label;
5065e5e52638SMatthew G. Knepley     PetscObject disc  = dm->fields[f].disc;
5066e5e52638SMatthew G. Knepley 
5067e5e52638SMatthew G. Knepley     if (!label) {
5068e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(prob,  field++,  disc);CHKERRQ(ierr);
5069e5e52638SMatthew G. Knepley       if (probh) {
5070e5e52638SMatthew G. Knepley         PetscFE subfe;
5071e5e52638SMatthew G. Knepley 
5072e5e52638SMatthew G. Knepley         ierr = PetscFEGetHeightSubspace((PetscFE) disc, 1, &subfe);CHKERRQ(ierr);
5073e5e52638SMatthew G. Knepley         ierr = PetscDSSetDiscretization(probh, fieldh++, (PetscObject) subfe);CHKERRQ(ierr);
5074e5e52638SMatthew G. Knepley       }
5075e5e52638SMatthew G. Knepley     } else {
5076e5e52638SMatthew G. Knepley       ierr = PetscDSSetDiscretization(probh, fieldh++, disc);CHKERRQ(ierr);
5077e5e52638SMatthew G. Knepley     }
5078e5e52638SMatthew G. Knepley     /* We allow people to have placeholder fields and construct the Section by hand */
5079e5e52638SMatthew G. Knepley     {
5080e5e52638SMatthew G. Knepley       PetscClassId id;
5081e5e52638SMatthew G. Knepley 
5082e5e52638SMatthew G. Knepley       ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
5083e5e52638SMatthew G. Knepley       if ((id != PETSCFE_CLASSID) && (id != PETSCFV_CLASSID)) doSetup = PETSC_FALSE;
5084e5e52638SMatthew G. Knepley     }
5085e5e52638SMatthew G. Knepley   }
5086e5e52638SMatthew G. Knepley   ierr = PetscDSDestroy(&probh);CHKERRQ(ierr);
5087e5e52638SMatthew G. Knepley   /* Setup DSes */
5088e5e52638SMatthew G. Knepley   if (doSetup) {
5089e5e52638SMatthew G. Knepley     for (s = 0; s < dm->Nds; ++s) {ierr = PetscDSSetUp(dm->probs[s].ds);CHKERRQ(ierr);}
5090e5e52638SMatthew G. Knepley   }
5091e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5092e5e52638SMatthew G. Knepley }
5093e5e52638SMatthew G. Knepley 
5094e5e52638SMatthew G. Knepley /*@
5095e5e52638SMatthew G. Knepley   DMCopyDS - Copy the discrete systems for the DM into another DM
5096e5e52638SMatthew G. Knepley 
5097d083f849SBarry Smith   Collective on dm
5098e5e52638SMatthew G. Knepley 
5099e5e52638SMatthew G. Knepley   Input Parameter:
5100e5e52638SMatthew G. Knepley . dm - The DM
5101e5e52638SMatthew G. Knepley 
5102e5e52638SMatthew G. Knepley   Output Parameter:
5103e5e52638SMatthew G. Knepley . newdm - The DM
5104e5e52638SMatthew G. Knepley 
5105e5e52638SMatthew G. Knepley   Level: advanced
5106e5e52638SMatthew G. Knepley 
5107e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMAddField(), DMGetDS(), DMGetCellDS(), DMGetRegionDS(), DMSetRegionDS()
5108e5e52638SMatthew G. Knepley @*/
5109e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDS(DM dm, DM newdm)
5110e5e52638SMatthew G. Knepley {
5111e5e52638SMatthew G. Knepley   PetscInt       Nds, s;
5112e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5113e5e52638SMatthew G. Knepley 
5114e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5115e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5116e5e52638SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
5117e5e52638SMatthew G. Knepley   ierr = DMClearDS(newdm);CHKERRQ(ierr);
5118e5e52638SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
5119e5e52638SMatthew G. Knepley     DMLabel label;
5120b3cf3223SMatthew G. Knepley     IS      fields;
5121e5e52638SMatthew G. Knepley     PetscDS ds;
5122e5e52638SMatthew G. Knepley 
5123b3cf3223SMatthew G. Knepley     ierr = DMGetRegionNumDS(dm, s, &label, &fields, &ds);CHKERRQ(ierr);
5124b3cf3223SMatthew G. Knepley     ierr = DMSetRegionDS(newdm, label, fields, ds);CHKERRQ(ierr);
5125e5e52638SMatthew G. Knepley   }
5126e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5127e5e52638SMatthew G. Knepley }
5128e5e52638SMatthew G. Knepley 
5129e5e52638SMatthew G. Knepley /*@
5130e5e52638SMatthew G. Knepley   DMCopyDisc - Copy the fields and discrete systems for the DM into another DM
5131e5e52638SMatthew G. Knepley 
5132d083f849SBarry Smith   Collective on dm
5133e5e52638SMatthew G. Knepley 
5134e5e52638SMatthew G. Knepley   Input Parameter:
5135e5e52638SMatthew G. Knepley . dm - The DM
5136e5e52638SMatthew G. Knepley 
5137e5e52638SMatthew G. Knepley   Output Parameter:
5138e5e52638SMatthew G. Knepley . newdm - The DM
5139e5e52638SMatthew G. Knepley 
5140e5e52638SMatthew G. Knepley   Level: advanced
5141e5e52638SMatthew G. Knepley 
5142e5e52638SMatthew G. Knepley .seealso: DMCopyFields(), DMCopyDS()
5143e5e52638SMatthew G. Knepley @*/
5144e5e52638SMatthew G. Knepley PetscErrorCode DMCopyDisc(DM dm, DM newdm)
5145e5e52638SMatthew G. Knepley {
5146e5e52638SMatthew G. Knepley   PetscErrorCode ierr;
5147e5e52638SMatthew G. Knepley 
5148e5e52638SMatthew G. Knepley   PetscFunctionBegin;
5149e5e52638SMatthew G. Knepley   if (dm == newdm) PetscFunctionReturn(0);
5150e5e52638SMatthew G. Knepley   ierr = DMCopyFields(dm, newdm);CHKERRQ(ierr);
5151e5e52638SMatthew G. Knepley   ierr = DMCopyDS(dm, newdm);CHKERRQ(ierr);
5152e5e52638SMatthew G. Knepley   PetscFunctionReturn(0);
5153e5e52638SMatthew G. Knepley }
5154e5e52638SMatthew G. Knepley 
5155b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx)
5156b64e0483SPeter Brune {
5157b64e0483SPeter Brune   DM dm_coord,dmc_coord;
5158b64e0483SPeter Brune   PetscErrorCode ierr;
5159b64e0483SPeter Brune   Vec coords,ccoords;
51606dbf9973SLawrence Mitchell   Mat inject;
5161b64e0483SPeter Brune   PetscFunctionBegin;
5162b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
5163b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr);
5164b64e0483SPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
5165b64e0483SPeter Brune   ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr);
5166b64e0483SPeter Brune   if (coords && !ccoords) {
5167b64e0483SPeter Brune     ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr);
51686668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
51696dbf9973SLawrence Mitchell     ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr);
51702adcf181SLawrence Mitchell     ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr);
51716dbf9973SLawrence Mitchell     ierr = MatDestroy(&inject);CHKERRQ(ierr);
5172b64e0483SPeter Brune     ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr);
5173b64e0483SPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
5174b64e0483SPeter Brune   }
5175b64e0483SPeter Brune   PetscFunctionReturn(0);
5176b64e0483SPeter Brune }
5177b64e0483SPeter Brune 
517803dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx)
517903dadc2fSPeter Brune {
518003dadc2fSPeter Brune   DM dm_coord,subdm_coord;
518103dadc2fSPeter Brune   PetscErrorCode ierr;
518203dadc2fSPeter Brune   Vec coords,ccoords,clcoords;
518303dadc2fSPeter Brune   VecScatter *scat_i,*scat_g;
518403dadc2fSPeter Brune   PetscFunctionBegin;
518503dadc2fSPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
518603dadc2fSPeter Brune   ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr);
518703dadc2fSPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
518803dadc2fSPeter Brune   ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr);
518903dadc2fSPeter Brune   if (coords && !ccoords) {
519003dadc2fSPeter Brune     ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr);
51916668ed41SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject)ccoords,"coordinates");CHKERRQ(ierr);
519203dadc2fSPeter Brune     ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr);
519324640c55SToby Isaac     ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr);
519403dadc2fSPeter Brune     ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr);
519503dadc2fSPeter Brune     ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
519603dadc2fSPeter Brune     ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
519703dadc2fSPeter Brune     ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
519803dadc2fSPeter Brune     ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
519903dadc2fSPeter Brune     ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr);
520003dadc2fSPeter Brune     ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr);
520103dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr);
520203dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr);
520303dadc2fSPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
520403dadc2fSPeter Brune     ierr = VecDestroy(&clcoords);CHKERRQ(ierr);
520503dadc2fSPeter Brune     ierr = PetscFree(scat_i);CHKERRQ(ierr);
520603dadc2fSPeter Brune     ierr = PetscFree(scat_g);CHKERRQ(ierr);
520703dadc2fSPeter Brune   }
520803dadc2fSPeter Brune   PetscFunctionReturn(0);
520903dadc2fSPeter Brune }
521003dadc2fSPeter Brune 
5211c73cfb54SMatthew G. Knepley /*@
5212c73cfb54SMatthew G. Knepley   DMGetDimension - Return the topological dimension of the DM
5213c73cfb54SMatthew G. Knepley 
5214c73cfb54SMatthew G. Knepley   Not collective
5215c73cfb54SMatthew G. Knepley 
5216c73cfb54SMatthew G. Knepley   Input Parameter:
5217c73cfb54SMatthew G. Knepley . dm - The DM
5218c73cfb54SMatthew G. Knepley 
5219c73cfb54SMatthew G. Knepley   Output Parameter:
5220c73cfb54SMatthew G. Knepley . dim - The topological dimension
5221c73cfb54SMatthew G. Knepley 
5222c73cfb54SMatthew G. Knepley   Level: beginner
5223c73cfb54SMatthew G. Knepley 
5224c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate()
5225c73cfb54SMatthew G. Knepley @*/
5226c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim)
5227c73cfb54SMatthew G. Knepley {
5228c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5229c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5230*534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
5231c73cfb54SMatthew G. Knepley   *dim = dm->dim;
5232c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5233c73cfb54SMatthew G. Knepley }
5234c73cfb54SMatthew G. Knepley 
5235c73cfb54SMatthew G. Knepley /*@
5236c73cfb54SMatthew G. Knepley   DMSetDimension - Set the topological dimension of the DM
5237c73cfb54SMatthew G. Knepley 
5238c73cfb54SMatthew G. Knepley   Collective on dm
5239c73cfb54SMatthew G. Knepley 
5240c73cfb54SMatthew G. Knepley   Input Parameters:
5241c73cfb54SMatthew G. Knepley + dm - The DM
5242c73cfb54SMatthew G. Knepley - dim - The topological dimension
5243c73cfb54SMatthew G. Knepley 
5244c73cfb54SMatthew G. Knepley   Level: beginner
5245c73cfb54SMatthew G. Knepley 
5246c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate()
5247c73cfb54SMatthew G. Knepley @*/
5248c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim)
5249c73cfb54SMatthew G. Knepley {
5250e5e52638SMatthew G. Knepley   PetscDS        ds;
5251f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5252f17e8794SMatthew G. Knepley 
5253c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
5254c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5255c73cfb54SMatthew G. Knepley   PetscValidLogicalCollectiveInt(dm, dim, 2);
5256c73cfb54SMatthew G. Knepley   dm->dim = dim;
5257e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5258e5e52638SMatthew G. Knepley   if (ds->dimEmbed < 0) {ierr = PetscDSSetCoordinateDimension(ds, dm->dim);CHKERRQ(ierr);}
5259c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
5260c73cfb54SMatthew G. Knepley }
5261c73cfb54SMatthew G. Knepley 
5262793f3fe5SMatthew G. Knepley /*@
5263793f3fe5SMatthew G. Knepley   DMGetDimPoints - Get the half-open interval for all points of a given dimension
5264793f3fe5SMatthew G. Knepley 
5265d083f849SBarry Smith   Collective on dm
5266793f3fe5SMatthew G. Knepley 
5267793f3fe5SMatthew G. Knepley   Input Parameters:
5268793f3fe5SMatthew G. Knepley + dm - the DM
5269793f3fe5SMatthew G. Knepley - dim - the dimension
5270793f3fe5SMatthew G. Knepley 
5271793f3fe5SMatthew G. Knepley   Output Parameters:
5272793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension
5273aa049354SPatrick Sanan - pEnd - The first point following points of the given dimension
5274793f3fe5SMatthew G. Knepley 
5275793f3fe5SMatthew G. Knepley   Note:
5276793f3fe5SMatthew G. Knepley   The points are vertices in the Hasse diagram encoding the topology. This is explained in
5277a8d69d7bSBarry Smith   https://arxiv.org/abs/0908.4427. If no points exist of this dimension in the storage scheme,
5278793f3fe5SMatthew G. Knepley   then the interval is empty.
5279793f3fe5SMatthew G. Knepley 
5280793f3fe5SMatthew G. Knepley   Level: intermediate
5281793f3fe5SMatthew G. Knepley 
5282793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum()
5283793f3fe5SMatthew G. Knepley @*/
5284793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
5285793f3fe5SMatthew G. Knepley {
5286793f3fe5SMatthew G. Knepley   PetscInt       d;
5287793f3fe5SMatthew G. Knepley   PetscErrorCode ierr;
5288793f3fe5SMatthew G. Knepley 
5289793f3fe5SMatthew G. Knepley   PetscFunctionBegin;
5290793f3fe5SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5291793f3fe5SMatthew G. Knepley   ierr = DMGetDimension(dm, &d);CHKERRQ(ierr);
5292793f3fe5SMatthew G. Knepley   if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d);
5293b9d85ea2SLisandro Dalcin   if (!dm->ops->getdimpoints) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DM type %s does not implement DMGetDimPoints",((PetscObject)dm)->type_name);
5294793f3fe5SMatthew G. Knepley   ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr);
5295793f3fe5SMatthew G. Knepley   PetscFunctionReturn(0);
5296793f3fe5SMatthew G. Knepley }
5297793f3fe5SMatthew G. Knepley 
52986636e97aSMatthew G Knepley /*@
52996636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
53006636e97aSMatthew G Knepley 
5301d083f849SBarry Smith   Collective on dm
53026636e97aSMatthew G Knepley 
53036636e97aSMatthew G Knepley   Input Parameters:
53046636e97aSMatthew G Knepley + dm - the DM
53056636e97aSMatthew G Knepley - c - coordinate vector
53066636e97aSMatthew G Knepley 
53072dd40e9bSPatrick Sanan   Notes:
53082dd40e9bSPatrick Sanan   The coordinates do include those for ghost points, which are in the local vector.
53092dd40e9bSPatrick Sanan 
53102dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
53116636e97aSMatthew G Knepley 
53126636e97aSMatthew G Knepley   Level: intermediate
53136636e97aSMatthew G Knepley 
53142dd40e9bSPatrick Sanan .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
53156636e97aSMatthew G Knepley @*/
53166636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
53176636e97aSMatthew G Knepley {
53186636e97aSMatthew G Knepley   PetscErrorCode ierr;
53196636e97aSMatthew G Knepley 
53206636e97aSMatthew G Knepley   PetscFunctionBegin;
53216636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
53226636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
53236636e97aSMatthew G Knepley   ierr            = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
53246636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
53256636e97aSMatthew G Knepley   dm->coordinates = c;
53266636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
5327b64e0483SPeter Brune   ierr            = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
532803dadc2fSPeter Brune   ierr            = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
53296636e97aSMatthew G Knepley   PetscFunctionReturn(0);
53306636e97aSMatthew G Knepley }
53316636e97aSMatthew G Knepley 
53326636e97aSMatthew G Knepley /*@
53336636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
53346636e97aSMatthew G Knepley 
53357058e716SVaclav Hapla   Not collective
53366636e97aSMatthew G Knepley 
53376636e97aSMatthew G Knepley    Input Parameters:
53386636e97aSMatthew G Knepley +  dm - the DM
53396636e97aSMatthew G Knepley -  c - coordinate vector
53406636e97aSMatthew G Knepley 
53412dd40e9bSPatrick Sanan   Notes:
53426636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
53436636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
53446636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
53456636e97aSMatthew G Knepley 
53462dd40e9bSPatrick Sanan   The vector c should be destroyed by the caller.
53472dd40e9bSPatrick Sanan 
53486636e97aSMatthew G Knepley   Level: intermediate
53496636e97aSMatthew G Knepley 
53506636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
53516636e97aSMatthew G Knepley @*/
53526636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
53536636e97aSMatthew G Knepley {
53546636e97aSMatthew G Knepley   PetscErrorCode ierr;
53556636e97aSMatthew G Knepley 
53566636e97aSMatthew G Knepley   PetscFunctionBegin;
53576636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
53586636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
53596636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
53606636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
53618865f1eaSKarl Rupp 
53626636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
53638865f1eaSKarl Rupp 
53646636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
53656636e97aSMatthew G Knepley   PetscFunctionReturn(0);
53666636e97aSMatthew G Knepley }
53676636e97aSMatthew G Knepley 
53686636e97aSMatthew G Knepley /*@
53696636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
53706636e97aSMatthew G Knepley 
5371d083f849SBarry Smith   Collective on dm
53726636e97aSMatthew G Knepley 
53736636e97aSMatthew G Knepley   Input Parameter:
53746636e97aSMatthew G Knepley . dm - the DM
53756636e97aSMatthew G Knepley 
53766636e97aSMatthew G Knepley   Output Parameter:
53776636e97aSMatthew G Knepley . c - global coordinate vector
53786636e97aSMatthew G Knepley 
53796636e97aSMatthew G Knepley   Note:
53806636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
53816636e97aSMatthew G Knepley 
53826636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
53836636e97aSMatthew G Knepley 
53846636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
53856636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
53866636e97aSMatthew G Knepley 
53876636e97aSMatthew G Knepley   Level: intermediate
53886636e97aSMatthew G Knepley 
53896636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
53906636e97aSMatthew G Knepley @*/
53916636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
53926636e97aSMatthew G Knepley {
53936636e97aSMatthew G Knepley   PetscErrorCode ierr;
53946636e97aSMatthew G Knepley 
53956636e97aSMatthew G Knepley   PetscFunctionBegin;
53966636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
53976636e97aSMatthew G Knepley   PetscValidPointer(c,2);
53981f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
53990298fd71SBarry Smith     DM        cdm = NULL;
54001970a576SMatthew G. Knepley     PetscBool localized;
54016636e97aSMatthew G Knepley 
54026636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
54036636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
54041970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
54051970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateGlobalVector() if coordinates are localized */
54061970a576SMatthew G. Knepley     if (localized) {
54071970a576SMatthew G. Knepley       PetscInt cdim;
54081970a576SMatthew G. Knepley 
54091970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
54101970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
54111970a576SMatthew G. Knepley     }
54126636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
54136636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
54146636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
54156636e97aSMatthew G Knepley   }
54166636e97aSMatthew G Knepley   *c = dm->coordinates;
54176636e97aSMatthew G Knepley   PetscFunctionReturn(0);
54186636e97aSMatthew G Knepley }
54196636e97aSMatthew G Knepley 
54206636e97aSMatthew G Knepley /*@
542181e9a530SVaclav Hapla   DMGetCoordinatesLocalSetUp - Prepares a local vector of coordinates, so that DMGetCoordinatesLocalNoncollective() can be used as non-collective afterwards.
542281e9a530SVaclav Hapla 
5423d083f849SBarry Smith   Collective on dm
542481e9a530SVaclav Hapla 
542581e9a530SVaclav Hapla   Input Parameter:
542681e9a530SVaclav Hapla . dm - the DM
542781e9a530SVaclav Hapla 
542881e9a530SVaclav Hapla   Level: advanced
542981e9a530SVaclav Hapla 
543081e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalNoncollective()
543181e9a530SVaclav Hapla @*/
543281e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalSetUp(DM dm)
543381e9a530SVaclav Hapla {
543481e9a530SVaclav Hapla   PetscErrorCode ierr;
543581e9a530SVaclav Hapla 
543681e9a530SVaclav Hapla   PetscFunctionBegin;
543781e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
543881e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) {
54391970a576SMatthew G. Knepley     DM        cdm = NULL;
54401970a576SMatthew G. Knepley     PetscBool localized;
54411970a576SMatthew G. Knepley 
544281e9a530SVaclav Hapla     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
544381e9a530SVaclav Hapla     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
54441970a576SMatthew G. Knepley     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
54451970a576SMatthew G. Knepley     /* Block size is not correctly set by CreateLocalVector() if coordinates are localized */
54461970a576SMatthew G. Knepley     if (localized) {
54471970a576SMatthew G. Knepley       PetscInt cdim;
54481970a576SMatthew G. Knepley 
54491970a576SMatthew G. Knepley       ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr);
54501970a576SMatthew G. Knepley       ierr = VecSetBlockSize(dm->coordinates, cdim);CHKERRQ(ierr);
54511970a576SMatthew G. Knepley     }
545281e9a530SVaclav Hapla     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
545381e9a530SVaclav Hapla     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
545481e9a530SVaclav Hapla     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
545581e9a530SVaclav Hapla   }
545681e9a530SVaclav Hapla   PetscFunctionReturn(0);
545781e9a530SVaclav Hapla }
545881e9a530SVaclav Hapla 
545981e9a530SVaclav Hapla /*@
54606636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
54616636e97aSMatthew G Knepley 
5462d083f849SBarry Smith   Collective on dm
54636636e97aSMatthew G Knepley 
54646636e97aSMatthew G Knepley   Input Parameter:
54656636e97aSMatthew G Knepley . dm - the DM
54666636e97aSMatthew G Knepley 
54676636e97aSMatthew G Knepley   Output Parameter:
54686636e97aSMatthew G Knepley . c - coordinate vector
54696636e97aSMatthew G Knepley 
54706636e97aSMatthew G Knepley   Note:
54716636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
54726636e97aSMatthew G Knepley 
54736636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
54746636e97aSMatthew G Knepley 
54756636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
54766636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
54776636e97aSMatthew G Knepley 
54786636e97aSMatthew G Knepley   Level: intermediate
54796636e97aSMatthew G Knepley 
548081e9a530SVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM(), DMGetCoordinatesLocalNoncollective()
54816636e97aSMatthew G Knepley @*/
54826636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
54836636e97aSMatthew G Knepley {
54846636e97aSMatthew G Knepley   PetscErrorCode ierr;
54856636e97aSMatthew G Knepley 
54866636e97aSMatthew G Knepley   PetscFunctionBegin;
54876636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
54886636e97aSMatthew G Knepley   PetscValidPointer(c,2);
548981e9a530SVaclav Hapla   ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr);
54906636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
54916636e97aSMatthew G Knepley   PetscFunctionReturn(0);
54926636e97aSMatthew G Knepley }
54936636e97aSMatthew G Knepley 
549481e9a530SVaclav Hapla /*@
549581e9a530SVaclav Hapla   DMGetCoordinatesLocalNoncollective - Non-collective version of DMGetCoordinatesLocal(). Fails if global coordinates have been set and DMGetCoordinatesLocalSetUp() not called.
549681e9a530SVaclav Hapla 
549781e9a530SVaclav Hapla   Not collective
549881e9a530SVaclav Hapla 
549981e9a530SVaclav Hapla   Input Parameter:
550081e9a530SVaclav Hapla . dm - the DM
550181e9a530SVaclav Hapla 
550281e9a530SVaclav Hapla   Output Parameter:
550381e9a530SVaclav Hapla . c - coordinate vector
550481e9a530SVaclav Hapla 
550581e9a530SVaclav Hapla   Level: advanced
550681e9a530SVaclav Hapla 
550781e9a530SVaclav Hapla .seealso: DMGetCoordinatesLocalSetUp(), DMGetCoordinatesLocal(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
550881e9a530SVaclav Hapla @*/
550981e9a530SVaclav Hapla PetscErrorCode DMGetCoordinatesLocalNoncollective(DM dm, Vec *c)
551081e9a530SVaclav Hapla {
551181e9a530SVaclav Hapla   PetscFunctionBegin;
551281e9a530SVaclav Hapla   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
551381e9a530SVaclav Hapla   PetscValidPointer(c,2);
551481e9a530SVaclav Hapla   if (!dm->coordinatesLocal && dm->coordinates) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called");
55156636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
55166636e97aSMatthew G Knepley   PetscFunctionReturn(0);
55176636e97aSMatthew G Knepley }
55186636e97aSMatthew G Knepley 
55192db98f8dSVaclav Hapla /*@
55202db98f8dSVaclav Hapla   DMGetCoordinatesLocalTuple - Gets a local vector with the coordinates of specified points and section describing its layout.
55212db98f8dSVaclav Hapla 
55222db98f8dSVaclav Hapla   Not collective
55232db98f8dSVaclav Hapla 
55242db98f8dSVaclav Hapla   Input Parameter:
55252db98f8dSVaclav Hapla + dm - the DM
55262db98f8dSVaclav Hapla - p - the IS of points whose coordinates will be returned
55272db98f8dSVaclav Hapla 
55282db98f8dSVaclav Hapla   Output Parameter:
55292db98f8dSVaclav Hapla + pCoordSection - the PetscSection describing the layout of pCoord, i.e. each point corresponds to one point in p, and DOFs correspond to coordinates
55302db98f8dSVaclav Hapla - pCoord - the Vec with coordinates of points in p
55312db98f8dSVaclav Hapla 
55322db98f8dSVaclav Hapla   Note:
55332db98f8dSVaclav Hapla   DMGetCoordinatesLocalSetUp() must be called first. This function employs DMGetCoordinatesLocalNoncollective() so it is not collective.
55342db98f8dSVaclav Hapla 
55352db98f8dSVaclav Hapla   This creates a new vector, so the user SHOULD destroy this vector
55362db98f8dSVaclav Hapla 
55372db98f8dSVaclav Hapla   Each process has the local and ghost coordinates
55382db98f8dSVaclav Hapla 
55392db98f8dSVaclav Hapla   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
55402db98f8dSVaclav Hapla   and (x_0,y_0,z_0,x_1,y_1,z_1...)
55412db98f8dSVaclav Hapla 
55422db98f8dSVaclav Hapla   Level: advanced
55432db98f8dSVaclav Hapla 
55442db98f8dSVaclav Hapla .seealso: DMSetCoordinatesLocal(), DMGetCoordinatesLocal(), DMGetCoordinatesLocalNoncollective(), DMGetCoordinatesLocalSetUp(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
55452db98f8dSVaclav Hapla @*/
55462db98f8dSVaclav Hapla PetscErrorCode DMGetCoordinatesLocalTuple(DM dm, IS p, PetscSection *pCoordSection, Vec *pCoord)
55472db98f8dSVaclav Hapla {
55482db98f8dSVaclav Hapla   PetscSection        cs, newcs;
55492db98f8dSVaclav Hapla   Vec                 coords;
55502db98f8dSVaclav Hapla   const PetscScalar   *arr;
55512db98f8dSVaclav Hapla   PetscScalar         *newarr=NULL;
55522db98f8dSVaclav Hapla   PetscInt            n;
55532db98f8dSVaclav Hapla   PetscErrorCode      ierr;
55542db98f8dSVaclav Hapla 
55552db98f8dSVaclav Hapla   PetscFunctionBegin;
55562db98f8dSVaclav Hapla   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
55572db98f8dSVaclav Hapla   PetscValidHeaderSpecific(p, IS_CLASSID, 2);
55582db98f8dSVaclav Hapla   if (pCoordSection) PetscValidPointer(pCoordSection, 3);
55592db98f8dSVaclav Hapla   if (pCoord) PetscValidPointer(pCoord, 4);
55602db98f8dSVaclav Hapla   if (!dm->coordinatesLocal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMGetCoordinatesLocalSetUp() has not been called or coordinates not set");
55612db98f8dSVaclav Hapla   if (!dm->coordinateDM || !dm->coordinateDM->defaultSection) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM not supported");
55622db98f8dSVaclav Hapla   cs = dm->coordinateDM->defaultSection;
55632db98f8dSVaclav Hapla   coords = dm->coordinatesLocal;
55642db98f8dSVaclav Hapla   ierr = VecGetArrayRead(coords, &arr);CHKERRQ(ierr);
55652db98f8dSVaclav Hapla   ierr = PetscSectionExtractDofsFromArray(cs, MPIU_SCALAR, arr, p, &newcs, pCoord ? ((void**)&newarr) : NULL);CHKERRQ(ierr);
55662db98f8dSVaclav Hapla   ierr = VecRestoreArrayRead(coords, &arr);CHKERRQ(ierr);
55672db98f8dSVaclav Hapla   if (pCoord) {
55682db98f8dSVaclav Hapla     ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr);
55692db98f8dSVaclav Hapla     /* set array in two steps to mimic PETSC_OWN_POINTER */
55702db98f8dSVaclav Hapla     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)p), 1, n, NULL, pCoord);CHKERRQ(ierr);
55712db98f8dSVaclav Hapla     ierr = VecReplaceArray(*pCoord, newarr);CHKERRQ(ierr);
5572ad9ac99dSVaclav Hapla   } else {
5573ad9ac99dSVaclav Hapla     ierr = PetscFree(newarr);CHKERRQ(ierr);
55742db98f8dSVaclav Hapla   }
5575ad9ac99dSVaclav Hapla   if (pCoordSection) {*pCoordSection = newcs;}
5576ad9ac99dSVaclav Hapla   else               {ierr = PetscSectionDestroy(&newcs);CHKERRQ(ierr);}
55772db98f8dSVaclav Hapla   PetscFunctionReturn(0);
55782db98f8dSVaclav Hapla }
55792db98f8dSVaclav Hapla 
5580f19dbd58SToby Isaac PetscErrorCode DMGetCoordinateField(DM dm, DMField *field)
5581f19dbd58SToby Isaac {
5582f19dbd58SToby Isaac   PetscErrorCode ierr;
5583f19dbd58SToby Isaac 
5584f19dbd58SToby Isaac   PetscFunctionBegin;
5585f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5586f19dbd58SToby Isaac   PetscValidPointer(field,2);
5587f19dbd58SToby Isaac   if (!dm->coordinateField) {
5588f19dbd58SToby Isaac     if (dm->ops->createcoordinatefield) {
5589f19dbd58SToby Isaac       ierr = (*dm->ops->createcoordinatefield)(dm,&dm->coordinateField);CHKERRQ(ierr);
5590f19dbd58SToby Isaac     }
5591f19dbd58SToby Isaac   }
5592f19dbd58SToby Isaac   *field = dm->coordinateField;
5593f19dbd58SToby Isaac   PetscFunctionReturn(0);
5594f19dbd58SToby Isaac }
5595f19dbd58SToby Isaac 
5596f19dbd58SToby Isaac PetscErrorCode DMSetCoordinateField(DM dm, DMField field)
5597f19dbd58SToby Isaac {
5598f19dbd58SToby Isaac   PetscErrorCode ierr;
5599f19dbd58SToby Isaac 
5600f19dbd58SToby Isaac   PetscFunctionBegin;
5601f19dbd58SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5602f19dbd58SToby Isaac   if (field) PetscValidHeaderSpecific(field,DMFIELD_CLASSID,2);
5603c4e6da2cSBarry Smith   ierr = PetscObjectReference((PetscObject)field);CHKERRQ(ierr);
5604f19dbd58SToby Isaac   ierr = DMFieldDestroy(&dm->coordinateField);CHKERRQ(ierr);
5605f19dbd58SToby Isaac   dm->coordinateField = field;
5606f19dbd58SToby Isaac   PetscFunctionReturn(0);
5607f19dbd58SToby Isaac }
5608f19dbd58SToby Isaac 
56096636e97aSMatthew G Knepley /*@
56101cfe2091SMatthew G. Knepley   DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates
56116636e97aSMatthew G Knepley 
5612d083f849SBarry Smith   Collective on dm
56136636e97aSMatthew G Knepley 
56146636e97aSMatthew G Knepley   Input Parameter:
56156636e97aSMatthew G Knepley . dm - the DM
56166636e97aSMatthew G Knepley 
56176636e97aSMatthew G Knepley   Output Parameter:
56186636e97aSMatthew G Knepley . cdm - coordinate DM
56196636e97aSMatthew G Knepley 
56206636e97aSMatthew G Knepley   Level: intermediate
56216636e97aSMatthew G Knepley 
56221cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
56236636e97aSMatthew G Knepley @*/
56246636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
56256636e97aSMatthew G Knepley {
56266636e97aSMatthew G Knepley   PetscErrorCode ierr;
56276636e97aSMatthew G Knepley 
56286636e97aSMatthew G Knepley   PetscFunctionBegin;
56296636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
56306636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
56316636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
5632308f8a94SToby Isaac     DM cdm;
5633308f8a94SToby Isaac 
563482f516ccSBarry Smith     if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM");
5635308f8a94SToby Isaac     ierr = (*dm->ops->createcoordinatedm)(dm, &cdm);CHKERRQ(ierr);
5636308f8a94SToby Isaac     /* Just in case the DM sets the coordinate DM when creating it (DMP4est can do this, because it may not setup
5637308f8a94SToby Isaac      * until the call to CreateCoordinateDM) */
5638308f8a94SToby Isaac     ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
5639308f8a94SToby Isaac     dm->coordinateDM = cdm;
56406636e97aSMatthew G Knepley   }
56416636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
56426636e97aSMatthew G Knepley   PetscFunctionReturn(0);
56436636e97aSMatthew G Knepley }
5644e87bb0d3SMatthew G Knepley 
56451cfe2091SMatthew G. Knepley /*@
56461cfe2091SMatthew G. Knepley   DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates
56471cfe2091SMatthew G. Knepley 
5648d083f849SBarry Smith   Logically Collective on dm
56491cfe2091SMatthew G. Knepley 
56501cfe2091SMatthew G. Knepley   Input Parameters:
56511cfe2091SMatthew G. Knepley + dm - the DM
56521cfe2091SMatthew G. Knepley - cdm - coordinate DM
56531cfe2091SMatthew G. Knepley 
56541cfe2091SMatthew G. Knepley   Level: intermediate
56551cfe2091SMatthew G. Knepley 
56561cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
56571cfe2091SMatthew G. Knepley @*/
56581cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm)
56591cfe2091SMatthew G. Knepley {
56601cfe2091SMatthew G. Knepley   PetscErrorCode ierr;
56611cfe2091SMatthew G. Knepley 
56621cfe2091SMatthew G. Knepley   PetscFunctionBegin;
56631cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
56641cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(cdm,DM_CLASSID,2);
5665f26b38b9SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
56661cfe2091SMatthew G. Knepley   ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
56671cfe2091SMatthew G. Knepley   dm->coordinateDM = cdm;
56681cfe2091SMatthew G. Knepley   PetscFunctionReturn(0);
56691cfe2091SMatthew G. Knepley }
56701cfe2091SMatthew G. Knepley 
567146e270d4SMatthew G. Knepley /*@
567246e270d4SMatthew G. Knepley   DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values.
567346e270d4SMatthew G. Knepley 
567446e270d4SMatthew G. Knepley   Not Collective
567546e270d4SMatthew G. Knepley 
567646e270d4SMatthew G. Knepley   Input Parameter:
567746e270d4SMatthew G. Knepley . dm - The DM object
567846e270d4SMatthew G. Knepley 
567946e270d4SMatthew G. Knepley   Output Parameter:
568046e270d4SMatthew G. Knepley . dim - The embedding dimension
568146e270d4SMatthew G. Knepley 
568246e270d4SMatthew G. Knepley   Level: intermediate
568346e270d4SMatthew G. Knepley 
5684e87a4003SBarry Smith .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetSection(), DMSetSection()
568546e270d4SMatthew G. Knepley @*/
568646e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim)
568746e270d4SMatthew G. Knepley {
568846e270d4SMatthew G. Knepley   PetscFunctionBegin;
568946e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5690*534a8f05SLisandro Dalcin   PetscValidIntPointer(dim, 2);
56919a9a41abSToby Isaac   if (dm->dimEmbed == PETSC_DEFAULT) {
56929a9a41abSToby Isaac     dm->dimEmbed = dm->dim;
56939a9a41abSToby Isaac   }
569446e270d4SMatthew G. Knepley   *dim = dm->dimEmbed;
569546e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
569646e270d4SMatthew G. Knepley }
569746e270d4SMatthew G. Knepley 
569846e270d4SMatthew G. Knepley /*@
569946e270d4SMatthew G. Knepley   DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values.
570046e270d4SMatthew G. Knepley 
570146e270d4SMatthew G. Knepley   Not Collective
570246e270d4SMatthew G. Knepley 
570346e270d4SMatthew G. Knepley   Input Parameters:
570446e270d4SMatthew G. Knepley + dm  - The DM object
570546e270d4SMatthew G. Knepley - dim - The embedding dimension
570646e270d4SMatthew G. Knepley 
570746e270d4SMatthew G. Knepley   Level: intermediate
570846e270d4SMatthew G. Knepley 
5709e87a4003SBarry Smith .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetSection(), DMSetSection()
571046e270d4SMatthew G. Knepley @*/
571146e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim)
571246e270d4SMatthew G. Knepley {
5713e5e52638SMatthew G. Knepley   PetscDS        ds;
5714f17e8794SMatthew G. Knepley   PetscErrorCode ierr;
5715f17e8794SMatthew G. Knepley 
571646e270d4SMatthew G. Knepley   PetscFunctionBegin;
571746e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
571846e270d4SMatthew G. Knepley   dm->dimEmbed = dim;
5719e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
5720e5e52638SMatthew G. Knepley   ierr = PetscDSSetCoordinateDimension(ds, dim);CHKERRQ(ierr);
572146e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
572246e270d4SMatthew G. Knepley }
572346e270d4SMatthew G. Knepley 
5724e8abe2deSMatthew G. Knepley /*@
5725e8abe2deSMatthew G. Knepley   DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh.
5726e8abe2deSMatthew G. Knepley 
5727d083f849SBarry Smith   Collective on dm
5728e8abe2deSMatthew G. Knepley 
5729e8abe2deSMatthew G. Knepley   Input Parameter:
5730e8abe2deSMatthew G. Knepley . dm - The DM object
5731e8abe2deSMatthew G. Knepley 
5732e8abe2deSMatthew G. Knepley   Output Parameter:
5733e8abe2deSMatthew G. Knepley . section - The PetscSection object
5734e8abe2deSMatthew G. Knepley 
5735e8abe2deSMatthew G. Knepley   Level: intermediate
5736e8abe2deSMatthew G. Knepley 
5737e87a4003SBarry Smith .seealso: DMGetCoordinateDM(), DMGetSection(), DMSetSection()
5738e8abe2deSMatthew G. Knepley @*/
5739e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section)
5740e8abe2deSMatthew G. Knepley {
5741e8abe2deSMatthew G. Knepley   DM             cdm;
5742e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5743e8abe2deSMatthew G. Knepley 
5744e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5745e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5746e8abe2deSMatthew G. Knepley   PetscValidPointer(section, 2);
5747e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
5748e87a4003SBarry Smith   ierr = DMGetSection(cdm, section);CHKERRQ(ierr);
5749e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5750e8abe2deSMatthew G. Knepley }
5751e8abe2deSMatthew G. Knepley 
5752e8abe2deSMatthew G. Knepley /*@
5753e8abe2deSMatthew G. Knepley   DMSetCoordinateSection - Set the layout of coordinate values over the mesh.
5754e8abe2deSMatthew G. Knepley 
5755e8abe2deSMatthew G. Knepley   Not Collective
5756e8abe2deSMatthew G. Knepley 
5757e8abe2deSMatthew G. Knepley   Input Parameters:
5758e8abe2deSMatthew G. Knepley + dm      - The DM object
575946e270d4SMatthew G. Knepley . dim     - The embedding dimension, or PETSC_DETERMINE
5760e8abe2deSMatthew G. Knepley - section - The PetscSection object
5761e8abe2deSMatthew G. Knepley 
5762e8abe2deSMatthew G. Knepley   Level: intermediate
5763e8abe2deSMatthew G. Knepley 
5764e87a4003SBarry Smith .seealso: DMGetCoordinateSection(), DMGetSection(), DMSetSection()
5765e8abe2deSMatthew G. Knepley @*/
576646e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section)
5767e8abe2deSMatthew G. Knepley {
5768e8abe2deSMatthew G. Knepley   DM             cdm;
5769e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
5770e8abe2deSMatthew G. Knepley 
5771e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
5772e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
577346e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3);
5774e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
5775e87a4003SBarry Smith   ierr = DMSetSection(cdm, section);CHKERRQ(ierr);
577646e270d4SMatthew G. Knepley   if (dim == PETSC_DETERMINE) {
57774c1069a6SMatthew G. Knepley     PetscInt d = PETSC_DEFAULT;
577846e270d4SMatthew G. Knepley     PetscInt pStart, pEnd, vStart, vEnd, v, dd;
577946e270d4SMatthew G. Knepley 
578046e270d4SMatthew G. Knepley     ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
578146e270d4SMatthew G. Knepley     ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
578246e270d4SMatthew G. Knepley     pStart = PetscMax(vStart, pStart);
578346e270d4SMatthew G. Knepley     pEnd   = PetscMin(vEnd, pEnd);
578446e270d4SMatthew G. Knepley     for (v = pStart; v < pEnd; ++v) {
578546e270d4SMatthew G. Knepley       ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr);
578646e270d4SMatthew G. Knepley       if (dd) {d = dd; break;}
578746e270d4SMatthew G. Knepley     }
5788ebfe4b0dSMatthew G. Knepley     if (d >= 0) {ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);}
578946e270d4SMatthew G. Knepley   }
5790e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
5791e8abe2deSMatthew G. Knepley }
5792e8abe2deSMatthew G. Knepley 
57935dc8c3f7SMatthew G. Knepley /*@C
579490b157c4SStefano Zampini   DMGetPeriodicity - Get the description of mesh periodicity
57955dc8c3f7SMatthew G. Knepley 
57965dc8c3f7SMatthew G. Knepley   Input Parameters:
579790b157c4SStefano Zampini . dm      - The DM object
579890b157c4SStefano Zampini 
579990b157c4SStefano Zampini   Output Parameters:
580090b157c4SStefano Zampini + per     - Whether the DM is periodic or not
58015dc8c3f7SMatthew 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
58025dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
58035dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
58045dc8c3f7SMatthew G. Knepley 
58055dc8c3f7SMatthew G. Knepley   Level: developer
58065dc8c3f7SMatthew G. Knepley 
58075dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
58085dc8c3f7SMatthew G. Knepley @*/
580990b157c4SStefano Zampini PetscErrorCode DMGetPeriodicity(DM dm, PetscBool *per, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd)
5810c6b900c6SMatthew G. Knepley {
5811c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
5812c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
581390b157c4SStefano Zampini   if (per)     *per     = dm->periodic;
5814c6b900c6SMatthew G. Knepley   if (L)       *L       = dm->L;
5815c6b900c6SMatthew G. Knepley   if (maxCell) *maxCell = dm->maxCell;
58165dc8c3f7SMatthew G. Knepley   if (bd)      *bd      = dm->bdtype;
5817c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
5818c6b900c6SMatthew G. Knepley }
5819c6b900c6SMatthew G. Knepley 
58205dc8c3f7SMatthew G. Knepley /*@C
58215dc8c3f7SMatthew G. Knepley   DMSetPeriodicity - Set the description of mesh periodicity
58225dc8c3f7SMatthew G. Knepley 
58235dc8c3f7SMatthew G. Knepley   Input Parameters:
58245dc8c3f7SMatthew G. Knepley + dm      - The DM object
582590b157c4SStefano Zampini . per     - Whether the DM is periodic or not. If maxCell is not provided, coordinates need to be localized
58265dc8c3f7SMatthew 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
58275dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
58285dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
58295dc8c3f7SMatthew G. Knepley 
58305dc8c3f7SMatthew G. Knepley   Level: developer
58315dc8c3f7SMatthew G. Knepley 
58325dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
58335dc8c3f7SMatthew G. Knepley @*/
583490b157c4SStefano Zampini PetscErrorCode DMSetPeriodicity(DM dm, PetscBool per, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[])
5835c6b900c6SMatthew G. Knepley {
5836c6b900c6SMatthew G. Knepley   PetscInt       dim, d;
5837c6b900c6SMatthew G. Knepley   PetscErrorCode ierr;
5838c6b900c6SMatthew G. Knepley 
5839c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
5840c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
584190b157c4SStefano Zampini   PetscValidLogicalCollectiveBool(dm,per,2);
584290b157c4SStefano Zampini   if (maxCell) {
5843*534a8f05SLisandro Dalcin     PetscValidRealPointer(maxCell,3);
5844*534a8f05SLisandro Dalcin     PetscValidRealPointer(L,4);
584590b157c4SStefano Zampini     PetscValidPointer(bd,5);
584690b157c4SStefano Zampini   }
58475dc8c3f7SMatthew G. Knepley   ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr);
58485dc8c3f7SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
584990b157c4SStefano Zampini   if (maxCell) {
58505dc8c3f7SMatthew G. Knepley     ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr);
58515dc8c3f7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];}
585290b157c4SStefano Zampini   }
5853072d7d67SStefano Zampini   dm->periodic = per;
5854c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
5855c6b900c6SMatthew G. Knepley }
5856c6b900c6SMatthew G. Knepley 
58572e17dfb7SMatthew G. Knepley /*@
58582e17dfb7SMatthew 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.
58592e17dfb7SMatthew G. Knepley 
58602e17dfb7SMatthew G. Knepley   Input Parameters:
58612e17dfb7SMatthew G. Knepley + dm     - The DM
586265da65dcSMatthew G. Knepley . in     - The input coordinate point (dim numbers)
586365da65dcSMatthew G. Knepley - endpoint - Include the endpoint L_i
58642e17dfb7SMatthew G. Knepley 
58652e17dfb7SMatthew G. Knepley   Output Parameter:
58662e17dfb7SMatthew G. Knepley . out - The localized coordinate point
58672e17dfb7SMatthew G. Knepley 
58682e17dfb7SMatthew G. Knepley   Level: developer
58692e17dfb7SMatthew G. Knepley 
58702e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
58712e17dfb7SMatthew G. Knepley @*/
587265da65dcSMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate(DM dm, const PetscScalar in[], PetscBool endpoint, PetscScalar out[])
58732e17dfb7SMatthew G. Knepley {
58742e17dfb7SMatthew G. Knepley   PetscInt       dim, d;
58752e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
58762e17dfb7SMatthew G. Knepley 
58772e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
58782e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr);
58792e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
58802e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
58812e17dfb7SMatthew G. Knepley   } else {
588265da65dcSMatthew G. Knepley     if (endpoint) {
588365da65dcSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
5884da3333bfSMatthew 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)) {
5885da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*(PetscFloorReal(PetscRealPart(in[d])/dm->L[d]) - 1);
588665da65dcSMatthew G. Knepley         } else {
5887da3333bfSMatthew G. Knepley           out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
588865da65dcSMatthew G. Knepley         }
588965da65dcSMatthew G. Knepley       }
589065da65dcSMatthew G. Knepley     } else {
58912e17dfb7SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
58921118d4bcSLisandro Dalcin         out[d] = in[d] - dm->L[d]*PetscFloorReal(PetscRealPart(in[d])/dm->L[d]);
58932e17dfb7SMatthew G. Knepley       }
58942e17dfb7SMatthew G. Knepley     }
589565da65dcSMatthew G. Knepley   }
58962e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
58972e17dfb7SMatthew G. Knepley }
58982e17dfb7SMatthew G. Knepley 
58992e17dfb7SMatthew G. Knepley /*
59002e17dfb7SMatthew 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.
59012e17dfb7SMatthew G. Knepley 
59022e17dfb7SMatthew G. Knepley   Input Parameters:
59032e17dfb7SMatthew G. Knepley + dm     - The DM
59042e17dfb7SMatthew G. Knepley . dim    - The spatial dimension
59052e17dfb7SMatthew G. Knepley . anchor - The anchor point, the input point can be no more than maxCell away from it
59062e17dfb7SMatthew G. Knepley - in     - The input coordinate point (dim numbers)
59072e17dfb7SMatthew G. Knepley 
59082e17dfb7SMatthew G. Knepley   Output Parameter:
59092e17dfb7SMatthew G. Knepley . out - The localized coordinate point
59102e17dfb7SMatthew G. Knepley 
59112e17dfb7SMatthew G. Knepley   Level: developer
59122e17dfb7SMatthew G. Knepley 
59132e17dfb7SMatthew 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
59142e17dfb7SMatthew G. Knepley 
59152e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeAddCoordinate()
59162e17dfb7SMatthew G. Knepley */
59172e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
59182e17dfb7SMatthew G. Knepley {
59192e17dfb7SMatthew G. Knepley   PetscInt d;
59202e17dfb7SMatthew G. Knepley 
59212e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
59222e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
59232e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
59242e17dfb7SMatthew G. Knepley   } else {
59252e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5926908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
59272e17dfb7SMatthew G. Knepley         out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
59282e17dfb7SMatthew G. Knepley       } else {
59292e17dfb7SMatthew G. Knepley         out[d] = in[d];
59302e17dfb7SMatthew G. Knepley       }
59312e17dfb7SMatthew G. Knepley     }
59322e17dfb7SMatthew G. Knepley   }
59332e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
59342e17dfb7SMatthew G. Knepley }
59352e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinateReal_Internal(DM dm, PetscInt dim, const PetscReal anchor[], const PetscReal in[], PetscReal out[])
59362e17dfb7SMatthew G. Knepley {
59372e17dfb7SMatthew G. Knepley   PetscInt d;
59382e17dfb7SMatthew G. Knepley 
59392e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
59402e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
59412e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] = in[d];
59422e17dfb7SMatthew G. Knepley   } else {
59432e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5944908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsReal(anchor[d] - in[d]) > dm->maxCell[d])) {
59452e17dfb7SMatthew G. Knepley         out[d] = anchor[d] > in[d] ? dm->L[d] + in[d] : in[d] - dm->L[d];
59462e17dfb7SMatthew G. Knepley       } else {
59472e17dfb7SMatthew G. Knepley         out[d] = in[d];
59482e17dfb7SMatthew G. Knepley       }
59492e17dfb7SMatthew G. Knepley     }
59502e17dfb7SMatthew G. Knepley   }
59512e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
59522e17dfb7SMatthew G. Knepley }
59532e17dfb7SMatthew G. Knepley 
59542e17dfb7SMatthew G. Knepley /*
59552e17dfb7SMatthew 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.
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 delta (dim numbers)
59622e17dfb7SMatthew G. Knepley - out    - The input coordinate point (dim numbers)
59632e17dfb7SMatthew G. Knepley 
59642e17dfb7SMatthew G. Knepley   Output Parameter:
59652e17dfb7SMatthew G. Knepley . out    - The localized coordinate in + out
59662e17dfb7SMatthew G. Knepley 
59672e17dfb7SMatthew G. Knepley   Level: developer
59682e17dfb7SMatthew G. Knepley 
59692e17dfb7SMatthew 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
59702e17dfb7SMatthew G. Knepley 
59712e17dfb7SMatthew G. Knepley .seealso: DMLocalizeCoordinates(), DMLocalizeCoordinate()
59722e17dfb7SMatthew G. Knepley */
59732e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[])
59742e17dfb7SMatthew G. Knepley {
59752e17dfb7SMatthew G. Knepley   PetscInt d;
59762e17dfb7SMatthew G. Knepley 
59772e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
59782e17dfb7SMatthew G. Knepley   if (!dm->maxCell) {
59792e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) out[d] += in[d];
59802e17dfb7SMatthew G. Knepley   } else {
59812e17dfb7SMatthew G. Knepley     for (d = 0; d < dim; ++d) {
5982908eca10SMatthew G. Knepley       if ((dm->bdtype[d] != DM_BOUNDARY_NONE) && (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d])) {
59832e17dfb7SMatthew G. Knepley         out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d];
59842e17dfb7SMatthew G. Knepley       } else {
59852e17dfb7SMatthew G. Knepley         out[d] += in[d];
59862e17dfb7SMatthew G. Knepley       }
59872e17dfb7SMatthew G. Knepley     }
59882e17dfb7SMatthew G. Knepley   }
59892e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
59902e17dfb7SMatthew G. Knepley }
59912e17dfb7SMatthew G. Knepley 
599236447a5eSToby Isaac /*@
59938f700142SStefano Zampini   DMGetCoordinatesLocalizedLocal - Check if the DM coordinates have been localized for cells on this process
59948f700142SStefano Zampini 
59958f700142SStefano Zampini   Not collective
599636447a5eSToby Isaac 
599736447a5eSToby Isaac   Input Parameter:
599836447a5eSToby Isaac . dm - The DM
599936447a5eSToby Isaac 
600036447a5eSToby Isaac   Output Parameter:
600136447a5eSToby Isaac   areLocalized - True if localized
600236447a5eSToby Isaac 
600336447a5eSToby Isaac   Level: developer
600436447a5eSToby Isaac 
60058f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMGetCoordinatesLocalized(), DMSetPeriodicity()
600636447a5eSToby Isaac @*/
60078f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalizedLocal(DM dm,PetscBool *areLocalized)
600836447a5eSToby Isaac {
600936447a5eSToby Isaac   DM             cdm;
601036447a5eSToby Isaac   PetscSection   coordSection;
601146a3a80fSLisandro Dalcin   PetscInt       cStart, cEnd, sStart, sEnd, c, dof;
601246a3a80fSLisandro Dalcin   PetscBool      isPlex, alreadyLocalized;
601336447a5eSToby Isaac   PetscErrorCode ierr;
601436447a5eSToby Isaac 
601536447a5eSToby Isaac   PetscFunctionBegin;
601636447a5eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6017*534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
60188b09590cSToby Isaac   *areLocalized = PETSC_FALSE;
601946a3a80fSLisandro Dalcin 
602036447a5eSToby Isaac   /* We need some generic way of refering to cells/vertices */
602136447a5eSToby Isaac   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
602246a3a80fSLisandro Dalcin   ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isPlex);CHKERRQ(ierr);
60239f7230bfSMatthew G. Knepley   if (!isPlex) PetscFunctionReturn(0);
602446a3a80fSLisandro Dalcin 
60259f7230bfSMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
602646a3a80fSLisandro Dalcin   ierr = DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd);CHKERRQ(ierr);
602736447a5eSToby Isaac   ierr = PetscSectionGetChart(coordSection, &sStart, &sEnd);CHKERRQ(ierr);
602836447a5eSToby Isaac   alreadyLocalized = PETSC_FALSE;
602946a3a80fSLisandro Dalcin   for (c = cStart; c < cEnd; ++c) {
603046a3a80fSLisandro Dalcin     if (c < sStart || c >= sEnd) continue;
603136447a5eSToby Isaac     ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr);
603246a3a80fSLisandro Dalcin     if (dof) { alreadyLocalized = PETSC_TRUE; break; }
603336447a5eSToby Isaac   }
60348f700142SStefano Zampini   *areLocalized = alreadyLocalized;
603536447a5eSToby Isaac   PetscFunctionReturn(0);
603636447a5eSToby Isaac }
603736447a5eSToby Isaac 
60388f700142SStefano Zampini /*@
60398f700142SStefano Zampini   DMGetCoordinatesLocalized - Check if the DM coordinates have been localized for cells
60408f700142SStefano Zampini 
60418f700142SStefano Zampini   Collective on dm
60428f700142SStefano Zampini 
60438f700142SStefano Zampini   Input Parameter:
60448f700142SStefano Zampini . dm - The DM
60458f700142SStefano Zampini 
60468f700142SStefano Zampini   Output Parameter:
60478f700142SStefano Zampini   areLocalized - True if localized
60488f700142SStefano Zampini 
60498f700142SStefano Zampini   Level: developer
60508f700142SStefano Zampini 
60518f700142SStefano Zampini .seealso: DMLocalizeCoordinates(), DMSetPeriodicity(), DMGetCoordinatesLocalizedLocal()
60528f700142SStefano Zampini @*/
60538f700142SStefano Zampini PetscErrorCode DMGetCoordinatesLocalized(DM dm,PetscBool *areLocalized)
60548f700142SStefano Zampini {
60558f700142SStefano Zampini   PetscBool      localized;
60568f700142SStefano Zampini   PetscErrorCode ierr;
60578f700142SStefano Zampini 
60588f700142SStefano Zampini   PetscFunctionBegin;
60598f700142SStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6060*534a8f05SLisandro Dalcin   PetscValidBoolPointer(areLocalized, 2);
60618f700142SStefano Zampini   ierr = DMGetCoordinatesLocalizedLocal(dm,&localized);CHKERRQ(ierr);
60628f700142SStefano Zampini   ierr = MPIU_Allreduce(&localized,areLocalized,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
60638f700142SStefano Zampini   PetscFunctionReturn(0);
60648f700142SStefano Zampini }
606536447a5eSToby Isaac 
60662e17dfb7SMatthew G. Knepley /*@
6067492b8470SStefano Zampini   DMLocalizeCoordinates - If a mesh is periodic, create local coordinates for cells having periodic faces
60682e17dfb7SMatthew G. Knepley 
60698f700142SStefano Zampini   Collective on dm
60708f700142SStefano Zampini 
60712e17dfb7SMatthew G. Knepley   Input Parameter:
60722e17dfb7SMatthew G. Knepley . dm - The DM
60732e17dfb7SMatthew G. Knepley 
60742e17dfb7SMatthew G. Knepley   Level: developer
60752e17dfb7SMatthew G. Knepley 
60768f700142SStefano Zampini .seealso: DMSetPeriodicity(), DMLocalizeCoordinate(), DMLocalizeAddCoordinate()
60772e17dfb7SMatthew G. Knepley @*/
60782e17dfb7SMatthew G. Knepley PetscErrorCode DMLocalizeCoordinates(DM dm)
60792e17dfb7SMatthew G. Knepley {
60802e17dfb7SMatthew G. Knepley   DM             cdm;
60812e17dfb7SMatthew G. Knepley   PetscSection   coordSection, cSection;
60822e17dfb7SMatthew G. Knepley   Vec            coordinates,  cVec;
60833e922f36SToby Isaac   PetscScalar   *coords, *coords2, *anchor, *localized;
60843e922f36SToby Isaac   PetscInt       Nc, vStart, vEnd, v, sStart, sEnd, newStart = PETSC_MAX_INT, newEnd = PETSC_MIN_INT, dof, d, off, off2, bs, coordSize;
6085e0ae35bbSToby Isaac   PetscBool      alreadyLocalized, alreadyLocalizedGlobal;
60863e922f36SToby Isaac   PetscInt       maxHeight = 0, h;
60873e922f36SToby Isaac   PetscInt       *pStart = NULL, *pEnd = NULL;
60882e17dfb7SMatthew G. Knepley   PetscErrorCode ierr;
60892e17dfb7SMatthew G. Knepley 
60902e17dfb7SMatthew G. Knepley   PetscFunctionBegin;
60912e17dfb7SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
609292c9c85fSStefano Zampini   if (!dm->periodic) PetscFunctionReturn(0);
6093f7cbd40bSStefano Zampini   ierr = DMGetCoordinatesLocalized(dm, &alreadyLocalized);CHKERRQ(ierr);
6094f7cbd40bSStefano Zampini   if (alreadyLocalized) PetscFunctionReturn(0);
6095f7cbd40bSStefano Zampini 
60962e17dfb7SMatthew G. Knepley   /* We need some generic way of refering to cells/vertices */
60972e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
60982e17dfb7SMatthew G. Knepley   {
60992e17dfb7SMatthew G. Knepley     PetscBool isplex;
61002e17dfb7SMatthew G. Knepley 
61012e17dfb7SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) cdm, DMPLEX, &isplex);CHKERRQ(ierr);
61022e17dfb7SMatthew G. Knepley     if (isplex) {
61032e17dfb7SMatthew G. Knepley       ierr = DMPlexGetDepthStratum(cdm, 0, &vStart, &vEnd);CHKERRQ(ierr);
61043e922f36SToby Isaac       ierr = DMPlexGetMaxProjectionHeight(cdm,&maxHeight);CHKERRQ(ierr);
610569291d52SBarry Smith       ierr = DMGetWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
61063e922f36SToby Isaac       pEnd = &pStart[maxHeight + 1];
61073e922f36SToby Isaac       newStart = vStart;
61083e922f36SToby Isaac       newEnd   = vEnd;
61093e922f36SToby Isaac       for (h = 0; h <= maxHeight; h++) {
61103e922f36SToby Isaac         ierr = DMPlexGetHeightStratum(cdm, h, &pStart[h], &pEnd[h]);CHKERRQ(ierr);
61113e922f36SToby Isaac         newStart = PetscMin(newStart,pStart[h]);
61123e922f36SToby Isaac         newEnd   = PetscMax(newEnd,pEnd[h]);
61133e922f36SToby Isaac       }
61142e17dfb7SMatthew G. Knepley     } else SETERRQ(PetscObjectComm((PetscObject) cdm), PETSC_ERR_ARG_WRONG, "Coordinate localization requires a DMPLEX coordinate DM");
61152e17dfb7SMatthew G. Knepley   }
61162e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
611743eeeb2dSStefano Zampini   if (!coordinates) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Missing local coordinates vector");
61182e17dfb7SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
61193e922f36SToby Isaac   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
6120e0ae35bbSToby Isaac   ierr = PetscSectionGetChart(coordSection,&sStart,&sEnd);CHKERRQ(ierr);
61213e922f36SToby Isaac 
61222e17dfb7SMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr);
61232e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr);
61242e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr);
61252e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr);
61263e922f36SToby Isaac   ierr = PetscSectionSetChart(cSection, newStart, newEnd);CHKERRQ(ierr);
61273e922f36SToby Isaac 
612869291d52SBarry Smith   ierr = DMGetWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
61293e922f36SToby Isaac   localized = &anchor[bs];
61303e922f36SToby Isaac   alreadyLocalized = alreadyLocalizedGlobal = PETSC_TRUE;
61313e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
61323e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
61333e922f36SToby Isaac 
61343e922f36SToby Isaac     for (c = cStart; c < cEnd; ++c) {
61353e922f36SToby Isaac       PetscScalar *cellCoords = NULL;
61363e922f36SToby Isaac       PetscInt     b;
61373e922f36SToby Isaac 
61383e922f36SToby Isaac       if (c < sStart || c >= sEnd) alreadyLocalized = PETSC_FALSE;
61393e922f36SToby Isaac       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
61403e922f36SToby Isaac       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
61413e922f36SToby Isaac       for (d = 0; d < dof/bs; ++d) {
61423e922f36SToby Isaac         ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], localized);CHKERRQ(ierr);
61433e922f36SToby Isaac         for (b = 0; b < bs; b++) {
61443e922f36SToby Isaac           if (cellCoords[d*bs + b] != localized[b]) break;
61453e922f36SToby Isaac         }
61463e922f36SToby Isaac         if (b < bs) break;
61473e922f36SToby Isaac       }
61483e922f36SToby Isaac       if (d < dof/bs) {
61493e922f36SToby Isaac         if (c >= sStart && c < sEnd) {
61503e922f36SToby Isaac           PetscInt cdof;
61513e922f36SToby Isaac 
61523e922f36SToby Isaac           ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
61533e922f36SToby Isaac           if (cdof != dof) alreadyLocalized = PETSC_FALSE;
61543e922f36SToby Isaac         }
61553e922f36SToby Isaac         ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr);
61563e922f36SToby Isaac         ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr);
61573e922f36SToby Isaac       }
61583e922f36SToby Isaac       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
61593e922f36SToby Isaac     }
61603e922f36SToby Isaac   }
61613e922f36SToby Isaac   ierr = MPI_Allreduce(&alreadyLocalized,&alreadyLocalizedGlobal,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
61623e922f36SToby Isaac   if (alreadyLocalizedGlobal) {
616369291d52SBarry Smith     ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
61643e922f36SToby Isaac     ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
616569291d52SBarry Smith     ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
61663e922f36SToby Isaac     PetscFunctionReturn(0);
61673e922f36SToby Isaac   }
61682e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
61692e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
61702e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr);
61712e17dfb7SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr);
61722e17dfb7SMatthew G. Knepley   }
61732e17dfb7SMatthew G. Knepley   ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr);
61742e17dfb7SMatthew G. Knepley   ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr);
6175c2be7e5eSLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &cVec);CHKERRQ(ierr);
61762e17dfb7SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject)cVec,"coordinates");CHKERRQ(ierr);
61772e17dfb7SMatthew G. Knepley   ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr);
61782e17dfb7SMatthew G. Knepley   ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr);
61792e17dfb7SMatthew G. Knepley   ierr = VecSetType(cVec, VECSTANDARD);CHKERRQ(ierr);
6180c2be7e5eSLisandro Dalcin   ierr = VecGetArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
61812e17dfb7SMatthew G. Knepley   ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr);
61822e17dfb7SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
61832e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr);
61842e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
61852e17dfb7SMatthew G. Knepley     ierr = PetscSectionGetOffset(cSection,     v, &off2);CHKERRQ(ierr);
61862e17dfb7SMatthew G. Knepley     for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d];
61872e17dfb7SMatthew G. Knepley   }
61883e922f36SToby Isaac   for (h = 0; h <= maxHeight; h++) {
61893e922f36SToby Isaac     PetscInt cStart = pStart[h], cEnd = pEnd[h], c;
61903e922f36SToby Isaac 
61912e17dfb7SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
61922e17dfb7SMatthew G. Knepley       PetscScalar *cellCoords = NULL;
61933e922f36SToby Isaac       PetscInt     b, cdof;
61942e17dfb7SMatthew G. Knepley 
61953e922f36SToby Isaac       ierr = PetscSectionGetDof(cSection,c,&cdof);CHKERRQ(ierr);
61963e922f36SToby Isaac       if (!cdof) continue;
61972e17dfb7SMatthew G. Knepley       ierr = DMPlexVecGetClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
61982e17dfb7SMatthew G. Knepley       ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr);
61992e17dfb7SMatthew G. Knepley       for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b];
62002e17dfb7SMatthew G. Knepley       for (d = 0; d < dof/bs; ++d) {ierr = DMLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);}
62012e17dfb7SMatthew G. Knepley       ierr = DMPlexVecRestoreClosure(cdm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr);
62022e17dfb7SMatthew G. Knepley     }
62033e922f36SToby Isaac   }
620469291d52SBarry Smith   ierr = DMRestoreWorkArray(dm, 2 * bs, MPIU_SCALAR, &anchor);CHKERRQ(ierr);
620569291d52SBarry Smith   ierr = DMRestoreWorkArray(dm,2*(maxHeight + 1),MPIU_INT,&pStart);CHKERRQ(ierr);
6206c2be7e5eSLisandro Dalcin   ierr = VecRestoreArrayRead(coordinates, (const PetscScalar**)&coords);CHKERRQ(ierr);
62072e17dfb7SMatthew G. Knepley   ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr);
62082e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr);
62092e17dfb7SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr);
62102e17dfb7SMatthew G. Knepley   ierr = VecDestroy(&cVec);CHKERRQ(ierr);
62112e17dfb7SMatthew G. Knepley   ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr);
62122e17dfb7SMatthew G. Knepley   PetscFunctionReturn(0);
62132e17dfb7SMatthew G. Knepley }
62142e17dfb7SMatthew G. Knepley 
6215e87bb0d3SMatthew G Knepley /*@
62163a93e3b7SToby Isaac   DMLocatePoints - Locate the points in v in the mesh and return a PetscSF of the containing cells
6217e87bb0d3SMatthew G Knepley 
6218d083f849SBarry Smith   Collective on v (see explanation below)
6219e87bb0d3SMatthew G Knepley 
6220e87bb0d3SMatthew G Knepley   Input Parameters:
6221e87bb0d3SMatthew G Knepley + dm - The DM
62223a93e3b7SToby Isaac . v - The Vec of points
622362a38674SMatthew G. Knepley . ltype - The type of point location, e.g. DM_POINTLOCATION_NONE or DM_POINTLOCATION_NEAREST
62243a93e3b7SToby Isaac - cells - Points to either NULL, or a PetscSF with guesses for which cells contain each point.
6225e87bb0d3SMatthew G Knepley 
622661e3bb9bSMatthew G Knepley   Output Parameter:
622762a38674SMatthew G. Knepley + v - The Vec of points, which now contains the nearest mesh points to the given points if DM_POINTLOCATION_NEAREST is used
622862a38674SMatthew G. Knepley - cells - The PetscSF containing the ranks and local indices of the containing points.
62293a93e3b7SToby Isaac 
6230e87bb0d3SMatthew G Knepley 
6231e87bb0d3SMatthew G Knepley   Level: developer
623261e3bb9bSMatthew G Knepley 
623362a38674SMatthew G. Knepley   Notes:
62343a93e3b7SToby Isaac   To do a search of the local cells of the mesh, v should have PETSC_COMM_SELF as its communicator.
623562a38674SMatthew G. Knepley   To do a search of all the cells in the distributed mesh, v should have the same communicator as dm.
62363a93e3b7SToby Isaac 
62373a93e3b7SToby Isaac   If *cellSF is NULL on input, a PetscSF will be created.
623862a38674SMatthew G. Knepley   If *cellSF is not NULL on input, it should point to an existing PetscSF, whose graph will be used as initial guesses.
62393a93e3b7SToby Isaac 
62403a93e3b7SToby Isaac   An array that maps each point to its containing cell can be obtained with
62413a93e3b7SToby Isaac 
624262a38674SMatthew G. Knepley $    const PetscSFNode *cells;
624362a38674SMatthew G. Knepley $    PetscInt           nFound;
6244a6216909SToby Isaac $    const PetscInt    *found;
624562a38674SMatthew G. Knepley $
6246a6216909SToby Isaac $    PetscSFGetGraph(cellSF,NULL,&nFound,&found,&cells);
62473a93e3b7SToby Isaac 
62483a93e3b7SToby 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
62493a93e3b7SToby Isaac   the index of the cell in its rank's local numbering.
62503a93e3b7SToby Isaac 
625162a38674SMatthew G. Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMPointLocationType
625261e3bb9bSMatthew G Knepley @*/
625362a38674SMatthew G. Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, DMPointLocationType ltype, PetscSF *cellSF)
6254e87bb0d3SMatthew G Knepley {
6255735aa83eSMatthew G Knepley   PetscErrorCode ierr;
6256735aa83eSMatthew G Knepley 
6257e87bb0d3SMatthew G Knepley   PetscFunctionBegin;
6258e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6259e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
6260e0fc9d1bSMatthew G. Knepley   PetscValidPointer(cellSF,4);
62613a93e3b7SToby Isaac   if (*cellSF) {
62623a93e3b7SToby Isaac     PetscMPIInt result;
62633a93e3b7SToby Isaac 
6264e0fc9d1bSMatthew G. Knepley     PetscValidHeaderSpecific(*cellSF,PETSCSF_CLASSID,4);
6265a4f09dd6SDave May     ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)v),PetscObjectComm((PetscObject)*cellSF),&result);CHKERRQ(ierr);
62663a93e3b7SToby 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");
6267e0fc9d1bSMatthew G. Knepley   } else {
62683a93e3b7SToby Isaac     ierr = PetscSFCreate(PetscObjectComm((PetscObject)v),cellSF);CHKERRQ(ierr);
62693a93e3b7SToby Isaac   }
6270b9d85ea2SLisandro Dalcin   if (!dm->ops->locatepoints) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM");
627147a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
627262a38674SMatthew G. Knepley   ierr = (*dm->ops->locatepoints)(dm,v,ltype,*cellSF);CHKERRQ(ierr);
627347a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
6274e87bb0d3SMatthew G Knepley   PetscFunctionReturn(0);
6275e87bb0d3SMatthew G Knepley }
627614f150ffSMatthew G. Knepley 
6277f4d763aaSMatthew G. Knepley /*@
6278f4d763aaSMatthew G. Knepley   DMGetOutputDM - Retrieve the DM associated with the layout for output
6279f4d763aaSMatthew G. Knepley 
62808f700142SStefano Zampini   Collective on dm
62818f700142SStefano Zampini 
6282f4d763aaSMatthew G. Knepley   Input Parameter:
6283f4d763aaSMatthew G. Knepley . dm - The original DM
6284f4d763aaSMatthew G. Knepley 
6285f4d763aaSMatthew G. Knepley   Output Parameter:
6286f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output
6287f4d763aaSMatthew G. Knepley 
6288f4d763aaSMatthew G. Knepley   Level: intermediate
6289f4d763aaSMatthew G. Knepley 
6290e87a4003SBarry Smith .seealso: VecView(), DMGetGlobalSection()
6291f4d763aaSMatthew G. Knepley @*/
629214f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm)
629314f150ffSMatthew G. Knepley {
6294c26acbdeSMatthew G. Knepley   PetscSection   section;
62952d4e4a49SMatthew G. Knepley   PetscBool      hasConstraints, ghasConstraints;
629614f150ffSMatthew G. Knepley   PetscErrorCode ierr;
629714f150ffSMatthew G. Knepley 
629814f150ffSMatthew G. Knepley   PetscFunctionBegin;
629914f150ffSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
630014f150ffSMatthew G. Knepley   PetscValidPointer(odm,2);
6301e87a4003SBarry Smith   ierr = DMGetSection(dm, &section);CHKERRQ(ierr);
6302c26acbdeSMatthew G. Knepley   ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr);
6303127fe6b9SMatthew G. Knepley   ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
63042d4e4a49SMatthew G. Knepley   if (!ghasConstraints) {
6305c26acbdeSMatthew G. Knepley     *odm = dm;
6306c26acbdeSMatthew G. Knepley     PetscFunctionReturn(0);
6307c26acbdeSMatthew G. Knepley   }
630814f150ffSMatthew G. Knepley   if (!dm->dmBC) {
6309c26acbdeSMatthew G. Knepley     PetscSection newSection, gsection;
631014f150ffSMatthew G. Knepley     PetscSF      sf;
631114f150ffSMatthew G. Knepley 
631214f150ffSMatthew G. Knepley     ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr);
6313e5e52638SMatthew G. Knepley     ierr = DMCopyDisc(dm, dm->dmBC);CHKERRQ(ierr);
631414f150ffSMatthew G. Knepley     ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr);
6315e87a4003SBarry Smith     ierr = DMSetSection(dm->dmBC, newSection);CHKERRQ(ierr);
631614f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);
631714f150ffSMatthew G. Knepley     ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr);
631815b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr);
6319e87a4003SBarry Smith     ierr = DMSetGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr);
632014f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr);
632114f150ffSMatthew G. Knepley   }
632214f150ffSMatthew G. Knepley   *odm = dm->dmBC;
632314f150ffSMatthew G. Knepley   PetscFunctionReturn(0);
632414f150ffSMatthew G. Knepley }
6325f4d763aaSMatthew G. Knepley 
6326f4d763aaSMatthew G. Knepley /*@
6327cdb7a50dSMatthew G. Knepley   DMGetOutputSequenceNumber - Retrieve the sequence number/value for output
6328f4d763aaSMatthew G. Knepley 
6329f4d763aaSMatthew G. Knepley   Input Parameter:
6330f4d763aaSMatthew G. Knepley . dm - The original DM
6331f4d763aaSMatthew G. Knepley 
6332cdb7a50dSMatthew G. Knepley   Output Parameters:
6333cdb7a50dSMatthew G. Knepley + num - The output sequence number
6334cdb7a50dSMatthew G. Knepley - val - The output sequence value
6335f4d763aaSMatthew G. Knepley 
6336f4d763aaSMatthew G. Knepley   Level: intermediate
6337f4d763aaSMatthew G. Knepley 
6338f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6339f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6340f4d763aaSMatthew G. Knepley 
6341f4d763aaSMatthew G. Knepley .seealso: VecView()
6342f4d763aaSMatthew G. Knepley @*/
6343cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val)
6344f4d763aaSMatthew G. Knepley {
6345f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6346f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6347*534a8f05SLisandro Dalcin   if (num) {PetscValidIntPointer(num,2); *num = dm->outputSequenceNum;}
6348*534a8f05SLisandro Dalcin   if (val) {PetscValidRealPointer(val,3);*val = dm->outputSequenceVal;}
6349f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6350f4d763aaSMatthew G. Knepley }
6351f4d763aaSMatthew G. Knepley 
6352f4d763aaSMatthew G. Knepley /*@
6353cdb7a50dSMatthew G. Knepley   DMSetOutputSequenceNumber - Set the sequence number/value for output
6354f4d763aaSMatthew G. Knepley 
6355f4d763aaSMatthew G. Knepley   Input Parameters:
6356f4d763aaSMatthew G. Knepley + dm - The original DM
6357cdb7a50dSMatthew G. Knepley . num - The output sequence number
6358cdb7a50dSMatthew G. Knepley - val - The output sequence value
6359f4d763aaSMatthew G. Knepley 
6360f4d763aaSMatthew G. Knepley   Level: intermediate
6361f4d763aaSMatthew G. Knepley 
6362f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6363f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6364f4d763aaSMatthew G. Knepley 
6365f4d763aaSMatthew G. Knepley .seealso: VecView()
6366f4d763aaSMatthew G. Knepley @*/
6367cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val)
6368f4d763aaSMatthew G. Knepley {
6369f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
6370f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6371f4d763aaSMatthew G. Knepley   dm->outputSequenceNum = num;
6372cdb7a50dSMatthew G. Knepley   dm->outputSequenceVal = val;
6373cdb7a50dSMatthew G. Knepley   PetscFunctionReturn(0);
6374cdb7a50dSMatthew G. Knepley }
6375cdb7a50dSMatthew G. Knepley 
6376cdb7a50dSMatthew G. Knepley /*@C
6377cdb7a50dSMatthew G. Knepley   DMOutputSequenceLoad - Retrieve the sequence value from a Viewer
6378cdb7a50dSMatthew G. Knepley 
6379cdb7a50dSMatthew G. Knepley   Input Parameters:
6380cdb7a50dSMatthew G. Knepley + dm   - The original DM
6381cdb7a50dSMatthew G. Knepley . name - The sequence name
6382cdb7a50dSMatthew G. Knepley - num  - The output sequence number
6383cdb7a50dSMatthew G. Knepley 
6384cdb7a50dSMatthew G. Knepley   Output Parameter:
6385cdb7a50dSMatthew G. Knepley . val  - The output sequence value
6386cdb7a50dSMatthew G. Knepley 
6387cdb7a50dSMatthew G. Knepley   Level: intermediate
6388cdb7a50dSMatthew G. Knepley 
6389cdb7a50dSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
6390cdb7a50dSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
6391cdb7a50dSMatthew G. Knepley 
6392cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView()
6393cdb7a50dSMatthew G. Knepley @*/
6394cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val)
6395cdb7a50dSMatthew G. Knepley {
6396cdb7a50dSMatthew G. Knepley   PetscBool      ishdf5;
6397cdb7a50dSMatthew G. Knepley   PetscErrorCode ierr;
6398cdb7a50dSMatthew G. Knepley 
6399cdb7a50dSMatthew G. Knepley   PetscFunctionBegin;
6400cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6401cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
6402*534a8f05SLisandro Dalcin   PetscValidRealPointer(val,4);
6403cdb7a50dSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr);
6404cdb7a50dSMatthew G. Knepley   if (ishdf5) {
6405cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
6406cdb7a50dSMatthew G. Knepley     PetscScalar value;
6407cdb7a50dSMatthew G. Knepley 
640839d25373SMatthew G. Knepley     ierr = DMSequenceLoad_HDF5_Internal(dm, name, num, &value, viewer);CHKERRQ(ierr);
64094aeb217fSMatthew G. Knepley     *val = PetscRealPart(value);
6410cdb7a50dSMatthew G. Knepley #endif
6411cdb7a50dSMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()");
6412f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
6413f4d763aaSMatthew G. Knepley }
64148e4ac7eaSMatthew G. Knepley 
64158e4ac7eaSMatthew G. Knepley /*@
64168e4ac7eaSMatthew G. Knepley   DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution
64178e4ac7eaSMatthew G. Knepley 
64188e4ac7eaSMatthew G. Knepley   Not collective
64198e4ac7eaSMatthew G. Knepley 
64208e4ac7eaSMatthew G. Knepley   Input Parameter:
64218e4ac7eaSMatthew G. Knepley . dm - The DM
64228e4ac7eaSMatthew G. Knepley 
64238e4ac7eaSMatthew G. Knepley   Output Parameter:
64248e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution
64258e4ac7eaSMatthew G. Knepley 
64268e4ac7eaSMatthew G. Knepley   Level: beginner
64278e4ac7eaSMatthew G. Knepley 
64288e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate()
64298e4ac7eaSMatthew G. Knepley @*/
64308e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural)
64318e4ac7eaSMatthew G. Knepley {
64328e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
64338e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6434*534a8f05SLisandro Dalcin   PetscValidBoolPointer(useNatural, 2);
64358e4ac7eaSMatthew G. Knepley   *useNatural = dm->useNatural;
64368e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
64378e4ac7eaSMatthew G. Knepley }
64388e4ac7eaSMatthew G. Knepley 
64398e4ac7eaSMatthew G. Knepley /*@
64405d3b26e6SMatthew G. Knepley   DMSetUseNatural - Set the flag for creating a mapping to the natural order after distribution
64418e4ac7eaSMatthew G. Knepley 
64428e4ac7eaSMatthew G. Knepley   Collective on dm
64438e4ac7eaSMatthew G. Knepley 
64448e4ac7eaSMatthew G. Knepley   Input Parameters:
64458e4ac7eaSMatthew G. Knepley + dm - The DM
64468e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution
64478e4ac7eaSMatthew G. Knepley 
64485d3b26e6SMatthew G. Knepley   Note: This also causes the map to be build after DMCreateSubDM() and DMCreateSuperDM()
64495d3b26e6SMatthew G. Knepley 
64508e4ac7eaSMatthew G. Knepley   Level: beginner
64518e4ac7eaSMatthew G. Knepley 
64525d3b26e6SMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate(), DMPlexDistribute(), DMCreateSubDM(), DMCreateSuperDM()
64538e4ac7eaSMatthew G. Knepley @*/
64548e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural)
64558e4ac7eaSMatthew G. Knepley {
64568e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
64578e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
64588833efb5SBlaise Bourdin   PetscValidLogicalCollectiveBool(dm, useNatural, 2);
64598e4ac7eaSMatthew G. Knepley   dm->useNatural = useNatural;
64608e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
64618e4ac7eaSMatthew G. Knepley }
6462c58f1c22SToby Isaac 
6463c58f1c22SToby Isaac 
6464c58f1c22SToby Isaac /*@C
6465c58f1c22SToby Isaac   DMCreateLabel - Create a label of the given name if it does not already exist
6466c58f1c22SToby Isaac 
6467c58f1c22SToby Isaac   Not Collective
6468c58f1c22SToby Isaac 
6469c58f1c22SToby Isaac   Input Parameters:
6470c58f1c22SToby Isaac + dm   - The DM object
6471c58f1c22SToby Isaac - name - The label name
6472c58f1c22SToby Isaac 
6473c58f1c22SToby Isaac   Level: intermediate
6474c58f1c22SToby Isaac 
6475c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6476c58f1c22SToby Isaac @*/
6477c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[])
6478c58f1c22SToby Isaac {
6479c58f1c22SToby Isaac   DMLabelLink    next  = dm->labels->next;
6480c58f1c22SToby Isaac   PetscBool      flg   = PETSC_FALSE;
6481d67d17b1SMatthew G. Knepley   const char    *lname;
6482c58f1c22SToby Isaac   PetscErrorCode ierr;
6483c58f1c22SToby Isaac 
6484c58f1c22SToby Isaac   PetscFunctionBegin;
6485c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6486c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6487c58f1c22SToby Isaac   while (next) {
6488d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6489d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
6490c58f1c22SToby Isaac     if (flg) break;
6491c58f1c22SToby Isaac     next = next->next;
6492c58f1c22SToby Isaac   }
6493c58f1c22SToby Isaac   if (!flg) {
6494c58f1c22SToby Isaac     DMLabelLink tmpLabel;
6495c58f1c22SToby Isaac 
6496c58f1c22SToby Isaac     ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
6497d67d17b1SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, name, &tmpLabel->label);CHKERRQ(ierr);
6498c58f1c22SToby Isaac     tmpLabel->output = PETSC_TRUE;
6499c58f1c22SToby Isaac     tmpLabel->next   = dm->labels->next;
6500c58f1c22SToby Isaac     dm->labels->next = tmpLabel;
6501c58f1c22SToby Isaac   }
6502c58f1c22SToby Isaac   PetscFunctionReturn(0);
6503c58f1c22SToby Isaac }
6504c58f1c22SToby Isaac 
6505c58f1c22SToby Isaac /*@C
6506c58f1c22SToby Isaac   DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default
6507c58f1c22SToby Isaac 
6508c58f1c22SToby Isaac   Not Collective
6509c58f1c22SToby Isaac 
6510c58f1c22SToby Isaac   Input Parameters:
6511c58f1c22SToby Isaac + dm   - The DM object
6512c58f1c22SToby Isaac . name - The label name
6513c58f1c22SToby Isaac - point - The mesh point
6514c58f1c22SToby Isaac 
6515c58f1c22SToby Isaac   Output Parameter:
6516c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label
6517c58f1c22SToby Isaac 
6518c58f1c22SToby Isaac   Level: beginner
6519c58f1c22SToby Isaac 
6520c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS()
6521c58f1c22SToby Isaac @*/
6522c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value)
6523c58f1c22SToby Isaac {
6524c58f1c22SToby Isaac   DMLabel        label;
6525c58f1c22SToby Isaac   PetscErrorCode ierr;
6526c58f1c22SToby Isaac 
6527c58f1c22SToby Isaac   PetscFunctionBegin;
6528c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6529c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6530c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
653113903a91SSatish Balay   if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name);
6532c58f1c22SToby Isaac   ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr);
6533c58f1c22SToby Isaac   PetscFunctionReturn(0);
6534c58f1c22SToby Isaac }
6535c58f1c22SToby Isaac 
6536c58f1c22SToby Isaac /*@C
6537c58f1c22SToby Isaac   DMSetLabelValue - Add a point to a Sieve Label with given value
6538c58f1c22SToby Isaac 
6539c58f1c22SToby Isaac   Not Collective
6540c58f1c22SToby Isaac 
6541c58f1c22SToby Isaac   Input Parameters:
6542c58f1c22SToby Isaac + dm   - The DM object
6543c58f1c22SToby Isaac . name - The label name
6544c58f1c22SToby Isaac . point - The mesh point
6545c58f1c22SToby Isaac - value - The label value for this point
6546c58f1c22SToby Isaac 
6547c58f1c22SToby Isaac   Output Parameter:
6548c58f1c22SToby Isaac 
6549c58f1c22SToby Isaac   Level: beginner
6550c58f1c22SToby Isaac 
6551c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue()
6552c58f1c22SToby Isaac @*/
6553c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6554c58f1c22SToby Isaac {
6555c58f1c22SToby Isaac   DMLabel        label;
6556c58f1c22SToby Isaac   PetscErrorCode ierr;
6557c58f1c22SToby Isaac 
6558c58f1c22SToby Isaac   PetscFunctionBegin;
6559c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6560c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6561c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6562c58f1c22SToby Isaac   if (!label) {
6563c58f1c22SToby Isaac     ierr = DMCreateLabel(dm, name);CHKERRQ(ierr);
6564c58f1c22SToby Isaac     ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6565c58f1c22SToby Isaac   }
6566c58f1c22SToby Isaac   ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr);
6567c58f1c22SToby Isaac   PetscFunctionReturn(0);
6568c58f1c22SToby Isaac }
6569c58f1c22SToby Isaac 
6570c58f1c22SToby Isaac /*@C
6571c58f1c22SToby Isaac   DMClearLabelValue - Remove a point from a Sieve Label with given value
6572c58f1c22SToby Isaac 
6573c58f1c22SToby Isaac   Not Collective
6574c58f1c22SToby Isaac 
6575c58f1c22SToby Isaac   Input Parameters:
6576c58f1c22SToby Isaac + dm   - The DM object
6577c58f1c22SToby Isaac . name - The label name
6578c58f1c22SToby Isaac . point - The mesh point
6579c58f1c22SToby Isaac - value - The label value for this point
6580c58f1c22SToby Isaac 
6581c58f1c22SToby Isaac   Output Parameter:
6582c58f1c22SToby Isaac 
6583c58f1c22SToby Isaac   Level: beginner
6584c58f1c22SToby Isaac 
6585c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS()
6586c58f1c22SToby Isaac @*/
6587c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
6588c58f1c22SToby Isaac {
6589c58f1c22SToby Isaac   DMLabel        label;
6590c58f1c22SToby Isaac   PetscErrorCode ierr;
6591c58f1c22SToby Isaac 
6592c58f1c22SToby Isaac   PetscFunctionBegin;
6593c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6594c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6595c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6596c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6597c58f1c22SToby Isaac   ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr);
6598c58f1c22SToby Isaac   PetscFunctionReturn(0);
6599c58f1c22SToby Isaac }
6600c58f1c22SToby Isaac 
6601c58f1c22SToby Isaac /*@C
6602c58f1c22SToby Isaac   DMGetLabelSize - Get the number of different integer ids in a Label
6603c58f1c22SToby Isaac 
6604c58f1c22SToby Isaac   Not Collective
6605c58f1c22SToby Isaac 
6606c58f1c22SToby Isaac   Input Parameters:
6607c58f1c22SToby Isaac + dm   - The DM object
6608c58f1c22SToby Isaac - name - The label name
6609c58f1c22SToby Isaac 
6610c58f1c22SToby Isaac   Output Parameter:
6611c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist
6612c58f1c22SToby Isaac 
6613c58f1c22SToby Isaac   Level: beginner
6614c58f1c22SToby Isaac 
6615df813f42SMatthew G. Knepley .seealso: DMLabelGetNumValues(), DMSetLabelValue()
6616c58f1c22SToby Isaac @*/
6617c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size)
6618c58f1c22SToby Isaac {
6619c58f1c22SToby Isaac   DMLabel        label;
6620c58f1c22SToby Isaac   PetscErrorCode ierr;
6621c58f1c22SToby Isaac 
6622c58f1c22SToby Isaac   PetscFunctionBegin;
6623c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6624c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6625*534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 3);
6626c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6627c58f1c22SToby Isaac   *size = 0;
6628c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6629c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr);
6630c58f1c22SToby Isaac   PetscFunctionReturn(0);
6631c58f1c22SToby Isaac }
6632c58f1c22SToby Isaac 
6633c58f1c22SToby Isaac /*@C
6634c58f1c22SToby Isaac   DMGetLabelIdIS - Get the integer ids in a label
6635c58f1c22SToby Isaac 
6636c58f1c22SToby Isaac   Not Collective
6637c58f1c22SToby Isaac 
6638c58f1c22SToby Isaac   Input Parameters:
6639c58f1c22SToby Isaac + mesh - The DM object
6640c58f1c22SToby Isaac - name - The label name
6641c58f1c22SToby Isaac 
6642c58f1c22SToby Isaac   Output Parameter:
6643c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist
6644c58f1c22SToby Isaac 
6645c58f1c22SToby Isaac   Level: beginner
6646c58f1c22SToby Isaac 
6647c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize()
6648c58f1c22SToby Isaac @*/
6649c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids)
6650c58f1c22SToby Isaac {
6651c58f1c22SToby Isaac   DMLabel        label;
6652c58f1c22SToby Isaac   PetscErrorCode ierr;
6653c58f1c22SToby Isaac 
6654c58f1c22SToby Isaac   PetscFunctionBegin;
6655c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6656c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6657c58f1c22SToby Isaac   PetscValidPointer(ids, 3);
6658c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6659c58f1c22SToby Isaac   *ids = NULL;
6660dab2e251SBlaise Bourdin  if (label) {
6661c58f1c22SToby Isaac     ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr);
6662dab2e251SBlaise Bourdin   } else {
6663dab2e251SBlaise Bourdin     /* returning an empty IS */
6664dab2e251SBlaise Bourdin     ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_USE_POINTER,ids);CHKERRQ(ierr);
6665dab2e251SBlaise Bourdin   }
6666c58f1c22SToby Isaac   PetscFunctionReturn(0);
6667c58f1c22SToby Isaac }
6668c58f1c22SToby Isaac 
6669c58f1c22SToby Isaac /*@C
6670c58f1c22SToby Isaac   DMGetStratumSize - Get the number of points in a label stratum
6671c58f1c22SToby Isaac 
6672c58f1c22SToby Isaac   Not Collective
6673c58f1c22SToby Isaac 
6674c58f1c22SToby Isaac   Input Parameters:
6675c58f1c22SToby Isaac + dm - The DM object
6676c58f1c22SToby Isaac . name - The label name
6677c58f1c22SToby Isaac - value - The stratum value
6678c58f1c22SToby Isaac 
6679c58f1c22SToby Isaac   Output Parameter:
6680c58f1c22SToby Isaac . size - The stratum size
6681c58f1c22SToby Isaac 
6682c58f1c22SToby Isaac   Level: beginner
6683c58f1c22SToby Isaac 
6684c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds()
6685c58f1c22SToby Isaac @*/
6686c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size)
6687c58f1c22SToby Isaac {
6688c58f1c22SToby Isaac   DMLabel        label;
6689c58f1c22SToby Isaac   PetscErrorCode ierr;
6690c58f1c22SToby Isaac 
6691c58f1c22SToby Isaac   PetscFunctionBegin;
6692c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6693c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6694*534a8f05SLisandro Dalcin   PetscValidIntPointer(size, 4);
6695c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6696c58f1c22SToby Isaac   *size = 0;
6697c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6698c58f1c22SToby Isaac   ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr);
6699c58f1c22SToby Isaac   PetscFunctionReturn(0);
6700c58f1c22SToby Isaac }
6701c58f1c22SToby Isaac 
6702c58f1c22SToby Isaac /*@C
6703c58f1c22SToby Isaac   DMGetStratumIS - Get the points in a label stratum
6704c58f1c22SToby Isaac 
6705c58f1c22SToby Isaac   Not Collective
6706c58f1c22SToby Isaac 
6707c58f1c22SToby Isaac   Input Parameters:
6708c58f1c22SToby Isaac + dm - The DM object
6709c58f1c22SToby Isaac . name - The label name
6710c58f1c22SToby Isaac - value - The stratum value
6711c58f1c22SToby Isaac 
6712c58f1c22SToby Isaac   Output Parameter:
6713c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value
6714c58f1c22SToby Isaac 
6715c58f1c22SToby Isaac   Level: beginner
6716c58f1c22SToby Isaac 
6717c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize()
6718c58f1c22SToby Isaac @*/
6719c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points)
6720c58f1c22SToby Isaac {
6721c58f1c22SToby Isaac   DMLabel        label;
6722c58f1c22SToby Isaac   PetscErrorCode ierr;
6723c58f1c22SToby Isaac 
6724c58f1c22SToby Isaac   PetscFunctionBegin;
6725c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6726c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6727c58f1c22SToby Isaac   PetscValidPointer(points, 4);
6728c58f1c22SToby Isaac   ierr    = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6729c58f1c22SToby Isaac   *points = NULL;
6730c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6731c58f1c22SToby Isaac   ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr);
6732c58f1c22SToby Isaac   PetscFunctionReturn(0);
6733c58f1c22SToby Isaac }
6734c58f1c22SToby Isaac 
67354de306b1SToby Isaac /*@C
67369044fa66SMatthew G. Knepley   DMSetStratumIS - Set the points in a label stratum
67374de306b1SToby Isaac 
67384de306b1SToby Isaac   Not Collective
67394de306b1SToby Isaac 
67404de306b1SToby Isaac   Input Parameters:
67414de306b1SToby Isaac + dm - The DM object
67424de306b1SToby Isaac . name - The label name
67434de306b1SToby Isaac . value - The stratum value
67444de306b1SToby Isaac - points - The stratum points
67454de306b1SToby Isaac 
67464de306b1SToby Isaac   Level: beginner
67474de306b1SToby Isaac 
67484de306b1SToby Isaac .seealso: DMLabelSetStratumIS(), DMGetStratumSize()
67494de306b1SToby Isaac @*/
67504de306b1SToby Isaac PetscErrorCode DMSetStratumIS(DM dm, const char name[], PetscInt value, IS points)
67514de306b1SToby Isaac {
67524de306b1SToby Isaac   DMLabel        label;
67534de306b1SToby Isaac   PetscErrorCode ierr;
67544de306b1SToby Isaac 
67554de306b1SToby Isaac   PetscFunctionBegin;
67564de306b1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
67574de306b1SToby Isaac   PetscValidCharPointer(name, 2);
67584de306b1SToby Isaac   PetscValidPointer(points, 4);
67594de306b1SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
67604de306b1SToby Isaac   if (!label) PetscFunctionReturn(0);
67614de306b1SToby Isaac   ierr = DMLabelSetStratumIS(label, value, points);CHKERRQ(ierr);
67624de306b1SToby Isaac   PetscFunctionReturn(0);
67634de306b1SToby Isaac }
67644de306b1SToby Isaac 
6765c58f1c22SToby Isaac /*@C
6766c58f1c22SToby Isaac   DMClearLabelStratum - Remove all points from a stratum from a Sieve Label
6767c58f1c22SToby Isaac 
6768c58f1c22SToby Isaac   Not Collective
6769c58f1c22SToby Isaac 
6770c58f1c22SToby Isaac   Input Parameters:
6771c58f1c22SToby Isaac + dm   - The DM object
6772c58f1c22SToby Isaac . name - The label name
6773c58f1c22SToby Isaac - value - The label value for this point
6774c58f1c22SToby Isaac 
6775c58f1c22SToby Isaac   Output Parameter:
6776c58f1c22SToby Isaac 
6777c58f1c22SToby Isaac   Level: beginner
6778c58f1c22SToby Isaac 
6779c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue()
6780c58f1c22SToby Isaac @*/
6781c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value)
6782c58f1c22SToby Isaac {
6783c58f1c22SToby Isaac   DMLabel        label;
6784c58f1c22SToby Isaac   PetscErrorCode ierr;
6785c58f1c22SToby Isaac 
6786c58f1c22SToby Isaac   PetscFunctionBegin;
6787c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6788c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6789c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
6790c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
6791c58f1c22SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
6792c58f1c22SToby Isaac   PetscFunctionReturn(0);
6793c58f1c22SToby Isaac }
6794c58f1c22SToby Isaac 
6795c58f1c22SToby Isaac /*@
6796c58f1c22SToby Isaac   DMGetNumLabels - Return the number of labels defined by the mesh
6797c58f1c22SToby Isaac 
6798c58f1c22SToby Isaac   Not Collective
6799c58f1c22SToby Isaac 
6800c58f1c22SToby Isaac   Input Parameter:
6801c58f1c22SToby Isaac . dm   - The DM object
6802c58f1c22SToby Isaac 
6803c58f1c22SToby Isaac   Output Parameter:
6804c58f1c22SToby Isaac . numLabels - the number of Labels
6805c58f1c22SToby Isaac 
6806c58f1c22SToby Isaac   Level: intermediate
6807c58f1c22SToby Isaac 
6808c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6809c58f1c22SToby Isaac @*/
6810c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels)
6811c58f1c22SToby Isaac {
6812c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
6813c58f1c22SToby Isaac   PetscInt  n    = 0;
6814c58f1c22SToby Isaac 
6815c58f1c22SToby Isaac   PetscFunctionBegin;
6816c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6817*534a8f05SLisandro Dalcin   PetscValidIntPointer(numLabels, 2);
6818c58f1c22SToby Isaac   while (next) {++n; next = next->next;}
6819c58f1c22SToby Isaac   *numLabels = n;
6820c58f1c22SToby Isaac   PetscFunctionReturn(0);
6821c58f1c22SToby Isaac }
6822c58f1c22SToby Isaac 
6823c58f1c22SToby Isaac /*@C
6824c58f1c22SToby Isaac   DMGetLabelName - Return the name of nth label
6825c58f1c22SToby Isaac 
6826c58f1c22SToby Isaac   Not Collective
6827c58f1c22SToby Isaac 
6828c58f1c22SToby Isaac   Input Parameters:
6829c58f1c22SToby Isaac + dm - The DM object
6830c58f1c22SToby Isaac - n  - the label number
6831c58f1c22SToby Isaac 
6832c58f1c22SToby Isaac   Output Parameter:
6833c58f1c22SToby Isaac . name - the label name
6834c58f1c22SToby Isaac 
6835c58f1c22SToby Isaac   Level: intermediate
6836c58f1c22SToby Isaac 
6837c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6838c58f1c22SToby Isaac @*/
6839c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name)
6840c58f1c22SToby Isaac {
6841c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6842c58f1c22SToby Isaac   PetscInt       l    = 0;
6843d67d17b1SMatthew G. Knepley   PetscErrorCode ierr;
6844c58f1c22SToby Isaac 
6845c58f1c22SToby Isaac   PetscFunctionBegin;
6846c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6847c58f1c22SToby Isaac   PetscValidPointer(name, 3);
6848c58f1c22SToby Isaac   while (next) {
6849c58f1c22SToby Isaac     if (l == n) {
6850d67d17b1SMatthew G. Knepley       ierr = PetscObjectGetName((PetscObject) next->label, name);CHKERRQ(ierr);
6851c58f1c22SToby Isaac       PetscFunctionReturn(0);
6852c58f1c22SToby Isaac     }
6853c58f1c22SToby Isaac     ++l;
6854c58f1c22SToby Isaac     next = next->next;
6855c58f1c22SToby Isaac   }
6856c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
6857c58f1c22SToby Isaac }
6858c58f1c22SToby Isaac 
6859c58f1c22SToby Isaac /*@C
6860c58f1c22SToby Isaac   DMHasLabel - Determine whether the mesh has a label of a given name
6861c58f1c22SToby Isaac 
6862c58f1c22SToby Isaac   Not Collective
6863c58f1c22SToby Isaac 
6864c58f1c22SToby Isaac   Input Parameters:
6865c58f1c22SToby Isaac + dm   - The DM object
6866c58f1c22SToby Isaac - name - The label name
6867c58f1c22SToby Isaac 
6868c58f1c22SToby Isaac   Output Parameter:
6869c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present
6870c58f1c22SToby Isaac 
6871c58f1c22SToby Isaac   Level: intermediate
6872c58f1c22SToby Isaac 
6873c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6874c58f1c22SToby Isaac @*/
6875c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel)
6876c58f1c22SToby Isaac {
6877c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6878d67d17b1SMatthew G. Knepley   const char    *lname;
6879c58f1c22SToby Isaac   PetscErrorCode ierr;
6880c58f1c22SToby Isaac 
6881c58f1c22SToby Isaac   PetscFunctionBegin;
6882c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6883c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6884*534a8f05SLisandro Dalcin   PetscValidBoolPointer(hasLabel, 3);
6885c58f1c22SToby Isaac   *hasLabel = PETSC_FALSE;
6886c58f1c22SToby Isaac   while (next) {
6887d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6888d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, hasLabel);CHKERRQ(ierr);
6889c58f1c22SToby Isaac     if (*hasLabel) break;
6890c58f1c22SToby Isaac     next = next->next;
6891c58f1c22SToby Isaac   }
6892c58f1c22SToby Isaac   PetscFunctionReturn(0);
6893c58f1c22SToby Isaac }
6894c58f1c22SToby Isaac 
6895c58f1c22SToby Isaac /*@C
6896c58f1c22SToby Isaac   DMGetLabel - Return the label of a given name, or NULL
6897c58f1c22SToby Isaac 
6898c58f1c22SToby Isaac   Not Collective
6899c58f1c22SToby Isaac 
6900c58f1c22SToby Isaac   Input Parameters:
6901c58f1c22SToby Isaac + dm   - The DM object
6902c58f1c22SToby Isaac - name - The label name
6903c58f1c22SToby Isaac 
6904c58f1c22SToby Isaac   Output Parameter:
6905c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
6906c58f1c22SToby Isaac 
6907c58f1c22SToby Isaac   Level: intermediate
6908c58f1c22SToby Isaac 
6909c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6910c58f1c22SToby Isaac @*/
6911c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label)
6912c58f1c22SToby Isaac {
6913c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
6914c58f1c22SToby Isaac   PetscBool      hasLabel;
6915d67d17b1SMatthew G. Knepley   const char    *lname;
6916c58f1c22SToby Isaac   PetscErrorCode ierr;
6917c58f1c22SToby Isaac 
6918c58f1c22SToby Isaac   PetscFunctionBegin;
6919c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6920c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
6921c58f1c22SToby Isaac   PetscValidPointer(label, 3);
6922c58f1c22SToby Isaac   *label = NULL;
6923c58f1c22SToby Isaac   while (next) {
6924d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
6925d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
6926c58f1c22SToby Isaac     if (hasLabel) {
6927c58f1c22SToby Isaac       *label = next->label;
6928c58f1c22SToby Isaac       break;
6929c58f1c22SToby Isaac     }
6930c58f1c22SToby Isaac     next = next->next;
6931c58f1c22SToby Isaac   }
6932c58f1c22SToby Isaac   PetscFunctionReturn(0);
6933c58f1c22SToby Isaac }
6934c58f1c22SToby Isaac 
6935c58f1c22SToby Isaac /*@C
6936c58f1c22SToby Isaac   DMGetLabelByNum - Return the nth label
6937c58f1c22SToby Isaac 
6938c58f1c22SToby Isaac   Not Collective
6939c58f1c22SToby Isaac 
6940c58f1c22SToby Isaac   Input Parameters:
6941c58f1c22SToby Isaac + dm - The DM object
6942c58f1c22SToby Isaac - n  - the label number
6943c58f1c22SToby Isaac 
6944c58f1c22SToby Isaac   Output Parameter:
6945c58f1c22SToby Isaac . label - the label
6946c58f1c22SToby Isaac 
6947c58f1c22SToby Isaac   Level: intermediate
6948c58f1c22SToby Isaac 
6949c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6950c58f1c22SToby Isaac @*/
6951c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label)
6952c58f1c22SToby Isaac {
6953c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
6954c58f1c22SToby Isaac   PetscInt    l    = 0;
6955c58f1c22SToby Isaac 
6956c58f1c22SToby Isaac   PetscFunctionBegin;
6957c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6958c58f1c22SToby Isaac   PetscValidPointer(label, 3);
6959c58f1c22SToby Isaac   while (next) {
6960c58f1c22SToby Isaac     if (l == n) {
6961c58f1c22SToby Isaac       *label = next->label;
6962c58f1c22SToby Isaac       PetscFunctionReturn(0);
6963c58f1c22SToby Isaac     }
6964c58f1c22SToby Isaac     ++l;
6965c58f1c22SToby Isaac     next = next->next;
6966c58f1c22SToby Isaac   }
6967c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
6968c58f1c22SToby Isaac }
6969c58f1c22SToby Isaac 
6970c58f1c22SToby Isaac /*@C
6971c58f1c22SToby Isaac   DMAddLabel - Add the label to this mesh
6972c58f1c22SToby Isaac 
6973c58f1c22SToby Isaac   Not Collective
6974c58f1c22SToby Isaac 
6975c58f1c22SToby Isaac   Input Parameters:
6976c58f1c22SToby Isaac + dm   - The DM object
6977c58f1c22SToby Isaac - label - The DMLabel
6978c58f1c22SToby Isaac 
6979c58f1c22SToby Isaac   Level: developer
6980c58f1c22SToby Isaac 
6981c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
6982c58f1c22SToby Isaac @*/
6983c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label)
6984c58f1c22SToby Isaac {
6985c58f1c22SToby Isaac   DMLabelLink    tmpLabel;
6986c58f1c22SToby Isaac   PetscBool      hasLabel;
6987d67d17b1SMatthew G. Knepley   const char    *lname;
6988c58f1c22SToby Isaac   PetscErrorCode ierr;
6989c58f1c22SToby Isaac 
6990c58f1c22SToby Isaac   PetscFunctionBegin;
6991c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6992d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
6993d67d17b1SMatthew G. Knepley   ierr = DMHasLabel(dm, lname, &hasLabel);CHKERRQ(ierr);
6994d67d17b1SMatthew G. Knepley   if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", lname);
6995c58f1c22SToby Isaac   ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
6996c58f1c22SToby Isaac   tmpLabel->label  = label;
6997c58f1c22SToby Isaac   tmpLabel->output = PETSC_TRUE;
6998c58f1c22SToby Isaac   tmpLabel->next   = dm->labels->next;
6999c58f1c22SToby Isaac   dm->labels->next = tmpLabel;
7000c58f1c22SToby Isaac   PetscFunctionReturn(0);
7001c58f1c22SToby Isaac }
7002c58f1c22SToby Isaac 
7003c58f1c22SToby Isaac /*@C
7004c58f1c22SToby Isaac   DMRemoveLabel - Remove the label from this mesh
7005c58f1c22SToby Isaac 
7006c58f1c22SToby Isaac   Not Collective
7007c58f1c22SToby Isaac 
7008c58f1c22SToby Isaac   Input Parameters:
7009c58f1c22SToby Isaac + dm   - The DM object
7010c58f1c22SToby Isaac - name - The label name
7011c58f1c22SToby Isaac 
7012c58f1c22SToby Isaac   Output Parameter:
7013c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
7014c58f1c22SToby Isaac 
7015c58f1c22SToby Isaac   Level: developer
7016c58f1c22SToby Isaac 
7017c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7018c58f1c22SToby Isaac @*/
7019c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label)
7020c58f1c22SToby Isaac {
7021c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
7022c58f1c22SToby Isaac   DMLabelLink    last = NULL;
7023c58f1c22SToby Isaac   PetscBool      hasLabel;
7024d67d17b1SMatthew G. Knepley   const char    *lname;
7025c58f1c22SToby Isaac   PetscErrorCode ierr;
7026c58f1c22SToby Isaac 
7027c58f1c22SToby Isaac   PetscFunctionBegin;
7028c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7029c58f1c22SToby Isaac   ierr   = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr);
7030c58f1c22SToby Isaac   *label = NULL;
7031c58f1c22SToby Isaac   if (!hasLabel) PetscFunctionReturn(0);
7032c58f1c22SToby Isaac   while (next) {
7033d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7034d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &hasLabel);CHKERRQ(ierr);
7035c58f1c22SToby Isaac     if (hasLabel) {
7036c58f1c22SToby Isaac       if (last) last->next       = next->next;
7037c58f1c22SToby Isaac       else      dm->labels->next = next->next;
7038c58f1c22SToby Isaac       next->next = NULL;
7039c58f1c22SToby Isaac       *label     = next->label;
7040c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr);
7041c58f1c22SToby Isaac       if (hasLabel) {
7042c58f1c22SToby Isaac         dm->depthLabel = NULL;
7043c58f1c22SToby Isaac       }
7044c58f1c22SToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
7045c58f1c22SToby Isaac       break;
7046c58f1c22SToby Isaac     }
7047c58f1c22SToby Isaac     last = next;
7048c58f1c22SToby Isaac     next = next->next;
7049c58f1c22SToby Isaac   }
7050c58f1c22SToby Isaac   PetscFunctionReturn(0);
7051c58f1c22SToby Isaac }
7052c58f1c22SToby Isaac 
7053c58f1c22SToby Isaac /*@C
7054c58f1c22SToby Isaac   DMGetLabelOutput - Get the output flag for a given label
7055c58f1c22SToby Isaac 
7056c58f1c22SToby Isaac   Not Collective
7057c58f1c22SToby Isaac 
7058c58f1c22SToby Isaac   Input Parameters:
7059c58f1c22SToby Isaac + dm   - The DM object
7060c58f1c22SToby Isaac - name - The label name
7061c58f1c22SToby Isaac 
7062c58f1c22SToby Isaac   Output Parameter:
7063c58f1c22SToby Isaac . output - The flag for output
7064c58f1c22SToby Isaac 
7065c58f1c22SToby Isaac   Level: developer
7066c58f1c22SToby Isaac 
7067c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7068c58f1c22SToby Isaac @*/
7069c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output)
7070c58f1c22SToby Isaac {
7071c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
7072d67d17b1SMatthew G. Knepley   const char    *lname;
7073c58f1c22SToby Isaac   PetscErrorCode ierr;
7074c58f1c22SToby Isaac 
7075c58f1c22SToby Isaac   PetscFunctionBegin;
7076c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7077c58f1c22SToby Isaac   PetscValidPointer(name, 2);
7078c58f1c22SToby Isaac   PetscValidPointer(output, 3);
7079c58f1c22SToby Isaac   while (next) {
7080c58f1c22SToby Isaac     PetscBool flg;
7081c58f1c22SToby Isaac 
7082d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7083d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7084c58f1c22SToby Isaac     if (flg) {*output = next->output; PetscFunctionReturn(0);}
7085c58f1c22SToby Isaac     next = next->next;
7086c58f1c22SToby Isaac   }
7087c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7088c58f1c22SToby Isaac }
7089c58f1c22SToby Isaac 
7090c58f1c22SToby Isaac /*@C
7091c58f1c22SToby Isaac   DMSetLabelOutput - Set the output flag for a given label
7092c58f1c22SToby Isaac 
7093c58f1c22SToby Isaac   Not Collective
7094c58f1c22SToby Isaac 
7095c58f1c22SToby Isaac   Input Parameters:
7096c58f1c22SToby Isaac + dm     - The DM object
7097c58f1c22SToby Isaac . name   - The label name
7098c58f1c22SToby Isaac - output - The flag for output
7099c58f1c22SToby Isaac 
7100c58f1c22SToby Isaac   Level: developer
7101c58f1c22SToby Isaac 
7102c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
7103c58f1c22SToby Isaac @*/
7104c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output)
7105c58f1c22SToby Isaac {
7106c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
7107d67d17b1SMatthew G. Knepley   const char    *lname;
7108c58f1c22SToby Isaac   PetscErrorCode ierr;
7109c58f1c22SToby Isaac 
7110c58f1c22SToby Isaac   PetscFunctionBegin;
7111c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7112*534a8f05SLisandro Dalcin   PetscValidCharPointer(name, 2);
7113c58f1c22SToby Isaac   while (next) {
7114c58f1c22SToby Isaac     PetscBool flg;
7115c58f1c22SToby Isaac 
7116d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) next->label, &lname);CHKERRQ(ierr);
7117d67d17b1SMatthew G. Knepley     ierr = PetscStrcmp(name, lname, &flg);CHKERRQ(ierr);
7118c58f1c22SToby Isaac     if (flg) {next->output = output; PetscFunctionReturn(0);}
7119c58f1c22SToby Isaac     next = next->next;
7120c58f1c22SToby Isaac   }
7121c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
7122c58f1c22SToby Isaac }
7123c58f1c22SToby Isaac 
7124c58f1c22SToby Isaac 
7125c58f1c22SToby Isaac /*@
7126c58f1c22SToby Isaac   DMCopyLabels - Copy labels from one mesh to another with a superset of the points
7127c58f1c22SToby Isaac 
7128d083f849SBarry Smith   Collective on dmA
7129c58f1c22SToby Isaac 
7130c58f1c22SToby Isaac   Input Parameter:
71312e17dfb7SMatthew G. Knepley . dmA - The DM object with initial labels
7132c58f1c22SToby Isaac 
7133c58f1c22SToby Isaac   Output Parameter:
71342e17dfb7SMatthew G. Knepley . dmB - The DM object with copied labels
7135c58f1c22SToby Isaac 
7136c58f1c22SToby Isaac   Level: intermediate
7137c58f1c22SToby Isaac 
7138c58f1c22SToby Isaac   Note: This is typically used when interpolating or otherwise adding to a mesh
7139c58f1c22SToby Isaac 
7140367003a6SStefano Zampini .seealso: DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection()
7141c58f1c22SToby Isaac @*/
7142c58f1c22SToby Isaac PetscErrorCode DMCopyLabels(DM dmA, DM dmB)
7143c58f1c22SToby Isaac {
7144c58f1c22SToby Isaac   PetscInt       numLabels, l;
7145c58f1c22SToby Isaac   PetscErrorCode ierr;
7146c58f1c22SToby Isaac 
7147c58f1c22SToby Isaac   PetscFunctionBegin;
7148c58f1c22SToby Isaac   if (dmA == dmB) PetscFunctionReturn(0);
7149c58f1c22SToby Isaac   ierr = DMGetNumLabels(dmA, &numLabels);CHKERRQ(ierr);
7150c58f1c22SToby Isaac   for (l = 0; l < numLabels; ++l) {
7151c58f1c22SToby Isaac     DMLabel     label, labelNew;
7152c58f1c22SToby Isaac     const char *name;
7153c58f1c22SToby Isaac     PetscBool   flg;
7154c58f1c22SToby Isaac 
7155c58f1c22SToby Isaac     ierr = DMGetLabelName(dmA, l, &name);CHKERRQ(ierr);
7156c58f1c22SToby Isaac     ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr);
7157c58f1c22SToby Isaac     if (flg) continue;
71587d5acc75SStefano Zampini     ierr = PetscStrcmp(name, "dim", &flg);CHKERRQ(ierr);
71597d5acc75SStefano Zampini     if (flg) continue;
7160c58f1c22SToby Isaac     ierr = DMGetLabel(dmA, name, &label);CHKERRQ(ierr);
7161c58f1c22SToby Isaac     ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr);
7162c58f1c22SToby Isaac     ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr);
7163c58f1c22SToby Isaac   }
7164c58f1c22SToby Isaac   PetscFunctionReturn(0);
7165c58f1c22SToby Isaac }
7166a8fb8f29SToby Isaac 
7167a8fb8f29SToby Isaac /*@
7168a8fb8f29SToby Isaac   DMGetCoarseDM - Get the coarse mesh from which this was obtained by refinement
7169a8fb8f29SToby Isaac 
7170a8fb8f29SToby Isaac   Input Parameter:
7171a8fb8f29SToby Isaac . dm - The DM object
7172a8fb8f29SToby Isaac 
7173a8fb8f29SToby Isaac   Output Parameter:
7174a8fb8f29SToby Isaac . cdm - The coarse DM
7175a8fb8f29SToby Isaac 
7176a8fb8f29SToby Isaac   Level: intermediate
7177a8fb8f29SToby Isaac 
7178a8fb8f29SToby Isaac .seealso: DMSetCoarseDM()
7179a8fb8f29SToby Isaac @*/
7180a8fb8f29SToby Isaac PetscErrorCode DMGetCoarseDM(DM dm, DM *cdm)
7181a8fb8f29SToby Isaac {
7182a8fb8f29SToby Isaac   PetscFunctionBegin;
7183a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7184a8fb8f29SToby Isaac   PetscValidPointer(cdm, 2);
7185a8fb8f29SToby Isaac   *cdm = dm->coarseMesh;
7186a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7187a8fb8f29SToby Isaac }
7188a8fb8f29SToby Isaac 
7189a8fb8f29SToby Isaac /*@
7190a8fb8f29SToby Isaac   DMSetCoarseDM - Set the coarse mesh from which this was obtained by refinement
7191a8fb8f29SToby Isaac 
7192a8fb8f29SToby Isaac   Input Parameters:
7193a8fb8f29SToby Isaac + dm - The DM object
7194a8fb8f29SToby Isaac - cdm - The coarse DM
7195a8fb8f29SToby Isaac 
7196a8fb8f29SToby Isaac   Level: intermediate
7197a8fb8f29SToby Isaac 
7198a8fb8f29SToby Isaac .seealso: DMGetCoarseDM()
7199a8fb8f29SToby Isaac @*/
7200a8fb8f29SToby Isaac PetscErrorCode DMSetCoarseDM(DM dm, DM cdm)
7201a8fb8f29SToby Isaac {
7202a8fb8f29SToby Isaac   PetscErrorCode ierr;
7203a8fb8f29SToby Isaac 
7204a8fb8f29SToby Isaac   PetscFunctionBegin;
7205a8fb8f29SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7206a8fb8f29SToby Isaac   if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2);
7207a8fb8f29SToby Isaac   ierr = PetscObjectReference((PetscObject)cdm);CHKERRQ(ierr);
7208a8fb8f29SToby Isaac   ierr = DMDestroy(&dm->coarseMesh);CHKERRQ(ierr);
7209a8fb8f29SToby Isaac   dm->coarseMesh = cdm;
7210a8fb8f29SToby Isaac   PetscFunctionReturn(0);
7211a8fb8f29SToby Isaac }
7212a8fb8f29SToby Isaac 
721388bdff64SToby Isaac /*@
721488bdff64SToby Isaac   DMGetFineDM - Get the fine mesh from which this was obtained by refinement
721588bdff64SToby Isaac 
721688bdff64SToby Isaac   Input Parameter:
721788bdff64SToby Isaac . dm - The DM object
721888bdff64SToby Isaac 
721988bdff64SToby Isaac   Output Parameter:
722088bdff64SToby Isaac . fdm - The fine DM
722188bdff64SToby Isaac 
722288bdff64SToby Isaac   Level: intermediate
722388bdff64SToby Isaac 
722488bdff64SToby Isaac .seealso: DMSetFineDM()
722588bdff64SToby Isaac @*/
722688bdff64SToby Isaac PetscErrorCode DMGetFineDM(DM dm, DM *fdm)
722788bdff64SToby Isaac {
722888bdff64SToby Isaac   PetscFunctionBegin;
722988bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
723088bdff64SToby Isaac   PetscValidPointer(fdm, 2);
723188bdff64SToby Isaac   *fdm = dm->fineMesh;
723288bdff64SToby Isaac   PetscFunctionReturn(0);
723388bdff64SToby Isaac }
723488bdff64SToby Isaac 
723588bdff64SToby Isaac /*@
723688bdff64SToby Isaac   DMSetFineDM - Set the fine mesh from which this was obtained by refinement
723788bdff64SToby Isaac 
723888bdff64SToby Isaac   Input Parameters:
723988bdff64SToby Isaac + dm - The DM object
724088bdff64SToby Isaac - fdm - The fine DM
724188bdff64SToby Isaac 
724288bdff64SToby Isaac   Level: intermediate
724388bdff64SToby Isaac 
724488bdff64SToby Isaac .seealso: DMGetFineDM()
724588bdff64SToby Isaac @*/
724688bdff64SToby Isaac PetscErrorCode DMSetFineDM(DM dm, DM fdm)
724788bdff64SToby Isaac {
724888bdff64SToby Isaac   PetscErrorCode ierr;
724988bdff64SToby Isaac 
725088bdff64SToby Isaac   PetscFunctionBegin;
725188bdff64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
725288bdff64SToby Isaac   if (fdm) PetscValidHeaderSpecific(fdm, DM_CLASSID, 2);
725388bdff64SToby Isaac   ierr = PetscObjectReference((PetscObject)fdm);CHKERRQ(ierr);
725488bdff64SToby Isaac   ierr = DMDestroy(&dm->fineMesh);CHKERRQ(ierr);
725588bdff64SToby Isaac   dm->fineMesh = fdm;
725688bdff64SToby Isaac   PetscFunctionReturn(0);
725788bdff64SToby Isaac }
725888bdff64SToby Isaac 
7259a6ba4734SToby Isaac /*=== DMBoundary code ===*/
7260a6ba4734SToby Isaac 
7261a6ba4734SToby Isaac PetscErrorCode DMCopyBoundary(DM dm, DM dmNew)
7262a6ba4734SToby Isaac {
7263e5e52638SMatthew G. Knepley   PetscInt       d;
7264a6ba4734SToby Isaac   PetscErrorCode ierr;
7265a6ba4734SToby Isaac 
7266a6ba4734SToby Isaac   PetscFunctionBegin;
7267e5e52638SMatthew G. Knepley   for (d = 0; d < dm->Nds; ++d) {
7268e5e52638SMatthew G. Knepley     ierr = PetscDSCopyBoundary(dm->probs[d].ds, dmNew->probs[d].ds);CHKERRQ(ierr);
7269e5e52638SMatthew G. Knepley   }
7270a6ba4734SToby Isaac   PetscFunctionReturn(0);
7271a6ba4734SToby Isaac }
7272a6ba4734SToby Isaac 
7273a6ba4734SToby Isaac /*@C
7274a6ba4734SToby Isaac   DMAddBoundary - Add a boundary condition to the model
7275a6ba4734SToby Isaac 
7276a6ba4734SToby Isaac   Input Parameters:
72774c258f51SMatthew G. Knepley + dm          - The DM, with a PetscDS that matches the problem being constrained
7278f971fd6bSMatthew G. Knepley . type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7279a6ba4734SToby Isaac . name        - The BC name
7280a6ba4734SToby Isaac . labelname   - The label defining constrained points
7281a6ba4734SToby Isaac . field       - The field to constrain
7282e8ecbf3fSStefano Zampini . numcomps    - The number of constrained field components (0 will constrain all fields)
7283a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7284a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7285a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7286a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7287a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7288a6ba4734SToby Isaac 
7289a6ba4734SToby Isaac   Options Database Keys:
7290a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7291a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7292a6ba4734SToby Isaac 
7293a6ba4734SToby Isaac   Level: developer
7294a6ba4734SToby Isaac 
7295a6ba4734SToby Isaac .seealso: DMGetBoundary()
7296a6ba4734SToby Isaac @*/
7297a30ec4eaSSatish 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)
7298a6ba4734SToby Isaac {
7299e5e52638SMatthew G. Knepley   PetscDS        ds;
7300a6ba4734SToby Isaac   PetscErrorCode ierr;
7301a6ba4734SToby Isaac 
7302a6ba4734SToby Isaac   PetscFunctionBegin;
7303a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7304e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7305e5e52638SMatthew G. Knepley   ierr = PetscDSAddBoundary(ds, type,name, labelname, field, numcomps, comps, bcFunc, numids, ids, ctx);CHKERRQ(ierr);
7306a6ba4734SToby Isaac   PetscFunctionReturn(0);
7307a6ba4734SToby Isaac }
7308a6ba4734SToby Isaac 
7309a6ba4734SToby Isaac /*@
7310a6ba4734SToby Isaac   DMGetNumBoundary - Get the number of registered BC
7311a6ba4734SToby Isaac 
7312a6ba4734SToby Isaac   Input Parameters:
7313a6ba4734SToby Isaac . dm - The mesh object
7314a6ba4734SToby Isaac 
7315a6ba4734SToby Isaac   Output Parameters:
7316a6ba4734SToby Isaac . numBd - The number of BC
7317a6ba4734SToby Isaac 
7318a6ba4734SToby Isaac   Level: intermediate
7319a6ba4734SToby Isaac 
7320a6ba4734SToby Isaac .seealso: DMAddBoundary(), DMGetBoundary()
7321a6ba4734SToby Isaac @*/
7322a6ba4734SToby Isaac PetscErrorCode DMGetNumBoundary(DM dm, PetscInt *numBd)
7323a6ba4734SToby Isaac {
7324e5e52638SMatthew G. Knepley   PetscDS        ds;
732558ebd649SToby Isaac   PetscErrorCode ierr;
7326a6ba4734SToby Isaac 
7327a6ba4734SToby Isaac   PetscFunctionBegin;
7328a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7329e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7330e5e52638SMatthew G. Knepley   ierr = PetscDSGetNumBoundary(ds, numBd);CHKERRQ(ierr);
7331a6ba4734SToby Isaac   PetscFunctionReturn(0);
7332a6ba4734SToby Isaac }
7333a6ba4734SToby Isaac 
7334a6ba4734SToby Isaac /*@C
73351c531cf8SMatthew G. Knepley   DMGetBoundary - Get a model boundary condition
7336a6ba4734SToby Isaac 
7337a6ba4734SToby Isaac   Input Parameters:
7338a6ba4734SToby Isaac + dm          - The mesh object
7339a6ba4734SToby Isaac - bd          - The BC number
7340a6ba4734SToby Isaac 
7341a6ba4734SToby Isaac   Output Parameters:
7342f971fd6bSMatthew G. Knepley + type        - The type of condition, e.g. DM_BC_ESSENTIAL_ANALYTIC/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
7343a6ba4734SToby Isaac . name        - The BC name
7344a6ba4734SToby Isaac . labelname   - The label defining constrained points
7345a6ba4734SToby Isaac . field       - The field to constrain
7346a6ba4734SToby Isaac . numcomps    - The number of constrained field components
7347a6ba4734SToby Isaac . comps       - An array of constrained component numbers
7348a6ba4734SToby Isaac . bcFunc      - A pointwise function giving boundary values
7349a6ba4734SToby Isaac . numids      - The number of DMLabel ids for constrained points
7350a6ba4734SToby Isaac . ids         - An array of ids for constrained points
7351a6ba4734SToby Isaac - ctx         - An optional user context for bcFunc
7352a6ba4734SToby Isaac 
7353a6ba4734SToby Isaac   Options Database Keys:
7354a6ba4734SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
7355a6ba4734SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
7356a6ba4734SToby Isaac 
7357a6ba4734SToby Isaac   Level: developer
7358a6ba4734SToby Isaac 
7359a6ba4734SToby Isaac .seealso: DMAddBoundary()
7360a6ba4734SToby Isaac @*/
7361a30ec4eaSSatish 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)
7362a6ba4734SToby Isaac {
7363e5e52638SMatthew G. Knepley   PetscDS        ds;
736458ebd649SToby Isaac   PetscErrorCode ierr;
7365a6ba4734SToby Isaac 
7366a6ba4734SToby Isaac   PetscFunctionBegin;
7367a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7368e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7369e5e52638SMatthew G. Knepley   ierr = PetscDSGetBoundary(ds, bd, type, name, labelname, field, numcomps, comps, func, numids, ids, ctx);CHKERRQ(ierr);
7370a6ba4734SToby Isaac   PetscFunctionReturn(0);
7371a6ba4734SToby Isaac }
7372a6ba4734SToby Isaac 
7373e6f8dbb6SToby Isaac static PetscErrorCode DMPopulateBoundary(DM dm)
7374e6f8dbb6SToby Isaac {
7375e5e52638SMatthew G. Knepley   PetscDS        ds;
7376dff059c6SToby Isaac   DMBoundary    *lastnext;
7377e6f8dbb6SToby Isaac   DSBoundary     dsbound;
7378e6f8dbb6SToby Isaac   PetscErrorCode ierr;
7379e6f8dbb6SToby Isaac 
7380e6f8dbb6SToby Isaac   PetscFunctionBegin;
7381e5e52638SMatthew G. Knepley   ierr = DMGetDS(dm, &ds);CHKERRQ(ierr);
7382e5e52638SMatthew G. Knepley   dsbound = ds->boundary;
738347a1f5adSToby Isaac   if (dm->boundary) {
738447a1f5adSToby Isaac     DMBoundary next = dm->boundary;
738547a1f5adSToby Isaac 
738647a1f5adSToby Isaac     /* quick check to see if the PetscDS has changed */
738747a1f5adSToby Isaac     if (next->dsboundary == dsbound) PetscFunctionReturn(0);
738847a1f5adSToby Isaac     /* the PetscDS has changed: tear down and rebuild */
738947a1f5adSToby Isaac     while (next) {
739047a1f5adSToby Isaac       DMBoundary b = next;
739147a1f5adSToby Isaac 
739247a1f5adSToby Isaac       next = b->next;
739347a1f5adSToby Isaac       ierr = PetscFree(b);CHKERRQ(ierr);
7394a6ba4734SToby Isaac     }
739547a1f5adSToby Isaac     dm->boundary = NULL;
7396a6ba4734SToby Isaac   }
739747a1f5adSToby Isaac 
7398dff059c6SToby Isaac   lastnext = &(dm->boundary);
7399e6f8dbb6SToby Isaac   while (dsbound) {
7400e6f8dbb6SToby Isaac     DMBoundary dmbound;
7401e6f8dbb6SToby Isaac 
7402e6f8dbb6SToby Isaac     ierr = PetscNew(&dmbound);CHKERRQ(ierr);
7403e6f8dbb6SToby Isaac     dmbound->dsboundary = dsbound;
7404e6f8dbb6SToby Isaac     ierr = DMGetLabel(dm, dsbound->labelname, &(dmbound->label));CHKERRQ(ierr);
7405994fe344SLisandro 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);}
740647a1f5adSToby Isaac     /* push on the back instead of the front so that it is in the same order as in the PetscDS */
7407dff059c6SToby Isaac     *lastnext = dmbound;
7408dff059c6SToby Isaac     lastnext = &(dmbound->next);
7409dff059c6SToby Isaac     dsbound = dsbound->next;
7410a6ba4734SToby Isaac   }
7411a6ba4734SToby Isaac   PetscFunctionReturn(0);
7412a6ba4734SToby Isaac }
7413a6ba4734SToby Isaac 
7414a6ba4734SToby Isaac PetscErrorCode DMIsBoundaryPoint(DM dm, PetscInt point, PetscBool *isBd)
7415a6ba4734SToby Isaac {
7416b95f2879SToby Isaac   DMBoundary     b;
7417a6ba4734SToby Isaac   PetscErrorCode ierr;
7418a6ba4734SToby Isaac 
7419a6ba4734SToby Isaac   PetscFunctionBegin;
7420a6ba4734SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7421*534a8f05SLisandro Dalcin   PetscValidBoolPointer(isBd, 3);
7422a6ba4734SToby Isaac   *isBd = PETSC_FALSE;
7423e6f8dbb6SToby Isaac   ierr = DMPopulateBoundary(dm);CHKERRQ(ierr);
7424b95f2879SToby Isaac   b = dm->boundary;
7425a6ba4734SToby Isaac   while (b && !(*isBd)) {
7426e6f8dbb6SToby Isaac     DMLabel    label = b->label;
7427e6f8dbb6SToby Isaac     DSBoundary dsb = b->dsboundary;
74283424c85cSToby Isaac 
74293424c85cSToby Isaac     if (label) {
7430a6ba4734SToby Isaac       PetscInt i;
7431a6ba4734SToby Isaac 
7432e6f8dbb6SToby Isaac       for (i = 0; i < dsb->numids && !(*isBd); ++i) {
7433e6f8dbb6SToby Isaac         ierr = DMLabelStratumHasPoint(label, dsb->ids[i], point, isBd);CHKERRQ(ierr);
7434a6ba4734SToby Isaac       }
7435a6ba4734SToby Isaac     }
7436a6ba4734SToby Isaac     b = b->next;
7437a6ba4734SToby Isaac   }
7438a6ba4734SToby Isaac   PetscFunctionReturn(0);
7439a6ba4734SToby Isaac }
74404d6f44ffSToby Isaac 
74414d6f44ffSToby Isaac /*@C
74424d6f44ffSToby Isaac   DMProjectFunction - This projects the given function into the function space provided.
74434d6f44ffSToby Isaac 
74444d6f44ffSToby Isaac   Input Parameters:
74454d6f44ffSToby Isaac + dm      - The DM
74460709b2feSToby Isaac . time    - The time
74474d6f44ffSToby Isaac . funcs   - The coordinate functions to evaluate, one per field
74484d6f44ffSToby Isaac . ctxs    - Optional array of contexts to pass to each coordinate function.  ctxs itself may be null.
74494d6f44ffSToby Isaac - mode    - The insertion mode for values
74504d6f44ffSToby Isaac 
74514d6f44ffSToby Isaac   Output Parameter:
74524d6f44ffSToby Isaac . X - vector
74534d6f44ffSToby Isaac 
74544d6f44ffSToby Isaac    Calling sequence of func:
74550709b2feSToby Isaac $    func(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx);
74564d6f44ffSToby Isaac 
74574d6f44ffSToby Isaac +  dim - The spatial dimension
74584d6f44ffSToby Isaac .  x   - The coordinates
74594d6f44ffSToby Isaac .  Nf  - The number of fields
74604d6f44ffSToby Isaac .  u   - The output field values
74614d6f44ffSToby Isaac -  ctx - optional user-defined function context
74624d6f44ffSToby Isaac 
74634d6f44ffSToby Isaac   Level: developer
74644d6f44ffSToby Isaac 
74652716604bSToby Isaac .seealso: DMComputeL2Diff()
74664d6f44ffSToby Isaac @*/
74670709b2feSToby Isaac PetscErrorCode DMProjectFunction(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec X)
74684d6f44ffSToby Isaac {
74694d6f44ffSToby Isaac   Vec            localX;
74704d6f44ffSToby Isaac   PetscErrorCode ierr;
74714d6f44ffSToby Isaac 
74724d6f44ffSToby Isaac   PetscFunctionBegin;
74734d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
74744d6f44ffSToby Isaac   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
74750709b2feSToby Isaac   ierr = DMProjectFunctionLocal(dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
74764d6f44ffSToby Isaac   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
74774d6f44ffSToby Isaac   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
74784d6f44ffSToby Isaac   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
74794d6f44ffSToby Isaac   PetscFunctionReturn(0);
74804d6f44ffSToby Isaac }
74814d6f44ffSToby Isaac 
74820709b2feSToby Isaac PetscErrorCode DMProjectFunctionLocal(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, InsertMode mode, Vec localX)
74834d6f44ffSToby Isaac {
74844d6f44ffSToby Isaac   PetscErrorCode ierr;
74854d6f44ffSToby Isaac 
74864d6f44ffSToby Isaac   PetscFunctionBegin;
74874d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
74884d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
74890918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLocal",((PetscObject)dm)->type_name);
74900709b2feSToby Isaac   ierr = (dm->ops->projectfunctionlocal) (dm, time, funcs, ctxs, mode, localX);CHKERRQ(ierr);
74914d6f44ffSToby Isaac   PetscFunctionReturn(0);
74924d6f44ffSToby Isaac }
74934d6f44ffSToby Isaac 
74942c53366bSMatthew 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)
74952c53366bSMatthew G. Knepley {
74962c53366bSMatthew G. Knepley   Vec            localX;
74972c53366bSMatthew G. Knepley   PetscErrorCode ierr;
74982c53366bSMatthew G. Knepley 
74992c53366bSMatthew G. Knepley   PetscFunctionBegin;
75002c53366bSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
75012c53366bSMatthew G. Knepley   ierr = DMGetLocalVector(dm, &localX);CHKERRQ(ierr);
75022c53366bSMatthew G. Knepley   ierr = DMProjectFunctionLabelLocal(dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
75032c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalBegin(dm, localX, mode, X);CHKERRQ(ierr);
75042c53366bSMatthew G. Knepley   ierr = DMLocalToGlobalEnd(dm, localX, mode, X);CHKERRQ(ierr);
75052c53366bSMatthew G. Knepley   ierr = DMRestoreLocalVector(dm, &localX);CHKERRQ(ierr);
75062c53366bSMatthew G. Knepley   PetscFunctionReturn(0);
75072c53366bSMatthew G. Knepley }
75082c53366bSMatthew G. Knepley 
75091c531cf8SMatthew 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)
75104d6f44ffSToby Isaac {
75114d6f44ffSToby Isaac   PetscErrorCode ierr;
75124d6f44ffSToby Isaac 
75134d6f44ffSToby Isaac   PetscFunctionBegin;
75144d6f44ffSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75154d6f44ffSToby Isaac   PetscValidHeaderSpecific(localX,VEC_CLASSID,5);
75160918c465SMatthew G. Knepley   if (!dm->ops->projectfunctionlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFunctionLabelLocal",((PetscObject)dm)->type_name);
75171c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfunctionlabellocal) (dm, time, label, numIds, ids, Nc, comps, funcs, ctxs, mode, localX);CHKERRQ(ierr);
75184d6f44ffSToby Isaac   PetscFunctionReturn(0);
75194d6f44ffSToby Isaac }
75202716604bSToby Isaac 
75218c6c5593SMatthew G. Knepley PetscErrorCode DMProjectFieldLocal(DM dm, PetscReal time, Vec localU,
75228c6c5593SMatthew G. Knepley                                    void (**funcs)(PetscInt, PetscInt, PetscInt,
75238c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
75248c6c5593SMatthew G. Knepley                                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7525191494d9SMatthew G. Knepley                                                   PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
75268c6c5593SMatthew G. Knepley                                    InsertMode mode, Vec localX)
75278c6c5593SMatthew G. Knepley {
75288c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
75298c6c5593SMatthew G. Knepley 
75308c6c5593SMatthew G. Knepley   PetscFunctionBegin;
75318c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75328c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,3);
75338c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,6);
75340918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
75358c6c5593SMatthew G. Knepley   ierr = (dm->ops->projectfieldlocal) (dm, time, localU, funcs, mode, localX);CHKERRQ(ierr);
75368c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
75378c6c5593SMatthew G. Knepley }
75388c6c5593SMatthew G. Knepley 
75391c531cf8SMatthew G. Knepley PetscErrorCode DMProjectFieldLabelLocal(DM dm, PetscReal time, DMLabel label, PetscInt numIds, const PetscInt ids[], PetscInt Nc, const PetscInt comps[], Vec localU,
75408c6c5593SMatthew G. Knepley                                         void (**funcs)(PetscInt, PetscInt, PetscInt,
75418c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
75428c6c5593SMatthew G. Knepley                                                        const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
7543191494d9SMatthew G. Knepley                                                        PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]),
75448c6c5593SMatthew G. Knepley                                         InsertMode mode, Vec localX)
75458c6c5593SMatthew G. Knepley {
75468c6c5593SMatthew G. Knepley   PetscErrorCode ierr;
75478c6c5593SMatthew G. Knepley 
75488c6c5593SMatthew G. Knepley   PetscFunctionBegin;
75498c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75508c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localU,VEC_CLASSID,6);
75518c6c5593SMatthew G. Knepley   PetscValidHeaderSpecific(localX,VEC_CLASSID,9);
75520918c465SMatthew G. Knepley   if (!dm->ops->projectfieldlabellocal) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMProjectFieldLocal",((PetscObject)dm)->type_name);
75531c531cf8SMatthew G. Knepley   ierr = (dm->ops->projectfieldlabellocal)(dm, time, label, numIds, ids, Nc, comps, localU, funcs, mode, localX);CHKERRQ(ierr);
75548c6c5593SMatthew G. Knepley   PetscFunctionReturn(0);
75558c6c5593SMatthew G. Knepley }
75568c6c5593SMatthew G. Knepley 
75572716604bSToby Isaac /*@C
75582716604bSToby Isaac   DMComputeL2Diff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h.
75592716604bSToby Isaac 
75602716604bSToby Isaac   Input Parameters:
75612716604bSToby Isaac + dm    - The DM
75620709b2feSToby Isaac . time  - The time
75632716604bSToby Isaac . funcs - The functions to evaluate for each field component
75642716604bSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7565574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
75662716604bSToby Isaac 
75672716604bSToby Isaac   Output Parameter:
75682716604bSToby Isaac . diff - The diff ||u - u_h||_2
75692716604bSToby Isaac 
75702716604bSToby Isaac   Level: developer
75712716604bSToby Isaac 
75721189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
75732716604bSToby Isaac @*/
75740709b2feSToby Isaac PetscErrorCode DMComputeL2Diff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal *diff)
75752716604bSToby Isaac {
75762716604bSToby Isaac   PetscErrorCode ierr;
75772716604bSToby Isaac 
75782716604bSToby Isaac   PetscFunctionBegin;
75792716604bSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7580b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
75810918c465SMatthew G. Knepley   if (!dm->ops->computel2diff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2Diff",((PetscObject)dm)->type_name);
75820709b2feSToby Isaac   ierr = (dm->ops->computel2diff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
75832716604bSToby Isaac   PetscFunctionReturn(0);
75842716604bSToby Isaac }
7585b698f381SToby Isaac 
7586b698f381SToby Isaac /*@C
7587b698f381SToby Isaac   DMComputeL2GradientDiff - This function computes the L_2 difference between the gradient of a function u and an FEM interpolant solution grad u_h.
7588b698f381SToby Isaac 
7589d083f849SBarry Smith   Collective on dm
7590d083f849SBarry Smith 
7591b698f381SToby Isaac   Input Parameters:
7592b698f381SToby Isaac + dm    - The DM
7593b698f381SToby Isaac , time  - The time
7594b698f381SToby Isaac . funcs - The gradient functions to evaluate for each field component
7595b698f381SToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7596574a98acSMatthew G. Knepley . X     - The coefficient vector u_h, a global vector
7597b698f381SToby Isaac - n     - The vector to project along
7598b698f381SToby Isaac 
7599b698f381SToby Isaac   Output Parameter:
7600b698f381SToby Isaac . diff - The diff ||(grad u - grad u_h) . n||_2
7601b698f381SToby Isaac 
7602b698f381SToby Isaac   Level: developer
7603b698f381SToby Isaac 
7604b698f381SToby Isaac .seealso: DMProjectFunction(), DMComputeL2Diff()
7605b698f381SToby Isaac @*/
7606b698f381SToby 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)
7607b698f381SToby Isaac {
7608b698f381SToby Isaac   PetscErrorCode ierr;
7609b698f381SToby Isaac 
7610b698f381SToby Isaac   PetscFunctionBegin;
7611b698f381SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7612b698f381SToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
7613b698f381SToby Isaac   if (!dm->ops->computel2gradientdiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2GradientDiff",((PetscObject)dm)->type_name);
7614b698f381SToby Isaac   ierr = (dm->ops->computel2gradientdiff)(dm,time,funcs,ctxs,X,n,diff);CHKERRQ(ierr);
7615b698f381SToby Isaac   PetscFunctionReturn(0);
7616b698f381SToby Isaac }
7617b698f381SToby Isaac 
76182a16baeaSToby Isaac /*@C
76192a16baeaSToby Isaac   DMComputeL2FieldDiff - This function computes the L_2 difference between a function u and an FEM interpolant solution u_h, separated into field components.
76202a16baeaSToby Isaac 
7621d083f849SBarry Smith   Collective on dm
7622d083f849SBarry Smith 
76232a16baeaSToby Isaac   Input Parameters:
76242a16baeaSToby Isaac + dm    - The DM
76252a16baeaSToby Isaac . time  - The time
76262a16baeaSToby Isaac . funcs - The functions to evaluate for each field component
76272a16baeaSToby Isaac . ctxs  - Optional array of contexts to pass to each function, or NULL.
7628574a98acSMatthew G. Knepley - X     - The coefficient vector u_h, a global vector
76292a16baeaSToby Isaac 
76302a16baeaSToby Isaac   Output Parameter:
76312a16baeaSToby Isaac . diff - The array of differences, ||u^f - u^f_h||_2
76322a16baeaSToby Isaac 
76332a16baeaSToby Isaac   Level: developer
76342a16baeaSToby Isaac 
76351189c1efSToby Isaac .seealso: DMProjectFunction(), DMComputeL2FieldDiff(), DMComputeL2GradientDiff()
76362a16baeaSToby Isaac @*/
76371189c1efSToby Isaac PetscErrorCode DMComputeL2FieldDiff(DM dm, PetscReal time, PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **ctxs, Vec X, PetscReal diff[])
76382a16baeaSToby Isaac {
76392a16baeaSToby Isaac   PetscErrorCode ierr;
76402a16baeaSToby Isaac 
76412a16baeaSToby Isaac   PetscFunctionBegin;
76422a16baeaSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
76432a16baeaSToby Isaac   PetscValidHeaderSpecific(X,VEC_CLASSID,5);
76440918c465SMatthew G. Knepley   if (!dm->ops->computel2fielddiff) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMComputeL2FieldDiff",((PetscObject)dm)->type_name);
76452a16baeaSToby Isaac   ierr = (dm->ops->computel2fielddiff)(dm,time,funcs,ctxs,X,diff);CHKERRQ(ierr);
76462a16baeaSToby Isaac   PetscFunctionReturn(0);
76472a16baeaSToby Isaac }
76482a16baeaSToby Isaac 
7649df0b854cSToby Isaac /*@C
7650df0b854cSToby Isaac   DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags.  Specific implementations of DM maybe have
7651cd3c525cSToby Isaac                  specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN.
7652df0b854cSToby Isaac 
7653df0b854cSToby Isaac   Collective on dm
7654df0b854cSToby Isaac 
7655df0b854cSToby Isaac   Input parameters:
7656df0b854cSToby Isaac + dm - the pre-adaptation DM object
7657a1b0c543SToby Isaac - label - label with the flags
7658df0b854cSToby Isaac 
7659df0b854cSToby Isaac   Output parameters:
76600d1cd5e0SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced.
7661df0b854cSToby Isaac 
7662df0b854cSToby Isaac   Level: intermediate
76630d1cd5e0SMatthew G. Knepley 
76640d1cd5e0SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine()
7665df0b854cSToby Isaac @*/
76660d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt)
7667df0b854cSToby Isaac {
7668df0b854cSToby Isaac   PetscErrorCode ierr;
7669df0b854cSToby Isaac 
7670df0b854cSToby Isaac   PetscFunctionBegin;
7671df0b854cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7672a1b0c543SToby Isaac   PetscValidPointer(label,2);
76730d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt,3);
76740d1cd5e0SMatthew G. Knepley   *dmAdapt = NULL;
76756f25b0d8SLisandro Dalcin   if (!dm->ops->adaptlabel) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptLabel",((PetscObject)dm)->type_name);
76760d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptlabel)(dm, label, dmAdapt);CHKERRQ(ierr);
76770d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
76780d1cd5e0SMatthew G. Knepley }
76790d1cd5e0SMatthew G. Knepley 
76800d1cd5e0SMatthew G. Knepley /*@C
76810d1cd5e0SMatthew G. Knepley   DMAdaptMetric - Generates a mesh adapted to the specified metric field using the pragmatic library.
76820d1cd5e0SMatthew G. Knepley 
76830d1cd5e0SMatthew G. Knepley   Input Parameters:
76840d1cd5e0SMatthew G. Knepley + dm - The DM object
76850d1cd5e0SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise.
76866f25b0d8SLisandro 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_".
76870d1cd5e0SMatthew G. Knepley 
76880d1cd5e0SMatthew G. Knepley   Output Parameter:
76890d1cd5e0SMatthew G. Knepley . dmAdapt  - Pointer to the DM object containing the adapted mesh
76900d1cd5e0SMatthew G. Knepley 
76910d1cd5e0SMatthew G. Knepley   Note: The label in the adapted mesh will be registered under the name of the input DMLabel object
76920d1cd5e0SMatthew G. Knepley 
76930d1cd5e0SMatthew G. Knepley   Level: advanced
76940d1cd5e0SMatthew G. Knepley 
76950d1cd5e0SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine()
76960d1cd5e0SMatthew G. Knepley @*/
76970d1cd5e0SMatthew G. Knepley PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DM *dmAdapt)
76980d1cd5e0SMatthew G. Knepley {
76990d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
77000d1cd5e0SMatthew G. Knepley 
77010d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
77020d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77030d1cd5e0SMatthew G. Knepley   PetscValidHeaderSpecific(metric, VEC_CLASSID, 2);
77040d1cd5e0SMatthew G. Knepley   if (bdLabel) PetscValidPointer(bdLabel, 3);
77050d1cd5e0SMatthew G. Knepley   PetscValidPointer(dmAdapt, 4);
77066f25b0d8SLisandro Dalcin   *dmAdapt = NULL;
77076f25b0d8SLisandro Dalcin   if (!dm->ops->adaptmetric) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMAdaptMetric",((PetscObject)dm)->type_name);
77080d1cd5e0SMatthew G. Knepley   ierr = (dm->ops->adaptmetric)(dm, metric, bdLabel, dmAdapt);CHKERRQ(ierr);
7709df0b854cSToby Isaac   PetscFunctionReturn(0);
7710df0b854cSToby Isaac }
7711c4088d22SMatthew G. Knepley 
7712502a2867SDave May /*@C
7713502a2867SDave May  DMGetNeighbors - Gets an array containing the MPI rank of all the processes neighbors
7714502a2867SDave May 
7715502a2867SDave May  Not Collective
7716502a2867SDave May 
7717502a2867SDave May  Input Parameter:
7718502a2867SDave May  . dm    - The DM
7719502a2867SDave May 
7720502a2867SDave May  Output Parameter:
7721502a2867SDave May  . nranks - the number of neighbours
7722502a2867SDave May  . ranks - the neighbors ranks
7723502a2867SDave May 
7724502a2867SDave May  Notes:
7725502a2867SDave May  Do not free the array, it is freed when the DM is destroyed.
7726502a2867SDave May 
7727502a2867SDave May  Level: beginner
7728502a2867SDave May 
7729dee935c1SDave May  .seealso: DMDAGetNeighbors(), PetscSFGetRanks()
7730502a2867SDave May @*/
7731502a2867SDave May PetscErrorCode DMGetNeighbors(DM dm,PetscInt *nranks,const PetscMPIInt *ranks[])
7732502a2867SDave May {
7733502a2867SDave May   PetscErrorCode ierr;
7734502a2867SDave May 
7735502a2867SDave May   PetscFunctionBegin;
7736502a2867SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
77370918c465SMatthew G. Knepley   if (!dm->ops->getneighbors) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM type %s does not implement DMGetNeighbors",((PetscObject)dm)->type_name);
7738502a2867SDave May   ierr = (dm->ops->getneighbors)(dm,nranks,ranks);CHKERRQ(ierr);
7739502a2867SDave May   PetscFunctionReturn(0);
7740502a2867SDave May }
7741502a2867SDave May 
7742531c7667SBarry Smith #include <petsc/private/matimpl.h> /* Needed because of coloring->ctype below */
7743531c7667SBarry Smith 
7744531c7667SBarry Smith /*
7745531c7667SBarry Smith     Converts the input vector to a ghosted vector and then calls the standard coloring code.
7746531c7667SBarry Smith     This has be a different function because it requires DM which is not defined in the Mat library
7747531c7667SBarry Smith */
7748531c7667SBarry Smith PetscErrorCode  MatFDColoringApply_AIJDM(Mat J,MatFDColoring coloring,Vec x1,void *sctx)
7749531c7667SBarry Smith {
7750531c7667SBarry Smith   PetscErrorCode ierr;
7751531c7667SBarry Smith 
7752531c7667SBarry Smith   PetscFunctionBegin;
7753531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7754531c7667SBarry Smith     Vec x1local;
7755531c7667SBarry Smith     DM  dm;
7756531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
7757531c7667SBarry Smith     if (!dm) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_INCOMP,"IS_COLORING_LOCAL requires a DM");
7758531c7667SBarry Smith     ierr = DMGetLocalVector(dm,&x1local);CHKERRQ(ierr);
7759531c7667SBarry Smith     ierr = DMGlobalToLocalBegin(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
7760531c7667SBarry Smith     ierr = DMGlobalToLocalEnd(dm,x1,INSERT_VALUES,x1local);CHKERRQ(ierr);
7761531c7667SBarry Smith     x1   = x1local;
7762531c7667SBarry Smith   }
7763531c7667SBarry Smith   ierr = MatFDColoringApply_AIJ(J,coloring,x1,sctx);CHKERRQ(ierr);
7764531c7667SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
7765531c7667SBarry Smith     DM  dm;
7766531c7667SBarry Smith     ierr = MatGetDM(J,&dm);CHKERRQ(ierr);
7767531c7667SBarry Smith     ierr = DMRestoreLocalVector(dm,&x1);CHKERRQ(ierr);
7768531c7667SBarry Smith   }
7769531c7667SBarry Smith   PetscFunctionReturn(0);
7770531c7667SBarry Smith }
7771531c7667SBarry Smith 
7772531c7667SBarry Smith /*@
7773531c7667SBarry Smith     MatFDColoringUseDM - allows a MatFDColoring object to use the DM associated with the matrix to use a IS_COLORING_LOCAL coloring
7774531c7667SBarry Smith 
7775531c7667SBarry Smith     Input Parameter:
7776531c7667SBarry Smith .    coloring - the MatFDColoring object
7777531c7667SBarry Smith 
777895452b02SPatrick Sanan     Developer Notes:
777995452b02SPatrick Sanan     this routine exists because the PETSc Mat library does not know about the DM objects
7780531c7667SBarry Smith 
77811b266c99SBarry Smith     Level: advanced
77821b266c99SBarry Smith 
7783531c7667SBarry Smith .seealso: MatFDColoring, MatFDColoringCreate(), ISColoringType
7784531c7667SBarry Smith @*/
7785531c7667SBarry Smith PetscErrorCode  MatFDColoringUseDM(Mat coloring,MatFDColoring fdcoloring)
7786531c7667SBarry Smith {
7787531c7667SBarry Smith   PetscFunctionBegin;
7788531c7667SBarry Smith   coloring->ops->fdcoloringapply = MatFDColoringApply_AIJDM;
7789531c7667SBarry Smith   PetscFunctionReturn(0);
7790531c7667SBarry Smith }
77918320bc6fSPatrick Sanan 
77928320bc6fSPatrick Sanan /*@
77938320bc6fSPatrick Sanan     DMGetCompatibility - determine if two DMs are compatible
77948320bc6fSPatrick Sanan 
77958320bc6fSPatrick Sanan     Collective
77968320bc6fSPatrick Sanan 
77978320bc6fSPatrick Sanan     Input Parameters:
77988320bc6fSPatrick Sanan +    dm - the first DM
77998320bc6fSPatrick Sanan -    dm2 - the second DM
78008320bc6fSPatrick Sanan 
78018320bc6fSPatrick Sanan     Output Parameters:
78028320bc6fSPatrick Sanan +    compatible - whether or not the two DMs are compatible
78038320bc6fSPatrick Sanan -    set - whether or not the compatible value was set
78048320bc6fSPatrick Sanan 
78058320bc6fSPatrick Sanan     Notes:
78068320bc6fSPatrick Sanan     Two DMs are deemed compatible if they represent the same parallel decomposition
78073d862458SPatrick Sanan     of the same topology. This implies that the section (field data) on one
78088320bc6fSPatrick Sanan     "makes sense" with respect to the topology and parallel decomposition of the other.
78093d862458SPatrick Sanan     Loosely speaking, compatible DMs represent the same domain and parallel
78103d862458SPatrick Sanan     decomposition, but hold different data.
78118320bc6fSPatrick Sanan 
78128320bc6fSPatrick Sanan     Typically, one would confirm compatibility if intending to simultaneously iterate
78138320bc6fSPatrick Sanan     over a pair of vectors obtained from different DMs.
78148320bc6fSPatrick Sanan 
78158320bc6fSPatrick Sanan     For example, two DMDA objects are compatible if they have the same local
78168320bc6fSPatrick Sanan     and global sizes and the same stencil width. They can have different numbers
78178320bc6fSPatrick Sanan     of degrees of freedom per node. Thus, one could use the node numbering from
78188320bc6fSPatrick Sanan     either DM in bounds for a loop over vectors derived from either DM.
78198320bc6fSPatrick Sanan 
78208320bc6fSPatrick Sanan     Consider the operation of summing data living on a 2-dof DMDA to data living
78218320bc6fSPatrick Sanan     on a 1-dof DMDA, which should be compatible, as in the following snippet.
78228320bc6fSPatrick Sanan .vb
78238320bc6fSPatrick Sanan   ...
78248320bc6fSPatrick Sanan   ierr = DMGetCompatibility(da1,da2,&compatible,&set);CHKERRQ(ierr);
78258320bc6fSPatrick Sanan   if (set && compatible)  {
78268320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
78278320bc6fSPatrick Sanan     ierr = DMDAVecGetArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
78283d862458SPatrick Sanan     ierr = DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL);CHKERRQ(ierr);
78298320bc6fSPatrick Sanan     for (j=y; j<y+n; ++j) {
78308320bc6fSPatrick Sanan       for (i=x; i<x+m, ++i) {
78318320bc6fSPatrick Sanan         arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1];
78328320bc6fSPatrick Sanan       }
78338320bc6fSPatrick Sanan     }
78348320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da1,vec1,&arr1);CHKERRQ(ierr);
78358320bc6fSPatrick Sanan     ierr = DMDAVecRestoreArrayDOF(da2,vec2,&arr2);CHKERRQ(ierr);
78368320bc6fSPatrick Sanan   } else {
78378320bc6fSPatrick Sanan     SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible");
78388320bc6fSPatrick Sanan   }
78398320bc6fSPatrick Sanan   ...
78408320bc6fSPatrick Sanan .ve
78418320bc6fSPatrick Sanan 
78428320bc6fSPatrick Sanan     Checking compatibility might be expensive for a given implementation of DM,
78438320bc6fSPatrick Sanan     or might be impossible to unambiguously confirm or deny. For this reason,
78448320bc6fSPatrick Sanan     this function may decline to determine compatibility, and hence users should
78458320bc6fSPatrick Sanan     always check the "set" output parameter.
78468320bc6fSPatrick Sanan 
78478320bc6fSPatrick Sanan     A DM is always compatible with itself.
78488320bc6fSPatrick Sanan 
78498320bc6fSPatrick Sanan     In the current implementation, DMs which live on "unequal" communicators
78508320bc6fSPatrick Sanan     (MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed
78518320bc6fSPatrick Sanan     incompatible.
78528320bc6fSPatrick Sanan 
78538320bc6fSPatrick Sanan     This function is labeled "Collective," as information about all subdomains
78548320bc6fSPatrick Sanan     is required on each rank. However, in DM implementations which store all this
78558320bc6fSPatrick Sanan     information locally, this function may be merely "Logically Collective".
78568320bc6fSPatrick Sanan 
78578320bc6fSPatrick Sanan     Developer Notes:
78583d862458SPatrick Sanan     Compatibility is assumed to be a symmetric concept; DM A is compatible with DM B
78593d862458SPatrick Sanan     iff B is compatible with A. Thus, this function checks the implementations
78608320bc6fSPatrick Sanan     of both dm and dm2 (if they are of different types), attempting to determine
78618320bc6fSPatrick Sanan     compatibility. It is left to DM implementers to ensure that symmetry is
78628320bc6fSPatrick Sanan     preserved. The simplest way to do this is, when implementing type-specific
78633d862458SPatrick Sanan     logic for this function, is to check for existing logic in the implementation
78643d862458SPatrick Sanan     of other DM types and let *set = PETSC_FALSE if found.
78658320bc6fSPatrick Sanan 
78668320bc6fSPatrick Sanan     Level: advanced
78678320bc6fSPatrick Sanan 
78683d862458SPatrick Sanan .seealso: DM, DMDACreateCompatibleDMDA(), DMStagCreateCompatibleDMStag()
78698320bc6fSPatrick Sanan @*/
78708320bc6fSPatrick Sanan 
78718320bc6fSPatrick Sanan PetscErrorCode DMGetCompatibility(DM dm,DM dm2,PetscBool *compatible,PetscBool *set)
78728320bc6fSPatrick Sanan {
78738320bc6fSPatrick Sanan   PetscErrorCode ierr;
78748320bc6fSPatrick Sanan   PetscMPIInt    compareResult;
78758320bc6fSPatrick Sanan   DMType         type,type2;
78768320bc6fSPatrick Sanan   PetscBool      sameType;
78778320bc6fSPatrick Sanan 
78788320bc6fSPatrick Sanan   PetscFunctionBegin;
78798320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
78808320bc6fSPatrick Sanan   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
78818320bc6fSPatrick Sanan 
78828320bc6fSPatrick Sanan   /* Declare a DM compatible with itself */
78838320bc6fSPatrick Sanan   if (dm == dm2) {
78848320bc6fSPatrick Sanan     *set = PETSC_TRUE;
78858320bc6fSPatrick Sanan     *compatible = PETSC_TRUE;
78868320bc6fSPatrick Sanan     PetscFunctionReturn(0);
78878320bc6fSPatrick Sanan   }
78888320bc6fSPatrick Sanan 
78898320bc6fSPatrick Sanan   /* Declare a DM incompatible with a DM that lives on an "unequal"
78908320bc6fSPatrick Sanan      communicator. Note that this does not preclude compatibility with
78918320bc6fSPatrick Sanan      DMs living on "congruent" or "similar" communicators, but this must be
78928320bc6fSPatrick Sanan      determined by the implementation-specific logic */
78938320bc6fSPatrick Sanan   ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)dm),PetscObjectComm((PetscObject)dm2),&compareResult);CHKERRQ(ierr);
78948320bc6fSPatrick Sanan   if (compareResult == MPI_UNEQUAL) {
78958320bc6fSPatrick Sanan     *set = PETSC_TRUE;
78968320bc6fSPatrick Sanan     *compatible = PETSC_FALSE;
78978320bc6fSPatrick Sanan     PetscFunctionReturn(0);
78988320bc6fSPatrick Sanan   }
78998320bc6fSPatrick Sanan 
79008320bc6fSPatrick Sanan   /* Pass to the implementation-specific routine, if one exists. */
79018320bc6fSPatrick Sanan   if (dm->ops->getcompatibility) {
79028320bc6fSPatrick Sanan     ierr = (*dm->ops->getcompatibility)(dm,dm2,compatible,set);CHKERRQ(ierr);
7903b9d85ea2SLisandro Dalcin     if (*set) PetscFunctionReturn(0);
79048320bc6fSPatrick Sanan   }
79058320bc6fSPatrick Sanan 
79068320bc6fSPatrick Sanan   /* If dm and dm2 are of different types, then attempt to check compatibility
79078320bc6fSPatrick Sanan      with an implementation of this function from dm2 */
79088320bc6fSPatrick Sanan   ierr = DMGetType(dm,&type);CHKERRQ(ierr);
79098320bc6fSPatrick Sanan   ierr = DMGetType(dm2,&type2);CHKERRQ(ierr);
79108320bc6fSPatrick Sanan   ierr = PetscStrcmp(type,type2,&sameType);CHKERRQ(ierr);
79118320bc6fSPatrick Sanan   if (!sameType && dm2->ops->getcompatibility) {
79128320bc6fSPatrick Sanan     ierr = (*dm2->ops->getcompatibility)(dm2,dm,compatible,set);CHKERRQ(ierr); /* Note argument order */
79138320bc6fSPatrick Sanan   } else {
79148320bc6fSPatrick Sanan     *set = PETSC_FALSE;
79158320bc6fSPatrick Sanan   }
79168320bc6fSPatrick Sanan   PetscFunctionReturn(0);
79178320bc6fSPatrick Sanan }
7918