xref: /petsc/src/dm/interface/dm.c (revision c58f1c226d931c4a5e770c4500cd78d45092fdba)
1af0996ceSBarry Smith #include <petsc/private/dmimpl.h>           /*I      "petscdm.h"          I*/
2*c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h>      /*I      "petscdmlabel.h"     I*/
30c312b8eSJed Brown #include <petscsf.h>
42764a2aaSMatthew G. Knepley #include <petscds.h>
547c6ae99SBarry Smith 
6732e2eb9SMatthew G Knepley PetscClassId  DM_CLASSID;
7cea54e9dSPatrick Farrell PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal, DM_LocatePoints, DM_Coarsen, DM_CreateInterpolation;
867a56275SMatthew G Knepley 
9bff4a2f0SMatthew G. Knepley const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DM_BOUNDARY_",0};
10bff4a2f0SMatthew G. Knepley 
1147c6ae99SBarry Smith #undef __FUNCT__
12a4121054SBarry Smith #define __FUNCT__ "DMCreate"
13a4121054SBarry Smith /*@
14de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
15a4121054SBarry Smith 
16a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
17a4121054SBarry Smith    error when you try to use the vector.
18a4121054SBarry Smith 
19a4121054SBarry Smith   Collective on MPI_Comm
20a4121054SBarry Smith 
21a4121054SBarry Smith   Input Parameter:
22a4121054SBarry Smith . comm - The communicator for the DM object
23a4121054SBarry Smith 
24a4121054SBarry Smith   Output Parameter:
25a4121054SBarry Smith . dm - The DM object
26a4121054SBarry Smith 
27a4121054SBarry Smith   Level: beginner
28a4121054SBarry Smith 
298472ad0fSDave May .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE, DMPLEX, DMMOAB, DMNETWORK
30a4121054SBarry Smith @*/
317087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
32a4121054SBarry Smith {
33a4121054SBarry Smith   DM             v;
34a4121054SBarry Smith   PetscErrorCode ierr;
35a4121054SBarry Smith 
36a4121054SBarry Smith   PetscFunctionBegin;
371411c6eeSJed Brown   PetscValidPointer(dm,2);
380298fd71SBarry Smith   *dm = NULL;
398b984314SMatthew G. Knepley   ierr = PetscSysInitializePackage();CHKERRQ(ierr);
40607a6623SBarry Smith   ierr = VecInitializePackage();CHKERRQ(ierr);
41607a6623SBarry Smith   ierr = MatInitializePackage();CHKERRQ(ierr);
42607a6623SBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
43a4121054SBarry Smith 
4473107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(v, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
45e7c4fc90SDmitry Karpeev 
460298fd71SBarry Smith   v->ltogmap                  = NULL;
471411c6eeSJed Brown   v->bs                       = 1;
48171400e9SBarry Smith   v->coloringtype             = IS_COLORING_GLOBAL;
4988ed4aceSMatthew G Knepley   ierr                        = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
5088ed4aceSMatthew G Knepley   ierr                        = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
51*c58f1c22SToby Isaac   v->labels                   = NULL;
52*c58f1c22SToby Isaac   v->depthLabel               = NULL;
530298fd71SBarry Smith   v->defaultSection           = NULL;
540298fd71SBarry Smith   v->defaultGlobalSection     = NULL;
55fba222abSToby Isaac   v->defaultConstraintSection = NULL;
56fba222abSToby Isaac   v->defaultConstraintMat     = NULL;
57c6b900c6SMatthew G. Knepley   v->L                        = NULL;
58c6b900c6SMatthew G. Knepley   v->maxCell                  = NULL;
595dc8c3f7SMatthew G. Knepley   v->bdtype                   = NULL;
609a9a41abSToby Isaac   v->dimEmbed                 = PETSC_DEFAULT;
61435a35e8SMatthew G Knepley   {
62435a35e8SMatthew G Knepley     PetscInt i;
63435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
640298fd71SBarry Smith       v->nullspaceConstructors[i] = NULL;
65435a35e8SMatthew G Knepley     }
66435a35e8SMatthew G Knepley   }
672764a2aaSMatthew G. Knepley   ierr = PetscDSCreate(comm, &v->prob);CHKERRQ(ierr);
6814f150ffSMatthew G. Knepley   v->dmBC = NULL;
69f4d763aaSMatthew G. Knepley   v->outputSequenceNum = -1;
70cdb7a50dSMatthew G. Knepley   v->outputSequenceVal = 0.0;
71c0dedaeaSBarry Smith   ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr);
72b412c318SBarry Smith   ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr);
73*c58f1c22SToby Isaac   ierr = PetscCalloc1(1,&(v->labels));CHKERRQ(ierr);
74*c58f1c22SToby Isaac   v->labels->refct = 1;
751411c6eeSJed Brown   *dm = v;
76a4121054SBarry Smith   PetscFunctionReturn(0);
77a4121054SBarry Smith }
78a4121054SBarry Smith 
79a4121054SBarry Smith #undef __FUNCT__
8038221697SMatthew G. Knepley #define __FUNCT__ "DMClone"
8138221697SMatthew G. Knepley /*@
8238221697SMatthew G. Knepley   DMClone - Creates a DM object with the same topology as the original.
8338221697SMatthew G. Knepley 
8438221697SMatthew G. Knepley   Collective on MPI_Comm
8538221697SMatthew G. Knepley 
8638221697SMatthew G. Knepley   Input Parameter:
8738221697SMatthew G. Knepley . dm - The original DM object
8838221697SMatthew G. Knepley 
8938221697SMatthew G. Knepley   Output Parameter:
9038221697SMatthew G. Knepley . newdm  - The new DM object
9138221697SMatthew G. Knepley 
9238221697SMatthew G. Knepley   Level: beginner
9338221697SMatthew G. Knepley 
9438221697SMatthew G. Knepley .keywords: DM, topology, create
9538221697SMatthew G. Knepley @*/
9638221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm)
9738221697SMatthew G. Knepley {
9838221697SMatthew G. Knepley   PetscSF        sf;
9938221697SMatthew G. Knepley   Vec            coords;
10038221697SMatthew G. Knepley   void          *ctx;
1011de53e9aSMatthew G. Knepley   PetscInt       dim;
10238221697SMatthew G. Knepley   PetscErrorCode ierr;
10338221697SMatthew G. Knepley 
10438221697SMatthew G. Knepley   PetscFunctionBegin;
10538221697SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10638221697SMatthew G. Knepley   PetscValidPointer(newdm,2);
10738221697SMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), newdm);CHKERRQ(ierr);
108*c58f1c22SToby Isaac   ierr = PetscFree((*newdm)->labels);CHKERRQ(ierr);
109*c58f1c22SToby Isaac   dm->labels->refct++;
110*c58f1c22SToby Isaac   (*newdm)->labels = dm->labels;
111*c58f1c22SToby Isaac   (*newdm)->depthLabel = dm->depthLabel;
1121de53e9aSMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
1131de53e9aSMatthew G. Knepley   ierr = DMSetDimension(*newdm, dim);CHKERRQ(ierr);
11438221697SMatthew G. Knepley   if (dm->ops->clone) {
11538221697SMatthew G. Knepley     ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr);
11638221697SMatthew G. Knepley   }
117cd27c7c9SMatthew G. Knepley   (*newdm)->setupcalled = PETSC_TRUE;
11838221697SMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
11938221697SMatthew G. Knepley   ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr);
12038221697SMatthew G. Knepley   ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr);
12138221697SMatthew G. Knepley   ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr);
12238221697SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr);
12338221697SMatthew G. Knepley   if (coords) {
12438221697SMatthew G. Knepley     ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr);
12538221697SMatthew G. Knepley   } else {
12638221697SMatthew G. Knepley     ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr);
12738221697SMatthew G. Knepley     if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);}
12838221697SMatthew G. Knepley   }
129c6b900c6SMatthew G. Knepley   if (dm->maxCell) {
130c6b900c6SMatthew G. Knepley     const PetscReal *maxCell, *L;
1315dc8c3f7SMatthew G. Knepley     const DMBoundaryType *bd;
1325dc8c3f7SMatthew G. Knepley     ierr = DMGetPeriodicity(dm,     &maxCell, &L, &bd);CHKERRQ(ierr);
1335dc8c3f7SMatthew G. Knepley     ierr = DMSetPeriodicity(*newdm,  maxCell,  L,  bd);CHKERRQ(ierr);
134c6b900c6SMatthew G. Knepley   }
13538221697SMatthew G. Knepley   PetscFunctionReturn(0);
13638221697SMatthew G. Knepley }
13738221697SMatthew G. Knepley 
13838221697SMatthew G. Knepley #undef __FUNCT__
1399a42bb27SBarry Smith #define __FUNCT__ "DMSetVecType"
1409a42bb27SBarry Smith /*@C
141564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
1429a42bb27SBarry Smith 
1438472ad0fSDave May    Logically Collective on DM
1449a42bb27SBarry Smith 
1459a42bb27SBarry Smith    Input Parameter:
1469a42bb27SBarry Smith +  da - initial distributed array
1478154be41SBarry Smith .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
1489a42bb27SBarry Smith 
1499a42bb27SBarry Smith    Options Database:
150dd85299cSBarry Smith .   -dm_vec_type ctype
1519a42bb27SBarry Smith 
1529a42bb27SBarry Smith    Level: intermediate
1539a42bb27SBarry Smith 
1548472ad0fSDave May .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType, DMGetVecType()
1559a42bb27SBarry Smith @*/
15619fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
1579a42bb27SBarry Smith {
1589a42bb27SBarry Smith   PetscErrorCode ierr;
1599a42bb27SBarry Smith 
1609a42bb27SBarry Smith   PetscFunctionBegin;
1619a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
1629a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
16319fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
1649a42bb27SBarry Smith   PetscFunctionReturn(0);
1659a42bb27SBarry Smith }
1669a42bb27SBarry Smith 
1679a42bb27SBarry Smith #undef __FUNCT__
168c0dedaeaSBarry Smith #define __FUNCT__ "DMGetVecType"
169c0dedaeaSBarry Smith /*@C
170c0dedaeaSBarry Smith        DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
171c0dedaeaSBarry Smith 
1728472ad0fSDave May    Logically Collective on DM
173c0dedaeaSBarry Smith 
174c0dedaeaSBarry Smith    Input Parameter:
175c0dedaeaSBarry Smith .  da - initial distributed array
176c0dedaeaSBarry Smith 
177c0dedaeaSBarry Smith    Output Parameter:
178c0dedaeaSBarry Smith .  ctype - the vector type
179c0dedaeaSBarry Smith 
180c0dedaeaSBarry Smith    Level: intermediate
181c0dedaeaSBarry Smith 
1828472ad0fSDave May .seealso: DMCreate(), DMDestroy(), DM, DMDAInterpolationType, VecType
183c0dedaeaSBarry Smith @*/
184c0dedaeaSBarry Smith PetscErrorCode  DMGetVecType(DM da,VecType *ctype)
185c0dedaeaSBarry Smith {
186c0dedaeaSBarry Smith   PetscFunctionBegin;
187c0dedaeaSBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
188c0dedaeaSBarry Smith   *ctype = da->vectype;
189c0dedaeaSBarry Smith   PetscFunctionReturn(0);
190c0dedaeaSBarry Smith }
191c0dedaeaSBarry Smith 
192c0dedaeaSBarry Smith #undef __FUNCT__
1935f1ad066SMatthew G Knepley #define __FUNCT__ "VecGetDM"
1945f1ad066SMatthew G Knepley /*@
19534f98d34SBarry Smith   VecGetDM - Gets the DM defining the data layout of the vector
1965f1ad066SMatthew G Knepley 
1975f1ad066SMatthew G Knepley   Not collective
1985f1ad066SMatthew G Knepley 
1995f1ad066SMatthew G Knepley   Input Parameter:
2005f1ad066SMatthew G Knepley . v - The Vec
2015f1ad066SMatthew G Knepley 
2025f1ad066SMatthew G Knepley   Output Parameter:
2035f1ad066SMatthew G Knepley . dm - The DM
2045f1ad066SMatthew G Knepley 
2055f1ad066SMatthew G Knepley   Level: intermediate
2065f1ad066SMatthew G Knepley 
2075f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2085f1ad066SMatthew G Knepley @*/
2095f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm)
2105f1ad066SMatthew G Knepley {
2115f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2125f1ad066SMatthew G Knepley 
2135f1ad066SMatthew G Knepley   PetscFunctionBegin;
2145f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
2155f1ad066SMatthew G Knepley   PetscValidPointer(dm,2);
2165f1ad066SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
2175f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2185f1ad066SMatthew G Knepley }
2195f1ad066SMatthew G Knepley 
2205f1ad066SMatthew G Knepley #undef __FUNCT__
2215f1ad066SMatthew G Knepley #define __FUNCT__ "VecSetDM"
2225f1ad066SMatthew G Knepley /*@
223d9805387SMatthew G. Knepley   VecSetDM - Sets the DM defining the data layout of the vector.
2245f1ad066SMatthew G Knepley 
2255f1ad066SMatthew G Knepley   Not collective
2265f1ad066SMatthew G Knepley 
2275f1ad066SMatthew G Knepley   Input Parameters:
2285f1ad066SMatthew G Knepley + v - The Vec
2295f1ad066SMatthew G Knepley - dm - The DM
2305f1ad066SMatthew G Knepley 
231d9805387SMatthew 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.
232d9805387SMatthew G. Knepley 
2335f1ad066SMatthew G Knepley   Level: intermediate
2345f1ad066SMatthew G Knepley 
2355f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2365f1ad066SMatthew G Knepley @*/
2375f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm)
2385f1ad066SMatthew G Knepley {
2395f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2405f1ad066SMatthew G Knepley 
2415f1ad066SMatthew G Knepley   PetscFunctionBegin;
2425f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
243d7f50e27SLisandro Dalcin   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
2445f1ad066SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
2455f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2465f1ad066SMatthew G Knepley }
2475f1ad066SMatthew G Knepley 
2485f1ad066SMatthew G Knepley #undef __FUNCT__
249521d9a4cSLisandro Dalcin #define __FUNCT__ "DMSetMatType"
250521d9a4cSLisandro Dalcin /*@C
251521d9a4cSLisandro Dalcin        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
252521d9a4cSLisandro Dalcin 
253521d9a4cSLisandro Dalcin    Logically Collective on DM
254521d9a4cSLisandro Dalcin 
255521d9a4cSLisandro Dalcin    Input Parameter:
256521d9a4cSLisandro Dalcin +  dm - the DM context
257521d9a4cSLisandro Dalcin .  ctype - the matrix type
258521d9a4cSLisandro Dalcin 
259521d9a4cSLisandro Dalcin    Options Database:
260521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
261521d9a4cSLisandro Dalcin 
262521d9a4cSLisandro Dalcin    Level: intermediate
263521d9a4cSLisandro Dalcin 
264c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType()
265521d9a4cSLisandro Dalcin @*/
26619fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
267521d9a4cSLisandro Dalcin {
268521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
26988f0584fSBarry Smith 
270521d9a4cSLisandro Dalcin   PetscFunctionBegin;
271521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
272521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
27319fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
274521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
275521d9a4cSLisandro Dalcin }
276521d9a4cSLisandro Dalcin 
277521d9a4cSLisandro Dalcin #undef __FUNCT__
278c0dedaeaSBarry Smith #define __FUNCT__ "DMGetMatType"
279c0dedaeaSBarry Smith /*@C
280c0dedaeaSBarry Smith        DMGetMatType - Gets the type of matrix created with DMCreateMatrix()
281c0dedaeaSBarry Smith 
282c0dedaeaSBarry Smith    Logically Collective on DM
283c0dedaeaSBarry Smith 
284c0dedaeaSBarry Smith    Input Parameter:
285c0dedaeaSBarry Smith .  dm - the DM context
286c0dedaeaSBarry Smith 
287c0dedaeaSBarry Smith    Output Parameter:
288c0dedaeaSBarry Smith .  ctype - the matrix type
289c0dedaeaSBarry Smith 
290c0dedaeaSBarry Smith    Options Database:
291c0dedaeaSBarry Smith .   -dm_mat_type ctype
292c0dedaeaSBarry Smith 
293c0dedaeaSBarry Smith    Level: intermediate
294c0dedaeaSBarry Smith 
295c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType()
296c0dedaeaSBarry Smith @*/
297c0dedaeaSBarry Smith PetscErrorCode  DMGetMatType(DM dm,MatType *ctype)
298c0dedaeaSBarry Smith {
299c0dedaeaSBarry Smith   PetscFunctionBegin;
300c0dedaeaSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
301c0dedaeaSBarry Smith   *ctype = dm->mattype;
302c0dedaeaSBarry Smith   PetscFunctionReturn(0);
303c0dedaeaSBarry Smith }
304c0dedaeaSBarry Smith 
305c0dedaeaSBarry Smith #undef __FUNCT__
306c688c046SMatthew G Knepley #define __FUNCT__ "MatGetDM"
307c688c046SMatthew G Knepley /*@
30834f98d34SBarry Smith   MatGetDM - Gets the DM defining the data layout of the matrix
309c688c046SMatthew G Knepley 
310c688c046SMatthew G Knepley   Not collective
311c688c046SMatthew G Knepley 
312c688c046SMatthew G Knepley   Input Parameter:
313c688c046SMatthew G Knepley . A - The Mat
314c688c046SMatthew G Knepley 
315c688c046SMatthew G Knepley   Output Parameter:
316c688c046SMatthew G Knepley . dm - The DM
317c688c046SMatthew G Knepley 
318c688c046SMatthew G Knepley   Level: intermediate
319c688c046SMatthew G Knepley 
320c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType()
321c688c046SMatthew G Knepley @*/
322c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm)
323c688c046SMatthew G Knepley {
324c688c046SMatthew G Knepley   PetscErrorCode ierr;
325c688c046SMatthew G Knepley 
326c688c046SMatthew G Knepley   PetscFunctionBegin;
327c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
328c688c046SMatthew G Knepley   PetscValidPointer(dm,2);
329c688c046SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
330c688c046SMatthew G Knepley   PetscFunctionReturn(0);
331c688c046SMatthew G Knepley }
332c688c046SMatthew G Knepley 
333c688c046SMatthew G Knepley #undef __FUNCT__
334c688c046SMatthew G Knepley #define __FUNCT__ "MatSetDM"
335c688c046SMatthew G Knepley /*@
336c688c046SMatthew G Knepley   MatSetDM - Sets the DM defining the data layout of the matrix
337c688c046SMatthew G Knepley 
338c688c046SMatthew G Knepley   Not collective
339c688c046SMatthew G Knepley 
340c688c046SMatthew G Knepley   Input Parameters:
341c688c046SMatthew G Knepley + A - The Mat
342c688c046SMatthew G Knepley - dm - The DM
343c688c046SMatthew G Knepley 
344c688c046SMatthew G Knepley   Level: intermediate
345c688c046SMatthew G Knepley 
346c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType()
347c688c046SMatthew G Knepley @*/
348c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm)
349c688c046SMatthew G Knepley {
350c688c046SMatthew G Knepley   PetscErrorCode ierr;
351c688c046SMatthew G Knepley 
352c688c046SMatthew G Knepley   PetscFunctionBegin;
353c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3548865f1eaSKarl Rupp   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
355c688c046SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
356c688c046SMatthew G Knepley   PetscFunctionReturn(0);
357c688c046SMatthew G Knepley }
358c688c046SMatthew G Knepley 
359c688c046SMatthew G Knepley #undef __FUNCT__
3609a42bb27SBarry Smith #define __FUNCT__ "DMSetOptionsPrefix"
3619a42bb27SBarry Smith /*@C
3629a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
3636757b960SDave May    DM options in the database.
3649a42bb27SBarry Smith 
3658353ddbbSDave May    Logically Collective on DM
3669a42bb27SBarry Smith 
3679a42bb27SBarry Smith    Input Parameter:
3688353ddbbSDave May +  da - the DM context
3699a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
3709a42bb27SBarry Smith 
3719a42bb27SBarry Smith    Notes:
3729a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
3739a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
3749a42bb27SBarry Smith 
3759a42bb27SBarry Smith    Level: advanced
3769a42bb27SBarry Smith 
3778353ddbbSDave May .keywords: DM, set, options, prefix, database
3789a42bb27SBarry Smith 
3799a42bb27SBarry Smith .seealso: DMSetFromOptions()
3809a42bb27SBarry Smith @*/
3817087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
3829a42bb27SBarry Smith {
3839a42bb27SBarry Smith   PetscErrorCode ierr;
3849a42bb27SBarry Smith 
3859a42bb27SBarry Smith   PetscFunctionBegin;
3869a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3879a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
388691be533SLawrence Mitchell   if (dm->sf) {
389691be533SLawrence Mitchell     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->sf,prefix);CHKERRQ(ierr);
390691be533SLawrence Mitchell   }
391691be533SLawrence Mitchell   if (dm->defaultSF) {
392691be533SLawrence Mitchell     ierr = PetscObjectSetOptionsPrefix((PetscObject)dm->defaultSF,prefix);CHKERRQ(ierr);
393691be533SLawrence Mitchell   }
3949a42bb27SBarry Smith   PetscFunctionReturn(0);
3959a42bb27SBarry Smith }
3969a42bb27SBarry Smith 
3979a42bb27SBarry Smith #undef __FUNCT__
39831697293SDave May #define __FUNCT__ "DMAppendOptionsPrefix"
39931697293SDave May /*@C
40031697293SDave May    DMAppendOptionsPrefix - Appends to the prefix used for searching for all
40131697293SDave May    DM options in the database.
40231697293SDave May 
40331697293SDave May    Logically Collective on DM
40431697293SDave May 
40531697293SDave May    Input Parameters:
40631697293SDave May +  dm - the DM context
40731697293SDave May -  prefix - the prefix string to prepend to all DM option requests
40831697293SDave May 
40931697293SDave May    Notes:
41031697293SDave May    A hyphen (-) must NOT be given at the beginning of the prefix name.
41131697293SDave May    The first character of all runtime options is AUTOMATICALLY the hyphen.
41231697293SDave May 
41331697293SDave May    Level: advanced
41431697293SDave May 
41531697293SDave May .keywords: DM, append, options, prefix, database
41631697293SDave May 
41731697293SDave May .seealso: DMSetOptionsPrefix(), DMGetOptionsPrefix()
41831697293SDave May @*/
41931697293SDave May PetscErrorCode  DMAppendOptionsPrefix(DM dm,const char prefix[])
42031697293SDave May {
42131697293SDave May   PetscErrorCode ierr;
42231697293SDave May 
42331697293SDave May   PetscFunctionBegin;
42431697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
42531697293SDave May   ierr = PetscObjectAppendOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
42631697293SDave May   PetscFunctionReturn(0);
42731697293SDave May }
42831697293SDave May 
42931697293SDave May #undef __FUNCT__
43031697293SDave May #define __FUNCT__ "DMGetOptionsPrefix"
43131697293SDave May /*@C
43231697293SDave May    DMGetOptionsPrefix - Gets the prefix used for searching for all
43331697293SDave May    DM options in the database.
43431697293SDave May 
43531697293SDave May    Not Collective
43631697293SDave May 
43731697293SDave May    Input Parameters:
43831697293SDave May .  dm - the DM context
43931697293SDave May 
44031697293SDave May    Output Parameters:
44131697293SDave May .  prefix - pointer to the prefix string used is returned
44231697293SDave May 
44331697293SDave May    Notes: On the fortran side, the user should pass in a string 'prefix' of
44431697293SDave May    sufficient length to hold the prefix.
44531697293SDave May 
44631697293SDave May    Level: advanced
44731697293SDave May 
44831697293SDave May .keywords: DM, set, options, prefix, database
44931697293SDave May 
45031697293SDave May .seealso: DMSetOptionsPrefix(), DMAppendOptionsPrefix()
45131697293SDave May @*/
45231697293SDave May PetscErrorCode  DMGetOptionsPrefix(DM dm,const char *prefix[])
45331697293SDave May {
45431697293SDave May   PetscErrorCode ierr;
45531697293SDave May 
45631697293SDave May   PetscFunctionBegin;
45731697293SDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
45831697293SDave May   ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
45931697293SDave May   PetscFunctionReturn(0);
46031697293SDave May }
46131697293SDave May 
46231697293SDave May #undef __FUNCT__
46347c6ae99SBarry Smith #define __FUNCT__ "DMDestroy"
46447c6ae99SBarry Smith /*@
4658472ad0fSDave May     DMDestroy - Destroys a vector packer or DM.
46647c6ae99SBarry Smith 
46747c6ae99SBarry Smith     Collective on DM
46847c6ae99SBarry Smith 
46947c6ae99SBarry Smith     Input Parameter:
47047c6ae99SBarry Smith .   dm - the DM object to destroy
47147c6ae99SBarry Smith 
47247c6ae99SBarry Smith     Level: developer
47347c6ae99SBarry Smith 
474e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
47547c6ae99SBarry Smith 
47647c6ae99SBarry Smith @*/
477fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
47847c6ae99SBarry Smith {
479c83e3748SMatthew G. Knepley   PetscInt       i, cnt = 0;
480dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
48147c6ae99SBarry Smith   PetscErrorCode ierr;
48247c6ae99SBarry Smith 
48347c6ae99SBarry Smith   PetscFunctionBegin;
4846bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
4856bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
48687e657c6SBarry Smith 
48787e657c6SBarry Smith   /* count all the circular references of DM and its contained Vecs */
488732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
4898865f1eaSKarl Rupp     if ((*dm)->localin[i])  cnt++;
4908865f1eaSKarl Rupp     if ((*dm)->globalin[i]) cnt++;
491732e2eb9SMatthew G Knepley   }
492dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++;
4932348bcf4SPeter Brune   for (nlink=(*dm)->namedlocal; nlink; nlink=nlink->next) cnt++;
4942348bcf4SPeter Brune   if ((*dm)->x) {
4952348bcf4SPeter Brune     DM obj;
4962348bcf4SPeter Brune     ierr = VecGetDM((*dm)->x, &obj);CHKERRQ(ierr);
4972348bcf4SPeter Brune     if (obj == *dm) cnt++;
4982348bcf4SPeter Brune   }
499732e2eb9SMatthew G Knepley 
5006bf464f9SBarry Smith   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
501732e2eb9SMatthew G Knepley   /*
502732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
503732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
504732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
505732e2eb9SMatthew G Knepley   */
5066bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
5076bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
508732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
5096bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
5106bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
511732e2eb9SMatthew G Knepley   }
512f490541aSPeter Brune   nnext=(*dm)->namedglobal;
5130298fd71SBarry Smith   (*dm)->namedglobal = NULL;
514f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */
5152348bcf4SPeter Brune     nnext = nlink->next;
5162348bcf4SPeter 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);
5172348bcf4SPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
5182348bcf4SPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
5192348bcf4SPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
5202348bcf4SPeter Brune   }
521f490541aSPeter Brune   nnext=(*dm)->namedlocal;
5220298fd71SBarry Smith   (*dm)->namedlocal = NULL;
523f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */
524f490541aSPeter Brune     nnext = nlink->next;
525f490541aSPeter 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);
526f490541aSPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
527f490541aSPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
528f490541aSPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
529f490541aSPeter Brune   }
5302348bcf4SPeter Brune 
531b17ce1afSJed Brown   /* Destroy the list of hooks */
532c833c3b5SJed Brown   {
533c833c3b5SJed Brown     DMCoarsenHookLink link,next;
534b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
535b17ce1afSJed Brown       next = link->next;
536b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
537b17ce1afSJed Brown     }
5380298fd71SBarry Smith     (*dm)->coarsenhook = NULL;
539c833c3b5SJed Brown   }
540c833c3b5SJed Brown   {
541c833c3b5SJed Brown     DMRefineHookLink link,next;
542c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
543c833c3b5SJed Brown       next = link->next;
544c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
545c833c3b5SJed Brown     }
5460298fd71SBarry Smith     (*dm)->refinehook = NULL;
547c833c3b5SJed Brown   }
548be081cd6SPeter Brune   {
549be081cd6SPeter Brune     DMSubDomainHookLink link,next;
550be081cd6SPeter Brune     for (link=(*dm)->subdomainhook; link; link=next) {
551be081cd6SPeter Brune       next = link->next;
552be081cd6SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
553be081cd6SPeter Brune     }
5540298fd71SBarry Smith     (*dm)->subdomainhook = NULL;
555be081cd6SPeter Brune   }
556baf369e7SPeter Brune   {
557baf369e7SPeter Brune     DMGlobalToLocalHookLink link,next;
558baf369e7SPeter Brune     for (link=(*dm)->gtolhook; link; link=next) {
559baf369e7SPeter Brune       next = link->next;
560baf369e7SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
561baf369e7SPeter Brune     }
5620298fd71SBarry Smith     (*dm)->gtolhook = NULL;
563baf369e7SPeter Brune   }
564d4d07f1eSToby Isaac   {
565d4d07f1eSToby Isaac     DMLocalToGlobalHookLink link,next;
566d4d07f1eSToby Isaac     for (link=(*dm)->ltoghook; link; link=next) {
567d4d07f1eSToby Isaac       next = link->next;
568d4d07f1eSToby Isaac       ierr = PetscFree(link);CHKERRQ(ierr);
569d4d07f1eSToby Isaac     }
570d4d07f1eSToby Isaac     (*dm)->ltoghook = NULL;
571d4d07f1eSToby Isaac   }
572aa1993deSMatthew G Knepley   /* Destroy the work arrays */
573aa1993deSMatthew G Knepley   {
574aa1993deSMatthew G Knepley     DMWorkLink link,next;
575aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
576aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
577aa1993deSMatthew G Knepley       next = link->next;
578aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
579aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
580aa1993deSMatthew G Knepley     }
5810298fd71SBarry Smith     (*dm)->workin = NULL;
582aa1993deSMatthew G Knepley   }
583*c58f1c22SToby Isaac   if (!--((*dm)->labels->refct)) {
584*c58f1c22SToby Isaac     DMLabelLink next = (*dm)->labels->next;
585*c58f1c22SToby Isaac 
586*c58f1c22SToby Isaac     /* destroy the labels */
587*c58f1c22SToby Isaac     while (next) {
588*c58f1c22SToby Isaac       DMLabelLink tmp = next->next;
589*c58f1c22SToby Isaac 
590*c58f1c22SToby Isaac       ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr);
591*c58f1c22SToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
592*c58f1c22SToby Isaac       next = tmp;
593*c58f1c22SToby Isaac     }
594*c58f1c22SToby Isaac     ierr = PetscFree((*dm)->labels);CHKERRQ(ierr);
595*c58f1c22SToby Isaac   }
596b17ce1afSJed Brown 
59752536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr);
59852536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr);
59952536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr);
60052536dc3SBarry Smith 
6011a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
6021a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
6031a266240SBarry Smith   }
60487e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
60571cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
6064dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
6076bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
6086bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
609073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
61088ed4aceSMatthew G Knepley 
61188ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
61288ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
6138b1ab98fSJed Brown   ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr);
614fba222abSToby Isaac   ierr = PetscSectionDestroy(&(*dm)->defaultConstraintSection);CHKERRQ(ierr);
615fba222abSToby Isaac   ierr = MatDestroy(&(*dm)->defaultConstraintMat);CHKERRQ(ierr);
61688ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
61788ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
6188e4ac7eaSMatthew G. Knepley   ierr = PetscSFDestroy(&(*dm)->sfNatural);CHKERRQ(ierr);
619af122d2aSMatthew G Knepley 
6206636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
6216636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
6226636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
6235dc8c3f7SMatthew G. Knepley   ierr = PetscFree3((*dm)->L,(*dm)->maxCell,(*dm)->bdtype);CHKERRQ(ierr);
6246636e97aSMatthew G Knepley 
6252764a2aaSMatthew G. Knepley   ierr = PetscDSDestroy(&(*dm)->prob);CHKERRQ(ierr);
62614f150ffSMatthew G. Knepley   ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr);
627e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
628e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr);
629732e2eb9SMatthew G Knepley 
6306bf464f9SBarry Smith   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
631435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
632732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
63347c6ae99SBarry Smith   PetscFunctionReturn(0);
63447c6ae99SBarry Smith }
63547c6ae99SBarry Smith 
63647c6ae99SBarry Smith #undef __FUNCT__
637d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp"
638d7bf68aeSBarry Smith /*@
639d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
640d7bf68aeSBarry Smith 
641d7bf68aeSBarry Smith     Collective on DM
642d7bf68aeSBarry Smith 
643d7bf68aeSBarry Smith     Input Parameter:
644d7bf68aeSBarry Smith .   dm - the DM object to setup
645d7bf68aeSBarry Smith 
646d7bf68aeSBarry Smith     Level: developer
647d7bf68aeSBarry Smith 
648e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
649d7bf68aeSBarry Smith 
650d7bf68aeSBarry Smith @*/
6517087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
652d7bf68aeSBarry Smith {
653d7bf68aeSBarry Smith   PetscErrorCode ierr;
654d7bf68aeSBarry Smith 
655d7bf68aeSBarry Smith   PetscFunctionBegin;
656171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6578387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
658d7bf68aeSBarry Smith   if (dm->ops->setup) {
659d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
660d7bf68aeSBarry Smith   }
6618387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
662d7bf68aeSBarry Smith   PetscFunctionReturn(0);
663d7bf68aeSBarry Smith }
664d7bf68aeSBarry Smith 
665d7bf68aeSBarry Smith #undef __FUNCT__
666d7bf68aeSBarry Smith #define __FUNCT__ "DMSetFromOptions"
667d7bf68aeSBarry Smith /*@
668d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
669d7bf68aeSBarry Smith 
670d7bf68aeSBarry Smith     Collective on DM
671d7bf68aeSBarry Smith 
672d7bf68aeSBarry Smith     Input Parameter:
673d7bf68aeSBarry Smith .   dm - the DM object to set options for
674d7bf68aeSBarry Smith 
675732e2eb9SMatthew G Knepley     Options Database:
6764164ae61SDominic Meiser +   -dm_preallocate_only - Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
6774164ae61SDominic Meiser .   -dm_vec_type <type>  - type of vector to create inside DM
6784164ae61SDominic Meiser .   -dm_mat_type <type>  - type of matrix to create inside DM
6794164ae61SDominic Meiser -   -dm_coloring_type    - <global or ghosted>
680732e2eb9SMatthew G Knepley 
681d7bf68aeSBarry Smith     Level: developer
682d7bf68aeSBarry Smith 
683e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
684d7bf68aeSBarry Smith 
685d7bf68aeSBarry Smith @*/
6867087cfbeSBarry Smith PetscErrorCode  DMSetFromOptions(DM dm)
687d7bf68aeSBarry Smith {
6887781c08eSBarry Smith   char           typeName[256];
689ca266f36SBarry Smith   PetscBool      flg;
690d7bf68aeSBarry Smith   PetscErrorCode ierr;
691d7bf68aeSBarry Smith 
692d7bf68aeSBarry Smith   PetscFunctionBegin;
693171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
694691be533SLawrence Mitchell   if (dm->sf) {
695691be533SLawrence Mitchell     ierr = PetscSFSetFromOptions(dm->sf);CHKERRQ(ierr);
696691be533SLawrence Mitchell   }
697691be533SLawrence Mitchell   if (dm->defaultSF) {
698691be533SLawrence Mitchell     ierr = PetscSFSetFromOptions(dm->defaultSF);CHKERRQ(ierr);
699691be533SLawrence Mitchell   }
7003194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
7010298fd71SBarry 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);
702a264d7a6SBarry Smith   ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
703f9ba7244SBarry Smith   if (flg) {
704f9ba7244SBarry Smith     ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
705f9ba7244SBarry Smith   }
706a264d7a6SBarry 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);
707073dac72SJed Brown   if (flg) {
708521d9a4cSLisandro Dalcin     ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
709073dac72SJed Brown   }
7100298fd71SBarry Smith   ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","ISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr);
711f9ba7244SBarry Smith   if (dm->ops->setfromoptions) {
712e55864a3SBarry Smith     ierr = (*dm->ops->setfromoptions)(PetscOptionsObject,dm);CHKERRQ(ierr);
713f9ba7244SBarry Smith   }
714f9ba7244SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
715f9ba7244SBarry Smith   ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
71682fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
717d7bf68aeSBarry Smith   PetscFunctionReturn(0);
718d7bf68aeSBarry Smith }
719d7bf68aeSBarry Smith 
720d7bf68aeSBarry Smith #undef __FUNCT__
72147c6ae99SBarry Smith #define __FUNCT__ "DMView"
722fc9bc008SSatish Balay /*@C
723224748a4SBarry Smith     DMView - Views a DM
72447c6ae99SBarry Smith 
72547c6ae99SBarry Smith     Collective on DM
72647c6ae99SBarry Smith 
72747c6ae99SBarry Smith     Input Parameter:
72847c6ae99SBarry Smith +   dm - the DM object to view
72947c6ae99SBarry Smith -   v - the viewer
73047c6ae99SBarry Smith 
731224748a4SBarry Smith     Level: beginner
73247c6ae99SBarry Smith 
733e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
73447c6ae99SBarry Smith 
73547c6ae99SBarry Smith @*/
7367087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
73747c6ae99SBarry Smith {
73847c6ae99SBarry Smith   PetscErrorCode ierr;
73932c0f0efSBarry Smith   PetscBool      isbinary;
74047c6ae99SBarry Smith 
74147c6ae99SBarry Smith   PetscFunctionBegin;
742171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7433014e516SBarry Smith   if (!v) {
744ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr);
7453014e516SBarry Smith   }
74698c3331eSBarry Smith   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr);
74732c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
74832c0f0efSBarry Smith   if (isbinary) {
74955849f57SBarry Smith     PetscInt classid = DM_FILE_CLASSID;
75032c0f0efSBarry Smith     char     type[256];
75132c0f0efSBarry Smith 
75232c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
75332c0f0efSBarry Smith     ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
75432c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
75532c0f0efSBarry Smith   }
7560c010503SBarry Smith   if (dm->ops->view) {
7570c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
75847c6ae99SBarry Smith   }
75947c6ae99SBarry Smith   PetscFunctionReturn(0);
76047c6ae99SBarry Smith }
76147c6ae99SBarry Smith 
76247c6ae99SBarry Smith #undef __FUNCT__
76347c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
76447c6ae99SBarry Smith /*@
7658472ad0fSDave May     DMCreateGlobalVector - Creates a global vector from a DM object
76647c6ae99SBarry Smith 
76747c6ae99SBarry Smith     Collective on DM
76847c6ae99SBarry Smith 
76947c6ae99SBarry Smith     Input Parameter:
77047c6ae99SBarry Smith .   dm - the DM object
77147c6ae99SBarry Smith 
77247c6ae99SBarry Smith     Output Parameter:
77347c6ae99SBarry Smith .   vec - the global vector
77447c6ae99SBarry Smith 
775073dac72SJed Brown     Level: beginner
77647c6ae99SBarry Smith 
777e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
77847c6ae99SBarry Smith 
77947c6ae99SBarry Smith @*/
7807087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
78147c6ae99SBarry Smith {
78247c6ae99SBarry Smith   PetscErrorCode ierr;
78347c6ae99SBarry Smith 
78447c6ae99SBarry Smith   PetscFunctionBegin;
785171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
78647c6ae99SBarry Smith   ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
78747c6ae99SBarry Smith   PetscFunctionReturn(0);
78847c6ae99SBarry Smith }
78947c6ae99SBarry Smith 
79047c6ae99SBarry Smith #undef __FUNCT__
79147c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
79247c6ae99SBarry Smith /*@
7938472ad0fSDave May     DMCreateLocalVector - Creates a local vector from a DM object
79447c6ae99SBarry Smith 
79547c6ae99SBarry Smith     Not Collective
79647c6ae99SBarry Smith 
79747c6ae99SBarry Smith     Input Parameter:
79847c6ae99SBarry Smith .   dm - the DM object
79947c6ae99SBarry Smith 
80047c6ae99SBarry Smith     Output Parameter:
80147c6ae99SBarry Smith .   vec - the local vector
80247c6ae99SBarry Smith 
803073dac72SJed Brown     Level: beginner
80447c6ae99SBarry Smith 
805e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
80647c6ae99SBarry Smith 
80747c6ae99SBarry Smith @*/
8087087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
80947c6ae99SBarry Smith {
81047c6ae99SBarry Smith   PetscErrorCode ierr;
81147c6ae99SBarry Smith 
81247c6ae99SBarry Smith   PetscFunctionBegin;
813171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
81447c6ae99SBarry Smith   ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
81547c6ae99SBarry Smith   PetscFunctionReturn(0);
81647c6ae99SBarry Smith }
81747c6ae99SBarry Smith 
81847c6ae99SBarry Smith #undef __FUNCT__
8191411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
8201411c6eeSJed Brown /*@
8211411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
8221411c6eeSJed Brown 
8231411c6eeSJed Brown    Collective on DM
8241411c6eeSJed Brown 
8251411c6eeSJed Brown    Input Parameter:
8261411c6eeSJed Brown .  dm - the DM that provides the mapping
8271411c6eeSJed Brown 
8281411c6eeSJed Brown    Output Parameter:
8291411c6eeSJed Brown .  ltog - the mapping
8301411c6eeSJed Brown 
8311411c6eeSJed Brown    Level: intermediate
8321411c6eeSJed Brown 
8331411c6eeSJed Brown    Notes:
8341411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
8351411c6eeSJed Brown    MatSetLocalToGlobalMapping().
8361411c6eeSJed Brown 
837fc31e74dSBarry Smith .seealso: DMCreateLocalVector()
8381411c6eeSJed Brown @*/
8397087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
8401411c6eeSJed Brown {
8411411c6eeSJed Brown   PetscErrorCode ierr;
8421411c6eeSJed Brown 
8431411c6eeSJed Brown   PetscFunctionBegin;
8441411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8451411c6eeSJed Brown   PetscValidPointer(ltog,2);
8461411c6eeSJed Brown   if (!dm->ltogmap) {
84737d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
84837d0c07bSMatthew G Knepley 
84937d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
85037d0c07bSMatthew G Knepley     if (section) {
85137d0c07bSMatthew G Knepley       PetscInt *ltog;
85237d0c07bSMatthew G Knepley       PetscInt pStart, pEnd, size, p, l;
85337d0c07bSMatthew G Knepley 
85437d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
85537d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
85637d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
857785e854fSJed Brown       ierr = PetscMalloc1(size, &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
85837d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
85937d0c07bSMatthew G Knepley         PetscInt dof, off, c;
86037d0c07bSMatthew G Knepley 
86137d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
86237d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
86337d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
86437d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
86537d0c07bSMatthew G Knepley           ltog[l] = off+c;
86637d0c07bSMatthew G Knepley         }
86737d0c07bSMatthew G Knepley       }
868f0413b6fSBarry Smith       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, 1,size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
8693bb1ff40SBarry Smith       ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr);
87037d0c07bSMatthew G Knepley     } else {
871184d77edSJed Brown       if (!dm->ops->getlocaltoglobalmapping) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
872184d77edSJed Brown       ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr);
8731411c6eeSJed Brown     }
87437d0c07bSMatthew G Knepley   }
8751411c6eeSJed Brown   *ltog = dm->ltogmap;
8761411c6eeSJed Brown   PetscFunctionReturn(0);
8771411c6eeSJed Brown }
8781411c6eeSJed Brown 
8791411c6eeSJed Brown #undef __FUNCT__
8801411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
8811411c6eeSJed Brown /*@
8821411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
8831411c6eeSJed Brown 
8841411c6eeSJed Brown    Not Collective
8851411c6eeSJed Brown 
8861411c6eeSJed Brown    Input Parameter:
8871411c6eeSJed Brown .  dm - the DM with block structure
8881411c6eeSJed Brown 
8891411c6eeSJed Brown    Output Parameter:
8901411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
8911411c6eeSJed Brown 
8921411c6eeSJed Brown    Level: intermediate
8931411c6eeSJed Brown 
894fc31e74dSBarry Smith .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMapping()
8951411c6eeSJed Brown @*/
8967087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
8971411c6eeSJed Brown {
8981411c6eeSJed Brown   PetscFunctionBegin;
8991411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9001411c6eeSJed Brown   PetscValidPointer(bs,2);
9011411c6eeSJed 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");
9021411c6eeSJed Brown   *bs = dm->bs;
9031411c6eeSJed Brown   PetscFunctionReturn(0);
9041411c6eeSJed Brown }
9051411c6eeSJed Brown 
9061411c6eeSJed Brown #undef __FUNCT__
907e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
90847c6ae99SBarry Smith /*@
9098472ad0fSDave May     DMCreateInterpolation - Gets interpolation matrix between two DM objects
91047c6ae99SBarry Smith 
91147c6ae99SBarry Smith     Collective on DM
91247c6ae99SBarry Smith 
91347c6ae99SBarry Smith     Input Parameter:
91447c6ae99SBarry Smith +   dm1 - the DM object
91547c6ae99SBarry Smith -   dm2 - the second, finer DM object
91647c6ae99SBarry Smith 
91747c6ae99SBarry Smith     Output Parameter:
91847c6ae99SBarry Smith +  mat - the interpolation
91947c6ae99SBarry Smith -  vec - the scaling (optional)
92047c6ae99SBarry Smith 
92147c6ae99SBarry Smith     Level: developer
92247c6ae99SBarry Smith 
92385afcc9aSBarry Smith     Notes:  For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
92485afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
925d52bd9f3SBarry Smith 
9261f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
927d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
92885afcc9aSBarry Smith 
92985afcc9aSBarry Smith 
930e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
93147c6ae99SBarry Smith 
93247c6ae99SBarry Smith @*/
933e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
93447c6ae99SBarry Smith {
93547c6ae99SBarry Smith   PetscErrorCode ierr;
93647c6ae99SBarry Smith 
93747c6ae99SBarry Smith   PetscFunctionBegin;
938171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
939171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
940cea54e9dSPatrick Farrell   ierr = PetscLogEventBegin(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
94125296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
942cea54e9dSPatrick Farrell   ierr = PetscLogEventEnd(DM_CreateInterpolation,dm1,dm2,0,0);CHKERRQ(ierr);
94347c6ae99SBarry Smith   PetscFunctionReturn(0);
94447c6ae99SBarry Smith }
94547c6ae99SBarry Smith 
94647c6ae99SBarry Smith #undef __FUNCT__
947e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
94847c6ae99SBarry Smith /*@
9498472ad0fSDave May     DMCreateInjection - Gets injection matrix between two DM objects
95047c6ae99SBarry Smith 
95147c6ae99SBarry Smith     Collective on DM
95247c6ae99SBarry Smith 
95347c6ae99SBarry Smith     Input Parameter:
95447c6ae99SBarry Smith +   dm1 - the DM object
95547c6ae99SBarry Smith -   dm2 - the second, finer DM object
95647c6ae99SBarry Smith 
95747c6ae99SBarry Smith     Output Parameter:
9586dbf9973SLawrence Mitchell .   mat - the injection
95947c6ae99SBarry Smith 
96047c6ae99SBarry Smith     Level: developer
96147c6ae99SBarry Smith 
96285afcc9aSBarry Smith    Notes:  For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
96385afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
96485afcc9aSBarry Smith 
965e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
96647c6ae99SBarry Smith 
96747c6ae99SBarry Smith @*/
9686dbf9973SLawrence Mitchell PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,Mat *mat)
96947c6ae99SBarry Smith {
97047c6ae99SBarry Smith   PetscErrorCode ierr;
97147c6ae99SBarry Smith 
97247c6ae99SBarry Smith   PetscFunctionBegin;
973171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
974171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
9756dbf9973SLawrence Mitchell   ierr = (*dm1->ops->getinjection)(dm1,dm2,mat);CHKERRQ(ierr);
97647c6ae99SBarry Smith   PetscFunctionReturn(0);
97747c6ae99SBarry Smith }
97847c6ae99SBarry Smith 
97947c6ae99SBarry Smith #undef __FUNCT__
980e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
981b412c318SBarry Smith /*@
982b412c318SBarry Smith     DMCreateColoring - Gets coloring for a DM
98347c6ae99SBarry Smith 
98447c6ae99SBarry Smith     Collective on DM
98547c6ae99SBarry Smith 
98647c6ae99SBarry Smith     Input Parameter:
98747c6ae99SBarry Smith +   dm - the DM object
988b412c318SBarry Smith -   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
98947c6ae99SBarry Smith 
99047c6ae99SBarry Smith     Output Parameter:
99147c6ae99SBarry Smith .   coloring - the coloring
99247c6ae99SBarry Smith 
99347c6ae99SBarry Smith     Level: developer
99447c6ae99SBarry Smith 
995b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType()
99647c6ae99SBarry Smith 
997aab9d709SJed Brown @*/
998b412c318SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring)
99947c6ae99SBarry Smith {
100047c6ae99SBarry Smith   PetscErrorCode ierr;
100147c6ae99SBarry Smith 
100247c6ae99SBarry Smith   PetscFunctionBegin;
1003171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1004ce94432eSBarry Smith   if (!dm->ops->getcoloring) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No coloring for this type of DM yet");
1005b412c318SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr);
100647c6ae99SBarry Smith   PetscFunctionReturn(0);
100747c6ae99SBarry Smith }
100847c6ae99SBarry Smith 
100947c6ae99SBarry Smith #undef __FUNCT__
1010950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
1011b412c318SBarry Smith /*@
10128472ad0fSDave May     DMCreateMatrix - Gets empty Jacobian for a DM
101347c6ae99SBarry Smith 
101447c6ae99SBarry Smith     Collective on DM
101547c6ae99SBarry Smith 
101647c6ae99SBarry Smith     Input Parameter:
1017b412c318SBarry Smith .   dm - the DM object
101847c6ae99SBarry Smith 
101947c6ae99SBarry Smith     Output Parameter:
102047c6ae99SBarry Smith .   mat - the empty Jacobian
102147c6ae99SBarry Smith 
1022073dac72SJed Brown     Level: beginner
102347c6ae99SBarry Smith 
102494013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
102594013140SBarry Smith        do not need to do it yourself.
102694013140SBarry Smith 
102794013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
1028aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
102994013140SBarry Smith 
103094013140SBarry 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
103194013140SBarry Smith        internally by PETSc.
103294013140SBarry Smith 
103394013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
1034aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
103594013140SBarry Smith 
1036b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType()
103747c6ae99SBarry Smith 
1038aab9d709SJed Brown @*/
1039b412c318SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,Mat *mat)
104047c6ae99SBarry Smith {
104147c6ae99SBarry Smith   PetscErrorCode ierr;
104247c6ae99SBarry Smith 
104347c6ae99SBarry Smith   PetscFunctionBegin;
1044171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1045607a6623SBarry Smith   ierr = MatInitializePackage();CHKERRQ(ierr);
1046c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1047c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
1048b412c318SBarry Smith   ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr);
104947c6ae99SBarry Smith   PetscFunctionReturn(0);
105047c6ae99SBarry Smith }
105147c6ae99SBarry Smith 
105247c6ae99SBarry Smith #undef __FUNCT__
1053732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
1054732e2eb9SMatthew G Knepley /*@
1055950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
1056732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
1057732e2eb9SMatthew G Knepley 
10588472ad0fSDave May   Logically Collective on DM
1059732e2eb9SMatthew G Knepley 
1060732e2eb9SMatthew G Knepley   Input Parameter:
1061732e2eb9SMatthew G Knepley + dm - the DM
1062732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
1063732e2eb9SMatthew G Knepley 
1064732e2eb9SMatthew G Knepley   Level: developer
1065950540a4SJed Brown .seealso DMCreateMatrix()
1066732e2eb9SMatthew G Knepley @*/
1067732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
1068732e2eb9SMatthew G Knepley {
1069732e2eb9SMatthew G Knepley   PetscFunctionBegin;
1070732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1071732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
1072732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
1073732e2eb9SMatthew G Knepley }
1074732e2eb9SMatthew G Knepley 
1075732e2eb9SMatthew G Knepley #undef __FUNCT__
1076a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
1077a89ea682SMatthew G Knepley /*@C
1078aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1079a89ea682SMatthew G Knepley 
1080a89ea682SMatthew G Knepley   Not Collective
1081a89ea682SMatthew G Knepley 
1082a89ea682SMatthew G Knepley   Input Parameters:
1083a89ea682SMatthew G Knepley + dm - the DM object
1084aa1993deSMatthew G Knepley . count - The minium size
1085aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
1086a89ea682SMatthew G Knepley 
1087a89ea682SMatthew G Knepley   Output Parameter:
1088a89ea682SMatthew G Knepley . array - the work array
1089a89ea682SMatthew G Knepley 
1090a89ea682SMatthew G Knepley   Level: developer
1091a89ea682SMatthew G Knepley 
1092a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
1093a89ea682SMatthew G Knepley @*/
1094aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1095a89ea682SMatthew G Knepley {
1096a89ea682SMatthew G Knepley   PetscErrorCode ierr;
1097aa1993deSMatthew G Knepley   DMWorkLink     link;
1098854ce69bSBarry Smith   size_t         dsize;
1099a89ea682SMatthew G Knepley 
1100a89ea682SMatthew G Knepley   PetscFunctionBegin;
1101a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1102aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1103aa1993deSMatthew G Knepley   if (dm->workin) {
1104aa1993deSMatthew G Knepley     link       = dm->workin;
1105aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
1106aa1993deSMatthew G Knepley   } else {
1107b00a9115SJed Brown     ierr = PetscNewLog(dm,&link);CHKERRQ(ierr);
1108a89ea682SMatthew G Knepley   }
1109854ce69bSBarry Smith   ierr = PetscDataTypeGetSize(dtype,&dsize);CHKERRQ(ierr);
1110854ce69bSBarry Smith   if (dsize*count > link->bytes) {
1111aa1993deSMatthew G Knepley     ierr        = PetscFree(link->mem);CHKERRQ(ierr);
1112854ce69bSBarry Smith     ierr        = PetscMalloc(dsize*count,&link->mem);CHKERRQ(ierr);
1113854ce69bSBarry Smith     link->bytes = dsize*count;
1114aa1993deSMatthew G Knepley   }
1115aa1993deSMatthew G Knepley   link->next   = dm->workout;
1116aa1993deSMatthew G Knepley   dm->workout  = link;
1117aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
1118a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
1119a89ea682SMatthew G Knepley }
1120a89ea682SMatthew G Knepley 
1121aa1993deSMatthew G Knepley #undef __FUNCT__
1122aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
1123aa1993deSMatthew G Knepley /*@C
1124aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1125aa1993deSMatthew G Knepley 
1126aa1993deSMatthew G Knepley   Not Collective
1127aa1993deSMatthew G Knepley 
1128aa1993deSMatthew G Knepley   Input Parameters:
1129aa1993deSMatthew G Knepley + dm - the DM object
1130aa1993deSMatthew G Knepley . count - The minium size
1131aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
1132aa1993deSMatthew G Knepley 
1133aa1993deSMatthew G Knepley   Output Parameter:
1134aa1993deSMatthew G Knepley . array - the work array
1135aa1993deSMatthew G Knepley 
1136aa1993deSMatthew G Knepley   Level: developer
1137aa1993deSMatthew G Knepley 
1138aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
1139aa1993deSMatthew G Knepley @*/
1140aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1141aa1993deSMatthew G Knepley {
1142aa1993deSMatthew G Knepley   DMWorkLink *p,link;
1143aa1993deSMatthew G Knepley 
1144aa1993deSMatthew G Knepley   PetscFunctionBegin;
1145aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1146aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1147aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
1148aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
1149aa1993deSMatthew G Knepley       *p           = link->next;
1150aa1993deSMatthew G Knepley       link->next   = dm->workin;
1151aa1993deSMatthew G Knepley       dm->workin   = link;
11520298fd71SBarry Smith       *(void**)mem = NULL;
1153aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
1154aa1993deSMatthew G Knepley     }
1155aa1993deSMatthew G Knepley   }
1156aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
1157aa1993deSMatthew G Knepley }
1158e7c4fc90SDmitry Karpeev 
1159e7c4fc90SDmitry Karpeev #undef __FUNCT__
1160435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
1161435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1162435a35e8SMatthew G Knepley {
1163435a35e8SMatthew G Knepley   PetscFunctionBegin;
1164435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
116582f516ccSBarry Smith   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1166435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
1167435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1168435a35e8SMatthew G Knepley }
1169435a35e8SMatthew G Knepley 
1170435a35e8SMatthew G Knepley #undef __FUNCT__
11714d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
11724f3b5142SJed Brown /*@C
11734d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
11744d343eeaSMatthew G Knepley 
11754d343eeaSMatthew G Knepley   Not collective
11764d343eeaSMatthew G Knepley 
11774d343eeaSMatthew G Knepley   Input Parameter:
11784d343eeaSMatthew G Knepley . dm - the DM object
11794d343eeaSMatthew G Knepley 
11804d343eeaSMatthew G Knepley   Output Parameters:
11810298fd71SBarry Smith + numFields  - The number of fields (or NULL if not requested)
11820298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested)
11830298fd71SBarry Smith - fields     - The global indices for each field (or NULL if not requested)
11844d343eeaSMatthew G Knepley 
11854d343eeaSMatthew G Knepley   Level: intermediate
11864d343eeaSMatthew G Knepley 
118721c9b008SJed Brown   Notes:
118821c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
118921c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
119021c9b008SJed Brown   PetscFree().
119121c9b008SJed Brown 
11924d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
11934d343eeaSMatthew G Knepley @*/
119437d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
11954d343eeaSMatthew G Knepley {
119637d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
11974d343eeaSMatthew G Knepley   PetscErrorCode ierr;
11984d343eeaSMatthew G Knepley 
11994d343eeaSMatthew G Knepley   PetscFunctionBegin;
12004d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
120169ca1f37SDmitry Karpeev   if (numFields) {
120269ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
120369ca1f37SDmitry Karpeev     *numFields = 0;
120469ca1f37SDmitry Karpeev   }
120537d0c07bSMatthew G Knepley   if (fieldNames) {
120637d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
12070298fd71SBarry Smith     *fieldNames = NULL;
120869ca1f37SDmitry Karpeev   }
120969ca1f37SDmitry Karpeev   if (fields) {
121069ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
12110298fd71SBarry Smith     *fields = NULL;
121269ca1f37SDmitry Karpeev   }
121337d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
121437d0c07bSMatthew G Knepley   if (section) {
121537d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
121637d0c07bSMatthew G Knepley     PetscInt nF, f, pStart, pEnd, p;
121737d0c07bSMatthew G Knepley 
121837d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
121937d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
1220dcca6d9dSJed Brown     ierr = PetscMalloc2(nF,&fieldSizes,nF,&fieldIndices);CHKERRQ(ierr);
122137d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
122237d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
122337d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
122437d0c07bSMatthew G Knepley     }
122537d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
122637d0c07bSMatthew G Knepley       PetscInt gdof;
122737d0c07bSMatthew G Knepley 
122837d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
122937d0c07bSMatthew G Knepley       if (gdof > 0) {
123037d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
123137d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
123237d0c07bSMatthew G Knepley 
123337d0c07bSMatthew G Knepley           ierr           = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
123437d0c07bSMatthew G Knepley           ierr           = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
123537d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
123637d0c07bSMatthew G Knepley         }
123737d0c07bSMatthew G Knepley       }
123837d0c07bSMatthew G Knepley     }
123937d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
1240785e854fSJed Brown       ierr          = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr);
124137d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
124237d0c07bSMatthew G Knepley     }
124337d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
124437d0c07bSMatthew G Knepley       PetscInt gdof, goff;
124537d0c07bSMatthew G Knepley 
124637d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
124737d0c07bSMatthew G Knepley       if (gdof > 0) {
124837d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
124937d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
125037d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
125137d0c07bSMatthew G Knepley 
125237d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
125337d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
125437d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
125537d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
125637d0c07bSMatthew G Knepley           }
125737d0c07bSMatthew G Knepley         }
125837d0c07bSMatthew G Knepley       }
125937d0c07bSMatthew G Knepley     }
12608865f1eaSKarl Rupp     if (numFields) *numFields = nF;
126137d0c07bSMatthew G Knepley     if (fieldNames) {
1262785e854fSJed Brown       ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr);
126337d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
126437d0c07bSMatthew G Knepley         const char *fieldName;
126537d0c07bSMatthew G Knepley 
126637d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
126737d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr);
126837d0c07bSMatthew G Knepley       }
126937d0c07bSMatthew G Knepley     }
127037d0c07bSMatthew G Knepley     if (fields) {
1271785e854fSJed Brown       ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr);
127237d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
127382f516ccSBarry Smith         ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
127437d0c07bSMatthew G Knepley       }
127537d0c07bSMatthew G Knepley     }
127637d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
12778865f1eaSKarl Rupp   } else if (dm->ops->createfieldis) {
12788865f1eaSKarl Rupp     ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);
127969ca1f37SDmitry Karpeev   }
12804d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
12814d343eeaSMatthew G Knepley }
12824d343eeaSMatthew G Knepley 
128316621825SDmitry Karpeev 
128416621825SDmitry Karpeev #undef __FUNCT__
128516621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
128616621825SDmitry Karpeev /*@C
128716621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
128816621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
128916621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1290e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1291e7c4fc90SDmitry Karpeev 
1292e7c4fc90SDmitry Karpeev   Not collective
1293e7c4fc90SDmitry Karpeev 
1294e7c4fc90SDmitry Karpeev   Input Parameter:
1295e7c4fc90SDmitry Karpeev . dm - the DM object
1296e7c4fc90SDmitry Karpeev 
1297e7c4fc90SDmitry Karpeev   Output Parameters:
12980298fd71SBarry Smith + len       - The number of subproblems in the field decomposition (or NULL if not requested)
12990298fd71SBarry Smith . namelist  - The name for each field (or NULL if not requested)
13000298fd71SBarry Smith . islist    - The global indices for each field (or NULL if not requested)
13010298fd71SBarry Smith - dmlist    - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
1302e7c4fc90SDmitry Karpeev 
1303e7c4fc90SDmitry Karpeev   Level: intermediate
1304e7c4fc90SDmitry Karpeev 
1305e7c4fc90SDmitry Karpeev   Notes:
1306e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1307e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1308e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1309e7c4fc90SDmitry Karpeev 
1310e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1311e7c4fc90SDmitry Karpeev @*/
131216621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1313e7c4fc90SDmitry Karpeev {
1314e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1315e7c4fc90SDmitry Karpeev 
1316e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1317e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13188865f1eaSKarl Rupp   if (len) {
13198865f1eaSKarl Rupp     PetscValidPointer(len,2);
13208865f1eaSKarl Rupp     *len = 0;
13218865f1eaSKarl Rupp   }
13228865f1eaSKarl Rupp   if (namelist) {
13238865f1eaSKarl Rupp     PetscValidPointer(namelist,3);
13248865f1eaSKarl Rupp     *namelist = 0;
13258865f1eaSKarl Rupp   }
13268865f1eaSKarl Rupp   if (islist) {
13278865f1eaSKarl Rupp     PetscValidPointer(islist,4);
13288865f1eaSKarl Rupp     *islist = 0;
13298865f1eaSKarl Rupp   }
13308865f1eaSKarl Rupp   if (dmlist) {
13318865f1eaSKarl Rupp     PetscValidPointer(dmlist,5);
13328865f1eaSKarl Rupp     *dmlist = 0;
13338865f1eaSKarl Rupp   }
1334f3f0edfdSDmitry Karpeev   /*
1335f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1336f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1337f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1338f3f0edfdSDmitry Karpeev    */
1339ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
134016621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1341435a35e8SMatthew G Knepley     PetscSection section;
1342435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1343435a35e8SMatthew G Knepley 
1344435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1345435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1346435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1347435a35e8SMatthew G Knepley       *len = numFields;
134803dc3394SMatthew G. Knepley       if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);}
134903dc3394SMatthew G. Knepley       if (islist)   {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);}
135003dc3394SMatthew G. Knepley       if (dmlist)   {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);}
1351435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1352435a35e8SMatthew G Knepley         const char *fieldName;
1353435a35e8SMatthew G Knepley 
135403dc3394SMatthew G. Knepley         ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr);
135503dc3394SMatthew G. Knepley         if (namelist) {
1356435a35e8SMatthew G Knepley           ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1357435a35e8SMatthew G Knepley           ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr);
1358435a35e8SMatthew G Knepley         }
135903dc3394SMatthew G. Knepley       }
1360435a35e8SMatthew G Knepley     } else {
136169ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1362e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
13630298fd71SBarry Smith       if (dmlist) *dmlist = NULL;
1364e7c4fc90SDmitry Karpeev     }
13658865f1eaSKarl Rupp   } else {
136616621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr);
136716621825SDmitry Karpeev   }
136816621825SDmitry Karpeev   PetscFunctionReturn(0);
136916621825SDmitry Karpeev }
137016621825SDmitry Karpeev 
137116621825SDmitry Karpeev #undef __FUNCT__
1372435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1373564cec59SMatthew G. Knepley /*@
1374435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1375435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1376435a35e8SMatthew G Knepley 
1377435a35e8SMatthew G Knepley   Not collective
1378435a35e8SMatthew G Knepley 
1379435a35e8SMatthew G Knepley   Input Parameters:
1380435a35e8SMatthew G Knepley + dm - the DM object
1381435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
13820298fd71SBarry Smith - len       - The number of subproblems in the decomposition (or NULL if not requested)
1383435a35e8SMatthew G Knepley 
1384435a35e8SMatthew G Knepley   Output Parameters:
1385435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1386435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1387435a35e8SMatthew G Knepley 
1388435a35e8SMatthew G Knepley   Level: intermediate
1389435a35e8SMatthew G Knepley 
1390435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1391435a35e8SMatthew G Knepley @*/
1392435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1393435a35e8SMatthew G Knepley {
1394435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1395435a35e8SMatthew G Knepley 
1396435a35e8SMatthew G Knepley   PetscFunctionBegin;
1397435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1398435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
13998865f1eaSKarl Rupp   if (is) PetscValidPointer(is,4);
14008865f1eaSKarl Rupp   if (subdm) PetscValidPointer(subdm,5);
1401435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1402435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
140382f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1404435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1405435a35e8SMatthew G Knepley }
1406435a35e8SMatthew G Knepley 
140716621825SDmitry Karpeev 
140816621825SDmitry Karpeev #undef __FUNCT__
140916621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
141016621825SDmitry Karpeev /*@C
14118d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
14128d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
14138d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
14148d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
14158d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
141616621825SDmitry Karpeev 
141716621825SDmitry Karpeev   Not collective
141816621825SDmitry Karpeev 
141916621825SDmitry Karpeev   Input Parameter:
142016621825SDmitry Karpeev . dm - the DM object
142116621825SDmitry Karpeev 
142216621825SDmitry Karpeev   Output Parameters:
14230298fd71SBarry Smith + len         - The number of subproblems in the domain decomposition (or NULL if not requested)
14240298fd71SBarry Smith . namelist    - The name for each subdomain (or NULL if not requested)
14250298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested)
14260298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested)
14270298fd71SBarry Smith - dmlist      - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
142816621825SDmitry Karpeev 
142916621825SDmitry Karpeev   Level: intermediate
143016621825SDmitry Karpeev 
143116621825SDmitry Karpeev   Notes:
143216621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
143316621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
143416621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
143516621825SDmitry Karpeev 
14368d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
143716621825SDmitry Karpeev @*/
14388d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
143916621825SDmitry Karpeev {
144016621825SDmitry Karpeev   PetscErrorCode      ierr;
1441be081cd6SPeter Brune   DMSubDomainHookLink link;
1442be081cd6SPeter Brune   PetscInt            i,l;
144316621825SDmitry Karpeev 
144416621825SDmitry Karpeev   PetscFunctionBegin;
144516621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
144614a18fd3SPeter Brune   if (len)           {PetscValidPointer(len,2);            *len         = 0;}
14470298fd71SBarry Smith   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = NULL;}
14480298fd71SBarry Smith   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = NULL;}
14490298fd71SBarry Smith   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = NULL;}
14500298fd71SBarry Smith   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = NULL;}
1451f3f0edfdSDmitry Karpeev   /*
1452f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1453f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1454f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1455f3f0edfdSDmitry Karpeev    */
1456ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
145716621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
1458be081cd6SPeter Brune     ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr);
145914a18fd3SPeter Brune     /* copy subdomain hooks and context over to the subdomain DMs */
146014a18fd3SPeter Brune     if (dmlist) {
1461be081cd6SPeter Brune       for (i = 0; i < l; i++) {
1462be081cd6SPeter Brune         for (link=dm->subdomainhook; link; link=link->next) {
1463be081cd6SPeter Brune           if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);}
1464be081cd6SPeter Brune         }
1465d425c654SPeter Brune         (*dmlist)[i]->ctx = dm->ctx;
1466e7c4fc90SDmitry Karpeev       }
146714a18fd3SPeter Brune     }
146814a18fd3SPeter Brune     if (len) *len = l;
146914a18fd3SPeter Brune   }
1470e30e807fSPeter Brune   PetscFunctionReturn(0);
1471e30e807fSPeter Brune }
1472e30e807fSPeter Brune 
1473e30e807fSPeter Brune 
1474e30e807fSPeter Brune #undef __FUNCT__
1475e30e807fSPeter Brune #define __FUNCT__ "DMCreateDomainDecompositionScatters"
1476e30e807fSPeter Brune /*@C
1477e30e807fSPeter Brune   DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector
1478e30e807fSPeter Brune 
1479e30e807fSPeter Brune   Not collective
1480e30e807fSPeter Brune 
1481e30e807fSPeter Brune   Input Parameters:
1482e30e807fSPeter Brune + dm - the DM object
1483e30e807fSPeter Brune . n  - the number of subdomain scatters
1484e30e807fSPeter Brune - subdms - the local subdomains
1485e30e807fSPeter Brune 
1486e30e807fSPeter Brune   Output Parameters:
1487e30e807fSPeter Brune + n     - the number of scatters returned
1488e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain
1489e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain
1490e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts)
1491e30e807fSPeter Brune 
1492e30e807fSPeter Brune   Notes: This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution
1493e30e807fSPeter Brune   of general nonlinear problems with overlapping subdomain methods.  While merely having index sets that enable subsets
1494e30e807fSPeter Brune   of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of
1495e30e807fSPeter Brune   solution and residual data.
1496e30e807fSPeter Brune 
1497e30e807fSPeter Brune   Level: developer
1498e30e807fSPeter Brune 
1499e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1500e30e807fSPeter Brune @*/
1501e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat)
1502e30e807fSPeter Brune {
1503e30e807fSPeter Brune   PetscErrorCode ierr;
1504e30e807fSPeter Brune 
1505e30e807fSPeter Brune   PetscFunctionBegin;
1506e30e807fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1507e30e807fSPeter Brune   PetscValidPointer(subdms,3);
1508e30e807fSPeter Brune   if (dm->ops->createddscatters) {
1509e30e807fSPeter Brune     ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr);
151082f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateDomainDecompositionLocalScatter implementation defined");
1511e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1512e7c4fc90SDmitry Karpeev }
1513e7c4fc90SDmitry Karpeev 
1514731c8d9eSDmitry Karpeev #undef __FUNCT__
151547c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
151647c6ae99SBarry Smith /*@
151747c6ae99SBarry Smith   DMRefine - Refines a DM object
151847c6ae99SBarry Smith 
151947c6ae99SBarry Smith   Collective on DM
152047c6ae99SBarry Smith 
152147c6ae99SBarry Smith   Input Parameter:
152247c6ae99SBarry Smith + dm   - the DM object
152391d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
152447c6ae99SBarry Smith 
152547c6ae99SBarry Smith   Output Parameter:
15260298fd71SBarry Smith . dmf - the refined DM, or NULL
1527ae0a1c52SMatthew G Knepley 
15280298fd71SBarry Smith   Note: If no refinement was done, the return value is NULL
152947c6ae99SBarry Smith 
153047c6ae99SBarry Smith   Level: developer
153147c6ae99SBarry Smith 
1532e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
153347c6ae99SBarry Smith @*/
15347087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
153547c6ae99SBarry Smith {
153647c6ae99SBarry Smith   PetscErrorCode   ierr;
1537c833c3b5SJed Brown   DMRefineHookLink link;
153847c6ae99SBarry Smith 
153947c6ae99SBarry Smith   PetscFunctionBegin;
1540732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
154147c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
15424057135bSMatthew G Knepley   if (*dmf) {
154343842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
15448865f1eaSKarl Rupp 
15458cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
15468865f1eaSKarl Rupp 
1547644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
15480598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1549656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
15508865f1eaSKarl Rupp 
1551e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1552c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
15538865f1eaSKarl Rupp       if (link->refinehook) {
15548865f1eaSKarl Rupp         ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);
15558865f1eaSKarl Rupp       }
1556c833c3b5SJed Brown     }
1557c833c3b5SJed Brown   }
1558c833c3b5SJed Brown   PetscFunctionReturn(0);
1559c833c3b5SJed Brown }
1560c833c3b5SJed Brown 
1561c833c3b5SJed Brown #undef __FUNCT__
1562c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1563bb9467b5SJed Brown /*@C
1564c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1565c833c3b5SJed Brown 
1566c833c3b5SJed Brown    Logically Collective
1567c833c3b5SJed Brown 
1568c833c3b5SJed Brown    Input Arguments:
1569c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1570c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1571c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
15720298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1573c833c3b5SJed Brown 
1574c833c3b5SJed Brown    Calling sequence of refinehook:
1575c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1576c833c3b5SJed Brown 
1577c833c3b5SJed Brown +  coarse - coarse level DM
1578c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1579c833c3b5SJed Brown -  ctx - optional user-defined function context
1580c833c3b5SJed Brown 
1581c833c3b5SJed Brown    Calling sequence for interphook:
1582c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1583c833c3b5SJed Brown 
1584c833c3b5SJed Brown +  coarse - coarse level DM
1585c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1586c833c3b5SJed Brown .  fine - fine level DM to update
1587c833c3b5SJed Brown -  ctx - optional user-defined function context
1588c833c3b5SJed Brown 
1589c833c3b5SJed Brown    Level: advanced
1590c833c3b5SJed Brown 
1591c833c3b5SJed Brown    Notes:
1592c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1593c833c3b5SJed Brown 
1594c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1595c833c3b5SJed Brown 
1596bb9467b5SJed Brown    This function is currently not available from Fortran.
1597bb9467b5SJed Brown 
1598c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1599c833c3b5SJed Brown @*/
1600c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1601c833c3b5SJed Brown {
1602c833c3b5SJed Brown   PetscErrorCode   ierr;
1603c833c3b5SJed Brown   DMRefineHookLink link,*p;
1604c833c3b5SJed Brown 
1605c833c3b5SJed Brown   PetscFunctionBegin;
1606c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1607c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1608c833c3b5SJed Brown   ierr             = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1609c833c3b5SJed Brown   link->refinehook = refinehook;
1610c833c3b5SJed Brown   link->interphook = interphook;
1611c833c3b5SJed Brown   link->ctx        = ctx;
16120298fd71SBarry Smith   link->next       = NULL;
1613c833c3b5SJed Brown   *p               = link;
1614c833c3b5SJed Brown   PetscFunctionReturn(0);
1615c833c3b5SJed Brown }
1616c833c3b5SJed Brown 
1617c833c3b5SJed Brown #undef __FUNCT__
1618c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1619c833c3b5SJed Brown /*@
1620c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1621c833c3b5SJed Brown 
1622c833c3b5SJed Brown    Collective if any hooks are
1623c833c3b5SJed Brown 
1624c833c3b5SJed Brown    Input Arguments:
1625c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1626c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1627c833c3b5SJed Brown -  fine - finer DM to update
1628c833c3b5SJed Brown 
1629c833c3b5SJed Brown    Level: developer
1630c833c3b5SJed Brown 
1631c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1632c833c3b5SJed Brown @*/
1633c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1634c833c3b5SJed Brown {
1635c833c3b5SJed Brown   PetscErrorCode   ierr;
1636c833c3b5SJed Brown   DMRefineHookLink link;
1637c833c3b5SJed Brown 
1638c833c3b5SJed Brown   PetscFunctionBegin;
1639c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
16408865f1eaSKarl Rupp     if (link->interphook) {
16418865f1eaSKarl Rupp       ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);
16428865f1eaSKarl Rupp     }
16434057135bSMatthew G Knepley   }
164447c6ae99SBarry Smith   PetscFunctionReturn(0);
164547c6ae99SBarry Smith }
164647c6ae99SBarry Smith 
164747c6ae99SBarry Smith #undef __FUNCT__
1648eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1649eb3f98d2SBarry Smith /*@
1650eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1651eb3f98d2SBarry Smith 
1652eb3f98d2SBarry Smith     Not Collective
1653eb3f98d2SBarry Smith 
1654eb3f98d2SBarry Smith     Input Parameter:
1655eb3f98d2SBarry Smith .   dm - the DM object
1656eb3f98d2SBarry Smith 
1657eb3f98d2SBarry Smith     Output Parameter:
1658eb3f98d2SBarry Smith .   level - number of refinements
1659eb3f98d2SBarry Smith 
1660eb3f98d2SBarry Smith     Level: developer
1661eb3f98d2SBarry Smith 
16626a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1663eb3f98d2SBarry Smith 
1664eb3f98d2SBarry Smith @*/
1665eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1666eb3f98d2SBarry Smith {
1667eb3f98d2SBarry Smith   PetscFunctionBegin;
1668eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1669eb3f98d2SBarry Smith   *level = dm->levelup;
1670eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1671eb3f98d2SBarry Smith }
1672eb3f98d2SBarry Smith 
1673eb3f98d2SBarry Smith #undef __FUNCT__
1674baf369e7SPeter Brune #define __FUNCT__ "DMGlobalToLocalHookAdd"
1675bb9467b5SJed Brown /*@C
1676baf369e7SPeter Brune    DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called
1677baf369e7SPeter Brune 
1678baf369e7SPeter Brune    Logically Collective
1679baf369e7SPeter Brune 
1680baf369e7SPeter Brune    Input Arguments:
1681baf369e7SPeter Brune +  dm - the DM
1682baf369e7SPeter Brune .  beginhook - function to run at the beginning of DMGlobalToLocalBegin()
1683baf369e7SPeter Brune .  endhook - function to run after DMGlobalToLocalEnd() has completed
16840298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1685baf369e7SPeter Brune 
1686baf369e7SPeter Brune    Calling sequence for beginhook:
1687baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1688baf369e7SPeter Brune 
1689baf369e7SPeter Brune +  dm - global DM
1690baf369e7SPeter Brune .  g - global vector
1691baf369e7SPeter Brune .  mode - mode
1692baf369e7SPeter Brune .  l - local vector
1693baf369e7SPeter Brune -  ctx - optional user-defined function context
1694baf369e7SPeter Brune 
1695baf369e7SPeter Brune 
1696baf369e7SPeter Brune    Calling sequence for endhook:
1697ec4806b8SPeter Brune $    endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1698baf369e7SPeter Brune 
1699baf369e7SPeter Brune +  global - global DM
1700baf369e7SPeter Brune -  ctx - optional user-defined function context
1701baf369e7SPeter Brune 
1702baf369e7SPeter Brune    Level: advanced
1703baf369e7SPeter Brune 
1704baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1705baf369e7SPeter Brune @*/
1706baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
1707baf369e7SPeter Brune {
1708baf369e7SPeter Brune   PetscErrorCode          ierr;
1709baf369e7SPeter Brune   DMGlobalToLocalHookLink link,*p;
1710baf369e7SPeter Brune 
1711baf369e7SPeter Brune   PetscFunctionBegin;
1712baf369e7SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1713baf369e7SPeter Brune   for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1714baf369e7SPeter Brune   ierr            = PetscMalloc(sizeof(struct _DMGlobalToLocalHookLink),&link);CHKERRQ(ierr);
1715baf369e7SPeter Brune   link->beginhook = beginhook;
1716baf369e7SPeter Brune   link->endhook   = endhook;
1717baf369e7SPeter Brune   link->ctx       = ctx;
17180298fd71SBarry Smith   link->next      = NULL;
1719baf369e7SPeter Brune   *p              = link;
1720baf369e7SPeter Brune   PetscFunctionReturn(0);
1721baf369e7SPeter Brune }
1722baf369e7SPeter Brune 
1723baf369e7SPeter Brune #undef __FUNCT__
17244c274da1SToby Isaac #define __FUNCT__ "DMGlobalToLocalHook_Constraints"
17254c274da1SToby Isaac static PetscErrorCode DMGlobalToLocalHook_Constraints(DM dm, Vec g, InsertMode mode, Vec l, void *ctx)
17264c274da1SToby Isaac {
17274c274da1SToby Isaac   Mat cMat;
17284c274da1SToby Isaac   Vec cVec;
17294c274da1SToby Isaac   PetscSection section, cSec;
17304c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
17314c274da1SToby Isaac   PetscErrorCode ierr;
17324c274da1SToby Isaac 
17334c274da1SToby Isaac   PetscFunctionBegin;
17344c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
17354c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
17364c274da1SToby Isaac   if (cMat && (mode == INSERT_VALUES || mode == INSERT_ALL_VALUES || mode == INSERT_BC_VALUES)) {
17374c274da1SToby Isaac     ierr = DMGetDefaultSection(dm,&section);CHKERRQ(ierr);
17387711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
17394c274da1SToby Isaac     ierr = MatMult(cMat,l,cVec);CHKERRQ(ierr);
17404c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
17414c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
17424c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
17434c274da1SToby Isaac       if (dof) {
17444c274da1SToby Isaac         PetscScalar *vals;
17454c274da1SToby Isaac         ierr = VecGetValuesSection(cVec,cSec,p,&vals);CHKERRQ(ierr);
17464c274da1SToby Isaac         ierr = VecSetValuesSection(l,section,p,vals,INSERT_ALL_VALUES);CHKERRQ(ierr);
17474c274da1SToby Isaac       }
17484c274da1SToby Isaac     }
17494c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
17504c274da1SToby Isaac   }
17514c274da1SToby Isaac   PetscFunctionReturn(0);
17524c274da1SToby Isaac }
17534c274da1SToby Isaac 
17544c274da1SToby Isaac #undef __FUNCT__
175547c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
175647c6ae99SBarry Smith /*@
175747c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
175847c6ae99SBarry Smith 
175947c6ae99SBarry Smith     Neighbor-wise Collective on DM
176047c6ae99SBarry Smith 
176147c6ae99SBarry Smith     Input Parameters:
176247c6ae99SBarry Smith +   dm - the DM object
176347c6ae99SBarry Smith .   g - the global vector
176447c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
176547c6ae99SBarry Smith -   l - the local vector
176647c6ae99SBarry Smith 
176747c6ae99SBarry Smith 
176847c6ae99SBarry Smith     Level: beginner
176947c6ae99SBarry Smith 
1770e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
177147c6ae99SBarry Smith 
177247c6ae99SBarry Smith @*/
17737087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
177447c6ae99SBarry Smith {
17757128ae9fSMatthew G Knepley   PetscSF                 sf;
177647c6ae99SBarry Smith   PetscErrorCode          ierr;
1777baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
177847c6ae99SBarry Smith 
177947c6ae99SBarry Smith   PetscFunctionBegin;
1780171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1781baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
17828865f1eaSKarl Rupp     if (link->beginhook) {
17838865f1eaSKarl Rupp       ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);
17848865f1eaSKarl Rupp     }
1785baf369e7SPeter Brune   }
17867128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17877128ae9fSMatthew G Knepley   if (sf) {
1788ae5cfb4aSMatthew G. Knepley     const PetscScalar *gArray;
1789ae5cfb4aSMatthew G. Knepley     PetscScalar       *lArray;
17907128ae9fSMatthew G Knepley 
179182f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17927128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
1793ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
17947128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
17957128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
1796ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
17977128ae9fSMatthew G Knepley   } else {
1798843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
17997128ae9fSMatthew G Knepley   }
180047c6ae99SBarry Smith   PetscFunctionReturn(0);
180147c6ae99SBarry Smith }
180247c6ae99SBarry Smith 
180347c6ae99SBarry Smith #undef __FUNCT__
180447c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
180547c6ae99SBarry Smith /*@
180647c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
180747c6ae99SBarry Smith 
180847c6ae99SBarry Smith     Neighbor-wise Collective on DM
180947c6ae99SBarry Smith 
181047c6ae99SBarry Smith     Input Parameters:
181147c6ae99SBarry Smith +   dm - the DM object
181247c6ae99SBarry Smith .   g - the global vector
181347c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
181447c6ae99SBarry Smith -   l - the local vector
181547c6ae99SBarry Smith 
181647c6ae99SBarry Smith 
181747c6ae99SBarry Smith     Level: beginner
181847c6ae99SBarry Smith 
1819e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
182047c6ae99SBarry Smith 
182147c6ae99SBarry Smith @*/
18227087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
182347c6ae99SBarry Smith {
18247128ae9fSMatthew G Knepley   PetscSF                 sf;
182547c6ae99SBarry Smith   PetscErrorCode          ierr;
1826ae5cfb4aSMatthew G. Knepley   const PetscScalar      *gArray;
1827ae5cfb4aSMatthew G. Knepley   PetscScalar            *lArray;
1828baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
182947c6ae99SBarry Smith 
183047c6ae99SBarry Smith   PetscFunctionBegin;
1831171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18327128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
18337128ae9fSMatthew G Knepley   if (sf) {
183482f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
18357128ae9fSMatthew G Knepley 
18367128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
1837ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(g, &gArray);CHKERRQ(ierr);
18387128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
18397128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
1840ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(g, &gArray);CHKERRQ(ierr);
18417128ae9fSMatthew G Knepley   } else {
1842843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
18437128ae9fSMatthew G Knepley   }
18444c274da1SToby Isaac   ierr = DMGlobalToLocalHook_Constraints(dm,g,mode,l,NULL);CHKERRQ(ierr);
1845baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
1846baf369e7SPeter Brune     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
1847baf369e7SPeter Brune   }
184847c6ae99SBarry Smith   PetscFunctionReturn(0);
184947c6ae99SBarry Smith }
185047c6ae99SBarry Smith 
185147c6ae99SBarry Smith #undef __FUNCT__
1852d4d07f1eSToby Isaac #define __FUNCT__ "DMLocalToGlobalHookAdd"
1853d4d07f1eSToby Isaac /*@C
1854d4d07f1eSToby Isaac    DMLocalToGlobalHookAdd - adds a callback to be run when a local to global is called
1855d4d07f1eSToby Isaac 
1856d4d07f1eSToby Isaac    Logically Collective
1857d4d07f1eSToby Isaac 
1858d4d07f1eSToby Isaac    Input Arguments:
1859d4d07f1eSToby Isaac +  dm - the DM
1860d4d07f1eSToby Isaac .  beginhook - function to run at the beginning of DMLocalToGlobalBegin()
1861d4d07f1eSToby Isaac .  endhook - function to run after DMLocalToGlobalEnd() has completed
1862d4d07f1eSToby Isaac -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1863d4d07f1eSToby Isaac 
1864d4d07f1eSToby Isaac    Calling sequence for beginhook:
1865d4d07f1eSToby Isaac $    beginhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
1866d4d07f1eSToby Isaac 
1867d4d07f1eSToby Isaac +  dm - global DM
1868d4d07f1eSToby Isaac .  l - local vector
1869d4d07f1eSToby Isaac .  mode - mode
1870d4d07f1eSToby Isaac .  g - global vector
1871d4d07f1eSToby Isaac -  ctx - optional user-defined function context
1872d4d07f1eSToby Isaac 
1873d4d07f1eSToby Isaac 
1874d4d07f1eSToby Isaac    Calling sequence for endhook:
1875d4d07f1eSToby Isaac $    endhook(DM fine,Vec l,InsertMode mode,Vec g,void *ctx)
1876d4d07f1eSToby Isaac 
1877d4d07f1eSToby Isaac +  global - global DM
1878d4d07f1eSToby Isaac .  l - local vector
1879d4d07f1eSToby Isaac .  mode - mode
1880d4d07f1eSToby Isaac .  g - global vector
1881d4d07f1eSToby Isaac -  ctx - optional user-defined function context
1882d4d07f1eSToby Isaac 
1883d4d07f1eSToby Isaac    Level: advanced
1884d4d07f1eSToby Isaac 
1885d4d07f1eSToby Isaac .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1886d4d07f1eSToby Isaac @*/
1887d4d07f1eSToby Isaac PetscErrorCode DMLocalToGlobalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
1888d4d07f1eSToby Isaac {
1889d4d07f1eSToby Isaac   PetscErrorCode          ierr;
1890d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link,*p;
1891d4d07f1eSToby Isaac 
1892d4d07f1eSToby Isaac   PetscFunctionBegin;
1893d4d07f1eSToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1894d4d07f1eSToby Isaac   for (p=&dm->ltoghook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1895d4d07f1eSToby Isaac   ierr            = PetscMalloc(sizeof(struct _DMLocalToGlobalHookLink),&link);CHKERRQ(ierr);
1896d4d07f1eSToby Isaac   link->beginhook = beginhook;
1897d4d07f1eSToby Isaac   link->endhook   = endhook;
1898d4d07f1eSToby Isaac   link->ctx       = ctx;
1899d4d07f1eSToby Isaac   link->next      = NULL;
1900d4d07f1eSToby Isaac   *p              = link;
1901d4d07f1eSToby Isaac   PetscFunctionReturn(0);
1902d4d07f1eSToby Isaac }
1903d4d07f1eSToby Isaac 
1904d4d07f1eSToby Isaac #undef __FUNCT__
19054c274da1SToby Isaac #define __FUNCT__ "DMLocalToGlobalHook_Constraints"
19064c274da1SToby Isaac static PetscErrorCode DMLocalToGlobalHook_Constraints(DM dm, Vec l, InsertMode mode, Vec g, void *ctx)
19074c274da1SToby Isaac {
19084c274da1SToby Isaac   Mat cMat;
19094c274da1SToby Isaac   Vec cVec;
19104c274da1SToby Isaac   PetscSection section, cSec;
19114c274da1SToby Isaac   PetscInt pStart, pEnd, p, dof;
19124c274da1SToby Isaac   PetscErrorCode ierr;
19134c274da1SToby Isaac 
19144c274da1SToby Isaac   PetscFunctionBegin;
19154c274da1SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
19164c274da1SToby Isaac   ierr = DMGetDefaultConstraints(dm,&cSec,&cMat);CHKERRQ(ierr);
19174c274da1SToby Isaac   if (cMat && (mode == ADD_VALUES || mode == ADD_ALL_VALUES || mode == ADD_BC_VALUES)) {
19184c274da1SToby Isaac     ierr = DMGetDefaultSection(dm,&section);CHKERRQ(ierr);
19197711e48fSToby Isaac     ierr = MatCreateVecs(cMat,NULL,&cVec);CHKERRQ(ierr);
19204c274da1SToby Isaac     ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr);
19214c274da1SToby Isaac     for (p = pStart; p < pEnd; p++) {
19224c274da1SToby Isaac       ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr);
19234c274da1SToby Isaac       if (dof) {
19244c274da1SToby Isaac         PetscInt d;
19254c274da1SToby Isaac         PetscScalar *vals;
19264c274da1SToby Isaac         ierr = VecGetValuesSection(l,section,p,&vals);CHKERRQ(ierr);
19274c274da1SToby Isaac         ierr = VecSetValuesSection(cVec,cSec,p,vals,mode);CHKERRQ(ierr);
19284c274da1SToby Isaac         /* for this to be the true transpose, we have to zero the values that
19294c274da1SToby Isaac          * we just extracted */
19304c274da1SToby Isaac         for (d = 0; d < dof; d++) {
19314c274da1SToby Isaac           vals[d] = 0.;
19324c274da1SToby Isaac         }
19334c274da1SToby Isaac       }
19344c274da1SToby Isaac     }
19354c274da1SToby Isaac     ierr = MatMultTransposeAdd(cMat,cVec,l,l);CHKERRQ(ierr);
19364c274da1SToby Isaac     ierr = VecDestroy(&cVec);CHKERRQ(ierr);
19374c274da1SToby Isaac   }
19384c274da1SToby Isaac   PetscFunctionReturn(0);
19394c274da1SToby Isaac }
19404c274da1SToby Isaac 
19414c274da1SToby Isaac #undef __FUNCT__
19429a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
194347c6ae99SBarry Smith /*@
19449a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
19459a42bb27SBarry Smith 
19469a42bb27SBarry Smith     Neighbor-wise Collective on DM
19479a42bb27SBarry Smith 
19489a42bb27SBarry Smith     Input Parameters:
19499a42bb27SBarry Smith +   dm - the DM object
1950f6813fd5SJed Brown .   l - the local vector
19511eb28f2eSBarry 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.
19521eb28f2eSBarry Smith -   g - the global vector
19539a42bb27SBarry Smith 
1954d96308ebSBarry Smith     Notes: In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation.
195584330215SMatthew 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.
19569a42bb27SBarry Smith 
19579a42bb27SBarry Smith     Level: beginner
19589a42bb27SBarry Smith 
1959e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
19609a42bb27SBarry Smith 
19619a42bb27SBarry Smith @*/
19627087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
19639a42bb27SBarry Smith {
19647128ae9fSMatthew G Knepley   PetscSF                 sf;
196584330215SMatthew G. Knepley   PetscSection            s, gs;
1966d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
1967ae5cfb4aSMatthew G. Knepley   const PetscScalar      *lArray;
1968ae5cfb4aSMatthew G. Knepley   PetscScalar            *gArray;
196984330215SMatthew G. Knepley   PetscBool               isInsert;
197084330215SMatthew G. Knepley   PetscErrorCode          ierr;
19719a42bb27SBarry Smith 
19729a42bb27SBarry Smith   PetscFunctionBegin;
1973171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1974d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
1975d4d07f1eSToby Isaac     if (link->beginhook) {
1976d4d07f1eSToby Isaac       ierr = (*link->beginhook)(dm,l,mode,g,link->ctx);CHKERRQ(ierr);
1977d4d07f1eSToby Isaac     }
1978d4d07f1eSToby Isaac   }
19794c274da1SToby Isaac   ierr = DMLocalToGlobalHook_Constraints(dm,l,mode,g,NULL);CHKERRQ(ierr);
19807128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
198184330215SMatthew G. Knepley   ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
19827128ae9fSMatthew G Knepley   switch (mode) {
19837128ae9fSMatthew G Knepley   case INSERT_VALUES:
19847128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
198584330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
19867128ae9fSMatthew G Knepley   case ADD_VALUES:
19877128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
198884330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
19897128ae9fSMatthew G Knepley   default:
199082f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
19917128ae9fSMatthew G Knepley   }
199284330215SMatthew G. Knepley   if (sf && !isInsert) {
1993ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
19947128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
1995a9b180a6SBarry Smith     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
1996ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
199784330215SMatthew G. Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
199884330215SMatthew G. Knepley   } else if (s && isInsert) {
199984330215SMatthew G. Knepley     PetscInt gStart, pStart, pEnd, p;
200084330215SMatthew G. Knepley 
200184330215SMatthew G. Knepley     ierr = DMGetDefaultGlobalSection(dm, &gs);CHKERRQ(ierr);
200284330215SMatthew G. Knepley     ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
200384330215SMatthew G. Knepley     ierr = VecGetOwnershipRange(g, &gStart, NULL);CHKERRQ(ierr);
2004ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
200584330215SMatthew G. Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
200684330215SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
2007b3b16f48SMatthew G. Knepley       PetscInt dof, gdof, cdof, gcdof, off, goff, d, e;
200884330215SMatthew G. Knepley 
200984330215SMatthew G. Knepley       ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr);
201003442857SMatthew G. Knepley       ierr = PetscSectionGetDof(gs, p, &gdof);CHKERRQ(ierr);
201184330215SMatthew G. Knepley       ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr);
2012b3b16f48SMatthew G. Knepley       ierr = PetscSectionGetConstraintDof(gs, p, &gcdof);CHKERRQ(ierr);
201384330215SMatthew G. Knepley       ierr = PetscSectionGetOffset(s, p, &off);CHKERRQ(ierr);
201484330215SMatthew G. Knepley       ierr = PetscSectionGetOffset(gs, p, &goff);CHKERRQ(ierr);
2015b3b16f48SMatthew G. Knepley       /* Ignore off-process data and points with no global data */
201603442857SMatthew G. Knepley       if (!gdof || goff < 0) continue;
2017b3b16f48SMatthew 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);
2018b3b16f48SMatthew G. Knepley       /* If no constraints are enforced in the global vector */
2019b3b16f48SMatthew G. Knepley       if (!gcdof) {
202084330215SMatthew G. Knepley         for (d = 0; d < dof; ++d) gArray[goff-gStart+d] = lArray[off+d];
2021b3b16f48SMatthew G. Knepley       /* If constraints are enforced in the global vector */
2022b3b16f48SMatthew G. Knepley       } else if (cdof == gcdof) {
202384330215SMatthew G. Knepley         const PetscInt *cdofs;
202484330215SMatthew G. Knepley         PetscInt        cind = 0;
202584330215SMatthew G. Knepley 
202684330215SMatthew G. Knepley         ierr = PetscSectionGetConstraintIndices(s, p, &cdofs);CHKERRQ(ierr);
2027b3b16f48SMatthew G. Knepley         for (d = 0, e = 0; d < dof; ++d) {
202884330215SMatthew G. Knepley           if ((cind < cdof) && (d == cdofs[cind])) {++cind; continue;}
2029b3b16f48SMatthew G. Knepley           gArray[goff-gStart+e++] = lArray[off+d];
203084330215SMatthew G. Knepley         }
2031b3b16f48SMatthew 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);
203284330215SMatthew G. Knepley     }
2033ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
20347128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
20357128ae9fSMatthew G Knepley   } else {
2036843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
20377128ae9fSMatthew G Knepley   }
20389a42bb27SBarry Smith   PetscFunctionReturn(0);
20399a42bb27SBarry Smith }
20409a42bb27SBarry Smith 
20419a42bb27SBarry Smith #undef __FUNCT__
20429a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
20439a42bb27SBarry Smith /*@
20449a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
204547c6ae99SBarry Smith 
204647c6ae99SBarry Smith     Neighbor-wise Collective on DM
204747c6ae99SBarry Smith 
204847c6ae99SBarry Smith     Input Parameters:
204947c6ae99SBarry Smith +   dm - the DM object
2050f6813fd5SJed Brown .   l - the local vector
205147c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
2052f6813fd5SJed Brown -   g - the global vector
205347c6ae99SBarry Smith 
205447c6ae99SBarry Smith 
205547c6ae99SBarry Smith     Level: beginner
205647c6ae99SBarry Smith 
2057e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
205847c6ae99SBarry Smith 
205947c6ae99SBarry Smith @*/
20607087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
206147c6ae99SBarry Smith {
20627128ae9fSMatthew G Knepley   PetscSF                 sf;
206384330215SMatthew G. Knepley   PetscSection            s;
2064d4d07f1eSToby Isaac   DMLocalToGlobalHookLink link;
206584330215SMatthew G. Knepley   PetscBool               isInsert;
206684330215SMatthew G. Knepley   PetscErrorCode          ierr;
206747c6ae99SBarry Smith 
206847c6ae99SBarry Smith   PetscFunctionBegin;
2069171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
20707128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
207184330215SMatthew G. Knepley   ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
20727128ae9fSMatthew G Knepley   switch (mode) {
20737128ae9fSMatthew G Knepley   case INSERT_VALUES:
20747128ae9fSMatthew G Knepley   case INSERT_ALL_VALUES:
207584330215SMatthew G. Knepley     isInsert = PETSC_TRUE; break;
20767128ae9fSMatthew G Knepley   case ADD_VALUES:
20777128ae9fSMatthew G Knepley   case ADD_ALL_VALUES:
207884330215SMatthew G. Knepley     isInsert = PETSC_FALSE; break;
20797128ae9fSMatthew G Knepley   default:
208082f516ccSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
20817128ae9fSMatthew G Knepley   }
208284330215SMatthew G. Knepley   if (sf && !isInsert) {
2083ae5cfb4aSMatthew G. Knepley     const PetscScalar *lArray;
2084ae5cfb4aSMatthew G. Knepley     PetscScalar       *gArray;
208584330215SMatthew G. Knepley 
2086ae5cfb4aSMatthew G. Knepley     ierr = VecGetArrayRead(l, &lArray);CHKERRQ(ierr);
20877128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
2088a9b180a6SBarry Smith     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_SUM);CHKERRQ(ierr);
2089ae5cfb4aSMatthew G. Knepley     ierr = VecRestoreArrayRead(l, &lArray);CHKERRQ(ierr);
20907128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
209184330215SMatthew G. Knepley   } else if (s && isInsert) {
20927128ae9fSMatthew G Knepley   } else {
2093843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
20947128ae9fSMatthew G Knepley   }
2095d4d07f1eSToby Isaac   for (link=dm->ltoghook; link; link=link->next) {
2096d4d07f1eSToby Isaac     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
2097d4d07f1eSToby Isaac   }
209847c6ae99SBarry Smith   PetscFunctionReturn(0);
209947c6ae99SBarry Smith }
210047c6ae99SBarry Smith 
210147c6ae99SBarry Smith #undef __FUNCT__
2102f089877aSRichard Tran Mills #define __FUNCT__ "DMLocalToLocalBegin"
2103f089877aSRichard Tran Mills /*@
2104bc0a1609SRichard Tran Mills    DMLocalToLocalBegin - Maps from a local vector (including ghost points
2105bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2106d78e899eSRichard Tran Mills    points in the second are set correctly. Must be followed by DMLocalToLocalEnd().
2107f089877aSRichard Tran Mills 
2108bc0a1609SRichard Tran Mills    Neighbor-wise Collective on DM and Vec
2109f089877aSRichard Tran Mills 
2110f089877aSRichard Tran Mills    Input Parameters:
2111f089877aSRichard Tran Mills +  dm - the DM object
2112bc0a1609SRichard Tran Mills .  g - the original local vector
2113bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2114f089877aSRichard Tran Mills 
2115bc0a1609SRichard Tran Mills    Output Parameter:
2116bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2117f089877aSRichard Tran Mills 
2118f089877aSRichard Tran Mills    Level: intermediate
2119f089877aSRichard Tran Mills 
2120bc0a1609SRichard Tran Mills    Notes:
2121bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2122bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2123bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2124bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2125bc0a1609SRichard Tran Mills 
2126bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, begin
2127bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2128f089877aSRichard Tran Mills 
2129f089877aSRichard Tran Mills @*/
2130f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
2131f089877aSRichard Tran Mills {
2132f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2133f089877aSRichard Tran Mills 
2134f089877aSRichard Tran Mills   PetscFunctionBegin;
2135f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2136f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2137f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2138f089877aSRichard Tran Mills }
2139f089877aSRichard Tran Mills 
2140f089877aSRichard Tran Mills #undef __FUNCT__
2141f089877aSRichard Tran Mills #define __FUNCT__ "DMLocalToLocalEnd"
2142f089877aSRichard Tran Mills /*@
2143bc0a1609SRichard Tran Mills    DMLocalToLocalEnd - Maps from a local vector (including ghost points
2144bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
2145d78e899eSRichard Tran Mills    points in the second are set correctly. Must be preceded by DMLocalToLocalBegin().
2146f089877aSRichard Tran Mills 
2147bc0a1609SRichard Tran Mills    Neighbor-wise Collective on DM and Vec
2148f089877aSRichard Tran Mills 
2149f089877aSRichard Tran Mills    Input Parameters:
2150bc0a1609SRichard Tran Mills +  da - the DM object
2151bc0a1609SRichard Tran Mills .  g - the original local vector
2152bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
2153f089877aSRichard Tran Mills 
2154bc0a1609SRichard Tran Mills    Output Parameter:
2155bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
2156f089877aSRichard Tran Mills 
2157f089877aSRichard Tran Mills    Level: intermediate
2158f089877aSRichard Tran Mills 
2159bc0a1609SRichard Tran Mills    Notes:
2160bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
2161bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
2162bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
2163bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
2164bc0a1609SRichard Tran Mills 
2165bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, end
2166bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
2167f089877aSRichard Tran Mills 
2168f089877aSRichard Tran Mills @*/
2169f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
2170f089877aSRichard Tran Mills {
2171f089877aSRichard Tran Mills   PetscErrorCode          ierr;
2172f089877aSRichard Tran Mills 
2173f089877aSRichard Tran Mills   PetscFunctionBegin;
2174f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2175f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
2176f089877aSRichard Tran Mills   PetscFunctionReturn(0);
2177f089877aSRichard Tran Mills }
2178f089877aSRichard Tran Mills 
2179f089877aSRichard Tran Mills 
2180f089877aSRichard Tran Mills #undef __FUNCT__
218147c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
218247c6ae99SBarry Smith /*@
218347c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
218447c6ae99SBarry Smith 
218547c6ae99SBarry Smith     Collective on DM
218647c6ae99SBarry Smith 
218747c6ae99SBarry Smith     Input Parameter:
218847c6ae99SBarry Smith +   dm - the DM object
218991d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
219047c6ae99SBarry Smith 
219147c6ae99SBarry Smith     Output Parameter:
219247c6ae99SBarry Smith .   dmc - the coarsened DM
219347c6ae99SBarry Smith 
219447c6ae99SBarry Smith     Level: developer
219547c6ae99SBarry Smith 
2196e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
219747c6ae99SBarry Smith 
219847c6ae99SBarry Smith @*/
21997087cfbeSBarry Smith PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
220047c6ae99SBarry Smith {
220147c6ae99SBarry Smith   PetscErrorCode    ierr;
2202b17ce1afSJed Brown   DMCoarsenHookLink link;
220347c6ae99SBarry Smith 
220447c6ae99SBarry Smith   PetscFunctionBegin;
2205171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
220647a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
220747c6ae99SBarry Smith   ierr                      = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
22088892b4c3SMatthew G. Knepley   if (!(*dmc)) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "NULL coarse mesh produced");
220943842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
22108cd211a4SJed Brown   ierr                      = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
2211644e2e5bSBarry Smith   (*dmc)->ctx               = dm->ctx;
22120598a293SJed Brown   (*dmc)->levelup           = dm->levelup;
2213656b349aSBarry Smith   (*dmc)->leveldown         = dm->leveldown + 1;
2214e4b4b23bSJed Brown   ierr                      = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
2215b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
2216b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
2217b17ce1afSJed Brown   }
221847a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_Coarsen,dm,0,0,0);CHKERRQ(ierr);
2219b17ce1afSJed Brown   PetscFunctionReturn(0);
2220b17ce1afSJed Brown }
2221b17ce1afSJed Brown 
2222b17ce1afSJed Brown #undef __FUNCT__
2223b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
2224bb9467b5SJed Brown /*@C
2225b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
2226b17ce1afSJed Brown 
2227b17ce1afSJed Brown    Logically Collective
2228b17ce1afSJed Brown 
2229b17ce1afSJed Brown    Input Arguments:
2230b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
2231b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
2232b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
22330298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
2234b17ce1afSJed Brown 
2235b17ce1afSJed Brown    Calling sequence of coarsenhook:
2236b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
2237b17ce1afSJed Brown 
2238b17ce1afSJed Brown +  fine - fine level DM
2239b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
2240b17ce1afSJed Brown -  ctx - optional user-defined function context
2241b17ce1afSJed Brown 
2242b17ce1afSJed Brown    Calling sequence for restricthook:
2243c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
2244b17ce1afSJed Brown 
2245b17ce1afSJed Brown +  fine - fine level DM
2246b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
2247c833c3b5SJed Brown .  rscale - scaling vector for restriction
2248c833c3b5SJed Brown .  inject - matrix restricting by injection
2249b17ce1afSJed Brown .  coarse - coarse level DM to update
2250b17ce1afSJed Brown -  ctx - optional user-defined function context
2251b17ce1afSJed Brown 
2252b17ce1afSJed Brown    Level: advanced
2253b17ce1afSJed Brown 
2254b17ce1afSJed Brown    Notes:
2255b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
2256b17ce1afSJed Brown 
2257b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
2258b17ce1afSJed Brown 
2259b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2260b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
2261b17ce1afSJed Brown 
2262bb9467b5SJed Brown    This function is currently not available from Fortran.
2263bb9467b5SJed Brown 
2264c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2265b17ce1afSJed Brown @*/
2266b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2267b17ce1afSJed Brown {
2268b17ce1afSJed Brown   PetscErrorCode    ierr;
2269b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
2270b17ce1afSJed Brown 
2271b17ce1afSJed Brown   PetscFunctionBegin;
2272b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
22736bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
2274b17ce1afSJed Brown   ierr               = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
2275b17ce1afSJed Brown   link->coarsenhook  = coarsenhook;
2276b17ce1afSJed Brown   link->restricthook = restricthook;
2277b17ce1afSJed Brown   link->ctx          = ctx;
22780298fd71SBarry Smith   link->next         = NULL;
2279b17ce1afSJed Brown   *p                 = link;
2280b17ce1afSJed Brown   PetscFunctionReturn(0);
2281b17ce1afSJed Brown }
2282b17ce1afSJed Brown 
2283b17ce1afSJed Brown #undef __FUNCT__
2284b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
2285b17ce1afSJed Brown /*@
2286b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
2287b17ce1afSJed Brown 
2288b17ce1afSJed Brown    Collective if any hooks are
2289b17ce1afSJed Brown 
2290b17ce1afSJed Brown    Input Arguments:
2291b17ce1afSJed Brown +  fine - finer DM to use as a base
2292b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
2293b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
2294b17ce1afSJed Brown -  coarse - coarer DM to update
2295b17ce1afSJed Brown 
2296b17ce1afSJed Brown    Level: developer
2297b17ce1afSJed Brown 
2298b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
2299b17ce1afSJed Brown @*/
2300b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
2301b17ce1afSJed Brown {
2302b17ce1afSJed Brown   PetscErrorCode    ierr;
2303b17ce1afSJed Brown   DMCoarsenHookLink link;
2304b17ce1afSJed Brown 
2305b17ce1afSJed Brown   PetscFunctionBegin;
2306b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
23078865f1eaSKarl Rupp     if (link->restricthook) {
23088865f1eaSKarl Rupp       ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);
23098865f1eaSKarl Rupp     }
2310b17ce1afSJed Brown   }
231147c6ae99SBarry Smith   PetscFunctionReturn(0);
231247c6ae99SBarry Smith }
231347c6ae99SBarry Smith 
231447c6ae99SBarry Smith #undef __FUNCT__
2315be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainHookAdd"
2316bb9467b5SJed Brown /*@C
2317be081cd6SPeter Brune    DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid
23185dbd56e3SPeter Brune 
23195dbd56e3SPeter Brune    Logically Collective
23205dbd56e3SPeter Brune 
23215dbd56e3SPeter Brune    Input Arguments:
23225dbd56e3SPeter Brune +  global - global DM
2323ec4806b8SPeter Brune .  ddhook - function to run to pass data to the decomposition DM upon its creation
23245dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
23250298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
23265dbd56e3SPeter Brune 
2327ec4806b8SPeter Brune 
2328ec4806b8SPeter Brune    Calling sequence for ddhook:
2329ec4806b8SPeter Brune $    ddhook(DM global,DM block,void *ctx)
2330ec4806b8SPeter Brune 
2331ec4806b8SPeter Brune +  global - global DM
2332ec4806b8SPeter Brune .  block  - block DM
2333ec4806b8SPeter Brune -  ctx - optional user-defined function context
2334ec4806b8SPeter Brune 
23355dbd56e3SPeter Brune    Calling sequence for restricthook:
2336ec4806b8SPeter Brune $    restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx)
23375dbd56e3SPeter Brune 
23385dbd56e3SPeter Brune +  global - global DM
23395dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
23405dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
2341ec4806b8SPeter Brune .  block  - block DM
23425dbd56e3SPeter Brune -  ctx - optional user-defined function context
23435dbd56e3SPeter Brune 
23445dbd56e3SPeter Brune    Level: advanced
23455dbd56e3SPeter Brune 
23465dbd56e3SPeter Brune    Notes:
2347ec4806b8SPeter Brune    This function is only needed if auxiliary data needs to be set up on subdomain DMs.
23485dbd56e3SPeter Brune 
23495dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
23505dbd56e3SPeter Brune 
23515dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2352ec4806b8SPeter Brune    extract the global information from its context (instead of from the SNES).
23535dbd56e3SPeter Brune 
2354bb9467b5SJed Brown    This function is currently not available from Fortran.
2355bb9467b5SJed Brown 
23565dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
23575dbd56e3SPeter Brune @*/
2358be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
23595dbd56e3SPeter Brune {
23605dbd56e3SPeter Brune   PetscErrorCode      ierr;
2361be081cd6SPeter Brune   DMSubDomainHookLink link,*p;
23625dbd56e3SPeter Brune 
23635dbd56e3SPeter Brune   PetscFunctionBegin;
23645dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
2365be081cd6SPeter Brune   for (p=&global->subdomainhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
2366be081cd6SPeter Brune   ierr               = PetscMalloc(sizeof(struct _DMSubDomainHookLink),&link);CHKERRQ(ierr);
23675dbd56e3SPeter Brune   link->restricthook = restricthook;
2368be081cd6SPeter Brune   link->ddhook       = ddhook;
23695dbd56e3SPeter Brune   link->ctx          = ctx;
23700298fd71SBarry Smith   link->next         = NULL;
23715dbd56e3SPeter Brune   *p                 = link;
23725dbd56e3SPeter Brune   PetscFunctionReturn(0);
23735dbd56e3SPeter Brune }
23745dbd56e3SPeter Brune 
23755dbd56e3SPeter Brune #undef __FUNCT__
2376be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainRestrict"
23775dbd56e3SPeter Brune /*@
2378be081cd6SPeter Brune    DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd()
23795dbd56e3SPeter Brune 
23805dbd56e3SPeter Brune    Collective if any hooks are
23815dbd56e3SPeter Brune 
23825dbd56e3SPeter Brune    Input Arguments:
23835dbd56e3SPeter Brune +  fine - finer DM to use as a base
2384be081cd6SPeter Brune .  oscatter - scatter from domain global vector filling subdomain global vector with overlap
2385be081cd6SPeter Brune .  gscatter - scatter from domain global vector filling subdomain local vector with ghosts
23865dbd56e3SPeter Brune -  coarse - coarer DM to update
23875dbd56e3SPeter Brune 
23885dbd56e3SPeter Brune    Level: developer
23895dbd56e3SPeter Brune 
23905dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
23915dbd56e3SPeter Brune @*/
2392be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm)
23935dbd56e3SPeter Brune {
23945dbd56e3SPeter Brune   PetscErrorCode      ierr;
2395be081cd6SPeter Brune   DMSubDomainHookLink link;
23965dbd56e3SPeter Brune 
23975dbd56e3SPeter Brune   PetscFunctionBegin;
2398be081cd6SPeter Brune   for (link=global->subdomainhook; link; link=link->next) {
23998865f1eaSKarl Rupp     if (link->restricthook) {
24008865f1eaSKarl Rupp       ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr);
24018865f1eaSKarl Rupp     }
24025dbd56e3SPeter Brune   }
24035dbd56e3SPeter Brune   PetscFunctionReturn(0);
24045dbd56e3SPeter Brune }
24055dbd56e3SPeter Brune 
24065dbd56e3SPeter Brune #undef __FUNCT__
24075fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
24085fe1f584SPeter Brune /*@
24096a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
24105fe1f584SPeter Brune 
24115fe1f584SPeter Brune     Not Collective
24125fe1f584SPeter Brune 
24135fe1f584SPeter Brune     Input Parameter:
24145fe1f584SPeter Brune .   dm - the DM object
24155fe1f584SPeter Brune 
24165fe1f584SPeter Brune     Output Parameter:
24176a7d9d85SPeter Brune .   level - number of coarsenings
24185fe1f584SPeter Brune 
24195fe1f584SPeter Brune     Level: developer
24205fe1f584SPeter Brune 
24216a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
24225fe1f584SPeter Brune 
24235fe1f584SPeter Brune @*/
24245fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
24255fe1f584SPeter Brune {
24265fe1f584SPeter Brune   PetscFunctionBegin;
24275fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
24285fe1f584SPeter Brune   *level = dm->leveldown;
24295fe1f584SPeter Brune   PetscFunctionReturn(0);
24305fe1f584SPeter Brune }
24315fe1f584SPeter Brune 
24325fe1f584SPeter Brune 
24335fe1f584SPeter Brune 
24345fe1f584SPeter Brune #undef __FUNCT__
243547c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
243647c6ae99SBarry Smith /*@C
243747c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
243847c6ae99SBarry Smith 
243947c6ae99SBarry Smith     Collective on DM
244047c6ae99SBarry Smith 
244147c6ae99SBarry Smith     Input Parameter:
244247c6ae99SBarry Smith +   dm - the DM object
244347c6ae99SBarry Smith -   nlevels - the number of levels of refinement
244447c6ae99SBarry Smith 
244547c6ae99SBarry Smith     Output Parameter:
244647c6ae99SBarry Smith .   dmf - the refined DM hierarchy
244747c6ae99SBarry Smith 
244847c6ae99SBarry Smith     Level: developer
244947c6ae99SBarry Smith 
2450e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
245147c6ae99SBarry Smith 
245247c6ae99SBarry Smith @*/
24537087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
245447c6ae99SBarry Smith {
245547c6ae99SBarry Smith   PetscErrorCode ierr;
245647c6ae99SBarry Smith 
245747c6ae99SBarry Smith   PetscFunctionBegin;
2458171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2459ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
246047c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
246147c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
246247c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
246347c6ae99SBarry Smith   } else if (dm->ops->refine) {
246447c6ae99SBarry Smith     PetscInt i;
246547c6ae99SBarry Smith 
2466ce94432eSBarry Smith     ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr);
246747c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
2468ce94432eSBarry Smith       ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr);
246947c6ae99SBarry Smith     }
2470ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
247147c6ae99SBarry Smith   PetscFunctionReturn(0);
247247c6ae99SBarry Smith }
247347c6ae99SBarry Smith 
247447c6ae99SBarry Smith #undef __FUNCT__
247547c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
247647c6ae99SBarry Smith /*@C
247747c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
247847c6ae99SBarry Smith 
247947c6ae99SBarry Smith     Collective on DM
248047c6ae99SBarry Smith 
248147c6ae99SBarry Smith     Input Parameter:
248247c6ae99SBarry Smith +   dm - the DM object
248347c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
248447c6ae99SBarry Smith 
248547c6ae99SBarry Smith     Output Parameter:
248647c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
248747c6ae99SBarry Smith 
248847c6ae99SBarry Smith     Level: developer
248947c6ae99SBarry Smith 
2490e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
249147c6ae99SBarry Smith 
249247c6ae99SBarry Smith @*/
24937087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
249447c6ae99SBarry Smith {
249547c6ae99SBarry Smith   PetscErrorCode ierr;
249647c6ae99SBarry Smith 
249747c6ae99SBarry Smith   PetscFunctionBegin;
2498171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2499ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
250047c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
250147c6ae99SBarry Smith   PetscValidPointer(dmc,3);
250247c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
250347c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
250447c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
250547c6ae99SBarry Smith     PetscInt i;
250647c6ae99SBarry Smith 
2507ce94432eSBarry Smith     ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr);
250847c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
2509ce94432eSBarry Smith       ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr);
251047c6ae99SBarry Smith     }
2511ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
251247c6ae99SBarry Smith   PetscFunctionReturn(0);
251347c6ae99SBarry Smith }
251447c6ae99SBarry Smith 
251547c6ae99SBarry Smith #undef __FUNCT__
2516e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
251747c6ae99SBarry Smith /*@
2518e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
251947c6ae99SBarry Smith    grids associated with two DMs.
252047c6ae99SBarry Smith 
252147c6ae99SBarry Smith    Collective on DM
252247c6ae99SBarry Smith 
252347c6ae99SBarry Smith    Input Parameters:
252447c6ae99SBarry Smith +  dmc - the coarse grid DM
252547c6ae99SBarry Smith -  dmf - the fine grid DM
252647c6ae99SBarry Smith 
252747c6ae99SBarry Smith    Output Parameters:
252847c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
252947c6ae99SBarry Smith 
253047c6ae99SBarry Smith    Level: intermediate
253147c6ae99SBarry Smith 
253247c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
253347c6ae99SBarry Smith 
2534e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
253547c6ae99SBarry Smith @*/
2536e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
253747c6ae99SBarry Smith {
253847c6ae99SBarry Smith   PetscErrorCode ierr;
253947c6ae99SBarry Smith 
254047c6ae99SBarry Smith   PetscFunctionBegin;
2541171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
2542171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
254347c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
254447c6ae99SBarry Smith   PetscFunctionReturn(0);
254547c6ae99SBarry Smith }
254647c6ae99SBarry Smith 
254747c6ae99SBarry Smith #undef __FUNCT__
25481a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
25491a266240SBarry Smith /*@C
25501a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
25511a266240SBarry Smith 
25521a266240SBarry Smith     Not Collective
25531a266240SBarry Smith 
25541a266240SBarry Smith     Input Parameters:
25551a266240SBarry Smith +   dm - the DM object
25561a266240SBarry Smith -   destroy - the destroy function
25571a266240SBarry Smith 
25581a266240SBarry Smith     Level: intermediate
25591a266240SBarry Smith 
2560e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
25611a266240SBarry Smith 
2562f07f9ceaSJed Brown @*/
25631a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
25641a266240SBarry Smith {
25651a266240SBarry Smith   PetscFunctionBegin;
2566171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
25671a266240SBarry Smith   dm->ctxdestroy = destroy;
25681a266240SBarry Smith   PetscFunctionReturn(0);
25691a266240SBarry Smith }
25701a266240SBarry Smith 
25711a266240SBarry Smith #undef __FUNCT__
25721b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
2573b07ff414SBarry Smith /*@
25741b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
257547c6ae99SBarry Smith 
257647c6ae99SBarry Smith     Not Collective
257747c6ae99SBarry Smith 
257847c6ae99SBarry Smith     Input Parameters:
257947c6ae99SBarry Smith +   dm - the DM object
258047c6ae99SBarry Smith -   ctx - the user context
258147c6ae99SBarry Smith 
258247c6ae99SBarry Smith     Level: intermediate
258347c6ae99SBarry Smith 
2584e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
258547c6ae99SBarry Smith 
258647c6ae99SBarry Smith @*/
25871b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
258847c6ae99SBarry Smith {
258947c6ae99SBarry Smith   PetscFunctionBegin;
2590171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
259147c6ae99SBarry Smith   dm->ctx = ctx;
259247c6ae99SBarry Smith   PetscFunctionReturn(0);
259347c6ae99SBarry Smith }
259447c6ae99SBarry Smith 
259547c6ae99SBarry Smith #undef __FUNCT__
25961b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
259747c6ae99SBarry Smith /*@
25981b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
259947c6ae99SBarry Smith 
260047c6ae99SBarry Smith     Not Collective
260147c6ae99SBarry Smith 
260247c6ae99SBarry Smith     Input Parameter:
260347c6ae99SBarry Smith .   dm - the DM object
260447c6ae99SBarry Smith 
260547c6ae99SBarry Smith     Output Parameter:
260647c6ae99SBarry Smith .   ctx - the user context
260747c6ae99SBarry Smith 
260847c6ae99SBarry Smith     Level: intermediate
260947c6ae99SBarry Smith 
2610e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
261147c6ae99SBarry Smith 
261247c6ae99SBarry Smith @*/
26131b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
261447c6ae99SBarry Smith {
261547c6ae99SBarry Smith   PetscFunctionBegin;
2616171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
26171b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
261847c6ae99SBarry Smith   PetscFunctionReturn(0);
261947c6ae99SBarry Smith }
262047c6ae99SBarry Smith 
262147c6ae99SBarry Smith #undef __FUNCT__
262208da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
262308da532bSDmitry Karpeev /*@C
2624df3898eeSBarry Smith     DMSetVariableBounds - sets a function to compute the lower and upper bound vectors for SNESVI.
262508da532bSDmitry Karpeev 
262608da532bSDmitry Karpeev     Logically Collective on DM
262708da532bSDmitry Karpeev 
262808da532bSDmitry Karpeev     Input Parameter:
262908da532bSDmitry Karpeev +   dm - the DM object
26300298fd71SBarry Smith -   f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set)
263108da532bSDmitry Karpeev 
263208da532bSDmitry Karpeev     Level: intermediate
263308da532bSDmitry Karpeev 
2634835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(),
263508da532bSDmitry Karpeev          DMSetJacobian()
263608da532bSDmitry Karpeev 
263708da532bSDmitry Karpeev @*/
263808da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
263908da532bSDmitry Karpeev {
264008da532bSDmitry Karpeev   PetscFunctionBegin;
264108da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
264208da532bSDmitry Karpeev   PetscFunctionReturn(0);
264308da532bSDmitry Karpeev }
264408da532bSDmitry Karpeev 
264508da532bSDmitry Karpeev #undef __FUNCT__
264608da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
264708da532bSDmitry Karpeev /*@
264808da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
264908da532bSDmitry Karpeev 
265008da532bSDmitry Karpeev     Not Collective
265108da532bSDmitry Karpeev 
265208da532bSDmitry Karpeev     Input Parameter:
265308da532bSDmitry Karpeev .   dm - the DM object to destroy
265408da532bSDmitry Karpeev 
265508da532bSDmitry Karpeev     Output Parameter:
265608da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
265708da532bSDmitry Karpeev 
265808da532bSDmitry Karpeev     Level: developer
265908da532bSDmitry Karpeev 
266074e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
266108da532bSDmitry Karpeev 
266208da532bSDmitry Karpeev @*/
266308da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
266408da532bSDmitry Karpeev {
266508da532bSDmitry Karpeev   PetscFunctionBegin;
266608da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
266708da532bSDmitry Karpeev   PetscFunctionReturn(0);
266808da532bSDmitry Karpeev }
266908da532bSDmitry Karpeev 
267008da532bSDmitry Karpeev #undef __FUNCT__
267108da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
267208da532bSDmitry Karpeev /*@C
267308da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
267408da532bSDmitry Karpeev 
267508da532bSDmitry Karpeev     Logically Collective on DM
267608da532bSDmitry Karpeev 
267708da532bSDmitry Karpeev     Input Parameters:
2678907376e6SBarry Smith .   dm - the DM object
267908da532bSDmitry Karpeev 
268008da532bSDmitry Karpeev     Output parameters:
268108da532bSDmitry Karpeev +   xl - lower bound
268208da532bSDmitry Karpeev -   xu - upper bound
268308da532bSDmitry Karpeev 
2684907376e6SBarry Smith     Level: advanced
2685907376e6SBarry Smith 
2686907376e6SBarry Smith     Notes: This is generally not called by users. It calls the function provided by the user with DMSetVariableBounds()
268708da532bSDmitry Karpeev 
268874e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
268908da532bSDmitry Karpeev 
269008da532bSDmitry Karpeev @*/
269108da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
269208da532bSDmitry Karpeev {
269308da532bSDmitry Karpeev   PetscErrorCode ierr;
26945fd66863SKarl Rupp 
269508da532bSDmitry Karpeev   PetscFunctionBegin;
269608da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
269708da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
269808da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
269908da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr);
27008865f1eaSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
270108da532bSDmitry Karpeev   PetscFunctionReturn(0);
270208da532bSDmitry Karpeev }
270308da532bSDmitry Karpeev 
270408da532bSDmitry Karpeev #undef __FUNCT__
2705b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2706b0ae01b7SPeter Brune /*@
2707b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2708b0ae01b7SPeter Brune 
2709b0ae01b7SPeter Brune     Not Collective
2710b0ae01b7SPeter Brune 
2711b0ae01b7SPeter Brune     Input Parameter:
2712b0ae01b7SPeter Brune .   dm - the DM object
2713b0ae01b7SPeter Brune 
2714b0ae01b7SPeter Brune     Output Parameter:
2715b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2716b0ae01b7SPeter Brune 
2717b0ae01b7SPeter Brune     Level: developer
2718b0ae01b7SPeter Brune 
2719b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2720b0ae01b7SPeter Brune 
2721b0ae01b7SPeter Brune @*/
2722b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2723b0ae01b7SPeter Brune {
2724b0ae01b7SPeter Brune   PetscFunctionBegin;
2725b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2726b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2727b0ae01b7SPeter Brune }
2728b0ae01b7SPeter Brune 
2729b0ae01b7SPeter Brune #undef  __FUNCT__
273008da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2731748fac09SDmitry Karpeev /*@C
273208da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
273308da532bSDmitry Karpeev 
273408da532bSDmitry Karpeev     Collective on DM
273508da532bSDmitry Karpeev 
273608da532bSDmitry Karpeev     Input Parameter:
273708da532bSDmitry Karpeev +   dm - the DM object
27380298fd71SBarry Smith -   x - location to compute residual and Jacobian, if NULL is passed to those routines; will be NULL for linear problems.
273908da532bSDmitry Karpeev 
274008da532bSDmitry Karpeev     Level: developer
274108da532bSDmitry Karpeev 
274274e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
274308da532bSDmitry Karpeev 
274408da532bSDmitry Karpeev @*/
274508da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
274608da532bSDmitry Karpeev {
274708da532bSDmitry Karpeev   PetscErrorCode ierr;
27485fd66863SKarl Rupp 
274908da532bSDmitry Karpeev   PetscFunctionBegin;
275008da532bSDmitry Karpeev   if (x) {
275108da532bSDmitry Karpeev     if (!dm->x) {
275208da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
275308da532bSDmitry Karpeev     }
275408da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
27558865f1eaSKarl Rupp   } else if (dm->x) {
275608da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);CHKERRQ(ierr);
275708da532bSDmitry Karpeev   }
275808da532bSDmitry Karpeev   PetscFunctionReturn(0);
275908da532bSDmitry Karpeev }
276008da532bSDmitry Karpeev 
27610298fd71SBarry Smith PetscFunctionList DMList              = NULL;
2762264ace61SBarry Smith PetscBool         DMRegisterAllCalled = PETSC_FALSE;
2763264ace61SBarry Smith 
2764264ace61SBarry Smith #undef __FUNCT__
2765264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2766264ace61SBarry Smith /*@C
2767264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2768264ace61SBarry Smith 
2769264ace61SBarry Smith   Collective on DM
2770264ace61SBarry Smith 
2771264ace61SBarry Smith   Input Parameters:
2772264ace61SBarry Smith + dm     - The DM object
2773264ace61SBarry Smith - method - The name of the DM type
2774264ace61SBarry Smith 
2775264ace61SBarry Smith   Options Database Key:
2776264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2777264ace61SBarry Smith 
2778264ace61SBarry Smith   Notes:
2779e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2780264ace61SBarry Smith 
2781264ace61SBarry Smith   Level: intermediate
2782264ace61SBarry Smith 
2783264ace61SBarry Smith .keywords: DM, set, type
2784264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2785264ace61SBarry Smith @*/
278619fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
2787264ace61SBarry Smith {
2788264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2789264ace61SBarry Smith   PetscBool      match;
2790264ace61SBarry Smith   PetscErrorCode ierr;
2791264ace61SBarry Smith 
2792264ace61SBarry Smith   PetscFunctionBegin;
2793264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2794251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2795264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2796264ace61SBarry Smith 
27970f51fdf8SToby Isaac   ierr = DMRegisterAll();CHKERRQ(ierr);
27981c9cd337SJed Brown   ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr);
2799ce94432eSBarry Smith   if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2800264ace61SBarry Smith 
2801264ace61SBarry Smith   if (dm->ops->destroy) {
2802264ace61SBarry Smith     ierr             = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
28030298fd71SBarry Smith     dm->ops->destroy = NULL;
2804264ace61SBarry Smith   }
2805264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2806264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2807264ace61SBarry Smith   PetscFunctionReturn(0);
2808264ace61SBarry Smith }
2809264ace61SBarry Smith 
2810264ace61SBarry Smith #undef __FUNCT__
2811264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2812264ace61SBarry Smith /*@C
2813264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2814264ace61SBarry Smith 
2815264ace61SBarry Smith   Not Collective
2816264ace61SBarry Smith 
2817264ace61SBarry Smith   Input Parameter:
2818264ace61SBarry Smith . dm  - The DM
2819264ace61SBarry Smith 
2820264ace61SBarry Smith   Output Parameter:
2821264ace61SBarry Smith . type - The DM type name
2822264ace61SBarry Smith 
2823264ace61SBarry Smith   Level: intermediate
2824264ace61SBarry Smith 
2825264ace61SBarry Smith .keywords: DM, get, type, name
2826264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2827264ace61SBarry Smith @*/
282819fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
2829264ace61SBarry Smith {
2830264ace61SBarry Smith   PetscErrorCode ierr;
2831264ace61SBarry Smith 
2832264ace61SBarry Smith   PetscFunctionBegin;
2833264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2834c959eef4SJed Brown   PetscValidPointer(type,2);
2835607a6623SBarry Smith   ierr = DMRegisterAll();CHKERRQ(ierr);
2836264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2837264ace61SBarry Smith   PetscFunctionReturn(0);
2838264ace61SBarry Smith }
2839264ace61SBarry Smith 
284067a56275SMatthew G Knepley #undef __FUNCT__
284167a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
284267a56275SMatthew G Knepley /*@C
284367a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
284467a56275SMatthew G Knepley 
284567a56275SMatthew G Knepley   Collective on DM
284667a56275SMatthew G Knepley 
284767a56275SMatthew G Knepley   Input Parameters:
284867a56275SMatthew G Knepley + dm - the DM
284967a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
285067a56275SMatthew G Knepley 
285167a56275SMatthew G Knepley   Output Parameter:
285267a56275SMatthew G Knepley . M - pointer to new DM
285367a56275SMatthew G Knepley 
285467a56275SMatthew G Knepley   Notes:
285567a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
285667a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
285767a56275SMatthew G Knepley   of the input DM.
285867a56275SMatthew G Knepley 
285967a56275SMatthew G Knepley   Level: intermediate
286067a56275SMatthew G Knepley 
286167a56275SMatthew G Knepley .seealso: DMCreate()
286267a56275SMatthew G Knepley @*/
286319fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
286467a56275SMatthew G Knepley {
286567a56275SMatthew G Knepley   DM             B;
286667a56275SMatthew G Knepley   char           convname[256];
286767a56275SMatthew G Knepley   PetscBool      sametype, issame;
286867a56275SMatthew G Knepley   PetscErrorCode ierr;
286967a56275SMatthew G Knepley 
287067a56275SMatthew G Knepley   PetscFunctionBegin;
287167a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
287267a56275SMatthew G Knepley   PetscValidType(dm,1);
287367a56275SMatthew G Knepley   PetscValidPointer(M,3);
2874251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
287567a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
287667a56275SMatthew G Knepley   {
28770298fd71SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM*) = NULL;
287867a56275SMatthew G Knepley 
287967a56275SMatthew G Knepley     /*
288067a56275SMatthew G Knepley        Order of precedence:
288167a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
288267a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
288367a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
288467a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
288567a56275SMatthew G Knepley        5) Use a really basic converter.
288667a56275SMatthew G Knepley     */
288767a56275SMatthew G Knepley 
288867a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
288967a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
289067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
289167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
289267a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
289367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
28940005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr);
289567a56275SMatthew G Knepley     if (conv) goto foundconv;
289667a56275SMatthew G Knepley 
289767a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
289882f516ccSBarry Smith     ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr);
289967a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
290067a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
290167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
290267a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
290367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
290467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
29050005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
290667a56275SMatthew G Knepley     if (conv) {
2907fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
290867a56275SMatthew G Knepley       goto foundconv;
290967a56275SMatthew G Knepley     }
291067a56275SMatthew G Knepley 
291167a56275SMatthew G Knepley #if 0
291267a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
291367a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2914fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
291567a56275SMatthew G Knepley     if (conv) goto foundconv;
291667a56275SMatthew G Knepley 
291767a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
291867a56275SMatthew G Knepley     if (dm->ops->convert) {
291967a56275SMatthew G Knepley       conv = dm->ops->convert;
292067a56275SMatthew G Knepley     }
292167a56275SMatthew G Knepley     if (conv) goto foundconv;
292267a56275SMatthew G Knepley #endif
292367a56275SMatthew G Knepley 
292467a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
292582f516ccSBarry Smith     SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
292667a56275SMatthew G Knepley 
292767a56275SMatthew G Knepley foundconv:
292867a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
292967a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
293067a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
293167a56275SMatthew G Knepley   }
293267a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
293367a56275SMatthew G Knepley   PetscFunctionReturn(0);
293467a56275SMatthew G Knepley }
2935264ace61SBarry Smith 
2936264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2937264ace61SBarry Smith 
2938264ace61SBarry Smith #undef __FUNCT__
2939264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2940264ace61SBarry Smith /*@C
29411c84c290SBarry Smith   DMRegister -  Adds a new DM component implementation
29421c84c290SBarry Smith 
29431c84c290SBarry Smith   Not Collective
29441c84c290SBarry Smith 
29451c84c290SBarry Smith   Input Parameters:
29461c84c290SBarry Smith + name        - The name of a new user-defined creation routine
29471c84c290SBarry Smith - create_func - The creation routine itself
29481c84c290SBarry Smith 
29491c84c290SBarry Smith   Notes:
29501c84c290SBarry Smith   DMRegister() may be called multiple times to add several user-defined DMs
29511c84c290SBarry Smith 
29521c84c290SBarry Smith 
29531c84c290SBarry Smith   Sample usage:
29541c84c290SBarry Smith .vb
2955bdf89e91SBarry Smith     DMRegister("my_da", MyDMCreate);
29561c84c290SBarry Smith .ve
29571c84c290SBarry Smith 
29581c84c290SBarry Smith   Then, your DM type can be chosen with the procedural interface via
29591c84c290SBarry Smith .vb
29601c84c290SBarry Smith     DMCreate(MPI_Comm, DM *);
29611c84c290SBarry Smith     DMSetType(DM,"my_da");
29621c84c290SBarry Smith .ve
29631c84c290SBarry Smith    or at runtime via the option
29641c84c290SBarry Smith .vb
29651c84c290SBarry Smith     -da_type my_da
29661c84c290SBarry Smith .ve
2967264ace61SBarry Smith 
2968264ace61SBarry Smith   Level: advanced
29691c84c290SBarry Smith 
29701c84c290SBarry Smith .keywords: DM, register
2971bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy()
29721c84c290SBarry Smith 
2973264ace61SBarry Smith @*/
2974bdf89e91SBarry Smith PetscErrorCode  DMRegister(const char sname[],PetscErrorCode (*function)(DM))
2975264ace61SBarry Smith {
2976264ace61SBarry Smith   PetscErrorCode ierr;
2977264ace61SBarry Smith 
2978264ace61SBarry Smith   PetscFunctionBegin;
2979a240a19fSJed Brown   ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr);
2980264ace61SBarry Smith   PetscFunctionReturn(0);
2981264ace61SBarry Smith }
2982264ace61SBarry Smith 
2983b859378eSBarry Smith #undef __FUNCT__
2984b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2985b859378eSBarry Smith /*@C
298655849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
2987b859378eSBarry Smith 
2988b859378eSBarry Smith   Collective on PetscViewer
2989b859378eSBarry Smith 
2990b859378eSBarry Smith   Input Parameters:
2991b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2992b859378eSBarry Smith            some related function before a call to DMLoad().
2993b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2994b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2995b859378eSBarry Smith 
2996b859378eSBarry Smith    Level: intermediate
2997b859378eSBarry Smith 
2998b859378eSBarry Smith   Notes:
299955849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
3000b859378eSBarry Smith 
3001b859378eSBarry Smith   Notes for advanced users:
3002b859378eSBarry Smith   Most users should not need to know the details of the binary storage
3003b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
3004b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
3005b859378eSBarry Smith   format is
3006b859378eSBarry Smith .vb
3007b859378eSBarry Smith      has not yet been determined
3008b859378eSBarry Smith .ve
3009b859378eSBarry Smith 
3010b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
3011b859378eSBarry Smith @*/
3012b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
3013b859378eSBarry Smith {
30149331c7a4SMatthew G. Knepley   PetscBool      isbinary, ishdf5;
3015b859378eSBarry Smith   PetscErrorCode ierr;
3016b859378eSBarry Smith 
3017b859378eSBarry Smith   PetscFunctionBegin;
3018b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
3019b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
302032c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
30219331c7a4SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
30229331c7a4SMatthew G. Knepley   if (isbinary) {
30239331c7a4SMatthew G. Knepley     PetscInt classid;
30249331c7a4SMatthew G. Knepley     char     type[256];
3025b859378eSBarry Smith 
3026060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
30279200755eSBarry Smith     if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid);
3028060da220SMatthew G. Knepley     ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
302932c0f0efSBarry Smith     ierr = DMSetType(newdm, type);CHKERRQ(ierr);
30309331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
30319331c7a4SMatthew G. Knepley   } else if (ishdf5) {
30329331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
30339331c7a4SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()");
3034b859378eSBarry Smith   PetscFunctionReturn(0);
3035b859378eSBarry Smith }
3036b859378eSBarry Smith 
30377da65231SMatthew G Knepley /******************************** FEM Support **********************************/
30387da65231SMatthew G Knepley 
30397da65231SMatthew G Knepley #undef __FUNCT__
30407da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
3041a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[])
3042a6dfd86eSKarl Rupp {
30431d47ebbbSSatish Balay   PetscInt       f;
30441b30c384SMatthew G Knepley   PetscErrorCode ierr;
30451b30c384SMatthew G Knepley 
30467da65231SMatthew G Knepley   PetscFunctionBegin;
304774778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
30481d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
304957622a8eSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr);
30507da65231SMatthew G Knepley   }
30517da65231SMatthew G Knepley   PetscFunctionReturn(0);
30527da65231SMatthew G Knepley }
30537da65231SMatthew G Knepley 
30547da65231SMatthew G Knepley #undef __FUNCT__
30557da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
3056a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[])
3057a6dfd86eSKarl Rupp {
30581b30c384SMatthew G Knepley   PetscInt       f, g;
30597da65231SMatthew G Knepley   PetscErrorCode ierr;
30607da65231SMatthew G Knepley 
30617da65231SMatthew G Knepley   PetscFunctionBegin;
306274778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
30631d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
306474778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
30651d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
3066e3556bceSMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
30677da65231SMatthew G Knepley     }
306874778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
30697da65231SMatthew G Knepley   }
30707da65231SMatthew G Knepley   PetscFunctionReturn(0);
30717da65231SMatthew G Knepley }
3072e7c4fc90SDmitry Karpeev 
3073970e74d5SMatthew G Knepley #undef __FUNCT__
3074e759306cSMatthew G. Knepley #define __FUNCT__ "DMPrintLocalVec"
30756113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X)
3076e759306cSMatthew G. Knepley {
3077e759306cSMatthew G. Knepley   PetscMPIInt    rank, numProcs;
3078e759306cSMatthew G. Knepley   PetscInt       p;
3079e759306cSMatthew G. Knepley   PetscErrorCode ierr;
3080e759306cSMatthew G. Knepley 
3081e759306cSMatthew G. Knepley   PetscFunctionBegin;
3082e759306cSMatthew G. Knepley   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr);
3083e759306cSMatthew G. Knepley   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr);
3084e759306cSMatthew G. Knepley   ierr = PetscPrintf(PetscObjectComm((PetscObject) dm), "%s:\n", name);CHKERRQ(ierr);
3085e759306cSMatthew G. Knepley   for (p = 0; p < numProcs; ++p) {
3086e759306cSMatthew G. Knepley     if (p == rank) {
3087e759306cSMatthew G. Knepley       Vec x;
3088e759306cSMatthew G. Knepley 
3089e759306cSMatthew G. Knepley       ierr = VecDuplicate(X, &x);CHKERRQ(ierr);
3090e759306cSMatthew G. Knepley       ierr = VecCopy(X, x);CHKERRQ(ierr);
30916113b454SMatthew G. Knepley       ierr = VecChop(x, tol);CHKERRQ(ierr);
3092e759306cSMatthew G. Knepley       ierr = VecView(x, PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);
3093e759306cSMatthew G. Knepley       ierr = VecDestroy(&x);CHKERRQ(ierr);
3094e759306cSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);
3095e759306cSMatthew G. Knepley     }
3096e759306cSMatthew G. Knepley     ierr = PetscBarrier((PetscObject) dm);CHKERRQ(ierr);
3097e759306cSMatthew G. Knepley   }
3098e759306cSMatthew G. Knepley   PetscFunctionReturn(0);
3099e759306cSMatthew G. Knepley }
3100e759306cSMatthew G. Knepley 
3101e759306cSMatthew G. Knepley #undef __FUNCT__
310288ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
310388ed4aceSMatthew G Knepley /*@
310488ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
310588ed4aceSMatthew G Knepley 
310688ed4aceSMatthew G Knepley   Input Parameter:
310788ed4aceSMatthew G Knepley . dm - The DM
310888ed4aceSMatthew G Knepley 
310988ed4aceSMatthew G Knepley   Output Parameter:
311088ed4aceSMatthew G Knepley . section - The PetscSection
311188ed4aceSMatthew G Knepley 
311288ed4aceSMatthew G Knepley   Level: intermediate
311388ed4aceSMatthew G Knepley 
311488ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
311588ed4aceSMatthew G Knepley 
311688ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
311788ed4aceSMatthew G Knepley @*/
31180adebc6cSBarry Smith PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section)
31190adebc6cSBarry Smith {
3120fd59a867SMatthew G. Knepley   PetscErrorCode ierr;
3121fd59a867SMatthew G. Knepley 
312288ed4aceSMatthew G Knepley   PetscFunctionBegin;
312388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
312488ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
31252f0f8703SMatthew G. Knepley   if (!dm->defaultSection && dm->ops->createdefaultsection) {
31262f0f8703SMatthew G. Knepley     ierr = (*dm->ops->createdefaultsection)(dm);CHKERRQ(ierr);
3127685405a1SBarry Smith     ierr = PetscObjectViewFromOptions((PetscObject) dm->defaultSection, NULL, "-dm_petscsection_view");CHKERRQ(ierr);
31282f0f8703SMatthew G. Knepley   }
312988ed4aceSMatthew G Knepley   *section = dm->defaultSection;
313088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
313188ed4aceSMatthew G Knepley }
313288ed4aceSMatthew G Knepley 
313388ed4aceSMatthew G Knepley #undef __FUNCT__
313488ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
313588ed4aceSMatthew G Knepley /*@
313688ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
313788ed4aceSMatthew G Knepley 
313888ed4aceSMatthew G Knepley   Input Parameters:
313988ed4aceSMatthew G Knepley + dm - The DM
314088ed4aceSMatthew G Knepley - section - The PetscSection
314188ed4aceSMatthew G Knepley 
314288ed4aceSMatthew G Knepley   Level: intermediate
314388ed4aceSMatthew G Knepley 
314488ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
314588ed4aceSMatthew G Knepley 
314688ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
314788ed4aceSMatthew G Knepley @*/
31480adebc6cSBarry Smith PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section)
31490adebc6cSBarry Smith {
3150c473ab19SMatthew G. Knepley   PetscInt       numFields = 0;
3151af122d2aSMatthew G Knepley   PetscInt       f;
315288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
315388ed4aceSMatthew G Knepley 
315488ed4aceSMatthew G Knepley   PetscFunctionBegin;
315588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3156c473ab19SMatthew G. Knepley   if (section) {
31571d799100SJed Brown     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
31581d799100SJed Brown     ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
3159c473ab19SMatthew G. Knepley   }
316088ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
316188ed4aceSMatthew G Knepley   dm->defaultSection = section;
3162c473ab19SMatthew G. Knepley   if (section) {ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);}
3163af122d2aSMatthew G Knepley   if (numFields) {
3164af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
3165af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
31660f21e855SMatthew G. Knepley       PetscObject disc;
3167af122d2aSMatthew G Knepley       const char *name;
3168af122d2aSMatthew G Knepley 
3169af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
31700f21e855SMatthew G. Knepley       ierr = DMGetField(dm, f, &disc);CHKERRQ(ierr);
31710f21e855SMatthew G. Knepley       ierr = PetscObjectSetName(disc, name);CHKERRQ(ierr);
3172af122d2aSMatthew G Knepley     }
3173af122d2aSMatthew G Knepley   }
31741d799100SJed Brown   /* The global section will be rebuilt in the next call to DMGetDefaultGlobalSection(). */
31751d799100SJed Brown   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
317688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
317788ed4aceSMatthew G Knepley }
317888ed4aceSMatthew G Knepley 
317988ed4aceSMatthew G Knepley #undef __FUNCT__
31809435951eSToby Isaac #define __FUNCT__ "DMGetDefaultConstraints"
31819435951eSToby Isaac /*@
31829435951eSToby Isaac   DMGetDefaultConstraints - Get the PetscSection and Mat the specify the local constraint interpolation. See DMSetDefaultConstraints() for a description of the purpose of constraint interpolation.
31839435951eSToby Isaac 
3184e228b242SToby Isaac   not collective
3185e228b242SToby Isaac 
31869435951eSToby Isaac   Input Parameter:
31879435951eSToby Isaac . dm - The DM
31889435951eSToby Isaac 
31899435951eSToby Isaac   Output Parameter:
31909435951eSToby 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.
31919435951eSToby 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.
31929435951eSToby Isaac 
31939435951eSToby Isaac   Level: advanced
31949435951eSToby Isaac 
31959435951eSToby Isaac   Note: This gets borrowed references, so the user should not destroy the PetscSection or the Mat.
31969435951eSToby Isaac 
31979435951eSToby Isaac .seealso: DMSetDefaultConstraints()
31989435951eSToby Isaac @*/
31999435951eSToby Isaac PetscErrorCode DMGetDefaultConstraints(DM dm, PetscSection *section, Mat *mat)
32009435951eSToby Isaac {
32019435951eSToby Isaac   PetscErrorCode ierr;
32029435951eSToby Isaac 
32039435951eSToby Isaac   PetscFunctionBegin;
32049435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
32059435951eSToby Isaac   if (!dm->defaultConstraintSection && !dm->defaultConstraintMat && dm->ops->createdefaultconstraints) {ierr = (*dm->ops->createdefaultconstraints)(dm);CHKERRQ(ierr);}
320645a75d81SToby Isaac   if (section) {*section = dm->defaultConstraintSection;}
320745a75d81SToby Isaac   if (mat) {*mat = dm->defaultConstraintMat;}
32089435951eSToby Isaac   PetscFunctionReturn(0);
32099435951eSToby Isaac }
32109435951eSToby Isaac 
32119435951eSToby Isaac #undef __FUNCT__
32129435951eSToby Isaac #define __FUNCT__ "DMSetDefaultConstraints"
32139435951eSToby Isaac /*@
32149435951eSToby Isaac   DMSetDefaultConstraints - Set the PetscSection and Mat the specify the local constraint interpolation.
32159435951eSToby Isaac 
32169435951eSToby 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().
32179435951eSToby Isaac 
32189435951eSToby 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.
32199435951eSToby Isaac 
3220e228b242SToby Isaac   collective on dm
3221e228b242SToby Isaac 
32229435951eSToby Isaac   Input Parameters:
32239435951eSToby Isaac + dm - The DM
3224e228b242SToby 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).
3225e228b242SToby 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).
32269435951eSToby Isaac 
32279435951eSToby Isaac   Level: advanced
32289435951eSToby Isaac 
32299435951eSToby Isaac   Note: This increments the references of the PetscSection and the Mat, so they user can destroy them
32309435951eSToby Isaac 
32319435951eSToby Isaac .seealso: DMGetDefaultConstraints()
32329435951eSToby Isaac @*/
32339435951eSToby Isaac PetscErrorCode DMSetDefaultConstraints(DM dm, PetscSection section, Mat mat)
32349435951eSToby Isaac {
3235e228b242SToby Isaac   PetscMPIInt result;
32369435951eSToby Isaac   PetscErrorCode ierr;
32379435951eSToby Isaac 
32389435951eSToby Isaac   PetscFunctionBegin;
32399435951eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3240e228b242SToby Isaac   if (section) {
3241e228b242SToby Isaac     PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
3242e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)section),&result);CHKERRQ(ierr);
3243e228b242SToby Isaac     if (result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint section must have local communicator");
3244e228b242SToby Isaac   }
3245e228b242SToby Isaac   if (mat) {
3246e228b242SToby Isaac     PetscValidHeaderSpecific(mat,MAT_CLASSID,3);
3247e228b242SToby Isaac     ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)mat),&result);CHKERRQ(ierr);
3248e228b242SToby Isaac     if (result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"constraint matrix must have local communicator");
3249e228b242SToby Isaac   }
32509435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
32519435951eSToby Isaac   ierr = PetscSectionDestroy(&dm->defaultConstraintSection);CHKERRQ(ierr);
32529435951eSToby Isaac   dm->defaultConstraintSection = section;
32539435951eSToby Isaac   ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
32549435951eSToby Isaac   ierr = MatDestroy(&dm->defaultConstraintMat);CHKERRQ(ierr);
32559435951eSToby Isaac   dm->defaultConstraintMat = mat;
32569435951eSToby Isaac   PetscFunctionReturn(0);
32579435951eSToby Isaac }
32589435951eSToby Isaac 
3259f741bcd2SMatthew G. Knepley #ifdef PETSC_USE_DEBUG
32609435951eSToby Isaac #undef __FUNCT__
3261284f5c8fSMatthew G. Knepley #define __FUNCT__ "DMDefaultSectionCheckConsistency_Internal"
3262507e4973SMatthew G. Knepley /*
3263507e4973SMatthew G. Knepley   DMDefaultSectionCheckConsistency - Check the consistentcy of the global and local sections.
3264507e4973SMatthew G. Knepley 
3265507e4973SMatthew G. Knepley   Input Parameters:
3266507e4973SMatthew G. Knepley + dm - The DM
3267507e4973SMatthew G. Knepley . localSection - PetscSection describing the local data layout
3268507e4973SMatthew G. Knepley - globalSection - PetscSection describing the global data layout
3269507e4973SMatthew G. Knepley 
3270507e4973SMatthew G. Knepley   Level: intermediate
3271507e4973SMatthew G. Knepley 
3272507e4973SMatthew G. Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
3273507e4973SMatthew G. Knepley */
3274f741bcd2SMatthew G. Knepley static PetscErrorCode DMDefaultSectionCheckConsistency_Internal(DM dm, PetscSection localSection, PetscSection globalSection)
3275507e4973SMatthew G. Knepley {
3276507e4973SMatthew G. Knepley   MPI_Comm        comm;
3277507e4973SMatthew G. Knepley   PetscLayout     layout;
3278507e4973SMatthew G. Knepley   const PetscInt *ranges;
3279507e4973SMatthew G. Knepley   PetscInt        pStart, pEnd, p, nroots;
3280507e4973SMatthew G. Knepley   PetscMPIInt     size, rank;
3281507e4973SMatthew G. Knepley   PetscBool       valid = PETSC_TRUE, gvalid;
3282507e4973SMatthew G. Knepley   PetscErrorCode  ierr;
3283507e4973SMatthew G. Knepley 
3284507e4973SMatthew G. Knepley   PetscFunctionBegin;
3285507e4973SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
3286507e4973SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3287507e4973SMatthew G. Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
3288507e4973SMatthew G. Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
3289507e4973SMatthew G. Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
3290507e4973SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
3291507e4973SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
3292507e4973SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
3293507e4973SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
3294507e4973SMatthew G. Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
3295507e4973SMatthew G. Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
3296507e4973SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
3297f741bcd2SMatthew G. Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d;
3298507e4973SMatthew G. Knepley 
3299507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
3300507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
3301507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
3302507e4973SMatthew G. Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
3303507e4973SMatthew G. Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
3304507e4973SMatthew G. Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
3305507e4973SMatthew G. Knepley     if (!gdof) continue; /* Censored point */
3306507e4973SMatthew 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;}
3307507e4973SMatthew 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;}
3308507e4973SMatthew G. Knepley     if (gdof < 0) {
3309507e4973SMatthew G. Knepley       gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
3310507e4973SMatthew G. Knepley       for (d = 0; d < gsize; ++d) {
3311507e4973SMatthew G. Knepley         PetscInt offset = -(goff+1) + d, r;
3312507e4973SMatthew G. Knepley 
3313507e4973SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
3314507e4973SMatthew G. Knepley         if (r < 0) r = -(r+2);
3315507e4973SMatthew 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;}
3316507e4973SMatthew G. Knepley       }
3317507e4973SMatthew G. Knepley     }
3318507e4973SMatthew G. Knepley   }
3319507e4973SMatthew G. Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
3320507e4973SMatthew G. Knepley   ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);
3321b2566f29SBarry Smith   ierr = MPIU_Allreduce(&valid, &gvalid, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRQ(ierr);
3322507e4973SMatthew G. Knepley   if (!gvalid) {
3323507e4973SMatthew G. Knepley     ierr = DMView(dm, NULL);CHKERRQ(ierr);
3324507e4973SMatthew G. Knepley     SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Inconsistent local and global sections");
3325507e4973SMatthew G. Knepley   }
3326507e4973SMatthew G. Knepley   PetscFunctionReturn(0);
3327507e4973SMatthew G. Knepley }
3328f741bcd2SMatthew G. Knepley #endif
3329507e4973SMatthew G. Knepley 
3330507e4973SMatthew G. Knepley #undef __FUNCT__
333188ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
333288ed4aceSMatthew G Knepley /*@
333388ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
333488ed4aceSMatthew G Knepley 
33358b1ab98fSJed Brown   Collective on DM
33368b1ab98fSJed Brown 
333788ed4aceSMatthew G Knepley   Input Parameter:
333888ed4aceSMatthew G Knepley . dm - The DM
333988ed4aceSMatthew G Knepley 
334088ed4aceSMatthew G Knepley   Output Parameter:
334188ed4aceSMatthew G Knepley . section - The PetscSection
334288ed4aceSMatthew G Knepley 
334388ed4aceSMatthew G Knepley   Level: intermediate
334488ed4aceSMatthew G Knepley 
334588ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
334688ed4aceSMatthew G Knepley 
334788ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
334888ed4aceSMatthew G Knepley @*/
33490adebc6cSBarry Smith PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section)
33500adebc6cSBarry Smith {
335188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
335288ed4aceSMatthew G Knepley 
335388ed4aceSMatthew G Knepley   PetscFunctionBegin;
335488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
335588ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
335688ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
3357fd59a867SMatthew G. Knepley     PetscSection s;
3358fd59a867SMatthew G. Knepley 
3359fd59a867SMatthew G. Knepley     ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
3360fd59a867SMatthew 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");
3361fd59a867SMatthew G. Knepley     if (!dm->sf) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSF in order to create a global PetscSection");
336215b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
3363cf06b437SMatthew G. Knepley     ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr);
3364ce94432eSBarry Smith     ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->defaultGlobalSection, &dm->map);CHKERRQ(ierr);
3365685405a1SBarry Smith     ierr = PetscSectionViewFromOptions(dm->defaultGlobalSection, NULL, "-global_section_view");CHKERRQ(ierr);
336688ed4aceSMatthew G Knepley   }
336788ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
336888ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
336988ed4aceSMatthew G Knepley }
337088ed4aceSMatthew G Knepley 
337188ed4aceSMatthew G Knepley #undef __FUNCT__
3372b21d0597SMatthew G Knepley #define __FUNCT__ "DMSetDefaultGlobalSection"
3373b21d0597SMatthew G Knepley /*@
3374b21d0597SMatthew G Knepley   DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM.
3375b21d0597SMatthew G Knepley 
3376b21d0597SMatthew G Knepley   Input Parameters:
3377b21d0597SMatthew G Knepley + dm - The DM
33785080bbdbSMatthew G Knepley - section - The PetscSection, or NULL
3379b21d0597SMatthew G Knepley 
3380b21d0597SMatthew G Knepley   Level: intermediate
3381b21d0597SMatthew G Knepley 
3382b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
3383b21d0597SMatthew G Knepley 
3384b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection()
3385b21d0597SMatthew G Knepley @*/
33860adebc6cSBarry Smith PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section)
33870adebc6cSBarry Smith {
3388b21d0597SMatthew G Knepley   PetscErrorCode ierr;
3389b21d0597SMatthew G Knepley 
3390b21d0597SMatthew G Knepley   PetscFunctionBegin;
3391b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
33925080bbdbSMatthew G Knepley   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
33931d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
3394b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
3395b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
3396507e4973SMatthew G. Knepley #ifdef PETSC_USE_DEBUG
3397f741bcd2SMatthew G. Knepley   if (section) {ierr = DMDefaultSectionCheckConsistency_Internal(dm, dm->defaultSection, section);CHKERRQ(ierr);}
3398507e4973SMatthew G. Knepley #endif
3399b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3400b21d0597SMatthew G Knepley }
3401b21d0597SMatthew G Knepley 
3402b21d0597SMatthew G Knepley #undef __FUNCT__
340388ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
340488ed4aceSMatthew G Knepley /*@
340588ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
340688ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
340788ed4aceSMatthew G Knepley 
340888ed4aceSMatthew G Knepley   Input Parameter:
340988ed4aceSMatthew G Knepley . dm - The DM
341088ed4aceSMatthew G Knepley 
341188ed4aceSMatthew G Knepley   Output Parameter:
341288ed4aceSMatthew G Knepley . sf - The PetscSF
341388ed4aceSMatthew G Knepley 
341488ed4aceSMatthew G Knepley   Level: intermediate
341588ed4aceSMatthew G Knepley 
341688ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
341788ed4aceSMatthew G Knepley 
341888ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
341988ed4aceSMatthew G Knepley @*/
34200adebc6cSBarry Smith PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf)
34210adebc6cSBarry Smith {
342288ed4aceSMatthew G Knepley   PetscInt       nroots;
342388ed4aceSMatthew G Knepley   PetscErrorCode ierr;
342488ed4aceSMatthew G Knepley 
342588ed4aceSMatthew G Knepley   PetscFunctionBegin;
342688ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
342788ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
34280298fd71SBarry Smith   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
342988ed4aceSMatthew G Knepley   if (nroots < 0) {
343088ed4aceSMatthew G Knepley     PetscSection section, gSection;
343188ed4aceSMatthew G Knepley 
343288ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
343331ea6d37SMatthew G Knepley     if (section) {
343488ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
343588ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
343631ea6d37SMatthew G Knepley     } else {
34370298fd71SBarry Smith       *sf = NULL;
343831ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
343931ea6d37SMatthew G Knepley     }
344088ed4aceSMatthew G Knepley   }
344188ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
344288ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
344388ed4aceSMatthew G Knepley }
344488ed4aceSMatthew G Knepley 
344588ed4aceSMatthew G Knepley #undef __FUNCT__
344688ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
344788ed4aceSMatthew G Knepley /*@
344888ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
344988ed4aceSMatthew G Knepley 
345088ed4aceSMatthew G Knepley   Input Parameters:
345188ed4aceSMatthew G Knepley + dm - The DM
345288ed4aceSMatthew G Knepley - sf - The PetscSF
345388ed4aceSMatthew G Knepley 
345488ed4aceSMatthew G Knepley   Level: intermediate
345588ed4aceSMatthew G Knepley 
345688ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
345788ed4aceSMatthew G Knepley 
345888ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
345988ed4aceSMatthew G Knepley @*/
34600adebc6cSBarry Smith PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf)
34610adebc6cSBarry Smith {
346288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
346388ed4aceSMatthew G Knepley 
346488ed4aceSMatthew G Knepley   PetscFunctionBegin;
346588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
346688ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
346788ed4aceSMatthew G Knepley   ierr          = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
346888ed4aceSMatthew G Knepley   dm->defaultSF = sf;
346988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
347088ed4aceSMatthew G Knepley }
347188ed4aceSMatthew G Knepley 
347288ed4aceSMatthew G Knepley #undef __FUNCT__
347388ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
347488ed4aceSMatthew G Knepley /*@C
347588ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
347688ed4aceSMatthew G Knepley   describing the data layout.
347788ed4aceSMatthew G Knepley 
347888ed4aceSMatthew G Knepley   Input Parameters:
347988ed4aceSMatthew G Knepley + dm - The DM
348088ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
348188ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
348288ed4aceSMatthew G Knepley 
348388ed4aceSMatthew G Knepley   Level: intermediate
348488ed4aceSMatthew G Knepley 
348588ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
348688ed4aceSMatthew G Knepley @*/
348788ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
348888ed4aceSMatthew G Knepley {
348982f516ccSBarry Smith   MPI_Comm       comm;
349088ed4aceSMatthew G Knepley   PetscLayout    layout;
349188ed4aceSMatthew G Knepley   const PetscInt *ranges;
349288ed4aceSMatthew G Knepley   PetscInt       *local;
349388ed4aceSMatthew G Knepley   PetscSFNode    *remote;
3494ecd73843SMatthew G. Knepley   PetscInt       pStart, pEnd, p, nroots, nleaves = 0, l;
349588ed4aceSMatthew G Knepley   PetscMPIInt    size, rank;
349688ed4aceSMatthew G Knepley   PetscErrorCode ierr;
349788ed4aceSMatthew G Knepley 
349888ed4aceSMatthew G Knepley   PetscFunctionBegin;
349982f516ccSBarry Smith   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
350088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
350188ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
350288ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
350388ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
350488ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
350588ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
350688ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
350788ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
350888ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
350988ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
3510ecd73843SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
35116636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
351288ed4aceSMatthew G Knepley 
35136636e97aSMatthew G Knepley     ierr     = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
35146636e97aSMatthew G Knepley     ierr     = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
3515235fbf56SMatthew 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));
35166636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
351788ed4aceSMatthew G Knepley   }
3518785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr);
3519785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr);
352088ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
35211f588964SMatthew G Knepley     const PetscInt *cind;
35226636e97aSMatthew G Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
352388ed4aceSMatthew G Knepley 
352488ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
352588ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
352688ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
352788ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
352888ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
35296636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
353088ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
35316636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
35326636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
35336636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
3534057b4bcdSMatthew 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);
35356636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
35366636e97aSMatthew G Knepley     }
353788ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
353888ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
353988ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
354088ed4aceSMatthew G Knepley     }
354188ed4aceSMatthew G Knepley     if (gdof < 0) {
35426636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
354388ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
354488ed4aceSMatthew G Knepley 
354505376888SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
354631d3f06eSJed Brown         if (r < 0) r = -(r+2);
354705376888SMatthew 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);
354888ed4aceSMatthew G Knepley         remote[l].rank  = r;
354988ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
355088ed4aceSMatthew G Knepley       }
355188ed4aceSMatthew G Knepley     } else {
35526636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
355388ed4aceSMatthew G Knepley         remote[l].rank  = rank;
355488ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
355588ed4aceSMatthew G Knepley       }
355688ed4aceSMatthew G Knepley     }
355788ed4aceSMatthew G Knepley   }
35586636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
355988ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
356088ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
356188ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
356288ed4aceSMatthew G Knepley }
3563af122d2aSMatthew G Knepley 
3564af122d2aSMatthew G Knepley #undef __FUNCT__
3565b21d0597SMatthew G Knepley #define __FUNCT__ "DMGetPointSF"
3566b21d0597SMatthew G Knepley /*@
3567b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
3568b21d0597SMatthew G Knepley 
3569b21d0597SMatthew G Knepley   Input Parameter:
3570b21d0597SMatthew G Knepley . dm - The DM
3571b21d0597SMatthew G Knepley 
3572b21d0597SMatthew G Knepley   Output Parameter:
3573b21d0597SMatthew G Knepley . sf - The PetscSF
3574b21d0597SMatthew G Knepley 
3575b21d0597SMatthew G Knepley   Level: intermediate
3576b21d0597SMatthew G Knepley 
3577b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
3578b21d0597SMatthew G Knepley 
3579057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3580b21d0597SMatthew G Knepley @*/
35810adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf)
35820adebc6cSBarry Smith {
3583b21d0597SMatthew G Knepley   PetscFunctionBegin;
3584b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3585b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
3586b21d0597SMatthew G Knepley   *sf = dm->sf;
3587b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3588b21d0597SMatthew G Knepley }
3589b21d0597SMatthew G Knepley 
3590b21d0597SMatthew G Knepley #undef __FUNCT__
3591057b4bcdSMatthew G Knepley #define __FUNCT__ "DMSetPointSF"
3592057b4bcdSMatthew G Knepley /*@
3593057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
3594057b4bcdSMatthew G Knepley 
3595057b4bcdSMatthew G Knepley   Input Parameters:
3596057b4bcdSMatthew G Knepley + dm - The DM
3597057b4bcdSMatthew G Knepley - sf - The PetscSF
3598057b4bcdSMatthew G Knepley 
3599057b4bcdSMatthew G Knepley   Level: intermediate
3600057b4bcdSMatthew G Knepley 
3601057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3602057b4bcdSMatthew G Knepley @*/
36030adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf)
36040adebc6cSBarry Smith {
3605057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
3606057b4bcdSMatthew G Knepley 
3607057b4bcdSMatthew G Knepley   PetscFunctionBegin;
3608057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3609057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1);
3610057b4bcdSMatthew G Knepley   ierr   = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
3611057b4bcdSMatthew G Knepley   ierr   = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
3612057b4bcdSMatthew G Knepley   dm->sf = sf;
3613057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
3614057b4bcdSMatthew G Knepley }
3615057b4bcdSMatthew G Knepley 
3616057b4bcdSMatthew G Knepley #undef __FUNCT__
36172764a2aaSMatthew G. Knepley #define __FUNCT__ "DMGetDS"
36182764a2aaSMatthew G. Knepley /*@
36192764a2aaSMatthew G. Knepley   DMGetDS - Get the PetscDS
36202764a2aaSMatthew G. Knepley 
36212764a2aaSMatthew G. Knepley   Input Parameter:
36222764a2aaSMatthew G. Knepley . dm - The DM
36232764a2aaSMatthew G. Knepley 
36242764a2aaSMatthew G. Knepley   Output Parameter:
36252764a2aaSMatthew G. Knepley . prob - The PetscDS
36262764a2aaSMatthew G. Knepley 
36272764a2aaSMatthew G. Knepley   Level: developer
36282764a2aaSMatthew G. Knepley 
36292764a2aaSMatthew G. Knepley .seealso: DMSetDS()
36302764a2aaSMatthew G. Knepley @*/
36312764a2aaSMatthew G. Knepley PetscErrorCode DMGetDS(DM dm, PetscDS *prob)
3632af122d2aSMatthew G Knepley {
3633af122d2aSMatthew G Knepley   PetscFunctionBegin;
3634af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
36350f21e855SMatthew G. Knepley   PetscValidPointer(prob, 2);
36360f21e855SMatthew G. Knepley   *prob = dm->prob;
36370f21e855SMatthew G. Knepley   PetscFunctionReturn(0);
36380f21e855SMatthew G. Knepley }
36390f21e855SMatthew G. Knepley 
36400f21e855SMatthew G. Knepley #undef __FUNCT__
36412764a2aaSMatthew G. Knepley #define __FUNCT__ "DMSetDS"
36422764a2aaSMatthew G. Knepley /*@
36432764a2aaSMatthew G. Knepley   DMSetDS - Set the PetscDS
36442764a2aaSMatthew G. Knepley 
36452764a2aaSMatthew G. Knepley   Input Parameters:
36462764a2aaSMatthew G. Knepley + dm - The DM
36472764a2aaSMatthew G. Knepley - prob - The PetscDS
36482764a2aaSMatthew G. Knepley 
36492764a2aaSMatthew G. Knepley   Level: developer
36502764a2aaSMatthew G. Knepley 
36512764a2aaSMatthew G. Knepley .seealso: DMGetDS()
36522764a2aaSMatthew G. Knepley @*/
36532764a2aaSMatthew G. Knepley PetscErrorCode DMSetDS(DM dm, PetscDS prob)
36540f21e855SMatthew G. Knepley {
36550f21e855SMatthew G. Knepley   PetscErrorCode ierr;
36560f21e855SMatthew G. Knepley 
36570f21e855SMatthew G. Knepley   PetscFunctionBegin;
36580f21e855SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
36592764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 2);
36602764a2aaSMatthew G. Knepley   ierr = PetscDSDestroy(&dm->prob);CHKERRQ(ierr);
36610f21e855SMatthew G. Knepley   dm->prob = prob;
36620f21e855SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) dm->prob);CHKERRQ(ierr);
36630f21e855SMatthew G. Knepley   PetscFunctionReturn(0);
36640f21e855SMatthew G. Knepley }
36650f21e855SMatthew G. Knepley 
36660f21e855SMatthew G. Knepley #undef __FUNCT__
36670f21e855SMatthew G. Knepley #define __FUNCT__ "DMGetNumFields"
36680f21e855SMatthew G. Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
36690f21e855SMatthew G. Knepley {
36700f21e855SMatthew G. Knepley   PetscErrorCode ierr;
36710f21e855SMatthew G. Knepley 
36720f21e855SMatthew G. Knepley   PetscFunctionBegin;
36730f21e855SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
36742764a2aaSMatthew G. Knepley   ierr = PetscDSGetNumFields(dm->prob, numFields);CHKERRQ(ierr);
3675af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3676af122d2aSMatthew G Knepley }
3677af122d2aSMatthew G Knepley 
3678af122d2aSMatthew G Knepley #undef __FUNCT__
3679af122d2aSMatthew G Knepley #define __FUNCT__ "DMSetNumFields"
3680af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
3681af122d2aSMatthew G Knepley {
36820f21e855SMatthew G. Knepley   PetscInt       Nf, f;
3683af122d2aSMatthew G Knepley   PetscErrorCode ierr;
3684af122d2aSMatthew G Knepley 
3685af122d2aSMatthew G Knepley   PetscFunctionBegin;
3686af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
36872764a2aaSMatthew G. Knepley   ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr);
36880f21e855SMatthew G. Knepley   for (f = Nf; f < numFields; ++f) {
36890f21e855SMatthew G. Knepley     PetscContainer obj;
36900f21e855SMatthew G. Knepley 
36910f21e855SMatthew G. Knepley     ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), &obj);CHKERRQ(ierr);
36922764a2aaSMatthew G. Knepley     ierr = PetscDSSetDiscretization(dm->prob, f, (PetscObject) obj);CHKERRQ(ierr);
36930f21e855SMatthew G. Knepley     ierr = PetscContainerDestroy(&obj);CHKERRQ(ierr);
3694af122d2aSMatthew G Knepley   }
3695af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3696af122d2aSMatthew G Knepley }
3697af122d2aSMatthew G Knepley 
3698af122d2aSMatthew G Knepley #undef __FUNCT__
3699af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetField"
3700c1929be8SMatthew G. Knepley /*@
3701c1929be8SMatthew G. Knepley   DMGetField - Return the discretization object for a given DM field
3702c1929be8SMatthew G. Knepley 
3703c1929be8SMatthew G. Knepley   Not collective
3704c1929be8SMatthew G. Knepley 
3705c1929be8SMatthew G. Knepley   Input Parameters:
3706c1929be8SMatthew G. Knepley + dm - The DM
3707c1929be8SMatthew G. Knepley - f  - The field number
3708c1929be8SMatthew G. Knepley 
3709c1929be8SMatthew G. Knepley   Output Parameter:
3710c1929be8SMatthew G. Knepley . field - The discretization object
3711c1929be8SMatthew G. Knepley 
3712c1929be8SMatthew G. Knepley   Level: developer
3713c1929be8SMatthew G. Knepley 
3714c1929be8SMatthew G. Knepley .seealso: DMSetField()
3715c1929be8SMatthew G. Knepley @*/
3716af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field)
3717af122d2aSMatthew G Knepley {
37180f21e855SMatthew G. Knepley   PetscErrorCode ierr;
37190f21e855SMatthew G. Knepley 
3720af122d2aSMatthew G Knepley   PetscFunctionBegin;
3721af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
37222764a2aaSMatthew G. Knepley   ierr = PetscDSGetDiscretization(dm->prob, f, field);CHKERRQ(ierr);
3723decb47aaSMatthew G. Knepley   PetscFunctionReturn(0);
3724decb47aaSMatthew G. Knepley }
3725decb47aaSMatthew G. Knepley 
3726decb47aaSMatthew G. Knepley #undef __FUNCT__
3727decb47aaSMatthew G. Knepley #define __FUNCT__ "DMSetField"
3728c1929be8SMatthew G. Knepley /*@
3729c1929be8SMatthew G. Knepley   DMSetField - Set the discretization object for a given DM field
3730c1929be8SMatthew G. Knepley 
3731c1929be8SMatthew G. Knepley   Logically collective on DM
3732c1929be8SMatthew G. Knepley 
3733c1929be8SMatthew G. Knepley   Input Parameters:
3734c1929be8SMatthew G. Knepley + dm - The DM
3735c1929be8SMatthew G. Knepley . f  - The field number
3736c1929be8SMatthew G. Knepley - field - The discretization object
3737c1929be8SMatthew G. Knepley 
3738c1929be8SMatthew G. Knepley   Level: developer
3739c1929be8SMatthew G. Knepley 
3740c1929be8SMatthew G. Knepley .seealso: DMGetField()
3741c1929be8SMatthew G. Knepley @*/
3742decb47aaSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, PetscObject field)
3743decb47aaSMatthew G. Knepley {
3744decb47aaSMatthew G. Knepley   PetscErrorCode ierr;
3745decb47aaSMatthew G. Knepley 
3746decb47aaSMatthew G. Knepley   PetscFunctionBegin;
3747decb47aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
37482764a2aaSMatthew G. Knepley   ierr = PetscDSSetDiscretization(dm->prob, f, field);CHKERRQ(ierr);
3749af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3750af122d2aSMatthew G Knepley }
37516636e97aSMatthew G Knepley 
37526636e97aSMatthew G Knepley #undef __FUNCT__
3753b64e0483SPeter Brune #define __FUNCT__ "DMRestrictHook_Coordinates"
3754b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx)
3755b64e0483SPeter Brune {
3756b64e0483SPeter Brune   DM dm_coord,dmc_coord;
3757b64e0483SPeter Brune   PetscErrorCode ierr;
3758b64e0483SPeter Brune   Vec coords,ccoords;
37596dbf9973SLawrence Mitchell   Mat inject;
3760b64e0483SPeter Brune   PetscFunctionBegin;
3761b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
3762b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr);
3763b64e0483SPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
3764b64e0483SPeter Brune   ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr);
3765b64e0483SPeter Brune   if (coords && !ccoords) {
3766b64e0483SPeter Brune     ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr);
37676dbf9973SLawrence Mitchell     ierr = DMCreateInjection(dmc_coord,dm_coord,&inject);CHKERRQ(ierr);
37682adcf181SLawrence Mitchell     ierr = MatRestrict(inject,coords,ccoords);CHKERRQ(ierr);
37696dbf9973SLawrence Mitchell     ierr = MatDestroy(&inject);CHKERRQ(ierr);
3770b64e0483SPeter Brune     ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr);
3771b64e0483SPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
3772b64e0483SPeter Brune   }
3773b64e0483SPeter Brune   PetscFunctionReturn(0);
3774b64e0483SPeter Brune }
3775b64e0483SPeter Brune 
3776b64e0483SPeter Brune #undef __FUNCT__
377703dadc2fSPeter Brune #define __FUNCT__ "DMSubDomainHook_Coordinates"
377803dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx)
377903dadc2fSPeter Brune {
378003dadc2fSPeter Brune   DM dm_coord,subdm_coord;
378103dadc2fSPeter Brune   PetscErrorCode ierr;
378203dadc2fSPeter Brune   Vec coords,ccoords,clcoords;
378303dadc2fSPeter Brune   VecScatter *scat_i,*scat_g;
378403dadc2fSPeter Brune   PetscFunctionBegin;
378503dadc2fSPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
378603dadc2fSPeter Brune   ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr);
378703dadc2fSPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
378803dadc2fSPeter Brune   ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr);
378903dadc2fSPeter Brune   if (coords && !ccoords) {
379003dadc2fSPeter Brune     ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr);
379103dadc2fSPeter Brune     ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr);
379224640c55SToby Isaac     ierr = PetscObjectSetName((PetscObject)clcoords,"coordinates");CHKERRQ(ierr);
379303dadc2fSPeter Brune     ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr);
379403dadc2fSPeter Brune     ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
379503dadc2fSPeter Brune     ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
379603dadc2fSPeter Brune     ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
379703dadc2fSPeter Brune     ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
379803dadc2fSPeter Brune     ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr);
379903dadc2fSPeter Brune     ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr);
380003dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr);
380103dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr);
380203dadc2fSPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
380303dadc2fSPeter Brune     ierr = VecDestroy(&clcoords);CHKERRQ(ierr);
380403dadc2fSPeter Brune     ierr = PetscFree(scat_i);CHKERRQ(ierr);
380503dadc2fSPeter Brune     ierr = PetscFree(scat_g);CHKERRQ(ierr);
380603dadc2fSPeter Brune   }
380703dadc2fSPeter Brune   PetscFunctionReturn(0);
380803dadc2fSPeter Brune }
380903dadc2fSPeter Brune 
381003dadc2fSPeter Brune #undef __FUNCT__
3811c73cfb54SMatthew G. Knepley #define __FUNCT__ "DMGetDimension"
3812c73cfb54SMatthew G. Knepley /*@
3813c73cfb54SMatthew G. Knepley   DMGetDimension - Return the topological dimension of the DM
3814c73cfb54SMatthew G. Knepley 
3815c73cfb54SMatthew G. Knepley   Not collective
3816c73cfb54SMatthew G. Knepley 
3817c73cfb54SMatthew G. Knepley   Input Parameter:
3818c73cfb54SMatthew G. Knepley . dm - The DM
3819c73cfb54SMatthew G. Knepley 
3820c73cfb54SMatthew G. Knepley   Output Parameter:
3821c73cfb54SMatthew G. Knepley . dim - The topological dimension
3822c73cfb54SMatthew G. Knepley 
3823c73cfb54SMatthew G. Knepley   Level: beginner
3824c73cfb54SMatthew G. Knepley 
3825c73cfb54SMatthew G. Knepley .seealso: DMSetDimension(), DMCreate()
3826c73cfb54SMatthew G. Knepley @*/
3827c73cfb54SMatthew G. Knepley PetscErrorCode DMGetDimension(DM dm, PetscInt *dim)
3828c73cfb54SMatthew G. Knepley {
3829c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
3830c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3831c73cfb54SMatthew G. Knepley   PetscValidPointer(dim, 2);
3832c73cfb54SMatthew G. Knepley   *dim = dm->dim;
3833c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
3834c73cfb54SMatthew G. Knepley }
3835c73cfb54SMatthew G. Knepley 
3836c73cfb54SMatthew G. Knepley #undef __FUNCT__
3837c73cfb54SMatthew G. Knepley #define __FUNCT__ "DMSetDimension"
3838c73cfb54SMatthew G. Knepley /*@
3839c73cfb54SMatthew G. Knepley   DMSetDimension - Set the topological dimension of the DM
3840c73cfb54SMatthew G. Knepley 
3841c73cfb54SMatthew G. Knepley   Collective on dm
3842c73cfb54SMatthew G. Knepley 
3843c73cfb54SMatthew G. Knepley   Input Parameters:
3844c73cfb54SMatthew G. Knepley + dm - The DM
3845c73cfb54SMatthew G. Knepley - dim - The topological dimension
3846c73cfb54SMatthew G. Knepley 
3847c73cfb54SMatthew G. Knepley   Level: beginner
3848c73cfb54SMatthew G. Knepley 
3849c73cfb54SMatthew G. Knepley .seealso: DMGetDimension(), DMCreate()
3850c73cfb54SMatthew G. Knepley @*/
3851c73cfb54SMatthew G. Knepley PetscErrorCode DMSetDimension(DM dm, PetscInt dim)
3852c73cfb54SMatthew G. Knepley {
3853c73cfb54SMatthew G. Knepley   PetscFunctionBegin;
3854c73cfb54SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3855c73cfb54SMatthew G. Knepley   PetscValidLogicalCollectiveInt(dm, dim, 2);
3856c73cfb54SMatthew G. Knepley   dm->dim = dim;
3857c73cfb54SMatthew G. Knepley   PetscFunctionReturn(0);
3858c73cfb54SMatthew G. Knepley }
3859c73cfb54SMatthew G. Knepley 
3860793f3fe5SMatthew G. Knepley #undef __FUNCT__
3861793f3fe5SMatthew G. Knepley #define __FUNCT__ "DMGetDimPoints"
3862793f3fe5SMatthew G. Knepley /*@
3863793f3fe5SMatthew G. Knepley   DMGetDimPoints - Get the half-open interval for all points of a given dimension
3864793f3fe5SMatthew G. Knepley 
3865793f3fe5SMatthew G. Knepley   Collective on DM
3866793f3fe5SMatthew G. Knepley 
3867793f3fe5SMatthew G. Knepley   Input Parameters:
3868793f3fe5SMatthew G. Knepley + dm - the DM
3869793f3fe5SMatthew G. Knepley - dim - the dimension
3870793f3fe5SMatthew G. Knepley 
3871793f3fe5SMatthew G. Knepley   Output Parameters:
3872793f3fe5SMatthew G. Knepley + pStart - The first point of the given dimension
3873793f3fe5SMatthew G. Knepley . pEnd - The first point following points of the given dimension
3874793f3fe5SMatthew G. Knepley 
3875793f3fe5SMatthew G. Knepley   Note:
3876793f3fe5SMatthew G. Knepley   The points are vertices in the Hasse diagram encoding the topology. This is explained in
3877793f3fe5SMatthew G. Knepley   http://arxiv.org/abs/0908.4427. If not points exist of this dimension in the storage scheme,
3878793f3fe5SMatthew G. Knepley   then the interval is empty.
3879793f3fe5SMatthew G. Knepley 
3880793f3fe5SMatthew G. Knepley   Level: intermediate
3881793f3fe5SMatthew G. Knepley 
3882793f3fe5SMatthew G. Knepley .keywords: point, Hasse Diagram, dimension
3883793f3fe5SMatthew G. Knepley .seealso: DMPLEX, DMPlexGetDepthStratum(), DMPlexGetHeightStratum()
3884793f3fe5SMatthew G. Knepley @*/
3885793f3fe5SMatthew G. Knepley PetscErrorCode DMGetDimPoints(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
3886793f3fe5SMatthew G. Knepley {
3887793f3fe5SMatthew G. Knepley   PetscInt       d;
3888793f3fe5SMatthew G. Knepley   PetscErrorCode ierr;
3889793f3fe5SMatthew G. Knepley 
3890793f3fe5SMatthew G. Knepley   PetscFunctionBegin;
3891793f3fe5SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3892793f3fe5SMatthew G. Knepley   ierr = DMGetDimension(dm, &d);CHKERRQ(ierr);
3893793f3fe5SMatthew G. Knepley   if ((dim < 0) || (dim > d)) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension %d 1", dim, d);
3894793f3fe5SMatthew G. Knepley   ierr = (*dm->ops->getdimpoints)(dm, dim, pStart, pEnd);CHKERRQ(ierr);
3895793f3fe5SMatthew G. Knepley   PetscFunctionReturn(0);
3896793f3fe5SMatthew G. Knepley }
3897793f3fe5SMatthew G. Knepley 
3898793f3fe5SMatthew G. Knepley #undef __FUNCT__
38996636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinates"
39006636e97aSMatthew G Knepley /*@
39016636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
39026636e97aSMatthew G Knepley 
39036636e97aSMatthew G Knepley   Collective on DM
39046636e97aSMatthew G Knepley 
39056636e97aSMatthew G Knepley   Input Parameters:
39066636e97aSMatthew G Knepley + dm - the DM
39076636e97aSMatthew G Knepley - c - coordinate vector
39086636e97aSMatthew G Knepley 
39096636e97aSMatthew G Knepley   Note:
39106636e97aSMatthew G Knepley   The coordinates do include those for ghost points, which are in the local vector
39116636e97aSMatthew G Knepley 
39126636e97aSMatthew G Knepley   Level: intermediate
39136636e97aSMatthew G Knepley 
39146636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
39156636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM()
39166636e97aSMatthew G Knepley @*/
39176636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
39186636e97aSMatthew G Knepley {
39196636e97aSMatthew G Knepley   PetscErrorCode ierr;
39206636e97aSMatthew G Knepley 
39216636e97aSMatthew G Knepley   PetscFunctionBegin;
39226636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
39236636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
39246636e97aSMatthew G Knepley   ierr            = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
39256636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
39266636e97aSMatthew G Knepley   dm->coordinates = c;
39276636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
3928b64e0483SPeter Brune   ierr            = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
392903dadc2fSPeter Brune   ierr            = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
39306636e97aSMatthew G Knepley   PetscFunctionReturn(0);
39316636e97aSMatthew G Knepley }
39326636e97aSMatthew G Knepley 
39336636e97aSMatthew G Knepley #undef __FUNCT__
39346636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinatesLocal"
39356636e97aSMatthew G Knepley /*@
39366636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
39376636e97aSMatthew G Knepley 
39386636e97aSMatthew G Knepley   Collective on DM
39396636e97aSMatthew G Knepley 
39406636e97aSMatthew G Knepley    Input Parameters:
39416636e97aSMatthew G Knepley +  dm - the DM
39426636e97aSMatthew G Knepley -  c - coordinate vector
39436636e97aSMatthew G Knepley 
39446636e97aSMatthew G Knepley   Note:
39456636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
39466636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
39476636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
39486636e97aSMatthew G Knepley 
39496636e97aSMatthew G Knepley   Level: intermediate
39506636e97aSMatthew G Knepley 
39516636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
39526636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
39536636e97aSMatthew G Knepley @*/
39546636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
39556636e97aSMatthew G Knepley {
39566636e97aSMatthew G Knepley   PetscErrorCode ierr;
39576636e97aSMatthew G Knepley 
39586636e97aSMatthew G Knepley   PetscFunctionBegin;
39596636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
39606636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
39616636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
39626636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
39638865f1eaSKarl Rupp 
39646636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
39658865f1eaSKarl Rupp 
39666636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
39676636e97aSMatthew G Knepley   PetscFunctionReturn(0);
39686636e97aSMatthew G Knepley }
39696636e97aSMatthew G Knepley 
39706636e97aSMatthew G Knepley #undef __FUNCT__
39716636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinates"
39726636e97aSMatthew G Knepley /*@
39736636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
39746636e97aSMatthew G Knepley 
39756636e97aSMatthew G Knepley   Not Collective
39766636e97aSMatthew G Knepley 
39776636e97aSMatthew G Knepley   Input Parameter:
39786636e97aSMatthew G Knepley . dm - the DM
39796636e97aSMatthew G Knepley 
39806636e97aSMatthew G Knepley   Output Parameter:
39816636e97aSMatthew G Knepley . c - global coordinate vector
39826636e97aSMatthew G Knepley 
39836636e97aSMatthew G Knepley   Note:
39846636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
39856636e97aSMatthew G Knepley 
39866636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
39876636e97aSMatthew G Knepley 
39886636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
39896636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
39906636e97aSMatthew G Knepley 
39916636e97aSMatthew G Knepley   Level: intermediate
39926636e97aSMatthew G Knepley 
39936636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
39946636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
39956636e97aSMatthew G Knepley @*/
39966636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
39976636e97aSMatthew G Knepley {
39986636e97aSMatthew G Knepley   PetscErrorCode ierr;
39996636e97aSMatthew G Knepley 
40006636e97aSMatthew G Knepley   PetscFunctionBegin;
40016636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
40026636e97aSMatthew G Knepley   PetscValidPointer(c,2);
40031f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
40040298fd71SBarry Smith     DM cdm = NULL;
40056636e97aSMatthew G Knepley 
40066636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
40076636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
40086636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
40096636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
40106636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
40116636e97aSMatthew G Knepley   }
40126636e97aSMatthew G Knepley   *c = dm->coordinates;
40136636e97aSMatthew G Knepley   PetscFunctionReturn(0);
40146636e97aSMatthew G Knepley }
40156636e97aSMatthew G Knepley 
40166636e97aSMatthew G Knepley #undef __FUNCT__
40176636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinatesLocal"
40186636e97aSMatthew G Knepley /*@
40196636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
40206636e97aSMatthew G Knepley 
40216636e97aSMatthew G Knepley   Collective on DM
40226636e97aSMatthew G Knepley 
40236636e97aSMatthew G Knepley   Input Parameter:
40246636e97aSMatthew G Knepley . dm - the DM
40256636e97aSMatthew G Knepley 
40266636e97aSMatthew G Knepley   Output Parameter:
40276636e97aSMatthew G Knepley . c - coordinate vector
40286636e97aSMatthew G Knepley 
40296636e97aSMatthew G Knepley   Note:
40306636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
40316636e97aSMatthew G Knepley 
40326636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
40336636e97aSMatthew G Knepley 
40346636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
40356636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
40366636e97aSMatthew G Knepley 
40376636e97aSMatthew G Knepley   Level: intermediate
40386636e97aSMatthew G Knepley 
40396636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
40406636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
40416636e97aSMatthew G Knepley @*/
40426636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
40436636e97aSMatthew G Knepley {
40446636e97aSMatthew G Knepley   PetscErrorCode ierr;
40456636e97aSMatthew G Knepley 
40466636e97aSMatthew G Knepley   PetscFunctionBegin;
40476636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
40486636e97aSMatthew G Knepley   PetscValidPointer(c,2);
40491f588964SMatthew G Knepley   if (!dm->coordinatesLocal && dm->coordinates) {
40500298fd71SBarry Smith     DM cdm = NULL;
40516636e97aSMatthew G Knepley 
40526636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
40536636e97aSMatthew G Knepley     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
40546636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
40556636e97aSMatthew G Knepley     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
40566636e97aSMatthew G Knepley     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
40576636e97aSMatthew G Knepley   }
40586636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
40596636e97aSMatthew G Knepley   PetscFunctionReturn(0);
40606636e97aSMatthew G Knepley }
40616636e97aSMatthew G Knepley 
40626636e97aSMatthew G Knepley #undef __FUNCT__
40636636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinateDM"
40646636e97aSMatthew G Knepley /*@
40651cfe2091SMatthew G. Knepley   DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates
40666636e97aSMatthew G Knepley 
40676636e97aSMatthew G Knepley   Collective on DM
40686636e97aSMatthew G Knepley 
40696636e97aSMatthew G Knepley   Input Parameter:
40706636e97aSMatthew G Knepley . dm - the DM
40716636e97aSMatthew G Knepley 
40726636e97aSMatthew G Knepley   Output Parameter:
40736636e97aSMatthew G Knepley . cdm - coordinate DM
40746636e97aSMatthew G Knepley 
40756636e97aSMatthew G Knepley   Level: intermediate
40766636e97aSMatthew G Knepley 
40776636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
40781cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
40796636e97aSMatthew G Knepley @*/
40806636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
40816636e97aSMatthew G Knepley {
40826636e97aSMatthew G Knepley   PetscErrorCode ierr;
40836636e97aSMatthew G Knepley 
40846636e97aSMatthew G Knepley   PetscFunctionBegin;
40856636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
40866636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
40876636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
408882f516ccSBarry Smith     if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM");
40896636e97aSMatthew G Knepley     ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr);
40906636e97aSMatthew G Knepley   }
40916636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
40926636e97aSMatthew G Knepley   PetscFunctionReturn(0);
40936636e97aSMatthew G Knepley }
4094e87bb0d3SMatthew G Knepley 
4095e87bb0d3SMatthew G Knepley #undef __FUNCT__
40961cfe2091SMatthew G. Knepley #define __FUNCT__ "DMSetCoordinateDM"
40971cfe2091SMatthew G. Knepley /*@
40981cfe2091SMatthew G. Knepley   DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates
40991cfe2091SMatthew G. Knepley 
41001cfe2091SMatthew G. Knepley   Logically Collective on DM
41011cfe2091SMatthew G. Knepley 
41021cfe2091SMatthew G. Knepley   Input Parameters:
41031cfe2091SMatthew G. Knepley + dm - the DM
41041cfe2091SMatthew G. Knepley - cdm - coordinate DM
41051cfe2091SMatthew G. Knepley 
41061cfe2091SMatthew G. Knepley   Level: intermediate
41071cfe2091SMatthew G. Knepley 
41081cfe2091SMatthew G. Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
41091cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
41101cfe2091SMatthew G. Knepley @*/
41111cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm)
41121cfe2091SMatthew G. Knepley {
41131cfe2091SMatthew G. Knepley   PetscErrorCode ierr;
41141cfe2091SMatthew G. Knepley 
41151cfe2091SMatthew G. Knepley   PetscFunctionBegin;
41161cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
41171cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(cdm,DM_CLASSID,2);
41181cfe2091SMatthew G. Knepley   ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
41191cfe2091SMatthew G. Knepley   dm->coordinateDM = cdm;
41201cfe2091SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) dm->coordinateDM);CHKERRQ(ierr);
41211cfe2091SMatthew G. Knepley   PetscFunctionReturn(0);
41221cfe2091SMatthew G. Knepley }
41231cfe2091SMatthew G. Knepley 
41241cfe2091SMatthew G. Knepley #undef __FUNCT__
412546e270d4SMatthew G. Knepley #define __FUNCT__ "DMGetCoordinateDim"
412646e270d4SMatthew G. Knepley /*@
412746e270d4SMatthew G. Knepley   DMGetCoordinateDim - Retrieve the dimension of embedding space for coordinate values.
412846e270d4SMatthew G. Knepley 
412946e270d4SMatthew G. Knepley   Not Collective
413046e270d4SMatthew G. Knepley 
413146e270d4SMatthew G. Knepley   Input Parameter:
413246e270d4SMatthew G. Knepley . dm - The DM object
413346e270d4SMatthew G. Knepley 
413446e270d4SMatthew G. Knepley   Output Parameter:
413546e270d4SMatthew G. Knepley . dim - The embedding dimension
413646e270d4SMatthew G. Knepley 
413746e270d4SMatthew G. Knepley   Level: intermediate
413846e270d4SMatthew G. Knepley 
413946e270d4SMatthew G. Knepley .keywords: mesh, coordinates
414046e270d4SMatthew G. Knepley .seealso: DMSetCoordinateDim(), DMGetCoordinateSection(), DMGetCoordinateDM(), DMGetDefaultSection(), DMSetDefaultSection()
414146e270d4SMatthew G. Knepley @*/
414246e270d4SMatthew G. Knepley PetscErrorCode DMGetCoordinateDim(DM dm, PetscInt *dim)
414346e270d4SMatthew G. Knepley {
414446e270d4SMatthew G. Knepley   PetscFunctionBegin;
414546e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
414646e270d4SMatthew G. Knepley   PetscValidPointer(dim, 2);
41479a9a41abSToby Isaac   if (dm->dimEmbed == PETSC_DEFAULT) {
41489a9a41abSToby Isaac     dm->dimEmbed = dm->dim;
41499a9a41abSToby Isaac   }
415046e270d4SMatthew G. Knepley   *dim = dm->dimEmbed;
415146e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
415246e270d4SMatthew G. Knepley }
415346e270d4SMatthew G. Knepley 
415446e270d4SMatthew G. Knepley #undef __FUNCT__
415546e270d4SMatthew G. Knepley #define __FUNCT__ "DMSetCoordinateDim"
415646e270d4SMatthew G. Knepley /*@
415746e270d4SMatthew G. Knepley   DMSetCoordinateDim - Set the dimension of the embedding space for coordinate values.
415846e270d4SMatthew G. Knepley 
415946e270d4SMatthew G. Knepley   Not Collective
416046e270d4SMatthew G. Knepley 
416146e270d4SMatthew G. Knepley   Input Parameters:
416246e270d4SMatthew G. Knepley + dm  - The DM object
416346e270d4SMatthew G. Knepley - dim - The embedding dimension
416446e270d4SMatthew G. Knepley 
416546e270d4SMatthew G. Knepley   Level: intermediate
416646e270d4SMatthew G. Knepley 
416746e270d4SMatthew G. Knepley .keywords: mesh, coordinates
416846e270d4SMatthew G. Knepley .seealso: DMGetCoordinateDim(), DMSetCoordinateSection(), DMGetCoordinateSection(), DMGetDefaultSection(), DMSetDefaultSection()
416946e270d4SMatthew G. Knepley @*/
417046e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateDim(DM dm, PetscInt dim)
417146e270d4SMatthew G. Knepley {
417246e270d4SMatthew G. Knepley   PetscFunctionBegin;
417346e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
417446e270d4SMatthew G. Knepley   dm->dimEmbed = dim;
417546e270d4SMatthew G. Knepley   PetscFunctionReturn(0);
417646e270d4SMatthew G. Knepley }
417746e270d4SMatthew G. Knepley 
417846e270d4SMatthew G. Knepley #undef __FUNCT__
4179e8abe2deSMatthew G. Knepley #define __FUNCT__ "DMGetCoordinateSection"
4180e8abe2deSMatthew G. Knepley /*@
4181e8abe2deSMatthew G. Knepley   DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh.
4182e8abe2deSMatthew G. Knepley 
4183e8abe2deSMatthew G. Knepley   Not Collective
4184e8abe2deSMatthew G. Knepley 
4185e8abe2deSMatthew G. Knepley   Input Parameter:
4186e8abe2deSMatthew G. Knepley . dm - The DM object
4187e8abe2deSMatthew G. Knepley 
4188e8abe2deSMatthew G. Knepley   Output Parameter:
4189e8abe2deSMatthew G. Knepley . section - The PetscSection object
4190e8abe2deSMatthew G. Knepley 
4191e8abe2deSMatthew G. Knepley   Level: intermediate
4192e8abe2deSMatthew G. Knepley 
4193e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates
4194e8abe2deSMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMGetDefaultSection(), DMSetDefaultSection()
4195e8abe2deSMatthew G. Knepley @*/
4196e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section)
4197e8abe2deSMatthew G. Knepley {
4198e8abe2deSMatthew G. Knepley   DM             cdm;
4199e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
4200e8abe2deSMatthew G. Knepley 
4201e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
4202e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4203e8abe2deSMatthew G. Knepley   PetscValidPointer(section, 2);
4204e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
4205e8abe2deSMatthew G. Knepley   ierr = DMGetDefaultSection(cdm, section);CHKERRQ(ierr);
4206e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
4207e8abe2deSMatthew G. Knepley }
4208e8abe2deSMatthew G. Knepley 
4209e8abe2deSMatthew G. Knepley #undef __FUNCT__
4210e8abe2deSMatthew G. Knepley #define __FUNCT__ "DMSetCoordinateSection"
4211e8abe2deSMatthew G. Knepley /*@
4212e8abe2deSMatthew G. Knepley   DMSetCoordinateSection - Set the layout of coordinate values over the mesh.
4213e8abe2deSMatthew G. Knepley 
4214e8abe2deSMatthew G. Knepley   Not Collective
4215e8abe2deSMatthew G. Knepley 
4216e8abe2deSMatthew G. Knepley   Input Parameters:
4217e8abe2deSMatthew G. Knepley + dm      - The DM object
421846e270d4SMatthew G. Knepley . dim     - The embedding dimension, or PETSC_DETERMINE
4219e8abe2deSMatthew G. Knepley - section - The PetscSection object
4220e8abe2deSMatthew G. Knepley 
4221e8abe2deSMatthew G. Knepley   Level: intermediate
4222e8abe2deSMatthew G. Knepley 
4223e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates
4224e8abe2deSMatthew G. Knepley .seealso: DMGetCoordinateSection(), DMGetDefaultSection(), DMSetDefaultSection()
4225e8abe2deSMatthew G. Knepley @*/
422646e270d4SMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscInt dim, PetscSection section)
4227e8abe2deSMatthew G. Knepley {
4228e8abe2deSMatthew G. Knepley   DM             cdm;
4229e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
4230e8abe2deSMatthew G. Knepley 
4231e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
4232e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
423346e270d4SMatthew G. Knepley   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,3);
4234e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
4235e8abe2deSMatthew G. Knepley   ierr = DMSetDefaultSection(cdm, section);CHKERRQ(ierr);
423646e270d4SMatthew G. Knepley   if (dim == PETSC_DETERMINE) {
423746e270d4SMatthew G. Knepley     PetscInt d = dim;
423846e270d4SMatthew G. Knepley     PetscInt pStart, pEnd, vStart, vEnd, v, dd;
423946e270d4SMatthew G. Knepley 
424046e270d4SMatthew G. Knepley     ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
424146e270d4SMatthew G. Knepley     ierr = DMGetDimPoints(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
424246e270d4SMatthew G. Knepley     pStart = PetscMax(vStart, pStart);
424346e270d4SMatthew G. Knepley     pEnd   = PetscMin(vEnd, pEnd);
424446e270d4SMatthew G. Knepley     for (v = pStart; v < pEnd; ++v) {
424546e270d4SMatthew G. Knepley       ierr = PetscSectionGetDof(section, v, &dd);CHKERRQ(ierr);
424646e270d4SMatthew G. Knepley       if (dd) {d = dd; break;}
424746e270d4SMatthew G. Knepley     }
424846e270d4SMatthew G. Knepley     ierr = DMSetCoordinateDim(dm, d);CHKERRQ(ierr);
424946e270d4SMatthew G. Knepley   }
4250e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
4251e8abe2deSMatthew G. Knepley }
4252e8abe2deSMatthew G. Knepley 
4253e8abe2deSMatthew G. Knepley #undef __FUNCT__
4254c6b900c6SMatthew G. Knepley #define __FUNCT__ "DMGetPeriodicity"
42555dc8c3f7SMatthew G. Knepley /*@C
42565dc8c3f7SMatthew G. Knepley   DMSetPeriodicity - Set the description of mesh periodicity
42575dc8c3f7SMatthew G. Knepley 
42585dc8c3f7SMatthew G. Knepley   Input Parameters:
42595dc8c3f7SMatthew G. Knepley + dm      - The DM object
42605dc8c3f7SMatthew 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
42615dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
42625dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
42635dc8c3f7SMatthew G. Knepley 
42645dc8c3f7SMatthew G. Knepley   Level: developer
42655dc8c3f7SMatthew G. Knepley 
42665dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
42675dc8c3f7SMatthew G. Knepley @*/
42685dc8c3f7SMatthew G. Knepley PetscErrorCode DMGetPeriodicity(DM dm, const PetscReal **maxCell, const PetscReal **L, const DMBoundaryType **bd)
4269c6b900c6SMatthew G. Knepley {
4270c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
4271c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4272c6b900c6SMatthew G. Knepley   if (L)       *L       = dm->L;
4273c6b900c6SMatthew G. Knepley   if (maxCell) *maxCell = dm->maxCell;
42745dc8c3f7SMatthew G. Knepley   if (bd)      *bd      = dm->bdtype;
4275c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
4276c6b900c6SMatthew G. Knepley }
4277c6b900c6SMatthew G. Knepley 
4278c6b900c6SMatthew G. Knepley #undef __FUNCT__
4279c6b900c6SMatthew G. Knepley #define __FUNCT__ "DMSetPeriodicity"
42805dc8c3f7SMatthew G. Knepley /*@C
42815dc8c3f7SMatthew G. Knepley   DMSetPeriodicity - Set the description of mesh periodicity
42825dc8c3f7SMatthew G. Knepley 
42835dc8c3f7SMatthew G. Knepley   Input Parameters:
42845dc8c3f7SMatthew G. Knepley + dm      - The DM object
42855dc8c3f7SMatthew 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
42865dc8c3f7SMatthew G. Knepley . L       - If we assume the mesh is a torus, this is the length of each coordinate
42875dc8c3f7SMatthew G. Knepley - bd      - This describes the type of periodicity in each topological dimension
42885dc8c3f7SMatthew G. Knepley 
42895dc8c3f7SMatthew G. Knepley   Level: developer
42905dc8c3f7SMatthew G. Knepley 
42915dc8c3f7SMatthew G. Knepley .seealso: DMGetPeriodicity()
42925dc8c3f7SMatthew G. Knepley @*/
42935dc8c3f7SMatthew G. Knepley PetscErrorCode DMSetPeriodicity(DM dm, const PetscReal maxCell[], const PetscReal L[], const DMBoundaryType bd[])
4294c6b900c6SMatthew G. Knepley {
4295c6b900c6SMatthew G. Knepley   PetscInt       dim, d;
4296c6b900c6SMatthew G. Knepley   PetscErrorCode ierr;
4297c6b900c6SMatthew G. Knepley 
4298c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
4299c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
43005dc8c3f7SMatthew G. Knepley   PetscValidPointer(L,3);PetscValidPointer(maxCell,2);PetscValidPointer(bd,4);
43015dc8c3f7SMatthew G. Knepley   ierr = PetscFree3(dm->L,dm->maxCell,dm->bdtype);CHKERRQ(ierr);
43025dc8c3f7SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
43035dc8c3f7SMatthew G. Knepley   ierr = PetscMalloc3(dim,&dm->L,dim,&dm->maxCell,dim,&dm->bdtype);CHKERRQ(ierr);
43045dc8c3f7SMatthew G. Knepley   for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d]; dm->bdtype[d] = bd[d];}
4305c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
4306c6b900c6SMatthew G. Knepley }
4307c6b900c6SMatthew G. Knepley 
4308c6b900c6SMatthew G. Knepley #undef __FUNCT__
4309e87bb0d3SMatthew G Knepley #define __FUNCT__ "DMLocatePoints"
4310e87bb0d3SMatthew G Knepley /*@
4311e87bb0d3SMatthew G Knepley   DMLocatePoints - Locate the points in v in the mesh and return an IS of the containing cells
4312e87bb0d3SMatthew G Knepley 
4313e87bb0d3SMatthew G Knepley   Not collective
4314e87bb0d3SMatthew G Knepley 
4315e87bb0d3SMatthew G Knepley   Input Parameters:
4316e87bb0d3SMatthew G Knepley + dm - The DM
4317e87bb0d3SMatthew G Knepley - v - The Vec of points
4318e87bb0d3SMatthew G Knepley 
431961e3bb9bSMatthew G Knepley   Output Parameter:
4320e87bb0d3SMatthew G Knepley . cells - The local cell numbers for cells which contain the points
4321e87bb0d3SMatthew G Knepley 
4322e87bb0d3SMatthew G Knepley   Level: developer
432361e3bb9bSMatthew G Knepley 
432461e3bb9bSMatthew G Knepley .keywords: point location, mesh
432561e3bb9bSMatthew G Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
432661e3bb9bSMatthew G Knepley @*/
4327e87bb0d3SMatthew G Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, IS *cells)
4328e87bb0d3SMatthew G Knepley {
4329735aa83eSMatthew G Knepley   PetscErrorCode ierr;
4330735aa83eSMatthew G Knepley 
4331e87bb0d3SMatthew G Knepley   PetscFunctionBegin;
4332e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4333e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4334e87bb0d3SMatthew G Knepley   PetscValidPointer(cells,3);
433547a35634SPatrick Farrell   ierr = PetscLogEventBegin(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
4336735aa83eSMatthew G Knepley   if (dm->ops->locatepoints) {
4337735aa83eSMatthew G Knepley     ierr = (*dm->ops->locatepoints)(dm,v,cells);CHKERRQ(ierr);
433882f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM");
433947a35634SPatrick Farrell   ierr = PetscLogEventEnd(DM_LocatePoints,dm,0,0,0);CHKERRQ(ierr);
4340e87bb0d3SMatthew G Knepley   PetscFunctionReturn(0);
4341e87bb0d3SMatthew G Knepley }
434214f150ffSMatthew G. Knepley 
434314f150ffSMatthew G. Knepley #undef __FUNCT__
434414f150ffSMatthew G. Knepley #define __FUNCT__ "DMGetOutputDM"
4345f4d763aaSMatthew G. Knepley /*@
4346f4d763aaSMatthew G. Knepley   DMGetOutputDM - Retrieve the DM associated with the layout for output
4347f4d763aaSMatthew G. Knepley 
4348f4d763aaSMatthew G. Knepley   Input Parameter:
4349f4d763aaSMatthew G. Knepley . dm - The original DM
4350f4d763aaSMatthew G. Knepley 
4351f4d763aaSMatthew G. Knepley   Output Parameter:
4352f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output
4353f4d763aaSMatthew G. Knepley 
4354f4d763aaSMatthew G. Knepley   Level: intermediate
4355f4d763aaSMatthew G. Knepley 
4356f4d763aaSMatthew G. Knepley .seealso: VecView(), DMGetDefaultGlobalSection()
4357f4d763aaSMatthew G. Knepley @*/
435814f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm)
435914f150ffSMatthew G. Knepley {
4360c26acbdeSMatthew G. Knepley   PetscSection   section;
4361c26acbdeSMatthew G. Knepley   PetscBool      hasConstraints;
436214f150ffSMatthew G. Knepley   PetscErrorCode ierr;
436314f150ffSMatthew G. Knepley 
436414f150ffSMatthew G. Knepley   PetscFunctionBegin;
436514f150ffSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
436614f150ffSMatthew G. Knepley   PetscValidPointer(odm,2);
4367c26acbdeSMatthew G. Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
4368c26acbdeSMatthew G. Knepley   ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr);
4369c26acbdeSMatthew G. Knepley   if (!hasConstraints) {
4370c26acbdeSMatthew G. Knepley     *odm = dm;
4371c26acbdeSMatthew G. Knepley     PetscFunctionReturn(0);
4372c26acbdeSMatthew G. Knepley   }
437314f150ffSMatthew G. Knepley   if (!dm->dmBC) {
4374c26acbdeSMatthew G. Knepley     PetscSection newSection, gsection;
437514f150ffSMatthew G. Knepley     PetscSF      sf;
437614f150ffSMatthew G. Knepley 
437714f150ffSMatthew G. Knepley     ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr);
437814f150ffSMatthew G. Knepley     ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr);
437914f150ffSMatthew G. Knepley     ierr = DMSetDefaultSection(dm->dmBC, newSection);CHKERRQ(ierr);
438014f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);
438114f150ffSMatthew G. Knepley     ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr);
438215b58121SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr);
438314f150ffSMatthew G. Knepley     ierr = DMSetDefaultGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr);
438414f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr);
438514f150ffSMatthew G. Knepley   }
438614f150ffSMatthew G. Knepley   *odm = dm->dmBC;
438714f150ffSMatthew G. Knepley   PetscFunctionReturn(0);
438814f150ffSMatthew G. Knepley }
4389f4d763aaSMatthew G. Knepley 
4390f4d763aaSMatthew G. Knepley #undef __FUNCT__
4391f4d763aaSMatthew G. Knepley #define __FUNCT__ "DMGetOutputSequenceNumber"
4392f4d763aaSMatthew G. Knepley /*@
4393cdb7a50dSMatthew G. Knepley   DMGetOutputSequenceNumber - Retrieve the sequence number/value for output
4394f4d763aaSMatthew G. Knepley 
4395f4d763aaSMatthew G. Knepley   Input Parameter:
4396f4d763aaSMatthew G. Knepley . dm - The original DM
4397f4d763aaSMatthew G. Knepley 
4398cdb7a50dSMatthew G. Knepley   Output Parameters:
4399cdb7a50dSMatthew G. Knepley + num - The output sequence number
4400cdb7a50dSMatthew G. Knepley - val - The output sequence value
4401f4d763aaSMatthew G. Knepley 
4402f4d763aaSMatthew G. Knepley   Level: intermediate
4403f4d763aaSMatthew G. Knepley 
4404f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
4405f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
4406f4d763aaSMatthew G. Knepley 
4407f4d763aaSMatthew G. Knepley .seealso: VecView()
4408f4d763aaSMatthew G. Knepley @*/
4409cdb7a50dSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num, PetscReal *val)
4410f4d763aaSMatthew G. Knepley {
4411f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
4412f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4413cdb7a50dSMatthew G. Knepley   if (num) {PetscValidPointer(num,2); *num = dm->outputSequenceNum;}
4414cdb7a50dSMatthew G. Knepley   if (val) {PetscValidPointer(val,3);*val = dm->outputSequenceVal;}
4415f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
4416f4d763aaSMatthew G. Knepley }
4417f4d763aaSMatthew G. Knepley 
4418f4d763aaSMatthew G. Knepley #undef __FUNCT__
4419f4d763aaSMatthew G. Knepley #define __FUNCT__ "DMSetOutputSequenceNumber"
4420f4d763aaSMatthew G. Knepley /*@
4421cdb7a50dSMatthew G. Knepley   DMSetOutputSequenceNumber - Set the sequence number/value for output
4422f4d763aaSMatthew G. Knepley 
4423f4d763aaSMatthew G. Knepley   Input Parameters:
4424f4d763aaSMatthew G. Knepley + dm - The original DM
4425cdb7a50dSMatthew G. Knepley . num - The output sequence number
4426cdb7a50dSMatthew G. Knepley - val - The output sequence value
4427f4d763aaSMatthew G. Knepley 
4428f4d763aaSMatthew G. Knepley   Level: intermediate
4429f4d763aaSMatthew G. Knepley 
4430f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
4431f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
4432f4d763aaSMatthew G. Knepley 
4433f4d763aaSMatthew G. Knepley .seealso: VecView()
4434f4d763aaSMatthew G. Knepley @*/
4435cdb7a50dSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num, PetscReal val)
4436f4d763aaSMatthew G. Knepley {
4437f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
4438f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4439f4d763aaSMatthew G. Knepley   dm->outputSequenceNum = num;
4440cdb7a50dSMatthew G. Knepley   dm->outputSequenceVal = val;
4441cdb7a50dSMatthew G. Knepley   PetscFunctionReturn(0);
4442cdb7a50dSMatthew G. Knepley }
4443cdb7a50dSMatthew G. Knepley 
4444cdb7a50dSMatthew G. Knepley #undef __FUNCT__
4445cdb7a50dSMatthew G. Knepley #define __FUNCT__ "DMOutputSequenceLoad"
4446cdb7a50dSMatthew G. Knepley /*@C
4447cdb7a50dSMatthew G. Knepley   DMOutputSequenceLoad - Retrieve the sequence value from a Viewer
4448cdb7a50dSMatthew G. Knepley 
4449cdb7a50dSMatthew G. Knepley   Input Parameters:
4450cdb7a50dSMatthew G. Knepley + dm   - The original DM
4451cdb7a50dSMatthew G. Knepley . name - The sequence name
4452cdb7a50dSMatthew G. Knepley - num  - The output sequence number
4453cdb7a50dSMatthew G. Knepley 
4454cdb7a50dSMatthew G. Knepley   Output Parameter:
4455cdb7a50dSMatthew G. Knepley . val  - The output sequence value
4456cdb7a50dSMatthew G. Knepley 
4457cdb7a50dSMatthew G. Knepley   Level: intermediate
4458cdb7a50dSMatthew G. Knepley 
4459cdb7a50dSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
4460cdb7a50dSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
4461cdb7a50dSMatthew G. Knepley 
4462cdb7a50dSMatthew G. Knepley .seealso: DMGetOutputSequenceNumber(), DMSetOutputSequenceNumber(), VecView()
4463cdb7a50dSMatthew G. Knepley @*/
4464cdb7a50dSMatthew G. Knepley PetscErrorCode DMOutputSequenceLoad(DM dm, PetscViewer viewer, const char *name, PetscInt num, PetscReal *val)
4465cdb7a50dSMatthew G. Knepley {
4466cdb7a50dSMatthew G. Knepley   PetscBool      ishdf5;
4467cdb7a50dSMatthew G. Knepley   PetscErrorCode ierr;
4468cdb7a50dSMatthew G. Knepley 
4469cdb7a50dSMatthew G. Knepley   PetscFunctionBegin;
4470cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4471cdb7a50dSMatthew G. Knepley   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
4472cdb7a50dSMatthew G. Knepley   PetscValidPointer(val,4);
4473cdb7a50dSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr);
4474cdb7a50dSMatthew G. Knepley   if (ishdf5) {
4475cdb7a50dSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
4476cdb7a50dSMatthew G. Knepley     PetscScalar value;
4477cdb7a50dSMatthew G. Knepley 
4478cdb7a50dSMatthew G. Knepley     ierr = DMSequenceLoad_HDF5(dm, name, num, &value, viewer);CHKERRQ(ierr);
44794aeb217fSMatthew G. Knepley     *val = PetscRealPart(value);
4480cdb7a50dSMatthew G. Knepley #endif
4481cdb7a50dSMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerHDF5Open()");
4482f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
4483f4d763aaSMatthew G. Knepley }
44848e4ac7eaSMatthew G. Knepley 
44858e4ac7eaSMatthew G. Knepley #undef __FUNCT__
44868e4ac7eaSMatthew G. Knepley #define __FUNCT__ "DMGetUseNatural"
44878e4ac7eaSMatthew G. Knepley /*@
44888e4ac7eaSMatthew G. Knepley   DMGetUseNatural - Get the flag for creating a mapping to the natural order on distribution
44898e4ac7eaSMatthew G. Knepley 
44908e4ac7eaSMatthew G. Knepley   Not collective
44918e4ac7eaSMatthew G. Knepley 
44928e4ac7eaSMatthew G. Knepley   Input Parameter:
44938e4ac7eaSMatthew G. Knepley . dm - The DM
44948e4ac7eaSMatthew G. Knepley 
44958e4ac7eaSMatthew G. Knepley   Output Parameter:
44968e4ac7eaSMatthew G. Knepley . useNatural - The flag to build the mapping to a natural order during distribution
44978e4ac7eaSMatthew G. Knepley 
44988e4ac7eaSMatthew G. Knepley   Level: beginner
44998e4ac7eaSMatthew G. Knepley 
45008e4ac7eaSMatthew G. Knepley .seealso: DMSetUseNatural(), DMCreate()
45018e4ac7eaSMatthew G. Knepley @*/
45028e4ac7eaSMatthew G. Knepley PetscErrorCode DMGetUseNatural(DM dm, PetscBool *useNatural)
45038e4ac7eaSMatthew G. Knepley {
45048e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
45058e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
45068e4ac7eaSMatthew G. Knepley   PetscValidPointer(useNatural, 2);
45078e4ac7eaSMatthew G. Knepley   *useNatural = dm->useNatural;
45088e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
45098e4ac7eaSMatthew G. Knepley }
45108e4ac7eaSMatthew G. Knepley 
45118e4ac7eaSMatthew G. Knepley #undef __FUNCT__
45128e4ac7eaSMatthew G. Knepley #define __FUNCT__ "DMSetUseNatural"
45138e4ac7eaSMatthew G. Knepley /*@
45148e4ac7eaSMatthew G. Knepley   DMSetUseNatural - Set the flag for creating a mapping to the natural order on distribution
45158e4ac7eaSMatthew G. Knepley 
45168e4ac7eaSMatthew G. Knepley   Collective on dm
45178e4ac7eaSMatthew G. Knepley 
45188e4ac7eaSMatthew G. Knepley   Input Parameters:
45198e4ac7eaSMatthew G. Knepley + dm - The DM
45208e4ac7eaSMatthew G. Knepley - useNatural - The flag to build the mapping to a natural order during distribution
45218e4ac7eaSMatthew G. Knepley 
45228e4ac7eaSMatthew G. Knepley   Level: beginner
45238e4ac7eaSMatthew G. Knepley 
45248e4ac7eaSMatthew G. Knepley .seealso: DMGetUseNatural(), DMCreate()
45258e4ac7eaSMatthew G. Knepley @*/
45268e4ac7eaSMatthew G. Knepley PetscErrorCode DMSetUseNatural(DM dm, PetscBool useNatural)
45278e4ac7eaSMatthew G. Knepley {
45288e4ac7eaSMatthew G. Knepley   PetscFunctionBegin;
45298e4ac7eaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
45308e4ac7eaSMatthew G. Knepley   PetscValidLogicalCollectiveInt(dm, useNatural, 2);
45318e4ac7eaSMatthew G. Knepley   dm->useNatural = useNatural;
45328e4ac7eaSMatthew G. Knepley   PetscFunctionReturn(0);
45338e4ac7eaSMatthew G. Knepley }
4534*c58f1c22SToby Isaac 
4535*c58f1c22SToby Isaac #undef __FUNCT__
4536*c58f1c22SToby Isaac #define __FUNCT__
4537*c58f1c22SToby Isaac 
4538*c58f1c22SToby Isaac #undef __FUNCT__
4539*c58f1c22SToby Isaac #define __FUNCT__ "DMCreateLabel"
4540*c58f1c22SToby Isaac /*@C
4541*c58f1c22SToby Isaac   DMCreateLabel - Create a label of the given name if it does not already exist
4542*c58f1c22SToby Isaac 
4543*c58f1c22SToby Isaac   Not Collective
4544*c58f1c22SToby Isaac 
4545*c58f1c22SToby Isaac   Input Parameters:
4546*c58f1c22SToby Isaac + dm   - The DM object
4547*c58f1c22SToby Isaac - name - The label name
4548*c58f1c22SToby Isaac 
4549*c58f1c22SToby Isaac   Level: intermediate
4550*c58f1c22SToby Isaac 
4551*c58f1c22SToby Isaac .keywords: mesh
4552*c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
4553*c58f1c22SToby Isaac @*/
4554*c58f1c22SToby Isaac PetscErrorCode DMCreateLabel(DM dm, const char name[])
4555*c58f1c22SToby Isaac {
4556*c58f1c22SToby Isaac   DMLabelLink    next  = dm->labels->next;
4557*c58f1c22SToby Isaac   PetscBool      flg   = PETSC_FALSE;
4558*c58f1c22SToby Isaac   PetscErrorCode ierr;
4559*c58f1c22SToby Isaac 
4560*c58f1c22SToby Isaac   PetscFunctionBegin;
4561*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4562*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4563*c58f1c22SToby Isaac   while (next) {
4564*c58f1c22SToby Isaac     ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr);
4565*c58f1c22SToby Isaac     if (flg) break;
4566*c58f1c22SToby Isaac     next = next->next;
4567*c58f1c22SToby Isaac   }
4568*c58f1c22SToby Isaac   if (!flg) {
4569*c58f1c22SToby Isaac     DMLabelLink tmpLabel;
4570*c58f1c22SToby Isaac 
4571*c58f1c22SToby Isaac     ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
4572*c58f1c22SToby Isaac     ierr = DMLabelCreate(name, &tmpLabel->label);CHKERRQ(ierr);
4573*c58f1c22SToby Isaac     tmpLabel->output = PETSC_TRUE;
4574*c58f1c22SToby Isaac     tmpLabel->next   = dm->labels->next;
4575*c58f1c22SToby Isaac     dm->labels->next = tmpLabel;
4576*c58f1c22SToby Isaac   }
4577*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4578*c58f1c22SToby Isaac }
4579*c58f1c22SToby Isaac 
4580*c58f1c22SToby Isaac #undef __FUNCT__
4581*c58f1c22SToby Isaac #define __FUNCT__ "DMGetLabelValue"
4582*c58f1c22SToby Isaac /*@C
4583*c58f1c22SToby Isaac   DMGetLabelValue - Get the value in a Sieve Label for the given point, with 0 as the default
4584*c58f1c22SToby Isaac 
4585*c58f1c22SToby Isaac   Not Collective
4586*c58f1c22SToby Isaac 
4587*c58f1c22SToby Isaac   Input Parameters:
4588*c58f1c22SToby Isaac + dm   - The DM object
4589*c58f1c22SToby Isaac . name - The label name
4590*c58f1c22SToby Isaac - point - The mesh point
4591*c58f1c22SToby Isaac 
4592*c58f1c22SToby Isaac   Output Parameter:
4593*c58f1c22SToby Isaac . value - The label value for this point, or -1 if the point is not in the label
4594*c58f1c22SToby Isaac 
4595*c58f1c22SToby Isaac   Level: beginner
4596*c58f1c22SToby Isaac 
4597*c58f1c22SToby Isaac .keywords: mesh
4598*c58f1c22SToby Isaac .seealso: DMLabelGetValue(), DMSetLabelValue(), DMGetStratumIS()
4599*c58f1c22SToby Isaac @*/
4600*c58f1c22SToby Isaac PetscErrorCode DMGetLabelValue(DM dm, const char name[], PetscInt point, PetscInt *value)
4601*c58f1c22SToby Isaac {
4602*c58f1c22SToby Isaac   DMLabel        label;
4603*c58f1c22SToby Isaac   PetscErrorCode ierr;
4604*c58f1c22SToby Isaac 
4605*c58f1c22SToby Isaac   PetscFunctionBegin;
4606*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4607*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4608*c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4609*c58f1c22SToby Isaac   if (!label) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No label named %s was found", name);CHKERRQ(ierr);
4610*c58f1c22SToby Isaac   ierr = DMLabelGetValue(label, point, value);CHKERRQ(ierr);
4611*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4612*c58f1c22SToby Isaac }
4613*c58f1c22SToby Isaac 
4614*c58f1c22SToby Isaac #undef __FUNCT__
4615*c58f1c22SToby Isaac #define __FUNCT__ "DMSetLabelValue"
4616*c58f1c22SToby Isaac /*@C
4617*c58f1c22SToby Isaac   DMSetLabelValue - Add a point to a Sieve Label with given value
4618*c58f1c22SToby Isaac 
4619*c58f1c22SToby Isaac   Not Collective
4620*c58f1c22SToby Isaac 
4621*c58f1c22SToby Isaac   Input Parameters:
4622*c58f1c22SToby Isaac + dm   - The DM object
4623*c58f1c22SToby Isaac . name - The label name
4624*c58f1c22SToby Isaac . point - The mesh point
4625*c58f1c22SToby Isaac - value - The label value for this point
4626*c58f1c22SToby Isaac 
4627*c58f1c22SToby Isaac   Output Parameter:
4628*c58f1c22SToby Isaac 
4629*c58f1c22SToby Isaac   Level: beginner
4630*c58f1c22SToby Isaac 
4631*c58f1c22SToby Isaac .keywords: mesh
4632*c58f1c22SToby Isaac .seealso: DMLabelSetValue(), DMGetStratumIS(), DMClearLabelValue()
4633*c58f1c22SToby Isaac @*/
4634*c58f1c22SToby Isaac PetscErrorCode DMSetLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
4635*c58f1c22SToby Isaac {
4636*c58f1c22SToby Isaac   DMLabel        label;
4637*c58f1c22SToby Isaac   PetscErrorCode ierr;
4638*c58f1c22SToby Isaac 
4639*c58f1c22SToby Isaac   PetscFunctionBegin;
4640*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4641*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4642*c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4643*c58f1c22SToby Isaac   if (!label) {
4644*c58f1c22SToby Isaac     ierr = DMCreateLabel(dm, name);CHKERRQ(ierr);
4645*c58f1c22SToby Isaac     ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4646*c58f1c22SToby Isaac   }
4647*c58f1c22SToby Isaac   ierr = DMLabelSetValue(label, point, value);CHKERRQ(ierr);
4648*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4649*c58f1c22SToby Isaac }
4650*c58f1c22SToby Isaac 
4651*c58f1c22SToby Isaac #undef __FUNCT__
4652*c58f1c22SToby Isaac #define __FUNCT__ "DMClearLabelValue"
4653*c58f1c22SToby Isaac /*@C
4654*c58f1c22SToby Isaac   DMClearLabelValue - Remove a point from a Sieve Label with given value
4655*c58f1c22SToby Isaac 
4656*c58f1c22SToby Isaac   Not Collective
4657*c58f1c22SToby Isaac 
4658*c58f1c22SToby Isaac   Input Parameters:
4659*c58f1c22SToby Isaac + dm   - The DM object
4660*c58f1c22SToby Isaac . name - The label name
4661*c58f1c22SToby Isaac . point - The mesh point
4662*c58f1c22SToby Isaac - value - The label value for this point
4663*c58f1c22SToby Isaac 
4664*c58f1c22SToby Isaac   Output Parameter:
4665*c58f1c22SToby Isaac 
4666*c58f1c22SToby Isaac   Level: beginner
4667*c58f1c22SToby Isaac 
4668*c58f1c22SToby Isaac .keywords: mesh
4669*c58f1c22SToby Isaac .seealso: DMLabelClearValue(), DMSetLabelValue(), DMGetStratumIS()
4670*c58f1c22SToby Isaac @*/
4671*c58f1c22SToby Isaac PetscErrorCode DMClearLabelValue(DM dm, const char name[], PetscInt point, PetscInt value)
4672*c58f1c22SToby Isaac {
4673*c58f1c22SToby Isaac   DMLabel        label;
4674*c58f1c22SToby Isaac   PetscErrorCode ierr;
4675*c58f1c22SToby Isaac 
4676*c58f1c22SToby Isaac   PetscFunctionBegin;
4677*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4678*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4679*c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4680*c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
4681*c58f1c22SToby Isaac   ierr = DMLabelClearValue(label, point, value);CHKERRQ(ierr);
4682*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4683*c58f1c22SToby Isaac }
4684*c58f1c22SToby Isaac 
4685*c58f1c22SToby Isaac #undef __FUNCT__
4686*c58f1c22SToby Isaac #define __FUNCT__ "DMGetLabelSize"
4687*c58f1c22SToby Isaac /*@C
4688*c58f1c22SToby Isaac   DMGetLabelSize - Get the number of different integer ids in a Label
4689*c58f1c22SToby Isaac 
4690*c58f1c22SToby Isaac   Not Collective
4691*c58f1c22SToby Isaac 
4692*c58f1c22SToby Isaac   Input Parameters:
4693*c58f1c22SToby Isaac + dm   - The DM object
4694*c58f1c22SToby Isaac - name - The label name
4695*c58f1c22SToby Isaac 
4696*c58f1c22SToby Isaac   Output Parameter:
4697*c58f1c22SToby Isaac . size - The number of different integer ids, or 0 if the label does not exist
4698*c58f1c22SToby Isaac 
4699*c58f1c22SToby Isaac   Level: beginner
4700*c58f1c22SToby Isaac 
4701*c58f1c22SToby Isaac .keywords: mesh
4702*c58f1c22SToby Isaac .seealso: DMLabeGetNumValues(), DMSetLabelValue()
4703*c58f1c22SToby Isaac @*/
4704*c58f1c22SToby Isaac PetscErrorCode DMGetLabelSize(DM dm, const char name[], PetscInt *size)
4705*c58f1c22SToby Isaac {
4706*c58f1c22SToby Isaac   DMLabel        label;
4707*c58f1c22SToby Isaac   PetscErrorCode ierr;
4708*c58f1c22SToby Isaac 
4709*c58f1c22SToby Isaac   PetscFunctionBegin;
4710*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4711*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4712*c58f1c22SToby Isaac   PetscValidPointer(size, 3);
4713*c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4714*c58f1c22SToby Isaac   *size = 0;
4715*c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
4716*c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, size);CHKERRQ(ierr);
4717*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4718*c58f1c22SToby Isaac }
4719*c58f1c22SToby Isaac 
4720*c58f1c22SToby Isaac #undef __FUNCT__
4721*c58f1c22SToby Isaac #define __FUNCT__ "DMGetLabelIdIS"
4722*c58f1c22SToby Isaac /*@C
4723*c58f1c22SToby Isaac   DMGetLabelIdIS - Get the integer ids in a label
4724*c58f1c22SToby Isaac 
4725*c58f1c22SToby Isaac   Not Collective
4726*c58f1c22SToby Isaac 
4727*c58f1c22SToby Isaac   Input Parameters:
4728*c58f1c22SToby Isaac + mesh - The DM object
4729*c58f1c22SToby Isaac - name - The label name
4730*c58f1c22SToby Isaac 
4731*c58f1c22SToby Isaac   Output Parameter:
4732*c58f1c22SToby Isaac . ids - The integer ids, or NULL if the label does not exist
4733*c58f1c22SToby Isaac 
4734*c58f1c22SToby Isaac   Level: beginner
4735*c58f1c22SToby Isaac 
4736*c58f1c22SToby Isaac .keywords: mesh
4737*c58f1c22SToby Isaac .seealso: DMLabelGetValueIS(), DMGetLabelSize()
4738*c58f1c22SToby Isaac @*/
4739*c58f1c22SToby Isaac PetscErrorCode DMGetLabelIdIS(DM dm, const char name[], IS *ids)
4740*c58f1c22SToby Isaac {
4741*c58f1c22SToby Isaac   DMLabel        label;
4742*c58f1c22SToby Isaac   PetscErrorCode ierr;
4743*c58f1c22SToby Isaac 
4744*c58f1c22SToby Isaac   PetscFunctionBegin;
4745*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4746*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4747*c58f1c22SToby Isaac   PetscValidPointer(ids, 3);
4748*c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4749*c58f1c22SToby Isaac   *ids = NULL;
4750*c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
4751*c58f1c22SToby Isaac   ierr = DMLabelGetValueIS(label, ids);CHKERRQ(ierr);
4752*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4753*c58f1c22SToby Isaac }
4754*c58f1c22SToby Isaac 
4755*c58f1c22SToby Isaac #undef __FUNCT__
4756*c58f1c22SToby Isaac #define __FUNCT__ "DMGetStratumSize"
4757*c58f1c22SToby Isaac /*@C
4758*c58f1c22SToby Isaac   DMGetStratumSize - Get the number of points in a label stratum
4759*c58f1c22SToby Isaac 
4760*c58f1c22SToby Isaac   Not Collective
4761*c58f1c22SToby Isaac 
4762*c58f1c22SToby Isaac   Input Parameters:
4763*c58f1c22SToby Isaac + dm - The DM object
4764*c58f1c22SToby Isaac . name - The label name
4765*c58f1c22SToby Isaac - value - The stratum value
4766*c58f1c22SToby Isaac 
4767*c58f1c22SToby Isaac   Output Parameter:
4768*c58f1c22SToby Isaac . size - The stratum size
4769*c58f1c22SToby Isaac 
4770*c58f1c22SToby Isaac   Level: beginner
4771*c58f1c22SToby Isaac 
4772*c58f1c22SToby Isaac .keywords: mesh
4773*c58f1c22SToby Isaac .seealso: DMLabelGetStratumSize(), DMGetLabelSize(), DMGetLabelIds()
4774*c58f1c22SToby Isaac @*/
4775*c58f1c22SToby Isaac PetscErrorCode DMGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size)
4776*c58f1c22SToby Isaac {
4777*c58f1c22SToby Isaac   DMLabel        label;
4778*c58f1c22SToby Isaac   PetscErrorCode ierr;
4779*c58f1c22SToby Isaac 
4780*c58f1c22SToby Isaac   PetscFunctionBegin;
4781*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4782*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4783*c58f1c22SToby Isaac   PetscValidPointer(size, 4);
4784*c58f1c22SToby Isaac   ierr  = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4785*c58f1c22SToby Isaac   *size = 0;
4786*c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
4787*c58f1c22SToby Isaac   ierr = DMLabelGetStratumSize(label, value, size);CHKERRQ(ierr);
4788*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4789*c58f1c22SToby Isaac }
4790*c58f1c22SToby Isaac 
4791*c58f1c22SToby Isaac #undef __FUNCT__
4792*c58f1c22SToby Isaac #define __FUNCT__ "DMGetStratumIS"
4793*c58f1c22SToby Isaac /*@C
4794*c58f1c22SToby Isaac   DMGetStratumIS - Get the points in a label stratum
4795*c58f1c22SToby Isaac 
4796*c58f1c22SToby Isaac   Not Collective
4797*c58f1c22SToby Isaac 
4798*c58f1c22SToby Isaac   Input Parameters:
4799*c58f1c22SToby Isaac + dm - The DM object
4800*c58f1c22SToby Isaac . name - The label name
4801*c58f1c22SToby Isaac - value - The stratum value
4802*c58f1c22SToby Isaac 
4803*c58f1c22SToby Isaac   Output Parameter:
4804*c58f1c22SToby Isaac . points - The stratum points, or NULL if the label does not exist or does not have that value
4805*c58f1c22SToby Isaac 
4806*c58f1c22SToby Isaac   Level: beginner
4807*c58f1c22SToby Isaac 
4808*c58f1c22SToby Isaac .keywords: mesh
4809*c58f1c22SToby Isaac .seealso: DMLabelGetStratumIS(), DMGetStratumSize()
4810*c58f1c22SToby Isaac @*/
4811*c58f1c22SToby Isaac PetscErrorCode DMGetStratumIS(DM dm, const char name[], PetscInt value, IS *points)
4812*c58f1c22SToby Isaac {
4813*c58f1c22SToby Isaac   DMLabel        label;
4814*c58f1c22SToby Isaac   PetscErrorCode ierr;
4815*c58f1c22SToby Isaac 
4816*c58f1c22SToby Isaac   PetscFunctionBegin;
4817*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4818*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4819*c58f1c22SToby Isaac   PetscValidPointer(points, 4);
4820*c58f1c22SToby Isaac   ierr    = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4821*c58f1c22SToby Isaac   *points = NULL;
4822*c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
4823*c58f1c22SToby Isaac   ierr = DMLabelGetStratumIS(label, value, points);CHKERRQ(ierr);
4824*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4825*c58f1c22SToby Isaac }
4826*c58f1c22SToby Isaac 
4827*c58f1c22SToby Isaac #undef __FUNCT__
4828*c58f1c22SToby Isaac #define __FUNCT__ "DMClearLabelStratum"
4829*c58f1c22SToby Isaac /*@C
4830*c58f1c22SToby Isaac   DMClearLabelStratum - Remove all points from a stratum from a Sieve Label
4831*c58f1c22SToby Isaac 
4832*c58f1c22SToby Isaac   Not Collective
4833*c58f1c22SToby Isaac 
4834*c58f1c22SToby Isaac   Input Parameters:
4835*c58f1c22SToby Isaac + dm   - The DM object
4836*c58f1c22SToby Isaac . name - The label name
4837*c58f1c22SToby Isaac - value - The label value for this point
4838*c58f1c22SToby Isaac 
4839*c58f1c22SToby Isaac   Output Parameter:
4840*c58f1c22SToby Isaac 
4841*c58f1c22SToby Isaac   Level: beginner
4842*c58f1c22SToby Isaac 
4843*c58f1c22SToby Isaac .keywords: mesh
4844*c58f1c22SToby Isaac .seealso: DMLabelClearStratum(), DMSetLabelValue(), DMGetStratumIS(), DMClearLabelValue()
4845*c58f1c22SToby Isaac @*/
4846*c58f1c22SToby Isaac PetscErrorCode DMClearLabelStratum(DM dm, const char name[], PetscInt value)
4847*c58f1c22SToby Isaac {
4848*c58f1c22SToby Isaac   DMLabel        label;
4849*c58f1c22SToby Isaac   PetscErrorCode ierr;
4850*c58f1c22SToby Isaac 
4851*c58f1c22SToby Isaac   PetscFunctionBegin;
4852*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4853*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4854*c58f1c22SToby Isaac   ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr);
4855*c58f1c22SToby Isaac   if (!label) PetscFunctionReturn(0);
4856*c58f1c22SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
4857*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4858*c58f1c22SToby Isaac }
4859*c58f1c22SToby Isaac 
4860*c58f1c22SToby Isaac #undef __FUNCT__
4861*c58f1c22SToby Isaac #define __FUNCT__ "DMGetNumLabels"
4862*c58f1c22SToby Isaac /*@
4863*c58f1c22SToby Isaac   DMGetNumLabels - Return the number of labels defined by the mesh
4864*c58f1c22SToby Isaac 
4865*c58f1c22SToby Isaac   Not Collective
4866*c58f1c22SToby Isaac 
4867*c58f1c22SToby Isaac   Input Parameter:
4868*c58f1c22SToby Isaac . dm   - The DM object
4869*c58f1c22SToby Isaac 
4870*c58f1c22SToby Isaac   Output Parameter:
4871*c58f1c22SToby Isaac . numLabels - the number of Labels
4872*c58f1c22SToby Isaac 
4873*c58f1c22SToby Isaac   Level: intermediate
4874*c58f1c22SToby Isaac 
4875*c58f1c22SToby Isaac .keywords: mesh
4876*c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
4877*c58f1c22SToby Isaac @*/
4878*c58f1c22SToby Isaac PetscErrorCode DMGetNumLabels(DM dm, PetscInt *numLabels)
4879*c58f1c22SToby Isaac {
4880*c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
4881*c58f1c22SToby Isaac   PetscInt  n    = 0;
4882*c58f1c22SToby Isaac 
4883*c58f1c22SToby Isaac   PetscFunctionBegin;
4884*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4885*c58f1c22SToby Isaac   PetscValidPointer(numLabels, 2);
4886*c58f1c22SToby Isaac   while (next) {++n; next = next->next;}
4887*c58f1c22SToby Isaac   *numLabels = n;
4888*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4889*c58f1c22SToby Isaac }
4890*c58f1c22SToby Isaac 
4891*c58f1c22SToby Isaac #undef __FUNCT__
4892*c58f1c22SToby Isaac #define __FUNCT__ "DMGetLabelName"
4893*c58f1c22SToby Isaac /*@C
4894*c58f1c22SToby Isaac   DMGetLabelName - Return the name of nth label
4895*c58f1c22SToby Isaac 
4896*c58f1c22SToby Isaac   Not Collective
4897*c58f1c22SToby Isaac 
4898*c58f1c22SToby Isaac   Input Parameters:
4899*c58f1c22SToby Isaac + dm - The DM object
4900*c58f1c22SToby Isaac - n  - the label number
4901*c58f1c22SToby Isaac 
4902*c58f1c22SToby Isaac   Output Parameter:
4903*c58f1c22SToby Isaac . name - the label name
4904*c58f1c22SToby Isaac 
4905*c58f1c22SToby Isaac   Level: intermediate
4906*c58f1c22SToby Isaac 
4907*c58f1c22SToby Isaac .keywords: mesh
4908*c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
4909*c58f1c22SToby Isaac @*/
4910*c58f1c22SToby Isaac PetscErrorCode DMGetLabelName(DM dm, PetscInt n, const char **name)
4911*c58f1c22SToby Isaac {
4912*c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
4913*c58f1c22SToby Isaac   PetscInt  l    = 0;
4914*c58f1c22SToby Isaac 
4915*c58f1c22SToby Isaac   PetscFunctionBegin;
4916*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4917*c58f1c22SToby Isaac   PetscValidPointer(name, 3);
4918*c58f1c22SToby Isaac   while (next) {
4919*c58f1c22SToby Isaac     if (l == n) {
4920*c58f1c22SToby Isaac       *name = next->label->name;
4921*c58f1c22SToby Isaac       PetscFunctionReturn(0);
4922*c58f1c22SToby Isaac     }
4923*c58f1c22SToby Isaac     ++l;
4924*c58f1c22SToby Isaac     next = next->next;
4925*c58f1c22SToby Isaac   }
4926*c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
4927*c58f1c22SToby Isaac }
4928*c58f1c22SToby Isaac 
4929*c58f1c22SToby Isaac #undef __FUNCT__
4930*c58f1c22SToby Isaac #define __FUNCT__ "DMHasLabel"
4931*c58f1c22SToby Isaac /*@C
4932*c58f1c22SToby Isaac   DMHasLabel - Determine whether the mesh has a label of a given name
4933*c58f1c22SToby Isaac 
4934*c58f1c22SToby Isaac   Not Collective
4935*c58f1c22SToby Isaac 
4936*c58f1c22SToby Isaac   Input Parameters:
4937*c58f1c22SToby Isaac + dm   - The DM object
4938*c58f1c22SToby Isaac - name - The label name
4939*c58f1c22SToby Isaac 
4940*c58f1c22SToby Isaac   Output Parameter:
4941*c58f1c22SToby Isaac . hasLabel - PETSC_TRUE if the label is present
4942*c58f1c22SToby Isaac 
4943*c58f1c22SToby Isaac   Level: intermediate
4944*c58f1c22SToby Isaac 
4945*c58f1c22SToby Isaac .keywords: mesh
4946*c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
4947*c58f1c22SToby Isaac @*/
4948*c58f1c22SToby Isaac PetscErrorCode DMHasLabel(DM dm, const char name[], PetscBool *hasLabel)
4949*c58f1c22SToby Isaac {
4950*c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
4951*c58f1c22SToby Isaac   PetscErrorCode ierr;
4952*c58f1c22SToby Isaac 
4953*c58f1c22SToby Isaac   PetscFunctionBegin;
4954*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4955*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4956*c58f1c22SToby Isaac   PetscValidPointer(hasLabel, 3);
4957*c58f1c22SToby Isaac   *hasLabel = PETSC_FALSE;
4958*c58f1c22SToby Isaac   while (next) {
4959*c58f1c22SToby Isaac     ierr = PetscStrcmp(name, next->label->name, hasLabel);CHKERRQ(ierr);
4960*c58f1c22SToby Isaac     if (*hasLabel) break;
4961*c58f1c22SToby Isaac     next = next->next;
4962*c58f1c22SToby Isaac   }
4963*c58f1c22SToby Isaac   PetscFunctionReturn(0);
4964*c58f1c22SToby Isaac }
4965*c58f1c22SToby Isaac 
4966*c58f1c22SToby Isaac #undef __FUNCT__
4967*c58f1c22SToby Isaac #define __FUNCT__ "DMGetLabel"
4968*c58f1c22SToby Isaac /*@C
4969*c58f1c22SToby Isaac   DMGetLabel - Return the label of a given name, or NULL
4970*c58f1c22SToby Isaac 
4971*c58f1c22SToby Isaac   Not Collective
4972*c58f1c22SToby Isaac 
4973*c58f1c22SToby Isaac   Input Parameters:
4974*c58f1c22SToby Isaac + dm   - The DM object
4975*c58f1c22SToby Isaac - name - The label name
4976*c58f1c22SToby Isaac 
4977*c58f1c22SToby Isaac   Output Parameter:
4978*c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
4979*c58f1c22SToby Isaac 
4980*c58f1c22SToby Isaac   Level: intermediate
4981*c58f1c22SToby Isaac 
4982*c58f1c22SToby Isaac .keywords: mesh
4983*c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
4984*c58f1c22SToby Isaac @*/
4985*c58f1c22SToby Isaac PetscErrorCode DMGetLabel(DM dm, const char name[], DMLabel *label)
4986*c58f1c22SToby Isaac {
4987*c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
4988*c58f1c22SToby Isaac   PetscBool      hasLabel;
4989*c58f1c22SToby Isaac   PetscErrorCode ierr;
4990*c58f1c22SToby Isaac 
4991*c58f1c22SToby Isaac   PetscFunctionBegin;
4992*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4993*c58f1c22SToby Isaac   PetscValidCharPointer(name, 2);
4994*c58f1c22SToby Isaac   PetscValidPointer(label, 3);
4995*c58f1c22SToby Isaac   *label = NULL;
4996*c58f1c22SToby Isaac   while (next) {
4997*c58f1c22SToby Isaac     ierr = PetscStrcmp(name, next->label->name, &hasLabel);CHKERRQ(ierr);
4998*c58f1c22SToby Isaac     if (hasLabel) {
4999*c58f1c22SToby Isaac       *label = next->label;
5000*c58f1c22SToby Isaac       break;
5001*c58f1c22SToby Isaac     }
5002*c58f1c22SToby Isaac     next = next->next;
5003*c58f1c22SToby Isaac   }
5004*c58f1c22SToby Isaac   PetscFunctionReturn(0);
5005*c58f1c22SToby Isaac }
5006*c58f1c22SToby Isaac 
5007*c58f1c22SToby Isaac #undef __FUNCT__
5008*c58f1c22SToby Isaac #define __FUNCT__ "DMGetLabelByNum"
5009*c58f1c22SToby Isaac /*@C
5010*c58f1c22SToby Isaac   DMGetLabelByNum - Return the nth label
5011*c58f1c22SToby Isaac 
5012*c58f1c22SToby Isaac   Not Collective
5013*c58f1c22SToby Isaac 
5014*c58f1c22SToby Isaac   Input Parameters:
5015*c58f1c22SToby Isaac + dm - The DM object
5016*c58f1c22SToby Isaac - n  - the label number
5017*c58f1c22SToby Isaac 
5018*c58f1c22SToby Isaac   Output Parameter:
5019*c58f1c22SToby Isaac . label - the label
5020*c58f1c22SToby Isaac 
5021*c58f1c22SToby Isaac   Level: intermediate
5022*c58f1c22SToby Isaac 
5023*c58f1c22SToby Isaac .keywords: mesh
5024*c58f1c22SToby Isaac .seealso: DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
5025*c58f1c22SToby Isaac @*/
5026*c58f1c22SToby Isaac PetscErrorCode DMGetLabelByNum(DM dm, PetscInt n, DMLabel *label)
5027*c58f1c22SToby Isaac {
5028*c58f1c22SToby Isaac   DMLabelLink next = dm->labels->next;
5029*c58f1c22SToby Isaac   PetscInt    l    = 0;
5030*c58f1c22SToby Isaac 
5031*c58f1c22SToby Isaac   PetscFunctionBegin;
5032*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5033*c58f1c22SToby Isaac   PetscValidPointer(label, 3);
5034*c58f1c22SToby Isaac   while (next) {
5035*c58f1c22SToby Isaac     if (l == n) {
5036*c58f1c22SToby Isaac       *label = next->label;
5037*c58f1c22SToby Isaac       PetscFunctionReturn(0);
5038*c58f1c22SToby Isaac     }
5039*c58f1c22SToby Isaac     ++l;
5040*c58f1c22SToby Isaac     next = next->next;
5041*c58f1c22SToby Isaac   }
5042*c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %D does not exist in this DM", n);
5043*c58f1c22SToby Isaac }
5044*c58f1c22SToby Isaac 
5045*c58f1c22SToby Isaac #undef __FUNCT__
5046*c58f1c22SToby Isaac #define __FUNCT__ "DMAddLabel"
5047*c58f1c22SToby Isaac /*@C
5048*c58f1c22SToby Isaac   DMAddLabel - Add the label to this mesh
5049*c58f1c22SToby Isaac 
5050*c58f1c22SToby Isaac   Not Collective
5051*c58f1c22SToby Isaac 
5052*c58f1c22SToby Isaac   Input Parameters:
5053*c58f1c22SToby Isaac + dm   - The DM object
5054*c58f1c22SToby Isaac - label - The DMLabel
5055*c58f1c22SToby Isaac 
5056*c58f1c22SToby Isaac   Level: developer
5057*c58f1c22SToby Isaac 
5058*c58f1c22SToby Isaac .keywords: mesh
5059*c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
5060*c58f1c22SToby Isaac @*/
5061*c58f1c22SToby Isaac PetscErrorCode DMAddLabel(DM dm, DMLabel label)
5062*c58f1c22SToby Isaac {
5063*c58f1c22SToby Isaac   DMLabelLink    tmpLabel;
5064*c58f1c22SToby Isaac   PetscBool      hasLabel;
5065*c58f1c22SToby Isaac   PetscErrorCode ierr;
5066*c58f1c22SToby Isaac 
5067*c58f1c22SToby Isaac   PetscFunctionBegin;
5068*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5069*c58f1c22SToby Isaac   ierr = DMHasLabel(dm, label->name, &hasLabel);CHKERRQ(ierr);
5070*c58f1c22SToby Isaac   if (hasLabel) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label %s already exists in this DM", label->name);
5071*c58f1c22SToby Isaac   ierr = PetscCalloc1(1, &tmpLabel);CHKERRQ(ierr);
5072*c58f1c22SToby Isaac   tmpLabel->label  = label;
5073*c58f1c22SToby Isaac   tmpLabel->output = PETSC_TRUE;
5074*c58f1c22SToby Isaac   tmpLabel->next   = dm->labels->next;
5075*c58f1c22SToby Isaac   dm->labels->next = tmpLabel;
5076*c58f1c22SToby Isaac   PetscFunctionReturn(0);
5077*c58f1c22SToby Isaac }
5078*c58f1c22SToby Isaac 
5079*c58f1c22SToby Isaac #undef __FUNCT__
5080*c58f1c22SToby Isaac #define __FUNCT__ "DMRemoveLabel"
5081*c58f1c22SToby Isaac /*@C
5082*c58f1c22SToby Isaac   DMRemoveLabel - Remove the label from this mesh
5083*c58f1c22SToby Isaac 
5084*c58f1c22SToby Isaac   Not Collective
5085*c58f1c22SToby Isaac 
5086*c58f1c22SToby Isaac   Input Parameters:
5087*c58f1c22SToby Isaac + dm   - The DM object
5088*c58f1c22SToby Isaac - name - The label name
5089*c58f1c22SToby Isaac 
5090*c58f1c22SToby Isaac   Output Parameter:
5091*c58f1c22SToby Isaac . label - The DMLabel, or NULL if the label is absent
5092*c58f1c22SToby Isaac 
5093*c58f1c22SToby Isaac   Level: developer
5094*c58f1c22SToby Isaac 
5095*c58f1c22SToby Isaac .keywords: mesh
5096*c58f1c22SToby Isaac .seealso: DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
5097*c58f1c22SToby Isaac @*/
5098*c58f1c22SToby Isaac PetscErrorCode DMRemoveLabel(DM dm, const char name[], DMLabel *label)
5099*c58f1c22SToby Isaac {
5100*c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
5101*c58f1c22SToby Isaac   DMLabelLink    last = NULL;
5102*c58f1c22SToby Isaac   PetscBool      hasLabel;
5103*c58f1c22SToby Isaac   PetscErrorCode ierr;
5104*c58f1c22SToby Isaac 
5105*c58f1c22SToby Isaac   PetscFunctionBegin;
5106*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5107*c58f1c22SToby Isaac   ierr   = DMHasLabel(dm, name, &hasLabel);CHKERRQ(ierr);
5108*c58f1c22SToby Isaac   *label = NULL;
5109*c58f1c22SToby Isaac   if (!hasLabel) PetscFunctionReturn(0);
5110*c58f1c22SToby Isaac   while (next) {
5111*c58f1c22SToby Isaac     ierr = PetscStrcmp(name, next->label->name, &hasLabel);CHKERRQ(ierr);
5112*c58f1c22SToby Isaac     if (hasLabel) {
5113*c58f1c22SToby Isaac       if (last) last->next       = next->next;
5114*c58f1c22SToby Isaac       else      dm->labels->next = next->next;
5115*c58f1c22SToby Isaac       next->next = NULL;
5116*c58f1c22SToby Isaac       *label     = next->label;
5117*c58f1c22SToby Isaac       ierr = PetscStrcmp(name, "depth", &hasLabel);CHKERRQ(ierr);
5118*c58f1c22SToby Isaac       if (hasLabel) {
5119*c58f1c22SToby Isaac         dm->depthLabel = NULL;
5120*c58f1c22SToby Isaac       }
5121*c58f1c22SToby Isaac       ierr = PetscFree(next);CHKERRQ(ierr);
5122*c58f1c22SToby Isaac       break;
5123*c58f1c22SToby Isaac     }
5124*c58f1c22SToby Isaac     last = next;
5125*c58f1c22SToby Isaac     next = next->next;
5126*c58f1c22SToby Isaac   }
5127*c58f1c22SToby Isaac   PetscFunctionReturn(0);
5128*c58f1c22SToby Isaac }
5129*c58f1c22SToby Isaac 
5130*c58f1c22SToby Isaac #undef __FUNCT__
5131*c58f1c22SToby Isaac #define __FUNCT__ "DMGetLabelOutput"
5132*c58f1c22SToby Isaac /*@C
5133*c58f1c22SToby Isaac   DMGetLabelOutput - Get the output flag for a given label
5134*c58f1c22SToby Isaac 
5135*c58f1c22SToby Isaac   Not Collective
5136*c58f1c22SToby Isaac 
5137*c58f1c22SToby Isaac   Input Parameters:
5138*c58f1c22SToby Isaac + dm   - The DM object
5139*c58f1c22SToby Isaac - name - The label name
5140*c58f1c22SToby Isaac 
5141*c58f1c22SToby Isaac   Output Parameter:
5142*c58f1c22SToby Isaac . output - The flag for output
5143*c58f1c22SToby Isaac 
5144*c58f1c22SToby Isaac   Level: developer
5145*c58f1c22SToby Isaac 
5146*c58f1c22SToby Isaac .keywords: mesh
5147*c58f1c22SToby Isaac .seealso: DMSetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
5148*c58f1c22SToby Isaac @*/
5149*c58f1c22SToby Isaac PetscErrorCode DMGetLabelOutput(DM dm, const char name[], PetscBool *output)
5150*c58f1c22SToby Isaac {
5151*c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
5152*c58f1c22SToby Isaac   PetscErrorCode ierr;
5153*c58f1c22SToby Isaac 
5154*c58f1c22SToby Isaac   PetscFunctionBegin;
5155*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5156*c58f1c22SToby Isaac   PetscValidPointer(name, 2);
5157*c58f1c22SToby Isaac   PetscValidPointer(output, 3);
5158*c58f1c22SToby Isaac   while (next) {
5159*c58f1c22SToby Isaac     PetscBool flg;
5160*c58f1c22SToby Isaac 
5161*c58f1c22SToby Isaac     ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr);
5162*c58f1c22SToby Isaac     if (flg) {*output = next->output; PetscFunctionReturn(0);}
5163*c58f1c22SToby Isaac     next = next->next;
5164*c58f1c22SToby Isaac   }
5165*c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
5166*c58f1c22SToby Isaac }
5167*c58f1c22SToby Isaac 
5168*c58f1c22SToby Isaac #undef __FUNCT__
5169*c58f1c22SToby Isaac #define __FUNCT__ "DMSetLabelOutput"
5170*c58f1c22SToby Isaac /*@C
5171*c58f1c22SToby Isaac   DMSetLabelOutput - Set the output flag for a given label
5172*c58f1c22SToby Isaac 
5173*c58f1c22SToby Isaac   Not Collective
5174*c58f1c22SToby Isaac 
5175*c58f1c22SToby Isaac   Input Parameters:
5176*c58f1c22SToby Isaac + dm     - The DM object
5177*c58f1c22SToby Isaac . name   - The label name
5178*c58f1c22SToby Isaac - output - The flag for output
5179*c58f1c22SToby Isaac 
5180*c58f1c22SToby Isaac   Level: developer
5181*c58f1c22SToby Isaac 
5182*c58f1c22SToby Isaac .keywords: mesh
5183*c58f1c22SToby Isaac .seealso: DMGetLabelOutput(), DMCreateLabel(), DMHasLabel(), DMGetLabelValue(), DMSetLabelValue(), DMGetStratumIS()
5184*c58f1c22SToby Isaac @*/
5185*c58f1c22SToby Isaac PetscErrorCode DMSetLabelOutput(DM dm, const char name[], PetscBool output)
5186*c58f1c22SToby Isaac {
5187*c58f1c22SToby Isaac   DMLabelLink    next = dm->labels->next;
5188*c58f1c22SToby Isaac   PetscErrorCode ierr;
5189*c58f1c22SToby Isaac 
5190*c58f1c22SToby Isaac   PetscFunctionBegin;
5191*c58f1c22SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5192*c58f1c22SToby Isaac   PetscValidPointer(name, 2);
5193*c58f1c22SToby Isaac   while (next) {
5194*c58f1c22SToby Isaac     PetscBool flg;
5195*c58f1c22SToby Isaac 
5196*c58f1c22SToby Isaac     ierr = PetscStrcmp(name, next->label->name, &flg);CHKERRQ(ierr);
5197*c58f1c22SToby Isaac     if (flg) {next->output = output; PetscFunctionReturn(0);}
5198*c58f1c22SToby Isaac     next = next->next;
5199*c58f1c22SToby Isaac   }
5200*c58f1c22SToby Isaac   SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No label named %s was present in this dm", name);
5201*c58f1c22SToby Isaac }
5202*c58f1c22SToby Isaac 
5203*c58f1c22SToby Isaac 
5204*c58f1c22SToby Isaac #undef __FUNCT__
5205*c58f1c22SToby Isaac #define __FUNCT__ "DMCopyLabels"
5206*c58f1c22SToby Isaac /*@
5207*c58f1c22SToby Isaac   DMCopyLabels - Copy labels from one mesh to another with a superset of the points
5208*c58f1c22SToby Isaac 
5209*c58f1c22SToby Isaac   Collective on DM
5210*c58f1c22SToby Isaac 
5211*c58f1c22SToby Isaac   Input Parameter:
5212*c58f1c22SToby Isaac . dmA - The DMPlex object with initial labels
5213*c58f1c22SToby Isaac 
5214*c58f1c22SToby Isaac   Output Parameter:
5215*c58f1c22SToby Isaac . dmB - The DMPlex object with copied labels
5216*c58f1c22SToby Isaac 
5217*c58f1c22SToby Isaac   Level: intermediate
5218*c58f1c22SToby Isaac 
5219*c58f1c22SToby Isaac   Note: This is typically used when interpolating or otherwise adding to a mesh
5220*c58f1c22SToby Isaac 
5221*c58f1c22SToby Isaac .keywords: mesh
5222*c58f1c22SToby Isaac .seealso: DMCopyCoordinates(), DMGetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM(), DMGetCoordinateSection()
5223*c58f1c22SToby Isaac @*/
5224*c58f1c22SToby Isaac PetscErrorCode DMCopyLabels(DM dmA, DM dmB)
5225*c58f1c22SToby Isaac {
5226*c58f1c22SToby Isaac   PetscInt       numLabels, l;
5227*c58f1c22SToby Isaac   PetscErrorCode ierr;
5228*c58f1c22SToby Isaac 
5229*c58f1c22SToby Isaac   PetscFunctionBegin;
5230*c58f1c22SToby Isaac   if (dmA == dmB) PetscFunctionReturn(0);
5231*c58f1c22SToby Isaac   ierr = DMGetNumLabels(dmA, &numLabels);CHKERRQ(ierr);
5232*c58f1c22SToby Isaac   for (l = 0; l < numLabels; ++l) {
5233*c58f1c22SToby Isaac     DMLabel     label, labelNew;
5234*c58f1c22SToby Isaac     const char *name;
5235*c58f1c22SToby Isaac     PetscBool   flg;
5236*c58f1c22SToby Isaac 
5237*c58f1c22SToby Isaac     ierr = DMGetLabelName(dmA, l, &name);CHKERRQ(ierr);
5238*c58f1c22SToby Isaac     ierr = PetscStrcmp(name, "depth", &flg);CHKERRQ(ierr);
5239*c58f1c22SToby Isaac     if (flg) continue;
5240*c58f1c22SToby Isaac     ierr = DMGetLabel(dmA, name, &label);CHKERRQ(ierr);
5241*c58f1c22SToby Isaac     ierr = DMLabelDuplicate(label, &labelNew);CHKERRQ(ierr);
5242*c58f1c22SToby Isaac     ierr = DMAddLabel(dmB, labelNew);CHKERRQ(ierr);
5243*c58f1c22SToby Isaac   }
5244*c58f1c22SToby Isaac   PetscFunctionReturn(0);
5245*c58f1c22SToby Isaac }
5246