xref: /petsc/src/dm/interface/dm.c (revision f0413b6f5d7c9354ff89613ff0ab87d5c3d1b2ee)
1b45d2f2cSJed Brown #include <petsc-private/dmimpl.h>     /*I      "petscdm.h"     I*/
20c312b8eSJed Brown #include <petscsf.h>
347c6ae99SBarry Smith 
4732e2eb9SMatthew G Knepley PetscClassId  DM_CLASSID;
5f089877aSRichard Tran Mills PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal, DM_LocalToLocal;
667a56275SMatthew G Knepley 
7bff4a2f0SMatthew G. Knepley const char *const DMBoundaryTypes[] = {"NONE","GHOSTED","MIRROR","PERIODIC","TWIST","DM_BOUNDARY_",0};
8bff4a2f0SMatthew G. Knepley 
947c6ae99SBarry Smith #undef __FUNCT__
10a4121054SBarry Smith #define __FUNCT__ "DMCreate"
11a4121054SBarry Smith /*@
12de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
13a4121054SBarry Smith 
14a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
15a4121054SBarry Smith    error when you try to use the vector.
16a4121054SBarry Smith 
17a4121054SBarry Smith   Collective on MPI_Comm
18a4121054SBarry Smith 
19a4121054SBarry Smith   Input Parameter:
20a4121054SBarry Smith . comm - The communicator for the DM object
21a4121054SBarry Smith 
22a4121054SBarry Smith   Output Parameter:
23a4121054SBarry Smith . dm - The DM object
24a4121054SBarry Smith 
25a4121054SBarry Smith   Level: beginner
26a4121054SBarry Smith 
27a4121054SBarry Smith .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE
28a4121054SBarry Smith @*/
297087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
30a4121054SBarry Smith {
31a4121054SBarry Smith   DM             v;
32a4121054SBarry Smith   PetscErrorCode ierr;
33a4121054SBarry Smith 
34a4121054SBarry Smith   PetscFunctionBegin;
351411c6eeSJed Brown   PetscValidPointer(dm,2);
360298fd71SBarry Smith   *dm = NULL;
378b984314SMatthew G. Knepley   ierr = PetscSysInitializePackage();CHKERRQ(ierr);
38607a6623SBarry Smith   ierr = VecInitializePackage();CHKERRQ(ierr);
39607a6623SBarry Smith   ierr = MatInitializePackage();CHKERRQ(ierr);
40607a6623SBarry Smith   ierr = DMInitializePackage();CHKERRQ(ierr);
41a4121054SBarry Smith 
4267c2884eSBarry Smith   ierr = PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
43a4121054SBarry Smith   ierr = PetscMemzero(v->ops, sizeof(struct _DMOps));CHKERRQ(ierr);
441411c6eeSJed Brown 
45e7c4fc90SDmitry Karpeev 
460298fd71SBarry Smith   v->ltogmap              = NULL;
470298fd71SBarry Smith   v->ltogmapb             = NULL;
481411c6eeSJed Brown   v->bs                   = 1;
49171400e9SBarry Smith   v->coloringtype         = IS_COLORING_GLOBAL;
5088ed4aceSMatthew G Knepley   ierr                    = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
5188ed4aceSMatthew G Knepley   ierr                    = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
520298fd71SBarry Smith   v->defaultSection       = NULL;
530298fd71SBarry Smith   v->defaultGlobalSection = NULL;
54c6b900c6SMatthew G. Knepley   v->L                    = NULL;
55c6b900c6SMatthew G. Knepley   v->maxCell              = NULL;
56435a35e8SMatthew G Knepley   {
57435a35e8SMatthew G Knepley     PetscInt i;
58435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
590298fd71SBarry Smith       v->nullspaceConstructors[i] = NULL;
60435a35e8SMatthew G Knepley     }
61435a35e8SMatthew G Knepley   }
62af122d2aSMatthew G Knepley   v->numFields = 0;
630298fd71SBarry Smith   v->fields    = NULL;
6414f150ffSMatthew G. Knepley   v->dmBC      = NULL;
65f4d763aaSMatthew G. Knepley   v->outputSequenceNum = -1;
66c0dedaeaSBarry Smith   ierr = DMSetVecType(v,VECSTANDARD);CHKERRQ(ierr);
67b412c318SBarry Smith   ierr = DMSetMatType(v,MATAIJ);CHKERRQ(ierr);
681411c6eeSJed Brown   *dm = v;
69a4121054SBarry Smith   PetscFunctionReturn(0);
70a4121054SBarry Smith }
71a4121054SBarry Smith 
72a4121054SBarry Smith #undef __FUNCT__
7338221697SMatthew G. Knepley #define __FUNCT__ "DMClone"
7438221697SMatthew G. Knepley /*@
7538221697SMatthew G. Knepley   DMClone - Creates a DM object with the same topology as the original.
7638221697SMatthew G. Knepley 
7738221697SMatthew G. Knepley   Collective on MPI_Comm
7838221697SMatthew G. Knepley 
7938221697SMatthew G. Knepley   Input Parameter:
8038221697SMatthew G. Knepley . dm - The original DM object
8138221697SMatthew G. Knepley 
8238221697SMatthew G. Knepley   Output Parameter:
8338221697SMatthew G. Knepley . newdm  - The new DM object
8438221697SMatthew G. Knepley 
8538221697SMatthew G. Knepley   Level: beginner
8638221697SMatthew G. Knepley 
8738221697SMatthew G. Knepley .keywords: DM, topology, create
8838221697SMatthew G. Knepley @*/
8938221697SMatthew G. Knepley PetscErrorCode DMClone(DM dm, DM *newdm)
9038221697SMatthew G. Knepley {
9138221697SMatthew G. Knepley   PetscSF        sf;
9238221697SMatthew G. Knepley   Vec            coords;
9338221697SMatthew G. Knepley   void          *ctx;
9438221697SMatthew G. Knepley   PetscErrorCode ierr;
9538221697SMatthew G. Knepley 
9638221697SMatthew G. Knepley   PetscFunctionBegin;
9738221697SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9838221697SMatthew G. Knepley   PetscValidPointer(newdm,2);
9938221697SMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), newdm);CHKERRQ(ierr);
10038221697SMatthew G. Knepley   if (dm->ops->clone) {
10138221697SMatthew G. Knepley     ierr = (*dm->ops->clone)(dm, newdm);CHKERRQ(ierr);
10238221697SMatthew G. Knepley   }
103cd27c7c9SMatthew G. Knepley   (*newdm)->setupcalled = PETSC_TRUE;
10438221697SMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
10538221697SMatthew G. Knepley   ierr = DMSetPointSF(*newdm, sf);CHKERRQ(ierr);
10638221697SMatthew G. Knepley   ierr = DMGetApplicationContext(dm, &ctx);CHKERRQ(ierr);
10738221697SMatthew G. Knepley   ierr = DMSetApplicationContext(*newdm, ctx);CHKERRQ(ierr);
10838221697SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coords);CHKERRQ(ierr);
10938221697SMatthew G. Knepley   if (coords) {
11038221697SMatthew G. Knepley     ierr = DMSetCoordinatesLocal(*newdm, coords);CHKERRQ(ierr);
11138221697SMatthew G. Knepley   } else {
11238221697SMatthew G. Knepley     ierr = DMGetCoordinates(dm, &coords);CHKERRQ(ierr);
11338221697SMatthew G. Knepley     if (coords) {ierr = DMSetCoordinates(*newdm, coords);CHKERRQ(ierr);}
11438221697SMatthew G. Knepley   }
115c6b900c6SMatthew G. Knepley   if (dm->maxCell) {
116c6b900c6SMatthew G. Knepley     const PetscReal *maxCell, *L;
117c6b900c6SMatthew G. Knepley     ierr = DMGetPeriodicity(dm,     &maxCell, &L);CHKERRQ(ierr);
118c6b900c6SMatthew G. Knepley     ierr = DMSetPeriodicity(*newdm,  maxCell,  L);CHKERRQ(ierr);
119c6b900c6SMatthew G. Knepley   }
12038221697SMatthew G. Knepley   PetscFunctionReturn(0);
12138221697SMatthew G. Knepley }
12238221697SMatthew G. Knepley 
12338221697SMatthew G. Knepley #undef __FUNCT__
1249a42bb27SBarry Smith #define __FUNCT__ "DMSetVecType"
1259a42bb27SBarry Smith /*@C
126564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
1279a42bb27SBarry Smith 
128aa219208SBarry Smith    Logically Collective on DMDA
1299a42bb27SBarry Smith 
1309a42bb27SBarry Smith    Input Parameter:
1319a42bb27SBarry Smith +  da - initial distributed array
1328154be41SBarry Smith .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
1339a42bb27SBarry Smith 
1349a42bb27SBarry Smith    Options Database:
135dd85299cSBarry Smith .   -dm_vec_type ctype
1369a42bb27SBarry Smith 
1379a42bb27SBarry Smith    Level: intermediate
1389a42bb27SBarry Smith 
139c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType, DMGetVecType()
1409a42bb27SBarry Smith @*/
14119fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
1429a42bb27SBarry Smith {
1439a42bb27SBarry Smith   PetscErrorCode ierr;
1449a42bb27SBarry Smith 
1459a42bb27SBarry Smith   PetscFunctionBegin;
1469a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
1479a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
14819fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
1499a42bb27SBarry Smith   PetscFunctionReturn(0);
1509a42bb27SBarry Smith }
1519a42bb27SBarry Smith 
1529a42bb27SBarry Smith #undef __FUNCT__
153c0dedaeaSBarry Smith #define __FUNCT__ "DMGetVecType"
154c0dedaeaSBarry Smith /*@C
155c0dedaeaSBarry Smith        DMGetVecType - Gets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
156c0dedaeaSBarry Smith 
157c0dedaeaSBarry Smith    Logically Collective on DMDA
158c0dedaeaSBarry Smith 
159c0dedaeaSBarry Smith    Input Parameter:
160c0dedaeaSBarry Smith .  da - initial distributed array
161c0dedaeaSBarry Smith 
162c0dedaeaSBarry Smith    Output Parameter:
163c0dedaeaSBarry Smith .  ctype - the vector type
164c0dedaeaSBarry Smith 
165c0dedaeaSBarry Smith    Level: intermediate
166c0dedaeaSBarry Smith 
167c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
168c0dedaeaSBarry Smith @*/
169c0dedaeaSBarry Smith PetscErrorCode  DMGetVecType(DM da,VecType *ctype)
170c0dedaeaSBarry Smith {
171c0dedaeaSBarry Smith   PetscFunctionBegin;
172c0dedaeaSBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
173c0dedaeaSBarry Smith   *ctype = da->vectype;
174c0dedaeaSBarry Smith   PetscFunctionReturn(0);
175c0dedaeaSBarry Smith }
176c0dedaeaSBarry Smith 
177c0dedaeaSBarry Smith #undef __FUNCT__
1785f1ad066SMatthew G Knepley #define __FUNCT__ "VecGetDM"
1795f1ad066SMatthew G Knepley /*@
18034f98d34SBarry Smith   VecGetDM - Gets the DM defining the data layout of the vector
1815f1ad066SMatthew G Knepley 
1825f1ad066SMatthew G Knepley   Not collective
1835f1ad066SMatthew G Knepley 
1845f1ad066SMatthew G Knepley   Input Parameter:
1855f1ad066SMatthew G Knepley . v - The Vec
1865f1ad066SMatthew G Knepley 
1875f1ad066SMatthew G Knepley   Output Parameter:
1885f1ad066SMatthew G Knepley . dm - The DM
1895f1ad066SMatthew G Knepley 
1905f1ad066SMatthew G Knepley   Level: intermediate
1915f1ad066SMatthew G Knepley 
1925f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
1935f1ad066SMatthew G Knepley @*/
1945f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm)
1955f1ad066SMatthew G Knepley {
1965f1ad066SMatthew G Knepley   PetscErrorCode ierr;
1975f1ad066SMatthew G Knepley 
1985f1ad066SMatthew G Knepley   PetscFunctionBegin;
1995f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
2005f1ad066SMatthew G Knepley   PetscValidPointer(dm,2);
2015f1ad066SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
2025f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2035f1ad066SMatthew G Knepley }
2045f1ad066SMatthew G Knepley 
2055f1ad066SMatthew G Knepley #undef __FUNCT__
2065f1ad066SMatthew G Knepley #define __FUNCT__ "VecSetDM"
2075f1ad066SMatthew G Knepley /*@
2085f1ad066SMatthew G Knepley   VecSetDM - Sets the DM defining the data layout of the vector
2095f1ad066SMatthew G Knepley 
2105f1ad066SMatthew G Knepley   Not collective
2115f1ad066SMatthew G Knepley 
2125f1ad066SMatthew G Knepley   Input Parameters:
2135f1ad066SMatthew G Knepley + v - The Vec
2145f1ad066SMatthew G Knepley - dm - The DM
2155f1ad066SMatthew G Knepley 
2165f1ad066SMatthew G Knepley   Level: intermediate
2175f1ad066SMatthew G Knepley 
2185f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
2195f1ad066SMatthew G Knepley @*/
2205f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm)
2215f1ad066SMatthew G Knepley {
2225f1ad066SMatthew G Knepley   PetscErrorCode ierr;
2235f1ad066SMatthew G Knepley 
2245f1ad066SMatthew G Knepley   PetscFunctionBegin;
2255f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
226d7f50e27SLisandro Dalcin   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
2275f1ad066SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
2285f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
2295f1ad066SMatthew G Knepley }
2305f1ad066SMatthew G Knepley 
2315f1ad066SMatthew G Knepley #undef __FUNCT__
232521d9a4cSLisandro Dalcin #define __FUNCT__ "DMSetMatType"
233521d9a4cSLisandro Dalcin /*@C
234521d9a4cSLisandro Dalcin        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
235521d9a4cSLisandro Dalcin 
236521d9a4cSLisandro Dalcin    Logically Collective on DM
237521d9a4cSLisandro Dalcin 
238521d9a4cSLisandro Dalcin    Input Parameter:
239521d9a4cSLisandro Dalcin +  dm - the DM context
240521d9a4cSLisandro Dalcin .  ctype - the matrix type
241521d9a4cSLisandro Dalcin 
242521d9a4cSLisandro Dalcin    Options Database:
243521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
244521d9a4cSLisandro Dalcin 
245521d9a4cSLisandro Dalcin    Level: intermediate
246521d9a4cSLisandro Dalcin 
247c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMGetMatType()
248521d9a4cSLisandro Dalcin @*/
24919fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
250521d9a4cSLisandro Dalcin {
251521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
25288f0584fSBarry Smith 
253521d9a4cSLisandro Dalcin   PetscFunctionBegin;
254521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
255521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
25619fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
257521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
258521d9a4cSLisandro Dalcin }
259521d9a4cSLisandro Dalcin 
260521d9a4cSLisandro Dalcin #undef __FUNCT__
261c0dedaeaSBarry Smith #define __FUNCT__ "DMGetMatType"
262c0dedaeaSBarry Smith /*@C
263c0dedaeaSBarry Smith        DMGetMatType - Gets the type of matrix created with DMCreateMatrix()
264c0dedaeaSBarry Smith 
265c0dedaeaSBarry Smith    Logically Collective on DM
266c0dedaeaSBarry Smith 
267c0dedaeaSBarry Smith    Input Parameter:
268c0dedaeaSBarry Smith .  dm - the DM context
269c0dedaeaSBarry Smith 
270c0dedaeaSBarry Smith    Output Parameter:
271c0dedaeaSBarry Smith .  ctype - the matrix type
272c0dedaeaSBarry Smith 
273c0dedaeaSBarry Smith    Options Database:
274c0dedaeaSBarry Smith .   -dm_mat_type ctype
275c0dedaeaSBarry Smith 
276c0dedaeaSBarry Smith    Level: intermediate
277c0dedaeaSBarry Smith 
278c0dedaeaSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType, DMSetMatType()
279c0dedaeaSBarry Smith @*/
280c0dedaeaSBarry Smith PetscErrorCode  DMGetMatType(DM dm,MatType *ctype)
281c0dedaeaSBarry Smith {
282c0dedaeaSBarry Smith   PetscFunctionBegin;
283c0dedaeaSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
284c0dedaeaSBarry Smith   *ctype = dm->mattype;
285c0dedaeaSBarry Smith   PetscFunctionReturn(0);
286c0dedaeaSBarry Smith }
287c0dedaeaSBarry Smith 
288c0dedaeaSBarry Smith #undef __FUNCT__
289c688c046SMatthew G Knepley #define __FUNCT__ "MatGetDM"
290c688c046SMatthew G Knepley /*@
29134f98d34SBarry Smith   MatGetDM - Gets the DM defining the data layout of the matrix
292c688c046SMatthew G Knepley 
293c688c046SMatthew G Knepley   Not collective
294c688c046SMatthew G Knepley 
295c688c046SMatthew G Knepley   Input Parameter:
296c688c046SMatthew G Knepley . A - The Mat
297c688c046SMatthew G Knepley 
298c688c046SMatthew G Knepley   Output Parameter:
299c688c046SMatthew G Knepley . dm - The DM
300c688c046SMatthew G Knepley 
301c688c046SMatthew G Knepley   Level: intermediate
302c688c046SMatthew G Knepley 
303c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType()
304c688c046SMatthew G Knepley @*/
305c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm)
306c688c046SMatthew G Knepley {
307c688c046SMatthew G Knepley   PetscErrorCode ierr;
308c688c046SMatthew G Knepley 
309c688c046SMatthew G Knepley   PetscFunctionBegin;
310c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
311c688c046SMatthew G Knepley   PetscValidPointer(dm,2);
312c688c046SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject*) dm);CHKERRQ(ierr);
313c688c046SMatthew G Knepley   PetscFunctionReturn(0);
314c688c046SMatthew G Knepley }
315c688c046SMatthew G Knepley 
316c688c046SMatthew G Knepley #undef __FUNCT__
317c688c046SMatthew G Knepley #define __FUNCT__ "MatSetDM"
318c688c046SMatthew G Knepley /*@
319c688c046SMatthew G Knepley   MatSetDM - Sets the DM defining the data layout of the matrix
320c688c046SMatthew G Knepley 
321c688c046SMatthew G Knepley   Not collective
322c688c046SMatthew G Knepley 
323c688c046SMatthew G Knepley   Input Parameters:
324c688c046SMatthew G Knepley + A - The Mat
325c688c046SMatthew G Knepley - dm - The DM
326c688c046SMatthew G Knepley 
327c688c046SMatthew G Knepley   Level: intermediate
328c688c046SMatthew G Knepley 
329c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType()
330c688c046SMatthew G Knepley @*/
331c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm)
332c688c046SMatthew G Knepley {
333c688c046SMatthew G Knepley   PetscErrorCode ierr;
334c688c046SMatthew G Knepley 
335c688c046SMatthew G Knepley   PetscFunctionBegin;
336c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3378865f1eaSKarl Rupp   if (dm) PetscValidHeaderSpecific(dm,DM_CLASSID,2);
338c688c046SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
339c688c046SMatthew G Knepley   PetscFunctionReturn(0);
340c688c046SMatthew G Knepley }
341c688c046SMatthew G Knepley 
342c688c046SMatthew G Knepley #undef __FUNCT__
3439a42bb27SBarry Smith #define __FUNCT__ "DMSetOptionsPrefix"
3449a42bb27SBarry Smith /*@C
3459a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
346aa219208SBarry Smith    DMDA options in the database.
3479a42bb27SBarry Smith 
348aa219208SBarry Smith    Logically Collective on DMDA
3499a42bb27SBarry Smith 
3509a42bb27SBarry Smith    Input Parameter:
351aa219208SBarry Smith +  da - the DMDA context
3529a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
3539a42bb27SBarry Smith 
3549a42bb27SBarry Smith    Notes:
3559a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
3569a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
3579a42bb27SBarry Smith 
3589a42bb27SBarry Smith    Level: advanced
3599a42bb27SBarry Smith 
360aa219208SBarry Smith .keywords: DMDA, set, options, prefix, database
3619a42bb27SBarry Smith 
3629a42bb27SBarry Smith .seealso: DMSetFromOptions()
3639a42bb27SBarry Smith @*/
3647087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
3659a42bb27SBarry Smith {
3669a42bb27SBarry Smith   PetscErrorCode ierr;
3679a42bb27SBarry Smith 
3689a42bb27SBarry Smith   PetscFunctionBegin;
3699a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3709a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
3719a42bb27SBarry Smith   PetscFunctionReturn(0);
3729a42bb27SBarry Smith }
3739a42bb27SBarry Smith 
3749a42bb27SBarry Smith #undef __FUNCT__
37547c6ae99SBarry Smith #define __FUNCT__ "DMDestroy"
37647c6ae99SBarry Smith /*@
377aa219208SBarry Smith     DMDestroy - Destroys a vector packer or DMDA.
37847c6ae99SBarry Smith 
37947c6ae99SBarry Smith     Collective on DM
38047c6ae99SBarry Smith 
38147c6ae99SBarry Smith     Input Parameter:
38247c6ae99SBarry Smith .   dm - the DM object to destroy
38347c6ae99SBarry Smith 
38447c6ae99SBarry Smith     Level: developer
38547c6ae99SBarry Smith 
386e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
38747c6ae99SBarry Smith 
38847c6ae99SBarry Smith @*/
389fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
39047c6ae99SBarry Smith {
391af122d2aSMatthew G Knepley   PetscInt       i, cnt = 0, f;
392dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
39347c6ae99SBarry Smith   PetscErrorCode ierr;
39447c6ae99SBarry Smith 
39547c6ae99SBarry Smith   PetscFunctionBegin;
3966bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
3976bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
39887e657c6SBarry Smith 
399a546ed68SMatthew G. Knepley   /* I think it makes sense to dump all attached things when you are destroyed, which also eliminates circular references */
400a546ed68SMatthew G. Knepley   for (f = 0; f < (*dm)->numFields; ++f) {
401decb47aaSMatthew G. Knepley     ierr = PetscObjectCompose((PetscObject) (*dm)->fields[f], "pmat", NULL);CHKERRQ(ierr);
402decb47aaSMatthew G. Knepley     ierr = PetscObjectCompose((PetscObject) (*dm)->fields[f], "nullspace", NULL);CHKERRQ(ierr);
403decb47aaSMatthew G. Knepley     ierr = PetscObjectCompose((PetscObject) (*dm)->fields[f], "nearnullspace", NULL);CHKERRQ(ierr);
404a546ed68SMatthew G. Knepley   }
40587e657c6SBarry Smith   /* count all the circular references of DM and its contained Vecs */
406732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
4078865f1eaSKarl Rupp     if ((*dm)->localin[i])  cnt++;
4088865f1eaSKarl Rupp     if ((*dm)->globalin[i]) cnt++;
409732e2eb9SMatthew G Knepley   }
410dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++;
4112348bcf4SPeter Brune   for (nlink=(*dm)->namedlocal; nlink; nlink=nlink->next) cnt++;
4122348bcf4SPeter Brune   if ((*dm)->x) {
4132348bcf4SPeter Brune     DM obj;
4142348bcf4SPeter Brune     ierr = VecGetDM((*dm)->x, &obj);CHKERRQ(ierr);
4152348bcf4SPeter Brune     if (obj == *dm) cnt++;
4162348bcf4SPeter Brune   }
417732e2eb9SMatthew G Knepley 
4186bf464f9SBarry Smith   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
419732e2eb9SMatthew G Knepley   /*
420732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
421732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
422732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
423732e2eb9SMatthew G Knepley   */
4246bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
4256bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
426732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
4276bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
4286bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
429732e2eb9SMatthew G Knepley   }
430f490541aSPeter Brune   nnext=(*dm)->namedglobal;
4310298fd71SBarry Smith   (*dm)->namedglobal = NULL;
432f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named vectors */
4332348bcf4SPeter Brune     nnext = nlink->next;
4342348bcf4SPeter 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);
4352348bcf4SPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
4362348bcf4SPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
4372348bcf4SPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
4382348bcf4SPeter Brune   }
439f490541aSPeter Brune   nnext=(*dm)->namedlocal;
4400298fd71SBarry Smith   (*dm)->namedlocal = NULL;
441f490541aSPeter Brune   for (nlink=nnext; nlink; nlink=nnext) { /* Destroy the named local vectors */
442f490541aSPeter Brune     nnext = nlink->next;
443f490541aSPeter 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);
444f490541aSPeter Brune     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
445f490541aSPeter Brune     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
446f490541aSPeter Brune     ierr = PetscFree(nlink);CHKERRQ(ierr);
447f490541aSPeter Brune   }
4482348bcf4SPeter Brune 
449b17ce1afSJed Brown   /* Destroy the list of hooks */
450c833c3b5SJed Brown   {
451c833c3b5SJed Brown     DMCoarsenHookLink link,next;
452b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
453b17ce1afSJed Brown       next = link->next;
454b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
455b17ce1afSJed Brown     }
4560298fd71SBarry Smith     (*dm)->coarsenhook = NULL;
457c833c3b5SJed Brown   }
458c833c3b5SJed Brown   {
459c833c3b5SJed Brown     DMRefineHookLink link,next;
460c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
461c833c3b5SJed Brown       next = link->next;
462c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
463c833c3b5SJed Brown     }
4640298fd71SBarry Smith     (*dm)->refinehook = NULL;
465c833c3b5SJed Brown   }
466be081cd6SPeter Brune   {
467be081cd6SPeter Brune     DMSubDomainHookLink link,next;
468be081cd6SPeter Brune     for (link=(*dm)->subdomainhook; link; link=next) {
469be081cd6SPeter Brune       next = link->next;
470be081cd6SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
471be081cd6SPeter Brune     }
4720298fd71SBarry Smith     (*dm)->subdomainhook = NULL;
473be081cd6SPeter Brune   }
474baf369e7SPeter Brune   {
475baf369e7SPeter Brune     DMGlobalToLocalHookLink link,next;
476baf369e7SPeter Brune     for (link=(*dm)->gtolhook; link; link=next) {
477baf369e7SPeter Brune       next = link->next;
478baf369e7SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
479baf369e7SPeter Brune     }
4800298fd71SBarry Smith     (*dm)->gtolhook = NULL;
481baf369e7SPeter Brune   }
482aa1993deSMatthew G Knepley   /* Destroy the work arrays */
483aa1993deSMatthew G Knepley   {
484aa1993deSMatthew G Knepley     DMWorkLink link,next;
485aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
486aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
487aa1993deSMatthew G Knepley       next = link->next;
488aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
489aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
490aa1993deSMatthew G Knepley     }
4910298fd71SBarry Smith     (*dm)->workin = NULL;
492aa1993deSMatthew G Knepley   }
493b17ce1afSJed Brown 
49452536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr);
49552536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr);
49652536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr);
49752536dc3SBarry Smith 
4981a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
4991a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
5001a266240SBarry Smith   }
50187e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
50271cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
5034dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
5046bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
5056bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr);
5066bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
507073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
50888ed4aceSMatthew G Knepley 
50988ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
51088ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
5118b1ab98fSJed Brown   ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr);
51288ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
51388ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
514af122d2aSMatthew G Knepley 
5156636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
5166636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
5176636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
518c6b900c6SMatthew G. Knepley   ierr = PetscFree((*dm)->maxCell);CHKERRQ(ierr);
519c6b900c6SMatthew G. Knepley   ierr = PetscFree((*dm)->L);CHKERRQ(ierr);
5206636e97aSMatthew G Knepley 
521af122d2aSMatthew G Knepley   for (f = 0; f < (*dm)->numFields; ++f) {
522decb47aaSMatthew G. Knepley     ierr = PetscObjectDestroy((PetscObject *) &(*dm)->fields[f]);CHKERRQ(ierr);
523af122d2aSMatthew G Knepley   }
524af122d2aSMatthew G Knepley   ierr = PetscFree((*dm)->fields);CHKERRQ(ierr);
52514f150ffSMatthew G. Knepley   ierr = DMDestroy(&(*dm)->dmBC);CHKERRQ(ierr);
526e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
527e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*dm);CHKERRQ(ierr);
528732e2eb9SMatthew G Knepley 
5296bf464f9SBarry Smith   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
530435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
531732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
53247c6ae99SBarry Smith   PetscFunctionReturn(0);
53347c6ae99SBarry Smith }
53447c6ae99SBarry Smith 
53547c6ae99SBarry Smith #undef __FUNCT__
536d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp"
537d7bf68aeSBarry Smith /*@
538d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
539d7bf68aeSBarry Smith 
540d7bf68aeSBarry Smith     Collective on DM
541d7bf68aeSBarry Smith 
542d7bf68aeSBarry Smith     Input Parameter:
543d7bf68aeSBarry Smith .   dm - the DM object to setup
544d7bf68aeSBarry Smith 
545d7bf68aeSBarry Smith     Level: developer
546d7bf68aeSBarry Smith 
547e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
548d7bf68aeSBarry Smith 
549d7bf68aeSBarry Smith @*/
5507087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
551d7bf68aeSBarry Smith {
552d7bf68aeSBarry Smith   PetscErrorCode ierr;
553d7bf68aeSBarry Smith 
554d7bf68aeSBarry Smith   PetscFunctionBegin;
555171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5568387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
557d7bf68aeSBarry Smith   if (dm->ops->setup) {
558d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
559d7bf68aeSBarry Smith   }
5608387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
561d7bf68aeSBarry Smith   PetscFunctionReturn(0);
562d7bf68aeSBarry Smith }
563d7bf68aeSBarry Smith 
564d7bf68aeSBarry Smith #undef __FUNCT__
565d7bf68aeSBarry Smith #define __FUNCT__ "DMSetFromOptions"
566d7bf68aeSBarry Smith /*@
567d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
568d7bf68aeSBarry Smith 
569d7bf68aeSBarry Smith     Collective on DM
570d7bf68aeSBarry Smith 
571d7bf68aeSBarry Smith     Input Parameter:
572d7bf68aeSBarry Smith .   dm - the DM object to set options for
573d7bf68aeSBarry Smith 
574732e2eb9SMatthew G Knepley     Options Database:
575dd85299cSBarry Smith +   -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
576dd85299cSBarry Smith .   -dm_vec_type <type>  type of vector to create inside DM
577171400e9SBarry Smith .   -dm_mat_type <type>  type of matrix to create inside DM
578171400e9SBarry Smith -   -dm_coloring_type <global or ghosted>
579732e2eb9SMatthew G Knepley 
580d7bf68aeSBarry Smith     Level: developer
581d7bf68aeSBarry Smith 
582e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
583d7bf68aeSBarry Smith 
584d7bf68aeSBarry Smith @*/
5857087cfbeSBarry Smith PetscErrorCode  DMSetFromOptions(DM dm)
586d7bf68aeSBarry Smith {
5877781c08eSBarry Smith   char           typeName[256];
588ca266f36SBarry Smith   PetscBool      flg;
589d7bf68aeSBarry Smith   PetscErrorCode ierr;
590d7bf68aeSBarry Smith 
591d7bf68aeSBarry Smith   PetscFunctionBegin;
592171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5933194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
5940298fd71SBarry 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);
595a264d7a6SBarry Smith   ierr = PetscOptionsFList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
596f9ba7244SBarry Smith   if (flg) {
597f9ba7244SBarry Smith     ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
598f9ba7244SBarry Smith   }
599a264d7a6SBarry 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);
600073dac72SJed Brown   if (flg) {
601521d9a4cSLisandro Dalcin     ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
602073dac72SJed Brown   }
6030298fd71SBarry Smith   ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","ISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,NULL);CHKERRQ(ierr);
604f9ba7244SBarry Smith   if (dm->ops->setfromoptions) {
605f9ba7244SBarry Smith     ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr);
606f9ba7244SBarry Smith   }
607f9ba7244SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
608f9ba7244SBarry Smith   ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
60982fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
610d7bf68aeSBarry Smith   PetscFunctionReturn(0);
611d7bf68aeSBarry Smith }
612d7bf68aeSBarry Smith 
613d7bf68aeSBarry Smith #undef __FUNCT__
61447c6ae99SBarry Smith #define __FUNCT__ "DMView"
615fc9bc008SSatish Balay /*@C
616aa219208SBarry Smith     DMView - Views a vector packer or DMDA.
61747c6ae99SBarry Smith 
61847c6ae99SBarry Smith     Collective on DM
61947c6ae99SBarry Smith 
62047c6ae99SBarry Smith     Input Parameter:
62147c6ae99SBarry Smith +   dm - the DM object to view
62247c6ae99SBarry Smith -   v - the viewer
62347c6ae99SBarry Smith 
62447c6ae99SBarry Smith     Level: developer
62547c6ae99SBarry Smith 
626e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
62747c6ae99SBarry Smith 
62847c6ae99SBarry Smith @*/
6297087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
63047c6ae99SBarry Smith {
63147c6ae99SBarry Smith   PetscErrorCode ierr;
63232c0f0efSBarry Smith   PetscBool      isbinary;
63347c6ae99SBarry Smith 
63447c6ae99SBarry Smith   PetscFunctionBegin;
635171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6363014e516SBarry Smith   if (!v) {
637ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)dm),&v);CHKERRQ(ierr);
6383014e516SBarry Smith   }
63998c3331eSBarry Smith   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)dm,v);CHKERRQ(ierr);
64032c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
64132c0f0efSBarry Smith   if (isbinary) {
64255849f57SBarry Smith     PetscInt classid = DM_FILE_CLASSID;
64332c0f0efSBarry Smith     char     type[256];
64432c0f0efSBarry Smith 
64532c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
64632c0f0efSBarry Smith     ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
64732c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
64832c0f0efSBarry Smith   }
6490c010503SBarry Smith   if (dm->ops->view) {
6500c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
65147c6ae99SBarry Smith   }
65247c6ae99SBarry Smith   PetscFunctionReturn(0);
65347c6ae99SBarry Smith }
65447c6ae99SBarry Smith 
65547c6ae99SBarry Smith #undef __FUNCT__
65647c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
65747c6ae99SBarry Smith /*@
658aa219208SBarry Smith     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
65947c6ae99SBarry Smith 
66047c6ae99SBarry Smith     Collective on DM
66147c6ae99SBarry Smith 
66247c6ae99SBarry Smith     Input Parameter:
66347c6ae99SBarry Smith .   dm - the DM object
66447c6ae99SBarry Smith 
66547c6ae99SBarry Smith     Output Parameter:
66647c6ae99SBarry Smith .   vec - the global vector
66747c6ae99SBarry Smith 
668073dac72SJed Brown     Level: beginner
66947c6ae99SBarry Smith 
670e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
67147c6ae99SBarry Smith 
67247c6ae99SBarry Smith @*/
6737087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
67447c6ae99SBarry Smith {
67547c6ae99SBarry Smith   PetscErrorCode ierr;
67647c6ae99SBarry Smith 
67747c6ae99SBarry Smith   PetscFunctionBegin;
678171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
67947c6ae99SBarry Smith   ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
68047c6ae99SBarry Smith   PetscFunctionReturn(0);
68147c6ae99SBarry Smith }
68247c6ae99SBarry Smith 
68347c6ae99SBarry Smith #undef __FUNCT__
68447c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
68547c6ae99SBarry Smith /*@
686aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
68747c6ae99SBarry Smith 
68847c6ae99SBarry Smith     Not Collective
68947c6ae99SBarry Smith 
69047c6ae99SBarry Smith     Input Parameter:
69147c6ae99SBarry Smith .   dm - the DM object
69247c6ae99SBarry Smith 
69347c6ae99SBarry Smith     Output Parameter:
69447c6ae99SBarry Smith .   vec - the local vector
69547c6ae99SBarry Smith 
696073dac72SJed Brown     Level: beginner
69747c6ae99SBarry Smith 
698e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
69947c6ae99SBarry Smith 
70047c6ae99SBarry Smith @*/
7017087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
70247c6ae99SBarry Smith {
70347c6ae99SBarry Smith   PetscErrorCode ierr;
70447c6ae99SBarry Smith 
70547c6ae99SBarry Smith   PetscFunctionBegin;
706171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
70747c6ae99SBarry Smith   ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
70847c6ae99SBarry Smith   PetscFunctionReturn(0);
70947c6ae99SBarry Smith }
71047c6ae99SBarry Smith 
71147c6ae99SBarry Smith #undef __FUNCT__
7121411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
7131411c6eeSJed Brown /*@
7141411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
7151411c6eeSJed Brown 
7161411c6eeSJed Brown    Collective on DM
7171411c6eeSJed Brown 
7181411c6eeSJed Brown    Input Parameter:
7191411c6eeSJed Brown .  dm - the DM that provides the mapping
7201411c6eeSJed Brown 
7211411c6eeSJed Brown    Output Parameter:
7221411c6eeSJed Brown .  ltog - the mapping
7231411c6eeSJed Brown 
7241411c6eeSJed Brown    Level: intermediate
7251411c6eeSJed Brown 
7261411c6eeSJed Brown    Notes:
7271411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
7281411c6eeSJed Brown    MatSetLocalToGlobalMapping().
7291411c6eeSJed Brown 
7301411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
7311411c6eeSJed Brown @*/
7327087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
7331411c6eeSJed Brown {
7341411c6eeSJed Brown   PetscErrorCode ierr;
7351411c6eeSJed Brown 
7361411c6eeSJed Brown   PetscFunctionBegin;
7371411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7381411c6eeSJed Brown   PetscValidPointer(ltog,2);
7391411c6eeSJed Brown   if (!dm->ltogmap) {
74037d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
74137d0c07bSMatthew G Knepley 
74237d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
74337d0c07bSMatthew G Knepley     if (section) {
74437d0c07bSMatthew G Knepley       PetscInt *ltog;
74537d0c07bSMatthew G Knepley       PetscInt pStart, pEnd, size, p, l;
74637d0c07bSMatthew G Knepley 
74737d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
74837d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
74937d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
750785e854fSJed Brown       ierr = PetscMalloc1(size, &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
75137d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
75237d0c07bSMatthew G Knepley         PetscInt dof, off, c;
75337d0c07bSMatthew G Knepley 
75437d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
75537d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
75637d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
75737d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
75837d0c07bSMatthew G Knepley           ltog[l] = off+c;
75937d0c07bSMatthew G Knepley         }
76037d0c07bSMatthew G Knepley       }
761*f0413b6fSBarry Smith       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, 1,size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
7623bb1ff40SBarry Smith       ierr = PetscLogObjectParent((PetscObject)dm, (PetscObject)dm->ltogmap);CHKERRQ(ierr);
76337d0c07bSMatthew G Knepley     } else {
764184d77edSJed Brown       if (!dm->ops->getlocaltoglobalmapping) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
765184d77edSJed Brown       ierr = (*dm->ops->getlocaltoglobalmapping)(dm);CHKERRQ(ierr);
7661411c6eeSJed Brown     }
76737d0c07bSMatthew G Knepley   }
7681411c6eeSJed Brown   *ltog = dm->ltogmap;
7691411c6eeSJed Brown   PetscFunctionReturn(0);
7701411c6eeSJed Brown }
7711411c6eeSJed Brown 
7721411c6eeSJed Brown #undef __FUNCT__
7731411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
7741411c6eeSJed Brown /*@
7751411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
7761411c6eeSJed Brown 
7771411c6eeSJed Brown    Collective on DM
7781411c6eeSJed Brown 
7791411c6eeSJed Brown    Input Parameter:
7801411c6eeSJed Brown .  da - the distributed array that provides the mapping
7811411c6eeSJed Brown 
7821411c6eeSJed Brown    Output Parameter:
7831411c6eeSJed Brown .  ltog - the block mapping
7841411c6eeSJed Brown 
7851411c6eeSJed Brown    Level: intermediate
7861411c6eeSJed Brown 
7871411c6eeSJed Brown    Notes:
7881411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
7891411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
7901411c6eeSJed Brown 
7911411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
7921411c6eeSJed Brown @*/
7937087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
7941411c6eeSJed Brown {
7951411c6eeSJed Brown   PetscErrorCode ierr;
7961411c6eeSJed Brown 
7971411c6eeSJed Brown   PetscFunctionBegin;
7981411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7991411c6eeSJed Brown   PetscValidPointer(ltog,2);
8001411c6eeSJed Brown   if (!dm->ltogmapb) {
8011411c6eeSJed Brown     PetscInt bs;
8021411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
8031411c6eeSJed Brown     if (bs > 1) {
804184d77edSJed Brown       if (!dm->ops->getlocaltoglobalmappingblock) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
805184d77edSJed Brown       ierr = (*dm->ops->getlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
8061411c6eeSJed Brown     } else {
8071411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
8081411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
8091411c6eeSJed Brown     }
8101411c6eeSJed Brown   }
8111411c6eeSJed Brown   *ltog = dm->ltogmapb;
8121411c6eeSJed Brown   PetscFunctionReturn(0);
8131411c6eeSJed Brown }
8141411c6eeSJed Brown 
8151411c6eeSJed Brown #undef __FUNCT__
8161411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
8171411c6eeSJed Brown /*@
8181411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
8191411c6eeSJed Brown 
8201411c6eeSJed Brown    Not Collective
8211411c6eeSJed Brown 
8221411c6eeSJed Brown    Input Parameter:
8231411c6eeSJed Brown .  dm - the DM with block structure
8241411c6eeSJed Brown 
8251411c6eeSJed Brown    Output Parameter:
8261411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
8271411c6eeSJed Brown 
8281411c6eeSJed Brown    Level: intermediate
8291411c6eeSJed Brown 
8301411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
8311411c6eeSJed Brown @*/
8327087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
8331411c6eeSJed Brown {
8341411c6eeSJed Brown   PetscFunctionBegin;
8351411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8361411c6eeSJed Brown   PetscValidPointer(bs,2);
8371411c6eeSJed 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");
8381411c6eeSJed Brown   *bs = dm->bs;
8391411c6eeSJed Brown   PetscFunctionReturn(0);
8401411c6eeSJed Brown }
8411411c6eeSJed Brown 
8421411c6eeSJed Brown #undef __FUNCT__
843e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
84447c6ae99SBarry Smith /*@
845e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
84647c6ae99SBarry Smith 
84747c6ae99SBarry Smith     Collective on DM
84847c6ae99SBarry Smith 
84947c6ae99SBarry Smith     Input Parameter:
85047c6ae99SBarry Smith +   dm1 - the DM object
85147c6ae99SBarry Smith -   dm2 - the second, finer DM object
85247c6ae99SBarry Smith 
85347c6ae99SBarry Smith     Output Parameter:
85447c6ae99SBarry Smith +  mat - the interpolation
85547c6ae99SBarry Smith -  vec - the scaling (optional)
85647c6ae99SBarry Smith 
85747c6ae99SBarry Smith     Level: developer
85847c6ae99SBarry Smith 
85985afcc9aSBarry 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
86085afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
861d52bd9f3SBarry Smith 
8621f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
863d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
86485afcc9aSBarry Smith 
86585afcc9aSBarry Smith 
866e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
86747c6ae99SBarry Smith 
86847c6ae99SBarry Smith @*/
869e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
87047c6ae99SBarry Smith {
87147c6ae99SBarry Smith   PetscErrorCode ierr;
87247c6ae99SBarry Smith 
87347c6ae99SBarry Smith   PetscFunctionBegin;
874171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
875171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
87625296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
87747c6ae99SBarry Smith   PetscFunctionReturn(0);
87847c6ae99SBarry Smith }
87947c6ae99SBarry Smith 
88047c6ae99SBarry Smith #undef __FUNCT__
881e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
88247c6ae99SBarry Smith /*@
883e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
88447c6ae99SBarry Smith 
88547c6ae99SBarry Smith     Collective on DM
88647c6ae99SBarry Smith 
88747c6ae99SBarry Smith     Input Parameter:
88847c6ae99SBarry Smith +   dm1 - the DM object
88947c6ae99SBarry Smith -   dm2 - the second, finer DM object
89047c6ae99SBarry Smith 
89147c6ae99SBarry Smith     Output Parameter:
89247c6ae99SBarry Smith .   ctx - the injection
89347c6ae99SBarry Smith 
89447c6ae99SBarry Smith     Level: developer
89547c6ae99SBarry Smith 
89685afcc9aSBarry 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
89785afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
89885afcc9aSBarry Smith 
899e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
90047c6ae99SBarry Smith 
90147c6ae99SBarry Smith @*/
902e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
90347c6ae99SBarry Smith {
90447c6ae99SBarry Smith   PetscErrorCode ierr;
90547c6ae99SBarry Smith 
90647c6ae99SBarry Smith   PetscFunctionBegin;
907171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
908171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
90947c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
91047c6ae99SBarry Smith   PetscFunctionReturn(0);
91147c6ae99SBarry Smith }
91247c6ae99SBarry Smith 
91347c6ae99SBarry Smith #undef __FUNCT__
914e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
915b412c318SBarry Smith /*@
916b412c318SBarry Smith     DMCreateColoring - Gets coloring for a DM
91747c6ae99SBarry Smith 
91847c6ae99SBarry Smith     Collective on DM
91947c6ae99SBarry Smith 
92047c6ae99SBarry Smith     Input Parameter:
92147c6ae99SBarry Smith +   dm - the DM object
922b412c318SBarry Smith -   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
92347c6ae99SBarry Smith 
92447c6ae99SBarry Smith     Output Parameter:
92547c6ae99SBarry Smith .   coloring - the coloring
92647c6ae99SBarry Smith 
92747c6ae99SBarry Smith     Level: developer
92847c6ae99SBarry Smith 
929b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix(), DMSetMatType()
93047c6ae99SBarry Smith 
931aab9d709SJed Brown @*/
932b412c318SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,ISColoring *coloring)
93347c6ae99SBarry Smith {
93447c6ae99SBarry Smith   PetscErrorCode ierr;
93547c6ae99SBarry Smith 
93647c6ae99SBarry Smith   PetscFunctionBegin;
937171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
938ce94432eSBarry Smith   if (!dm->ops->getcoloring) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No coloring for this type of DM yet");
939b412c318SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,coloring);CHKERRQ(ierr);
94047c6ae99SBarry Smith   PetscFunctionReturn(0);
94147c6ae99SBarry Smith }
94247c6ae99SBarry Smith 
94347c6ae99SBarry Smith #undef __FUNCT__
944950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
945b412c318SBarry Smith /*@
946950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
94747c6ae99SBarry Smith 
94847c6ae99SBarry Smith     Collective on DM
94947c6ae99SBarry Smith 
95047c6ae99SBarry Smith     Input Parameter:
951b412c318SBarry Smith .   dm - the DM object
95247c6ae99SBarry Smith 
95347c6ae99SBarry Smith     Output Parameter:
95447c6ae99SBarry Smith .   mat - the empty Jacobian
95547c6ae99SBarry Smith 
956073dac72SJed Brown     Level: beginner
95747c6ae99SBarry Smith 
95894013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
95994013140SBarry Smith        do not need to do it yourself.
96094013140SBarry Smith 
96194013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
962aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
96394013140SBarry Smith 
96494013140SBarry 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
96594013140SBarry Smith        internally by PETSc.
96694013140SBarry Smith 
96794013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
968aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
96994013140SBarry Smith 
970b412c318SBarry Smith .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMSetMatType()
97147c6ae99SBarry Smith 
972aab9d709SJed Brown @*/
973b412c318SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,Mat *mat)
97447c6ae99SBarry Smith {
97547c6ae99SBarry Smith   PetscErrorCode ierr;
97647c6ae99SBarry Smith 
97747c6ae99SBarry Smith   PetscFunctionBegin;
978171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
979607a6623SBarry Smith   ierr = MatInitializePackage();CHKERRQ(ierr);
980c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
981c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
982b412c318SBarry Smith   ierr = (*dm->ops->creatematrix)(dm,mat);CHKERRQ(ierr);
98347c6ae99SBarry Smith   PetscFunctionReturn(0);
98447c6ae99SBarry Smith }
98547c6ae99SBarry Smith 
98647c6ae99SBarry Smith #undef __FUNCT__
987732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
988732e2eb9SMatthew G Knepley /*@
989950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
990732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
991732e2eb9SMatthew G Knepley 
992732e2eb9SMatthew G Knepley   Logically Collective on DMDA
993732e2eb9SMatthew G Knepley 
994732e2eb9SMatthew G Knepley   Input Parameter:
995732e2eb9SMatthew G Knepley + dm - the DM
996732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
997732e2eb9SMatthew G Knepley 
998732e2eb9SMatthew G Knepley   Level: developer
999950540a4SJed Brown .seealso DMCreateMatrix()
1000732e2eb9SMatthew G Knepley @*/
1001732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
1002732e2eb9SMatthew G Knepley {
1003732e2eb9SMatthew G Knepley   PetscFunctionBegin;
1004732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1005732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
1006732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
1007732e2eb9SMatthew G Knepley }
1008732e2eb9SMatthew G Knepley 
1009732e2eb9SMatthew G Knepley #undef __FUNCT__
1010a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
1011a89ea682SMatthew G Knepley /*@C
1012aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1013a89ea682SMatthew G Knepley 
1014a89ea682SMatthew G Knepley   Not Collective
1015a89ea682SMatthew G Knepley 
1016a89ea682SMatthew G Knepley   Input Parameters:
1017a89ea682SMatthew G Knepley + dm - the DM object
1018aa1993deSMatthew G Knepley . count - The minium size
1019aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
1020a89ea682SMatthew G Knepley 
1021a89ea682SMatthew G Knepley   Output Parameter:
1022a89ea682SMatthew G Knepley . array - the work array
1023a89ea682SMatthew G Knepley 
1024a89ea682SMatthew G Knepley   Level: developer
1025a89ea682SMatthew G Knepley 
1026a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
1027a89ea682SMatthew G Knepley @*/
1028aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1029a89ea682SMatthew G Knepley {
1030a89ea682SMatthew G Knepley   PetscErrorCode ierr;
1031aa1993deSMatthew G Knepley   DMWorkLink     link;
1032aa1993deSMatthew G Knepley   size_t         size;
1033a89ea682SMatthew G Knepley 
1034a89ea682SMatthew G Knepley   PetscFunctionBegin;
1035a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1036aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1037aa1993deSMatthew G Knepley   if (dm->workin) {
1038aa1993deSMatthew G Knepley     link       = dm->workin;
1039aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
1040aa1993deSMatthew G Knepley   } else {
1041b00a9115SJed Brown     ierr = PetscNewLog(dm,&link);CHKERRQ(ierr);
1042a89ea682SMatthew G Knepley   }
1043aa1993deSMatthew G Knepley   ierr = PetscDataTypeGetSize(dtype,&size);CHKERRQ(ierr);
1044aa1993deSMatthew G Knepley   if (size*count > link->bytes) {
1045aa1993deSMatthew G Knepley     ierr        = PetscFree(link->mem);CHKERRQ(ierr);
1046aa1993deSMatthew G Knepley     ierr        = PetscMalloc(size*count,&link->mem);CHKERRQ(ierr);
1047aa1993deSMatthew G Knepley     link->bytes = size*count;
1048aa1993deSMatthew G Knepley   }
1049aa1993deSMatthew G Knepley   link->next   = dm->workout;
1050aa1993deSMatthew G Knepley   dm->workout  = link;
1051aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
1052a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
1053a89ea682SMatthew G Knepley }
1054a89ea682SMatthew G Knepley 
1055aa1993deSMatthew G Knepley #undef __FUNCT__
1056aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
1057aa1993deSMatthew G Knepley /*@C
1058aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1059aa1993deSMatthew G Knepley 
1060aa1993deSMatthew G Knepley   Not Collective
1061aa1993deSMatthew G Knepley 
1062aa1993deSMatthew G Knepley   Input Parameters:
1063aa1993deSMatthew G Knepley + dm - the DM object
1064aa1993deSMatthew G Knepley . count - The minium size
1065aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
1066aa1993deSMatthew G Knepley 
1067aa1993deSMatthew G Knepley   Output Parameter:
1068aa1993deSMatthew G Knepley . array - the work array
1069aa1993deSMatthew G Knepley 
1070aa1993deSMatthew G Knepley   Level: developer
1071aa1993deSMatthew G Knepley 
1072aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
1073aa1993deSMatthew G Knepley @*/
1074aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1075aa1993deSMatthew G Knepley {
1076aa1993deSMatthew G Knepley   DMWorkLink *p,link;
1077aa1993deSMatthew G Knepley 
1078aa1993deSMatthew G Knepley   PetscFunctionBegin;
1079aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1080aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1081aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
1082aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
1083aa1993deSMatthew G Knepley       *p           = link->next;
1084aa1993deSMatthew G Knepley       link->next   = dm->workin;
1085aa1993deSMatthew G Knepley       dm->workin   = link;
10860298fd71SBarry Smith       *(void**)mem = NULL;
1087aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
1088aa1993deSMatthew G Knepley     }
1089aa1993deSMatthew G Knepley   }
1090aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
1091aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
1092aa1993deSMatthew G Knepley }
1093e7c4fc90SDmitry Karpeev 
1094e7c4fc90SDmitry Karpeev #undef __FUNCT__
1095435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
1096435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1097435a35e8SMatthew G Knepley {
1098435a35e8SMatthew G Knepley   PetscFunctionBegin;
1099435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
110082f516ccSBarry Smith   if (field >= 10) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1101435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
1102435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1103435a35e8SMatthew G Knepley }
1104435a35e8SMatthew G Knepley 
1105435a35e8SMatthew G Knepley #undef __FUNCT__
11064d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
11074f3b5142SJed Brown /*@C
11084d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
11094d343eeaSMatthew G Knepley 
11104d343eeaSMatthew G Knepley   Not collective
11114d343eeaSMatthew G Knepley 
11124d343eeaSMatthew G Knepley   Input Parameter:
11134d343eeaSMatthew G Knepley . dm - the DM object
11144d343eeaSMatthew G Knepley 
11154d343eeaSMatthew G Knepley   Output Parameters:
11160298fd71SBarry Smith + numFields  - The number of fields (or NULL if not requested)
11170298fd71SBarry Smith . fieldNames - The name for each field (or NULL if not requested)
11180298fd71SBarry Smith - fields     - The global indices for each field (or NULL if not requested)
11194d343eeaSMatthew G Knepley 
11204d343eeaSMatthew G Knepley   Level: intermediate
11214d343eeaSMatthew G Knepley 
112221c9b008SJed Brown   Notes:
112321c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
112421c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
112521c9b008SJed Brown   PetscFree().
112621c9b008SJed Brown 
11274d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
11284d343eeaSMatthew G Knepley @*/
112937d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
11304d343eeaSMatthew G Knepley {
113137d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
11324d343eeaSMatthew G Knepley   PetscErrorCode ierr;
11334d343eeaSMatthew G Knepley 
11344d343eeaSMatthew G Knepley   PetscFunctionBegin;
11354d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
113669ca1f37SDmitry Karpeev   if (numFields) {
113769ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
113869ca1f37SDmitry Karpeev     *numFields = 0;
113969ca1f37SDmitry Karpeev   }
114037d0c07bSMatthew G Knepley   if (fieldNames) {
114137d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
11420298fd71SBarry Smith     *fieldNames = NULL;
114369ca1f37SDmitry Karpeev   }
114469ca1f37SDmitry Karpeev   if (fields) {
114569ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
11460298fd71SBarry Smith     *fields = NULL;
114769ca1f37SDmitry Karpeev   }
114837d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
114937d0c07bSMatthew G Knepley   if (section) {
115037d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
115137d0c07bSMatthew G Knepley     PetscInt nF, f, pStart, pEnd, p;
115237d0c07bSMatthew G Knepley 
115337d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
115437d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
1155dcca6d9dSJed Brown     ierr = PetscMalloc2(nF,&fieldSizes,nF,&fieldIndices);CHKERRQ(ierr);
115637d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
115737d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
115837d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
115937d0c07bSMatthew G Knepley     }
116037d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
116137d0c07bSMatthew G Knepley       PetscInt gdof;
116237d0c07bSMatthew G Knepley 
116337d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
116437d0c07bSMatthew G Knepley       if (gdof > 0) {
116537d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
116637d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
116737d0c07bSMatthew G Knepley 
116837d0c07bSMatthew G Knepley           ierr           = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
116937d0c07bSMatthew G Knepley           ierr           = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
117037d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
117137d0c07bSMatthew G Knepley         }
117237d0c07bSMatthew G Knepley       }
117337d0c07bSMatthew G Knepley     }
117437d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
1175785e854fSJed Brown       ierr          = PetscMalloc1(fieldSizes[f], &fieldIndices[f]);CHKERRQ(ierr);
117637d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
117737d0c07bSMatthew G Knepley     }
117837d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
117937d0c07bSMatthew G Knepley       PetscInt gdof, goff;
118037d0c07bSMatthew G Knepley 
118137d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
118237d0c07bSMatthew G Knepley       if (gdof > 0) {
118337d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
118437d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
118537d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
118637d0c07bSMatthew G Knepley 
118737d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
118837d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
118937d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
119037d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
119137d0c07bSMatthew G Knepley           }
119237d0c07bSMatthew G Knepley         }
119337d0c07bSMatthew G Knepley       }
119437d0c07bSMatthew G Knepley     }
11958865f1eaSKarl Rupp     if (numFields) *numFields = nF;
119637d0c07bSMatthew G Knepley     if (fieldNames) {
1197785e854fSJed Brown       ierr = PetscMalloc1(nF, fieldNames);CHKERRQ(ierr);
119837d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
119937d0c07bSMatthew G Knepley         const char *fieldName;
120037d0c07bSMatthew G Knepley 
120137d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
120237d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char**) &(*fieldNames)[f]);CHKERRQ(ierr);
120337d0c07bSMatthew G Knepley       }
120437d0c07bSMatthew G Knepley     }
120537d0c07bSMatthew G Knepley     if (fields) {
1206785e854fSJed Brown       ierr = PetscMalloc1(nF, fields);CHKERRQ(ierr);
120737d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
120882f516ccSBarry Smith         ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
120937d0c07bSMatthew G Knepley       }
121037d0c07bSMatthew G Knepley     }
121137d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
12128865f1eaSKarl Rupp   } else if (dm->ops->createfieldis) {
12138865f1eaSKarl Rupp     ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);
121469ca1f37SDmitry Karpeev   }
12154d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
12164d343eeaSMatthew G Knepley }
12174d343eeaSMatthew G Knepley 
121816621825SDmitry Karpeev 
121916621825SDmitry Karpeev #undef __FUNCT__
122016621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
122116621825SDmitry Karpeev /*@C
122216621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
122316621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
122416621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1225e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1226e7c4fc90SDmitry Karpeev 
1227e7c4fc90SDmitry Karpeev   Not collective
1228e7c4fc90SDmitry Karpeev 
1229e7c4fc90SDmitry Karpeev   Input Parameter:
1230e7c4fc90SDmitry Karpeev . dm - the DM object
1231e7c4fc90SDmitry Karpeev 
1232e7c4fc90SDmitry Karpeev   Output Parameters:
12330298fd71SBarry Smith + len       - The number of subproblems in the field decomposition (or NULL if not requested)
12340298fd71SBarry Smith . namelist  - The name for each field (or NULL if not requested)
12350298fd71SBarry Smith . islist    - The global indices for each field (or NULL if not requested)
12360298fd71SBarry Smith - dmlist    - The DMs for each field subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
1237e7c4fc90SDmitry Karpeev 
1238e7c4fc90SDmitry Karpeev   Level: intermediate
1239e7c4fc90SDmitry Karpeev 
1240e7c4fc90SDmitry Karpeev   Notes:
1241e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1242e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1243e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1244e7c4fc90SDmitry Karpeev 
1245e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1246e7c4fc90SDmitry Karpeev @*/
124716621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1248e7c4fc90SDmitry Karpeev {
1249e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1250e7c4fc90SDmitry Karpeev 
1251e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1252e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12538865f1eaSKarl Rupp   if (len) {
12548865f1eaSKarl Rupp     PetscValidPointer(len,2);
12558865f1eaSKarl Rupp     *len = 0;
12568865f1eaSKarl Rupp   }
12578865f1eaSKarl Rupp   if (namelist) {
12588865f1eaSKarl Rupp     PetscValidPointer(namelist,3);
12598865f1eaSKarl Rupp     *namelist = 0;
12608865f1eaSKarl Rupp   }
12618865f1eaSKarl Rupp   if (islist) {
12628865f1eaSKarl Rupp     PetscValidPointer(islist,4);
12638865f1eaSKarl Rupp     *islist = 0;
12648865f1eaSKarl Rupp   }
12658865f1eaSKarl Rupp   if (dmlist) {
12668865f1eaSKarl Rupp     PetscValidPointer(dmlist,5);
12678865f1eaSKarl Rupp     *dmlist = 0;
12688865f1eaSKarl Rupp   }
1269f3f0edfdSDmitry Karpeev   /*
1270f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1271f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1272f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1273f3f0edfdSDmitry Karpeev    */
1274ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
127516621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1276435a35e8SMatthew G Knepley     PetscSection section;
1277435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1278435a35e8SMatthew G Knepley 
1279435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1280435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1281435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1282435a35e8SMatthew G Knepley       *len = numFields;
128303dc3394SMatthew G. Knepley       if (namelist) {ierr = PetscMalloc1(numFields,namelist);CHKERRQ(ierr);}
128403dc3394SMatthew G. Knepley       if (islist)   {ierr = PetscMalloc1(numFields,islist);CHKERRQ(ierr);}
128503dc3394SMatthew G. Knepley       if (dmlist)   {ierr = PetscMalloc1(numFields,dmlist);CHKERRQ(ierr);}
1286435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1287435a35e8SMatthew G Knepley         const char *fieldName;
1288435a35e8SMatthew G Knepley 
128903dc3394SMatthew G. Knepley         ierr = DMCreateSubDM(dm, 1, &f, islist ? &(*islist)[f] : NULL, dmlist ? &(*dmlist)[f] : NULL);CHKERRQ(ierr);
129003dc3394SMatthew G. Knepley         if (namelist) {
1291435a35e8SMatthew G Knepley           ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1292435a35e8SMatthew G Knepley           ierr = PetscStrallocpy(fieldName, (char**) &(*namelist)[f]);CHKERRQ(ierr);
1293435a35e8SMatthew G Knepley         }
129403dc3394SMatthew G. Knepley       }
1295435a35e8SMatthew G Knepley     } else {
129669ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1297e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
12980298fd71SBarry Smith       if (dmlist) *dmlist = NULL;
1299e7c4fc90SDmitry Karpeev     }
13008865f1eaSKarl Rupp   } else {
130116621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist);CHKERRQ(ierr);
130216621825SDmitry Karpeev   }
130316621825SDmitry Karpeev   PetscFunctionReturn(0);
130416621825SDmitry Karpeev }
130516621825SDmitry Karpeev 
130616621825SDmitry Karpeev #undef __FUNCT__
1307435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1308435a35e8SMatthew G Knepley /*@C
1309435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1310435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1311435a35e8SMatthew G Knepley 
1312435a35e8SMatthew G Knepley   Not collective
1313435a35e8SMatthew G Knepley 
1314435a35e8SMatthew G Knepley   Input Parameters:
1315435a35e8SMatthew G Knepley + dm - the DM object
1316435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
13170298fd71SBarry Smith - len       - The number of subproblems in the decomposition (or NULL if not requested)
1318435a35e8SMatthew G Knepley 
1319435a35e8SMatthew G Knepley   Output Parameters:
1320435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1321435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1322435a35e8SMatthew G Knepley 
1323435a35e8SMatthew G Knepley   Level: intermediate
1324435a35e8SMatthew G Knepley 
1325435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1326435a35e8SMatthew G Knepley @*/
1327435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1328435a35e8SMatthew G Knepley {
1329435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1330435a35e8SMatthew G Knepley 
1331435a35e8SMatthew G Knepley   PetscFunctionBegin;
1332435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1333435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
13348865f1eaSKarl Rupp   if (is) PetscValidPointer(is,4);
13358865f1eaSKarl Rupp   if (subdm) PetscValidPointer(subdm,5);
1336435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1337435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
133882f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1339435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1340435a35e8SMatthew G Knepley }
1341435a35e8SMatthew G Knepley 
134216621825SDmitry Karpeev 
134316621825SDmitry Karpeev #undef __FUNCT__
134416621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
134516621825SDmitry Karpeev /*@C
13468d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
13478d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
13488d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
13498d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
13508d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
135116621825SDmitry Karpeev 
135216621825SDmitry Karpeev   Not collective
135316621825SDmitry Karpeev 
135416621825SDmitry Karpeev   Input Parameter:
135516621825SDmitry Karpeev . dm - the DM object
135616621825SDmitry Karpeev 
135716621825SDmitry Karpeev   Output Parameters:
13580298fd71SBarry Smith + len         - The number of subproblems in the domain decomposition (or NULL if not requested)
13590298fd71SBarry Smith . namelist    - The name for each subdomain (or NULL if not requested)
13600298fd71SBarry Smith . innerislist - The global indices for each inner subdomain (or NULL, if not requested)
13610298fd71SBarry Smith . outerislist - The global indices for each outer subdomain (or NULL, if not requested)
13620298fd71SBarry Smith - dmlist      - The DMs for each subdomain subproblem (or NULL, if not requested; if NULL is returned, no DMs are defined)
136316621825SDmitry Karpeev 
136416621825SDmitry Karpeev   Level: intermediate
136516621825SDmitry Karpeev 
136616621825SDmitry Karpeev   Notes:
136716621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
136816621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
136916621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
137016621825SDmitry Karpeev 
13718d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
137216621825SDmitry Karpeev @*/
13738d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
137416621825SDmitry Karpeev {
137516621825SDmitry Karpeev   PetscErrorCode      ierr;
1376be081cd6SPeter Brune   DMSubDomainHookLink link;
1377be081cd6SPeter Brune   PetscInt            i,l;
137816621825SDmitry Karpeev 
137916621825SDmitry Karpeev   PetscFunctionBegin;
138016621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
138114a18fd3SPeter Brune   if (len)           {PetscValidPointer(len,2);            *len         = 0;}
13820298fd71SBarry Smith   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = NULL;}
13830298fd71SBarry Smith   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = NULL;}
13840298fd71SBarry Smith   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = NULL;}
13850298fd71SBarry Smith   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = NULL;}
1386f3f0edfdSDmitry Karpeev   /*
1387f3f0edfdSDmitry Karpeev    Is it a good idea to apply the following check across all impls?
1388f3f0edfdSDmitry Karpeev    Perhaps some impls can have a well-defined decomposition before DMSetUp?
1389f3f0edfdSDmitry Karpeev    This, however, follows the general principle that accessors are not well-behaved until the object is set up.
1390f3f0edfdSDmitry Karpeev    */
1391ce94432eSBarry Smith   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE, "Decomposition defined only after DMSetUp");
139216621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
1393be081cd6SPeter Brune     ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist);CHKERRQ(ierr);
139414a18fd3SPeter Brune     /* copy subdomain hooks and context over to the subdomain DMs */
139514a18fd3SPeter Brune     if (dmlist) {
1396be081cd6SPeter Brune       for (i = 0; i < l; i++) {
1397be081cd6SPeter Brune         for (link=dm->subdomainhook; link; link=link->next) {
1398be081cd6SPeter Brune           if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);}
1399be081cd6SPeter Brune         }
1400d425c654SPeter Brune         (*dmlist)[i]->ctx = dm->ctx;
1401e7c4fc90SDmitry Karpeev       }
140214a18fd3SPeter Brune     }
140314a18fd3SPeter Brune     if (len) *len = l;
140414a18fd3SPeter Brune   }
1405e30e807fSPeter Brune   PetscFunctionReturn(0);
1406e30e807fSPeter Brune }
1407e30e807fSPeter Brune 
1408e30e807fSPeter Brune 
1409e30e807fSPeter Brune #undef __FUNCT__
1410e30e807fSPeter Brune #define __FUNCT__ "DMCreateDomainDecompositionScatters"
1411e30e807fSPeter Brune /*@C
1412e30e807fSPeter Brune   DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector
1413e30e807fSPeter Brune 
1414e30e807fSPeter Brune   Not collective
1415e30e807fSPeter Brune 
1416e30e807fSPeter Brune   Input Parameters:
1417e30e807fSPeter Brune + dm - the DM object
1418e30e807fSPeter Brune . n  - the number of subdomain scatters
1419e30e807fSPeter Brune - subdms - the local subdomains
1420e30e807fSPeter Brune 
1421e30e807fSPeter Brune   Output Parameters:
1422e30e807fSPeter Brune + n     - the number of scatters returned
1423e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain
1424e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain
1425e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts)
1426e30e807fSPeter Brune 
1427e30e807fSPeter Brune   Notes: This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution
1428e30e807fSPeter Brune   of general nonlinear problems with overlapping subdomain methods.  While merely having index sets that enable subsets
1429e30e807fSPeter Brune   of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of
1430e30e807fSPeter Brune   solution and residual data.
1431e30e807fSPeter Brune 
1432e30e807fSPeter Brune   Level: developer
1433e30e807fSPeter Brune 
1434e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1435e30e807fSPeter Brune @*/
1436e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat)
1437e30e807fSPeter Brune {
1438e30e807fSPeter Brune   PetscErrorCode ierr;
1439e30e807fSPeter Brune 
1440e30e807fSPeter Brune   PetscFunctionBegin;
1441e30e807fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1442e30e807fSPeter Brune   PetscValidPointer(subdms,3);
1443e30e807fSPeter Brune   if (dm->ops->createddscatters) {
1444e30e807fSPeter Brune     ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat);CHKERRQ(ierr);
144582f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "This type has no DMCreateDomainDecompositionLocalScatter implementation defined");
1446e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1447e7c4fc90SDmitry Karpeev }
1448e7c4fc90SDmitry Karpeev 
1449731c8d9eSDmitry Karpeev #undef __FUNCT__
145047c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
145147c6ae99SBarry Smith /*@
145247c6ae99SBarry Smith   DMRefine - Refines a DM object
145347c6ae99SBarry Smith 
145447c6ae99SBarry Smith   Collective on DM
145547c6ae99SBarry Smith 
145647c6ae99SBarry Smith   Input Parameter:
145747c6ae99SBarry Smith + dm   - the DM object
145891d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
145947c6ae99SBarry Smith 
146047c6ae99SBarry Smith   Output Parameter:
14610298fd71SBarry Smith . dmf - the refined DM, or NULL
1462ae0a1c52SMatthew G Knepley 
14630298fd71SBarry Smith   Note: If no refinement was done, the return value is NULL
146447c6ae99SBarry Smith 
146547c6ae99SBarry Smith   Level: developer
146647c6ae99SBarry Smith 
1467e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
146847c6ae99SBarry Smith @*/
14697087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
147047c6ae99SBarry Smith {
147147c6ae99SBarry Smith   PetscErrorCode   ierr;
1472c833c3b5SJed Brown   DMRefineHookLink link;
147347c6ae99SBarry Smith 
147447c6ae99SBarry Smith   PetscFunctionBegin;
1475732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
147647c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
14774057135bSMatthew G Knepley   if (*dmf) {
147843842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
14798865f1eaSKarl Rupp 
14808cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
14818865f1eaSKarl Rupp 
1482644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
14830598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1484656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
14858865f1eaSKarl Rupp 
1486e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1487c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
14888865f1eaSKarl Rupp       if (link->refinehook) {
14898865f1eaSKarl Rupp         ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);
14908865f1eaSKarl Rupp       }
1491c833c3b5SJed Brown     }
1492c833c3b5SJed Brown   }
1493c833c3b5SJed Brown   PetscFunctionReturn(0);
1494c833c3b5SJed Brown }
1495c833c3b5SJed Brown 
1496c833c3b5SJed Brown #undef __FUNCT__
1497c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1498bb9467b5SJed Brown /*@C
1499c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1500c833c3b5SJed Brown 
1501c833c3b5SJed Brown    Logically Collective
1502c833c3b5SJed Brown 
1503c833c3b5SJed Brown    Input Arguments:
1504c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1505c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1506c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
15070298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1508c833c3b5SJed Brown 
1509c833c3b5SJed Brown    Calling sequence of refinehook:
1510c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1511c833c3b5SJed Brown 
1512c833c3b5SJed Brown +  coarse - coarse level DM
1513c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1514c833c3b5SJed Brown -  ctx - optional user-defined function context
1515c833c3b5SJed Brown 
1516c833c3b5SJed Brown    Calling sequence for interphook:
1517c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1518c833c3b5SJed Brown 
1519c833c3b5SJed Brown +  coarse - coarse level DM
1520c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1521c833c3b5SJed Brown .  fine - fine level DM to update
1522c833c3b5SJed Brown -  ctx - optional user-defined function context
1523c833c3b5SJed Brown 
1524c833c3b5SJed Brown    Level: advanced
1525c833c3b5SJed Brown 
1526c833c3b5SJed Brown    Notes:
1527c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1528c833c3b5SJed Brown 
1529c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1530c833c3b5SJed Brown 
1531bb9467b5SJed Brown    This function is currently not available from Fortran.
1532bb9467b5SJed Brown 
1533c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1534c833c3b5SJed Brown @*/
1535c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1536c833c3b5SJed Brown {
1537c833c3b5SJed Brown   PetscErrorCode   ierr;
1538c833c3b5SJed Brown   DMRefineHookLink link,*p;
1539c833c3b5SJed Brown 
1540c833c3b5SJed Brown   PetscFunctionBegin;
1541c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1542c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1543c833c3b5SJed Brown   ierr             = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1544c833c3b5SJed Brown   link->refinehook = refinehook;
1545c833c3b5SJed Brown   link->interphook = interphook;
1546c833c3b5SJed Brown   link->ctx        = ctx;
15470298fd71SBarry Smith   link->next       = NULL;
1548c833c3b5SJed Brown   *p               = link;
1549c833c3b5SJed Brown   PetscFunctionReturn(0);
1550c833c3b5SJed Brown }
1551c833c3b5SJed Brown 
1552c833c3b5SJed Brown #undef __FUNCT__
1553c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1554c833c3b5SJed Brown /*@
1555c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1556c833c3b5SJed Brown 
1557c833c3b5SJed Brown    Collective if any hooks are
1558c833c3b5SJed Brown 
1559c833c3b5SJed Brown    Input Arguments:
1560c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1561c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1562c833c3b5SJed Brown -  fine - finer DM to update
1563c833c3b5SJed Brown 
1564c833c3b5SJed Brown    Level: developer
1565c833c3b5SJed Brown 
1566c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1567c833c3b5SJed Brown @*/
1568c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1569c833c3b5SJed Brown {
1570c833c3b5SJed Brown   PetscErrorCode   ierr;
1571c833c3b5SJed Brown   DMRefineHookLink link;
1572c833c3b5SJed Brown 
1573c833c3b5SJed Brown   PetscFunctionBegin;
1574c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
15758865f1eaSKarl Rupp     if (link->interphook) {
15768865f1eaSKarl Rupp       ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);
15778865f1eaSKarl Rupp     }
15784057135bSMatthew G Knepley   }
157947c6ae99SBarry Smith   PetscFunctionReturn(0);
158047c6ae99SBarry Smith }
158147c6ae99SBarry Smith 
158247c6ae99SBarry Smith #undef __FUNCT__
1583eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1584eb3f98d2SBarry Smith /*@
1585eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1586eb3f98d2SBarry Smith 
1587eb3f98d2SBarry Smith     Not Collective
1588eb3f98d2SBarry Smith 
1589eb3f98d2SBarry Smith     Input Parameter:
1590eb3f98d2SBarry Smith .   dm - the DM object
1591eb3f98d2SBarry Smith 
1592eb3f98d2SBarry Smith     Output Parameter:
1593eb3f98d2SBarry Smith .   level - number of refinements
1594eb3f98d2SBarry Smith 
1595eb3f98d2SBarry Smith     Level: developer
1596eb3f98d2SBarry Smith 
15976a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1598eb3f98d2SBarry Smith 
1599eb3f98d2SBarry Smith @*/
1600eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1601eb3f98d2SBarry Smith {
1602eb3f98d2SBarry Smith   PetscFunctionBegin;
1603eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1604eb3f98d2SBarry Smith   *level = dm->levelup;
1605eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1606eb3f98d2SBarry Smith }
1607eb3f98d2SBarry Smith 
1608eb3f98d2SBarry Smith #undef __FUNCT__
1609baf369e7SPeter Brune #define __FUNCT__ "DMGlobalToLocalHookAdd"
1610bb9467b5SJed Brown /*@C
1611baf369e7SPeter Brune    DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called
1612baf369e7SPeter Brune 
1613baf369e7SPeter Brune    Logically Collective
1614baf369e7SPeter Brune 
1615baf369e7SPeter Brune    Input Arguments:
1616baf369e7SPeter Brune +  dm - the DM
1617baf369e7SPeter Brune .  beginhook - function to run at the beginning of DMGlobalToLocalBegin()
1618baf369e7SPeter Brune .  endhook - function to run after DMGlobalToLocalEnd() has completed
16190298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1620baf369e7SPeter Brune 
1621baf369e7SPeter Brune    Calling sequence for beginhook:
1622baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1623baf369e7SPeter Brune 
1624baf369e7SPeter Brune +  dm - global DM
1625baf369e7SPeter Brune .  g - global vector
1626baf369e7SPeter Brune .  mode - mode
1627baf369e7SPeter Brune .  l - local vector
1628baf369e7SPeter Brune -  ctx - optional user-defined function context
1629baf369e7SPeter Brune 
1630baf369e7SPeter Brune 
1631baf369e7SPeter Brune    Calling sequence for endhook:
1632ec4806b8SPeter Brune $    endhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1633baf369e7SPeter Brune 
1634baf369e7SPeter Brune +  global - global DM
1635baf369e7SPeter Brune -  ctx - optional user-defined function context
1636baf369e7SPeter Brune 
1637baf369e7SPeter Brune    Level: advanced
1638baf369e7SPeter Brune 
1639baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1640baf369e7SPeter Brune @*/
1641baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
1642baf369e7SPeter Brune {
1643baf369e7SPeter Brune   PetscErrorCode          ierr;
1644baf369e7SPeter Brune   DMGlobalToLocalHookLink link,*p;
1645baf369e7SPeter Brune 
1646baf369e7SPeter Brune   PetscFunctionBegin;
1647baf369e7SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1648baf369e7SPeter Brune   for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1649baf369e7SPeter Brune   ierr            = PetscMalloc(sizeof(struct _DMGlobalToLocalHookLink),&link);CHKERRQ(ierr);
1650baf369e7SPeter Brune   link->beginhook = beginhook;
1651baf369e7SPeter Brune   link->endhook   = endhook;
1652baf369e7SPeter Brune   link->ctx       = ctx;
16530298fd71SBarry Smith   link->next      = NULL;
1654baf369e7SPeter Brune   *p              = link;
1655baf369e7SPeter Brune   PetscFunctionReturn(0);
1656baf369e7SPeter Brune }
1657baf369e7SPeter Brune 
1658baf369e7SPeter Brune #undef __FUNCT__
165947c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
166047c6ae99SBarry Smith /*@
166147c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
166247c6ae99SBarry Smith 
166347c6ae99SBarry Smith     Neighbor-wise Collective on DM
166447c6ae99SBarry Smith 
166547c6ae99SBarry Smith     Input Parameters:
166647c6ae99SBarry Smith +   dm - the DM object
166747c6ae99SBarry Smith .   g - the global vector
166847c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
166947c6ae99SBarry Smith -   l - the local vector
167047c6ae99SBarry Smith 
167147c6ae99SBarry Smith 
167247c6ae99SBarry Smith     Level: beginner
167347c6ae99SBarry Smith 
1674e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
167547c6ae99SBarry Smith 
167647c6ae99SBarry Smith @*/
16777087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
167847c6ae99SBarry Smith {
16797128ae9fSMatthew G Knepley   PetscSF                 sf;
168047c6ae99SBarry Smith   PetscErrorCode          ierr;
1681baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
168247c6ae99SBarry Smith 
168347c6ae99SBarry Smith   PetscFunctionBegin;
1684171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1685baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
16868865f1eaSKarl Rupp     if (link->beginhook) {
16878865f1eaSKarl Rupp       ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);
16888865f1eaSKarl Rupp     }
1689baf369e7SPeter Brune   }
16907128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
16917128ae9fSMatthew G Knepley   if (sf) {
16927128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
16937128ae9fSMatthew G Knepley 
169482f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
16957128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
16967128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
16977128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
16987128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
16997128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
17007128ae9fSMatthew G Knepley   } else {
1701843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
17027128ae9fSMatthew G Knepley   }
170347c6ae99SBarry Smith   PetscFunctionReturn(0);
170447c6ae99SBarry Smith }
170547c6ae99SBarry Smith 
170647c6ae99SBarry Smith #undef __FUNCT__
170747c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
170847c6ae99SBarry Smith /*@
170947c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
171047c6ae99SBarry Smith 
171147c6ae99SBarry Smith     Neighbor-wise Collective on DM
171247c6ae99SBarry Smith 
171347c6ae99SBarry Smith     Input Parameters:
171447c6ae99SBarry Smith +   dm - the DM object
171547c6ae99SBarry Smith .   g - the global vector
171647c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
171747c6ae99SBarry Smith -   l - the local vector
171847c6ae99SBarry Smith 
171947c6ae99SBarry Smith 
172047c6ae99SBarry Smith     Level: beginner
172147c6ae99SBarry Smith 
1722e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
172347c6ae99SBarry Smith 
172447c6ae99SBarry Smith @*/
17257087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
172647c6ae99SBarry Smith {
17277128ae9fSMatthew G Knepley   PetscSF                 sf;
172847c6ae99SBarry Smith   PetscErrorCode          ierr;
172961a3c1faSSatish Balay   PetscScalar             *lArray, *gArray;
1730baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
173147c6ae99SBarry Smith 
173247c6ae99SBarry Smith   PetscFunctionBegin;
1733171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17347128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17357128ae9fSMatthew G Knepley   if (sf) {
173682f516ccSBarry Smith     if (mode == ADD_VALUES) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17377128ae9fSMatthew G Knepley 
17387128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
17397128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
17407128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
17417128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
17427128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
17437128ae9fSMatthew G Knepley   } else {
1744843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
17457128ae9fSMatthew G Knepley   }
1746baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
1747baf369e7SPeter Brune     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
1748baf369e7SPeter Brune   }
174947c6ae99SBarry Smith   PetscFunctionReturn(0);
175047c6ae99SBarry Smith }
175147c6ae99SBarry Smith 
175247c6ae99SBarry Smith #undef __FUNCT__
17539a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
175447c6ae99SBarry Smith /*@
17559a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
17569a42bb27SBarry Smith 
17579a42bb27SBarry Smith     Neighbor-wise Collective on DM
17589a42bb27SBarry Smith 
17599a42bb27SBarry Smith     Input Parameters:
17609a42bb27SBarry Smith +   dm - the DM object
1761f6813fd5SJed Brown .   l - the local vector
17629a42bb27SBarry 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
17639a42bb27SBarry Smith            base point.
1764f6813fd5SJed Brown - - the global vector
17659a42bb27SBarry Smith 
17669a42bb27SBarry Smith     Notes: In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. If you would like to simply add the non-ghosted values in the local
17679a42bb27SBarry Smith            array into the global array you need to either (1) zero the ghosted locations and use ADD_VALUES or (2) use INSERT_VALUES into a work global array and then add the work
17689a42bb27SBarry Smith            global array to the final global array with VecAXPY().
17699a42bb27SBarry Smith 
17709a42bb27SBarry Smith     Level: beginner
17719a42bb27SBarry Smith 
1772e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
17739a42bb27SBarry Smith 
17749a42bb27SBarry Smith @*/
17757087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
17769a42bb27SBarry Smith {
17777128ae9fSMatthew G Knepley   PetscSF        sf;
17789a42bb27SBarry Smith   PetscErrorCode ierr;
17799a42bb27SBarry Smith 
17809a42bb27SBarry Smith   PetscFunctionBegin;
1781171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17827128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17837128ae9fSMatthew G Knepley   if (sf) {
17847128ae9fSMatthew G Knepley     MPI_Op      op;
17857128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
17867128ae9fSMatthew G Knepley 
17877128ae9fSMatthew G Knepley     switch (mode) {
17887128ae9fSMatthew G Knepley     case INSERT_VALUES:
17897128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
17908bfbc91cSJed Brown       op = MPIU_REPLACE; break;
17917128ae9fSMatthew G Knepley     case ADD_VALUES:
17927128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
17937128ae9fSMatthew G Knepley       op = MPI_SUM; break;
17947128ae9fSMatthew G Knepley     default:
179582f516ccSBarry Smith       SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17967128ae9fSMatthew G Knepley     }
17977128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
17987128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
17997128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
18007128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
18017128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
18027128ae9fSMatthew G Knepley   } else {
1803843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
18047128ae9fSMatthew G Knepley   }
18059a42bb27SBarry Smith   PetscFunctionReturn(0);
18069a42bb27SBarry Smith }
18079a42bb27SBarry Smith 
18089a42bb27SBarry Smith #undef __FUNCT__
18099a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
18109a42bb27SBarry Smith /*@
18119a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
181247c6ae99SBarry Smith 
181347c6ae99SBarry Smith     Neighbor-wise Collective on DM
181447c6ae99SBarry Smith 
181547c6ae99SBarry Smith     Input Parameters:
181647c6ae99SBarry Smith +   dm - the DM object
1817f6813fd5SJed Brown .   l - the local vector
181847c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1819f6813fd5SJed Brown -   g - the global vector
182047c6ae99SBarry Smith 
182147c6ae99SBarry Smith 
182247c6ae99SBarry Smith     Level: beginner
182347c6ae99SBarry Smith 
1824e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
182547c6ae99SBarry Smith 
182647c6ae99SBarry Smith @*/
18277087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
182847c6ae99SBarry Smith {
18297128ae9fSMatthew G Knepley   PetscSF        sf;
183047c6ae99SBarry Smith   PetscErrorCode ierr;
183147c6ae99SBarry Smith 
183247c6ae99SBarry Smith   PetscFunctionBegin;
1833171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18347128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
18357128ae9fSMatthew G Knepley   if (sf) {
18367128ae9fSMatthew G Knepley     MPI_Op      op;
18377128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
18387128ae9fSMatthew G Knepley 
18397128ae9fSMatthew G Knepley     switch (mode) {
18407128ae9fSMatthew G Knepley     case INSERT_VALUES:
18417128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
18428bfbc91cSJed Brown       op = MPIU_REPLACE; break;
18437128ae9fSMatthew G Knepley     case ADD_VALUES:
18447128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
18457128ae9fSMatthew G Knepley       op = MPI_SUM; break;
18467128ae9fSMatthew G Knepley     default:
184782f516ccSBarry Smith       SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
18487128ae9fSMatthew G Knepley     }
18497128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
18507128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
18517128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
18527128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
18537128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
18547128ae9fSMatthew G Knepley   } else {
1855843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
18567128ae9fSMatthew G Knepley   }
185747c6ae99SBarry Smith   PetscFunctionReturn(0);
185847c6ae99SBarry Smith }
185947c6ae99SBarry Smith 
186047c6ae99SBarry Smith #undef __FUNCT__
1861f089877aSRichard Tran Mills #define __FUNCT__ "DMLocalToLocalBegin"
1862f089877aSRichard Tran Mills /*@
1863bc0a1609SRichard Tran Mills    DMLocalToLocalBegin - Maps from a local vector (including ghost points
1864bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
1865d78e899eSRichard Tran Mills    points in the second are set correctly. Must be followed by DMLocalToLocalEnd().
1866f089877aSRichard Tran Mills 
1867bc0a1609SRichard Tran Mills    Neighbor-wise Collective on DM and Vec
1868f089877aSRichard Tran Mills 
1869f089877aSRichard Tran Mills    Input Parameters:
1870f089877aSRichard Tran Mills +  dm - the DM object
1871bc0a1609SRichard Tran Mills .  g - the original local vector
1872bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
1873f089877aSRichard Tran Mills 
1874bc0a1609SRichard Tran Mills    Output Parameter:
1875bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
1876f089877aSRichard Tran Mills 
1877f089877aSRichard Tran Mills    Level: intermediate
1878f089877aSRichard Tran Mills 
1879bc0a1609SRichard Tran Mills    Notes:
1880bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
1881bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
1882bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
1883bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
1884bc0a1609SRichard Tran Mills 
1885bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, begin
1886bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalEnd(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
1887f089877aSRichard Tran Mills 
1888f089877aSRichard Tran Mills @*/
1889f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
1890f089877aSRichard Tran Mills {
1891f089877aSRichard Tran Mills   PetscErrorCode          ierr;
1892f089877aSRichard Tran Mills 
1893f089877aSRichard Tran Mills   PetscFunctionBegin;
1894f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1895f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
1896f089877aSRichard Tran Mills   PetscFunctionReturn(0);
1897f089877aSRichard Tran Mills }
1898f089877aSRichard Tran Mills 
1899f089877aSRichard Tran Mills #undef __FUNCT__
1900f089877aSRichard Tran Mills #define __FUNCT__ "DMLocalToLocalEnd"
1901f089877aSRichard Tran Mills /*@
1902bc0a1609SRichard Tran Mills    DMLocalToLocalEnd - Maps from a local vector (including ghost points
1903bc0a1609SRichard Tran Mills    that contain irrelevant values) to another local vector where the ghost
1904d78e899eSRichard Tran Mills    points in the second are set correctly. Must be preceded by DMLocalToLocalBegin().
1905f089877aSRichard Tran Mills 
1906bc0a1609SRichard Tran Mills    Neighbor-wise Collective on DM and Vec
1907f089877aSRichard Tran Mills 
1908f089877aSRichard Tran Mills    Input Parameters:
1909bc0a1609SRichard Tran Mills +  da - the DM object
1910bc0a1609SRichard Tran Mills .  g - the original local vector
1911bc0a1609SRichard Tran Mills -  mode - one of INSERT_VALUES or ADD_VALUES
1912f089877aSRichard Tran Mills 
1913bc0a1609SRichard Tran Mills    Output Parameter:
1914bc0a1609SRichard Tran Mills .  l  - the local vector with correct ghost values
1915f089877aSRichard Tran Mills 
1916f089877aSRichard Tran Mills    Level: intermediate
1917f089877aSRichard Tran Mills 
1918bc0a1609SRichard Tran Mills    Notes:
1919bc0a1609SRichard Tran Mills    The local vectors used here need not be the same as those
1920bc0a1609SRichard Tran Mills    obtained from DMCreateLocalVector(), BUT they
1921bc0a1609SRichard Tran Mills    must have the same parallel data layout; they could, for example, be
1922bc0a1609SRichard Tran Mills    obtained with VecDuplicate() from the DM originating vectors.
1923bc0a1609SRichard Tran Mills 
1924bc0a1609SRichard Tran Mills .keywords: DM, local-to-local, end
1925bc0a1609SRichard Tran Mills .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateLocalVector(), DMCreateGlobalVector(), DMCreateInterpolation(), DMLocalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
1926f089877aSRichard Tran Mills 
1927f089877aSRichard Tran Mills @*/
1928f089877aSRichard Tran Mills PetscErrorCode  DMLocalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
1929f089877aSRichard Tran Mills {
1930f089877aSRichard Tran Mills   PetscErrorCode          ierr;
1931f089877aSRichard Tran Mills 
1932f089877aSRichard Tran Mills   PetscFunctionBegin;
1933f089877aSRichard Tran Mills   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1934f089877aSRichard Tran Mills   ierr = (*dm->ops->localtolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
1935f089877aSRichard Tran Mills   PetscFunctionReturn(0);
1936f089877aSRichard Tran Mills }
1937f089877aSRichard Tran Mills 
1938f089877aSRichard Tran Mills 
1939f089877aSRichard Tran Mills #undef __FUNCT__
194047c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
194147c6ae99SBarry Smith /*@
194247c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
194347c6ae99SBarry Smith 
194447c6ae99SBarry Smith     Collective on DM
194547c6ae99SBarry Smith 
194647c6ae99SBarry Smith     Input Parameter:
194747c6ae99SBarry Smith +   dm - the DM object
194891d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
194947c6ae99SBarry Smith 
195047c6ae99SBarry Smith     Output Parameter:
195147c6ae99SBarry Smith .   dmc - the coarsened DM
195247c6ae99SBarry Smith 
195347c6ae99SBarry Smith     Level: developer
195447c6ae99SBarry Smith 
1955e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
195647c6ae99SBarry Smith 
195747c6ae99SBarry Smith @*/
19587087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
195947c6ae99SBarry Smith {
196047c6ae99SBarry Smith   PetscErrorCode    ierr;
1961b17ce1afSJed Brown   DMCoarsenHookLink link;
196247c6ae99SBarry Smith 
196347c6ae99SBarry Smith   PetscFunctionBegin;
1964171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
196547c6ae99SBarry Smith   ierr                      = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
196643842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
19678cd211a4SJed Brown   ierr                      = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1968644e2e5bSBarry Smith   (*dmc)->ctx               = dm->ctx;
19690598a293SJed Brown   (*dmc)->levelup           = dm->levelup;
1970656b349aSBarry Smith   (*dmc)->leveldown         = dm->leveldown + 1;
1971e4b4b23bSJed Brown   ierr                      = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
1972b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1973b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1974b17ce1afSJed Brown   }
1975b17ce1afSJed Brown   PetscFunctionReturn(0);
1976b17ce1afSJed Brown }
1977b17ce1afSJed Brown 
1978b17ce1afSJed Brown #undef __FUNCT__
1979b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1980bb9467b5SJed Brown /*@C
1981b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1982b17ce1afSJed Brown 
1983b17ce1afSJed Brown    Logically Collective
1984b17ce1afSJed Brown 
1985b17ce1afSJed Brown    Input Arguments:
1986b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1987b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1988b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
19890298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
1990b17ce1afSJed Brown 
1991b17ce1afSJed Brown    Calling sequence of coarsenhook:
1992b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1993b17ce1afSJed Brown 
1994b17ce1afSJed Brown +  fine - fine level DM
1995b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1996b17ce1afSJed Brown -  ctx - optional user-defined function context
1997b17ce1afSJed Brown 
1998b17ce1afSJed Brown    Calling sequence for restricthook:
1999c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
2000b17ce1afSJed Brown 
2001b17ce1afSJed Brown +  fine - fine level DM
2002b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
2003c833c3b5SJed Brown .  rscale - scaling vector for restriction
2004c833c3b5SJed Brown .  inject - matrix restricting by injection
2005b17ce1afSJed Brown .  coarse - coarse level DM to update
2006b17ce1afSJed Brown -  ctx - optional user-defined function context
2007b17ce1afSJed Brown 
2008b17ce1afSJed Brown    Level: advanced
2009b17ce1afSJed Brown 
2010b17ce1afSJed Brown    Notes:
2011b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
2012b17ce1afSJed Brown 
2013b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
2014b17ce1afSJed Brown 
2015b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2016b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
2017b17ce1afSJed Brown 
2018bb9467b5SJed Brown    This function is currently not available from Fortran.
2019bb9467b5SJed Brown 
2020c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
2021b17ce1afSJed Brown @*/
2022b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
2023b17ce1afSJed Brown {
2024b17ce1afSJed Brown   PetscErrorCode    ierr;
2025b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
2026b17ce1afSJed Brown 
2027b17ce1afSJed Brown   PetscFunctionBegin;
2028b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
20296bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
2030b17ce1afSJed Brown   ierr               = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
2031b17ce1afSJed Brown   link->coarsenhook  = coarsenhook;
2032b17ce1afSJed Brown   link->restricthook = restricthook;
2033b17ce1afSJed Brown   link->ctx          = ctx;
20340298fd71SBarry Smith   link->next         = NULL;
2035b17ce1afSJed Brown   *p                 = link;
2036b17ce1afSJed Brown   PetscFunctionReturn(0);
2037b17ce1afSJed Brown }
2038b17ce1afSJed Brown 
2039b17ce1afSJed Brown #undef __FUNCT__
2040b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
2041b17ce1afSJed Brown /*@
2042b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
2043b17ce1afSJed Brown 
2044b17ce1afSJed Brown    Collective if any hooks are
2045b17ce1afSJed Brown 
2046b17ce1afSJed Brown    Input Arguments:
2047b17ce1afSJed Brown +  fine - finer DM to use as a base
2048b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
2049b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
2050b17ce1afSJed Brown -  coarse - coarer DM to update
2051b17ce1afSJed Brown 
2052b17ce1afSJed Brown    Level: developer
2053b17ce1afSJed Brown 
2054b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
2055b17ce1afSJed Brown @*/
2056b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
2057b17ce1afSJed Brown {
2058b17ce1afSJed Brown   PetscErrorCode    ierr;
2059b17ce1afSJed Brown   DMCoarsenHookLink link;
2060b17ce1afSJed Brown 
2061b17ce1afSJed Brown   PetscFunctionBegin;
2062b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
20638865f1eaSKarl Rupp     if (link->restricthook) {
20648865f1eaSKarl Rupp       ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);
20658865f1eaSKarl Rupp     }
2066b17ce1afSJed Brown   }
206747c6ae99SBarry Smith   PetscFunctionReturn(0);
206847c6ae99SBarry Smith }
206947c6ae99SBarry Smith 
207047c6ae99SBarry Smith #undef __FUNCT__
2071be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainHookAdd"
2072bb9467b5SJed Brown /*@C
2073be081cd6SPeter Brune    DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid
20745dbd56e3SPeter Brune 
20755dbd56e3SPeter Brune    Logically Collective
20765dbd56e3SPeter Brune 
20775dbd56e3SPeter Brune    Input Arguments:
20785dbd56e3SPeter Brune +  global - global DM
2079ec4806b8SPeter Brune .  ddhook - function to run to pass data to the decomposition DM upon its creation
20805dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
20810298fd71SBarry Smith -  ctx - [optional] user-defined context for provide data for the hooks (may be NULL)
20825dbd56e3SPeter Brune 
2083ec4806b8SPeter Brune 
2084ec4806b8SPeter Brune    Calling sequence for ddhook:
2085ec4806b8SPeter Brune $    ddhook(DM global,DM block,void *ctx)
2086ec4806b8SPeter Brune 
2087ec4806b8SPeter Brune +  global - global DM
2088ec4806b8SPeter Brune .  block  - block DM
2089ec4806b8SPeter Brune -  ctx - optional user-defined function context
2090ec4806b8SPeter Brune 
20915dbd56e3SPeter Brune    Calling sequence for restricthook:
2092ec4806b8SPeter Brune $    restricthook(DM global,VecScatter out,VecScatter in,DM block,void *ctx)
20935dbd56e3SPeter Brune 
20945dbd56e3SPeter Brune +  global - global DM
20955dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
20965dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
2097ec4806b8SPeter Brune .  block  - block DM
20985dbd56e3SPeter Brune -  ctx - optional user-defined function context
20995dbd56e3SPeter Brune 
21005dbd56e3SPeter Brune    Level: advanced
21015dbd56e3SPeter Brune 
21025dbd56e3SPeter Brune    Notes:
2103ec4806b8SPeter Brune    This function is only needed if auxiliary data needs to be set up on subdomain DMs.
21045dbd56e3SPeter Brune 
21055dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
21065dbd56e3SPeter Brune 
21075dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
2108ec4806b8SPeter Brune    extract the global information from its context (instead of from the SNES).
21095dbd56e3SPeter Brune 
2110bb9467b5SJed Brown    This function is currently not available from Fortran.
2111bb9467b5SJed Brown 
21125dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
21135dbd56e3SPeter Brune @*/
2114be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
21155dbd56e3SPeter Brune {
21165dbd56e3SPeter Brune   PetscErrorCode      ierr;
2117be081cd6SPeter Brune   DMSubDomainHookLink link,*p;
21185dbd56e3SPeter Brune 
21195dbd56e3SPeter Brune   PetscFunctionBegin;
21205dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
2121be081cd6SPeter Brune   for (p=&global->subdomainhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
2122be081cd6SPeter Brune   ierr               = PetscMalloc(sizeof(struct _DMSubDomainHookLink),&link);CHKERRQ(ierr);
21235dbd56e3SPeter Brune   link->restricthook = restricthook;
2124be081cd6SPeter Brune   link->ddhook       = ddhook;
21255dbd56e3SPeter Brune   link->ctx          = ctx;
21260298fd71SBarry Smith   link->next         = NULL;
21275dbd56e3SPeter Brune   *p                 = link;
21285dbd56e3SPeter Brune   PetscFunctionReturn(0);
21295dbd56e3SPeter Brune }
21305dbd56e3SPeter Brune 
21315dbd56e3SPeter Brune #undef __FUNCT__
2132be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainRestrict"
21335dbd56e3SPeter Brune /*@
2134be081cd6SPeter Brune    DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd()
21355dbd56e3SPeter Brune 
21365dbd56e3SPeter Brune    Collective if any hooks are
21375dbd56e3SPeter Brune 
21385dbd56e3SPeter Brune    Input Arguments:
21395dbd56e3SPeter Brune +  fine - finer DM to use as a base
2140be081cd6SPeter Brune .  oscatter - scatter from domain global vector filling subdomain global vector with overlap
2141be081cd6SPeter Brune .  gscatter - scatter from domain global vector filling subdomain local vector with ghosts
21425dbd56e3SPeter Brune -  coarse - coarer DM to update
21435dbd56e3SPeter Brune 
21445dbd56e3SPeter Brune    Level: developer
21455dbd56e3SPeter Brune 
21465dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
21475dbd56e3SPeter Brune @*/
2148be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm)
21495dbd56e3SPeter Brune {
21505dbd56e3SPeter Brune   PetscErrorCode      ierr;
2151be081cd6SPeter Brune   DMSubDomainHookLink link;
21525dbd56e3SPeter Brune 
21535dbd56e3SPeter Brune   PetscFunctionBegin;
2154be081cd6SPeter Brune   for (link=global->subdomainhook; link; link=link->next) {
21558865f1eaSKarl Rupp     if (link->restricthook) {
21568865f1eaSKarl Rupp       ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr);
21578865f1eaSKarl Rupp     }
21585dbd56e3SPeter Brune   }
21595dbd56e3SPeter Brune   PetscFunctionReturn(0);
21605dbd56e3SPeter Brune }
21615dbd56e3SPeter Brune 
21625dbd56e3SPeter Brune #undef __FUNCT__
21635fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
21645fe1f584SPeter Brune /*@
21656a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
21665fe1f584SPeter Brune 
21675fe1f584SPeter Brune     Not Collective
21685fe1f584SPeter Brune 
21695fe1f584SPeter Brune     Input Parameter:
21705fe1f584SPeter Brune .   dm - the DM object
21715fe1f584SPeter Brune 
21725fe1f584SPeter Brune     Output Parameter:
21736a7d9d85SPeter Brune .   level - number of coarsenings
21745fe1f584SPeter Brune 
21755fe1f584SPeter Brune     Level: developer
21765fe1f584SPeter Brune 
21776a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
21785fe1f584SPeter Brune 
21795fe1f584SPeter Brune @*/
21805fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
21815fe1f584SPeter Brune {
21825fe1f584SPeter Brune   PetscFunctionBegin;
21835fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21845fe1f584SPeter Brune   *level = dm->leveldown;
21855fe1f584SPeter Brune   PetscFunctionReturn(0);
21865fe1f584SPeter Brune }
21875fe1f584SPeter Brune 
21885fe1f584SPeter Brune 
21895fe1f584SPeter Brune 
21905fe1f584SPeter Brune #undef __FUNCT__
219147c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
219247c6ae99SBarry Smith /*@C
219347c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
219447c6ae99SBarry Smith 
219547c6ae99SBarry Smith     Collective on DM
219647c6ae99SBarry Smith 
219747c6ae99SBarry Smith     Input Parameter:
219847c6ae99SBarry Smith +   dm - the DM object
219947c6ae99SBarry Smith -   nlevels - the number of levels of refinement
220047c6ae99SBarry Smith 
220147c6ae99SBarry Smith     Output Parameter:
220247c6ae99SBarry Smith .   dmf - the refined DM hierarchy
220347c6ae99SBarry Smith 
220447c6ae99SBarry Smith     Level: developer
220547c6ae99SBarry Smith 
2206e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
220747c6ae99SBarry Smith 
220847c6ae99SBarry Smith @*/
22097087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
221047c6ae99SBarry Smith {
221147c6ae99SBarry Smith   PetscErrorCode ierr;
221247c6ae99SBarry Smith 
221347c6ae99SBarry Smith   PetscFunctionBegin;
2214171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2215ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
221647c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
221747c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
221847c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
221947c6ae99SBarry Smith   } else if (dm->ops->refine) {
222047c6ae99SBarry Smith     PetscInt i;
222147c6ae99SBarry Smith 
2222ce94432eSBarry Smith     ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr);
222347c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
2224ce94432eSBarry Smith       ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr);
222547c6ae99SBarry Smith     }
2226ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
222747c6ae99SBarry Smith   PetscFunctionReturn(0);
222847c6ae99SBarry Smith }
222947c6ae99SBarry Smith 
223047c6ae99SBarry Smith #undef __FUNCT__
223147c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
223247c6ae99SBarry Smith /*@C
223347c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
223447c6ae99SBarry Smith 
223547c6ae99SBarry Smith     Collective on DM
223647c6ae99SBarry Smith 
223747c6ae99SBarry Smith     Input Parameter:
223847c6ae99SBarry Smith +   dm - the DM object
223947c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
224047c6ae99SBarry Smith 
224147c6ae99SBarry Smith     Output Parameter:
224247c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
224347c6ae99SBarry Smith 
224447c6ae99SBarry Smith     Level: developer
224547c6ae99SBarry Smith 
2246e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
224747c6ae99SBarry Smith 
224847c6ae99SBarry Smith @*/
22497087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
225047c6ae99SBarry Smith {
225147c6ae99SBarry Smith   PetscErrorCode ierr;
225247c6ae99SBarry Smith 
225347c6ae99SBarry Smith   PetscFunctionBegin;
2254171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2255ce94432eSBarry Smith   if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
225647c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
225747c6ae99SBarry Smith   PetscValidPointer(dmc,3);
225847c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
225947c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
226047c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
226147c6ae99SBarry Smith     PetscInt i;
226247c6ae99SBarry Smith 
2263ce94432eSBarry Smith     ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr);
226447c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
2265ce94432eSBarry Smith       ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr);
226647c6ae99SBarry Smith     }
2267ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
226847c6ae99SBarry Smith   PetscFunctionReturn(0);
226947c6ae99SBarry Smith }
227047c6ae99SBarry Smith 
227147c6ae99SBarry Smith #undef __FUNCT__
2272e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
227347c6ae99SBarry Smith /*@
2274e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
227547c6ae99SBarry Smith    grids associated with two DMs.
227647c6ae99SBarry Smith 
227747c6ae99SBarry Smith    Collective on DM
227847c6ae99SBarry Smith 
227947c6ae99SBarry Smith    Input Parameters:
228047c6ae99SBarry Smith +  dmc - the coarse grid DM
228147c6ae99SBarry Smith -  dmf - the fine grid DM
228247c6ae99SBarry Smith 
228347c6ae99SBarry Smith    Output Parameters:
228447c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
228547c6ae99SBarry Smith 
228647c6ae99SBarry Smith    Level: intermediate
228747c6ae99SBarry Smith 
228847c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
228947c6ae99SBarry Smith 
2290e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
229147c6ae99SBarry Smith @*/
2292e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
229347c6ae99SBarry Smith {
229447c6ae99SBarry Smith   PetscErrorCode ierr;
229547c6ae99SBarry Smith 
229647c6ae99SBarry Smith   PetscFunctionBegin;
2297171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
2298171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
229947c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
230047c6ae99SBarry Smith   PetscFunctionReturn(0);
230147c6ae99SBarry Smith }
230247c6ae99SBarry Smith 
230347c6ae99SBarry Smith #undef __FUNCT__
23041a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
23051a266240SBarry Smith /*@C
23061a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
23071a266240SBarry Smith 
23081a266240SBarry Smith     Not Collective
23091a266240SBarry Smith 
23101a266240SBarry Smith     Input Parameters:
23111a266240SBarry Smith +   dm - the DM object
23121a266240SBarry Smith -   destroy - the destroy function
23131a266240SBarry Smith 
23141a266240SBarry Smith     Level: intermediate
23151a266240SBarry Smith 
2316e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
23171a266240SBarry Smith 
2318f07f9ceaSJed Brown @*/
23191a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
23201a266240SBarry Smith {
23211a266240SBarry Smith   PetscFunctionBegin;
2322171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
23231a266240SBarry Smith   dm->ctxdestroy = destroy;
23241a266240SBarry Smith   PetscFunctionReturn(0);
23251a266240SBarry Smith }
23261a266240SBarry Smith 
23271a266240SBarry Smith #undef __FUNCT__
23281b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
2329b07ff414SBarry Smith /*@
23301b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
233147c6ae99SBarry Smith 
233247c6ae99SBarry Smith     Not Collective
233347c6ae99SBarry Smith 
233447c6ae99SBarry Smith     Input Parameters:
233547c6ae99SBarry Smith +   dm - the DM object
233647c6ae99SBarry Smith -   ctx - the user context
233747c6ae99SBarry Smith 
233847c6ae99SBarry Smith     Level: intermediate
233947c6ae99SBarry Smith 
2340e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
234147c6ae99SBarry Smith 
234247c6ae99SBarry Smith @*/
23431b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
234447c6ae99SBarry Smith {
234547c6ae99SBarry Smith   PetscFunctionBegin;
2346171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
234747c6ae99SBarry Smith   dm->ctx = ctx;
234847c6ae99SBarry Smith   PetscFunctionReturn(0);
234947c6ae99SBarry Smith }
235047c6ae99SBarry Smith 
235147c6ae99SBarry Smith #undef __FUNCT__
23521b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
235347c6ae99SBarry Smith /*@
23541b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
235547c6ae99SBarry Smith 
235647c6ae99SBarry Smith     Not Collective
235747c6ae99SBarry Smith 
235847c6ae99SBarry Smith     Input Parameter:
235947c6ae99SBarry Smith .   dm - the DM object
236047c6ae99SBarry Smith 
236147c6ae99SBarry Smith     Output Parameter:
236247c6ae99SBarry Smith .   ctx - the user context
236347c6ae99SBarry Smith 
236447c6ae99SBarry Smith     Level: intermediate
236547c6ae99SBarry Smith 
2366e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
236747c6ae99SBarry Smith 
236847c6ae99SBarry Smith @*/
23691b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
237047c6ae99SBarry Smith {
237147c6ae99SBarry Smith   PetscFunctionBegin;
2372171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
23731b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
237447c6ae99SBarry Smith   PetscFunctionReturn(0);
237547c6ae99SBarry Smith }
237647c6ae99SBarry Smith 
237747c6ae99SBarry Smith #undef __FUNCT__
237808da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
237908da532bSDmitry Karpeev /*@C
238008da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
238108da532bSDmitry Karpeev 
238208da532bSDmitry Karpeev     Logically Collective on DM
238308da532bSDmitry Karpeev 
238408da532bSDmitry Karpeev     Input Parameter:
238508da532bSDmitry Karpeev +   dm - the DM object
23860298fd71SBarry Smith -   f - the function that computes variable bounds used by SNESVI (use NULL to cancel a previous function that was set)
238708da532bSDmitry Karpeev 
238808da532bSDmitry Karpeev     Level: intermediate
238908da532bSDmitry Karpeev 
2390835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(),
239108da532bSDmitry Karpeev          DMSetJacobian()
239208da532bSDmitry Karpeev 
239308da532bSDmitry Karpeev @*/
239408da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
239508da532bSDmitry Karpeev {
239608da532bSDmitry Karpeev   PetscFunctionBegin;
239708da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
239808da532bSDmitry Karpeev   PetscFunctionReturn(0);
239908da532bSDmitry Karpeev }
240008da532bSDmitry Karpeev 
240108da532bSDmitry Karpeev #undef __FUNCT__
240208da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
240308da532bSDmitry Karpeev /*@
240408da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
240508da532bSDmitry Karpeev 
240608da532bSDmitry Karpeev     Not Collective
240708da532bSDmitry Karpeev 
240808da532bSDmitry Karpeev     Input Parameter:
240908da532bSDmitry Karpeev .   dm - the DM object to destroy
241008da532bSDmitry Karpeev 
241108da532bSDmitry Karpeev     Output Parameter:
241208da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
241308da532bSDmitry Karpeev 
241408da532bSDmitry Karpeev     Level: developer
241508da532bSDmitry Karpeev 
241674e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
241708da532bSDmitry Karpeev 
241808da532bSDmitry Karpeev @*/
241908da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
242008da532bSDmitry Karpeev {
242108da532bSDmitry Karpeev   PetscFunctionBegin;
242208da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
242308da532bSDmitry Karpeev   PetscFunctionReturn(0);
242408da532bSDmitry Karpeev }
242508da532bSDmitry Karpeev 
242608da532bSDmitry Karpeev #undef __FUNCT__
242708da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
242808da532bSDmitry Karpeev /*@C
242908da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
243008da532bSDmitry Karpeev 
243108da532bSDmitry Karpeev     Logically Collective on DM
243208da532bSDmitry Karpeev 
243308da532bSDmitry Karpeev     Input Parameters:
243408da532bSDmitry Karpeev +   dm - the DM object to destroy
243508da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
243608da532bSDmitry Karpeev 
243708da532bSDmitry Karpeev     Output parameters:
243808da532bSDmitry Karpeev +   xl - lower bound
243908da532bSDmitry Karpeev -   xu - upper bound
244008da532bSDmitry Karpeev 
244108da532bSDmitry Karpeev     Level: intermediate
244208da532bSDmitry Karpeev 
244374e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
244408da532bSDmitry Karpeev 
244508da532bSDmitry Karpeev @*/
244608da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
244708da532bSDmitry Karpeev {
244808da532bSDmitry Karpeev   PetscErrorCode ierr;
24495fd66863SKarl Rupp 
245008da532bSDmitry Karpeev   PetscFunctionBegin;
245108da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
245208da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
245308da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
245408da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu);CHKERRQ(ierr);
24558865f1eaSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
245608da532bSDmitry Karpeev   PetscFunctionReturn(0);
245708da532bSDmitry Karpeev }
245808da532bSDmitry Karpeev 
245908da532bSDmitry Karpeev #undef __FUNCT__
2460b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2461b0ae01b7SPeter Brune /*@
2462b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2463b0ae01b7SPeter Brune 
2464b0ae01b7SPeter Brune     Not Collective
2465b0ae01b7SPeter Brune 
2466b0ae01b7SPeter Brune     Input Parameter:
2467b0ae01b7SPeter Brune .   dm - the DM object
2468b0ae01b7SPeter Brune 
2469b0ae01b7SPeter Brune     Output Parameter:
2470b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2471b0ae01b7SPeter Brune 
2472b0ae01b7SPeter Brune     Level: developer
2473b0ae01b7SPeter Brune 
2474b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2475b0ae01b7SPeter Brune 
2476b0ae01b7SPeter Brune @*/
2477b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2478b0ae01b7SPeter Brune {
2479b0ae01b7SPeter Brune   PetscFunctionBegin;
2480b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2481b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2482b0ae01b7SPeter Brune }
2483b0ae01b7SPeter Brune 
2484b0ae01b7SPeter Brune #undef  __FUNCT__
248508da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2486748fac09SDmitry Karpeev /*@C
248708da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
248808da532bSDmitry Karpeev 
248908da532bSDmitry Karpeev     Collective on DM
249008da532bSDmitry Karpeev 
249108da532bSDmitry Karpeev     Input Parameter:
249208da532bSDmitry Karpeev +   dm - the DM object
24930298fd71SBarry Smith -   x - location to compute residual and Jacobian, if NULL is passed to those routines; will be NULL for linear problems.
249408da532bSDmitry Karpeev 
249508da532bSDmitry Karpeev     Level: developer
249608da532bSDmitry Karpeev 
249774e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
249808da532bSDmitry Karpeev 
249908da532bSDmitry Karpeev @*/
250008da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
250108da532bSDmitry Karpeev {
250208da532bSDmitry Karpeev   PetscErrorCode ierr;
25035fd66863SKarl Rupp 
250408da532bSDmitry Karpeev   PetscFunctionBegin;
250508da532bSDmitry Karpeev   if (x) {
250608da532bSDmitry Karpeev     if (!dm->x) {
250708da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
250808da532bSDmitry Karpeev     }
250908da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
25108865f1eaSKarl Rupp   } else if (dm->x) {
251108da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);CHKERRQ(ierr);
251208da532bSDmitry Karpeev   }
251308da532bSDmitry Karpeev   PetscFunctionReturn(0);
251408da532bSDmitry Karpeev }
251508da532bSDmitry Karpeev 
25160298fd71SBarry Smith PetscFunctionList DMList              = NULL;
2517264ace61SBarry Smith PetscBool         DMRegisterAllCalled = PETSC_FALSE;
2518264ace61SBarry Smith 
2519264ace61SBarry Smith #undef __FUNCT__
2520264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2521264ace61SBarry Smith /*@C
2522264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2523264ace61SBarry Smith 
2524264ace61SBarry Smith   Collective on DM
2525264ace61SBarry Smith 
2526264ace61SBarry Smith   Input Parameters:
2527264ace61SBarry Smith + dm     - The DM object
2528264ace61SBarry Smith - method - The name of the DM type
2529264ace61SBarry Smith 
2530264ace61SBarry Smith   Options Database Key:
2531264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2532264ace61SBarry Smith 
2533264ace61SBarry Smith   Notes:
2534e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2535264ace61SBarry Smith 
2536264ace61SBarry Smith   Level: intermediate
2537264ace61SBarry Smith 
2538264ace61SBarry Smith .keywords: DM, set, type
2539264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2540264ace61SBarry Smith @*/
254119fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
2542264ace61SBarry Smith {
2543264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2544264ace61SBarry Smith   PetscBool      match;
2545264ace61SBarry Smith   PetscErrorCode ierr;
2546264ace61SBarry Smith 
2547264ace61SBarry Smith   PetscFunctionBegin;
2548264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2549251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2550264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2551264ace61SBarry Smith 
2552607a6623SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll();CHKERRQ(ierr);}
25531c9cd337SJed Brown   ierr = PetscFunctionListFind(DMList,method,&r);CHKERRQ(ierr);
2554ce94432eSBarry Smith   if (!r) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2555264ace61SBarry Smith 
2556264ace61SBarry Smith   if (dm->ops->destroy) {
2557264ace61SBarry Smith     ierr             = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
25580298fd71SBarry Smith     dm->ops->destroy = NULL;
2559264ace61SBarry Smith   }
2560264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2561264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2562264ace61SBarry Smith   PetscFunctionReturn(0);
2563264ace61SBarry Smith }
2564264ace61SBarry Smith 
2565264ace61SBarry Smith #undef __FUNCT__
2566264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2567264ace61SBarry Smith /*@C
2568264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2569264ace61SBarry Smith 
2570264ace61SBarry Smith   Not Collective
2571264ace61SBarry Smith 
2572264ace61SBarry Smith   Input Parameter:
2573264ace61SBarry Smith . dm  - The DM
2574264ace61SBarry Smith 
2575264ace61SBarry Smith   Output Parameter:
2576264ace61SBarry Smith . type - The DM type name
2577264ace61SBarry Smith 
2578264ace61SBarry Smith   Level: intermediate
2579264ace61SBarry Smith 
2580264ace61SBarry Smith .keywords: DM, get, type, name
2581264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2582264ace61SBarry Smith @*/
258319fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
2584264ace61SBarry Smith {
2585264ace61SBarry Smith   PetscErrorCode ierr;
2586264ace61SBarry Smith 
2587264ace61SBarry Smith   PetscFunctionBegin;
2588264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2589264ace61SBarry Smith   PetscValidCharPointer(type,2);
2590264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2591607a6623SBarry Smith     ierr = DMRegisterAll();CHKERRQ(ierr);
2592264ace61SBarry Smith   }
2593264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2594264ace61SBarry Smith   PetscFunctionReturn(0);
2595264ace61SBarry Smith }
2596264ace61SBarry Smith 
259767a56275SMatthew G Knepley #undef __FUNCT__
259867a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
259967a56275SMatthew G Knepley /*@C
260067a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
260167a56275SMatthew G Knepley 
260267a56275SMatthew G Knepley   Collective on DM
260367a56275SMatthew G Knepley 
260467a56275SMatthew G Knepley   Input Parameters:
260567a56275SMatthew G Knepley + dm - the DM
260667a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
260767a56275SMatthew G Knepley 
260867a56275SMatthew G Knepley   Output Parameter:
260967a56275SMatthew G Knepley . M - pointer to new DM
261067a56275SMatthew G Knepley 
261167a56275SMatthew G Knepley   Notes:
261267a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
261367a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
261467a56275SMatthew G Knepley   of the input DM.
261567a56275SMatthew G Knepley 
261667a56275SMatthew G Knepley   Level: intermediate
261767a56275SMatthew G Knepley 
261867a56275SMatthew G Knepley .seealso: DMCreate()
261967a56275SMatthew G Knepley @*/
262019fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
262167a56275SMatthew G Knepley {
262267a56275SMatthew G Knepley   DM             B;
262367a56275SMatthew G Knepley   char           convname[256];
262467a56275SMatthew G Knepley   PetscBool      sametype, issame;
262567a56275SMatthew G Knepley   PetscErrorCode ierr;
262667a56275SMatthew G Knepley 
262767a56275SMatthew G Knepley   PetscFunctionBegin;
262867a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
262967a56275SMatthew G Knepley   PetscValidType(dm,1);
263067a56275SMatthew G Knepley   PetscValidPointer(M,3);
2631251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
263267a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
263367a56275SMatthew G Knepley   {
26340298fd71SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM*) = NULL;
263567a56275SMatthew G Knepley 
263667a56275SMatthew G Knepley     /*
263767a56275SMatthew G Knepley        Order of precedence:
263867a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
263967a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
264067a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
264167a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
264267a56275SMatthew G Knepley        5) Use a really basic converter.
264367a56275SMatthew G Knepley     */
264467a56275SMatthew G Knepley 
264567a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
264667a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
264767a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
264867a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
264967a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
265067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
26510005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,&conv);CHKERRQ(ierr);
265267a56275SMatthew G Knepley     if (conv) goto foundconv;
265367a56275SMatthew G Knepley 
265467a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
265582f516ccSBarry Smith     ierr = DMCreate(PetscObjectComm((PetscObject)dm), &B);CHKERRQ(ierr);
265667a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
265767a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
265867a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
265967a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
266067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
266167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
26620005d66cSJed Brown     ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
266367a56275SMatthew G Knepley     if (conv) {
2664fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
266567a56275SMatthew G Knepley       goto foundconv;
266667a56275SMatthew G Knepley     }
266767a56275SMatthew G Knepley 
266867a56275SMatthew G Knepley #if 0
266967a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
267067a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2671fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
267267a56275SMatthew G Knepley     if (conv) goto foundconv;
267367a56275SMatthew G Knepley 
267467a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
267567a56275SMatthew G Knepley     if (dm->ops->convert) {
267667a56275SMatthew G Knepley       conv = dm->ops->convert;
267767a56275SMatthew G Knepley     }
267867a56275SMatthew G Knepley     if (conv) goto foundconv;
267967a56275SMatthew G Knepley #endif
268067a56275SMatthew G Knepley 
268167a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
268282f516ccSBarry Smith     SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
268367a56275SMatthew G Knepley 
268467a56275SMatthew G Knepley foundconv:
268567a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
268667a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
268767a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
268867a56275SMatthew G Knepley   }
268967a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
269067a56275SMatthew G Knepley   PetscFunctionReturn(0);
269167a56275SMatthew G Knepley }
2692264ace61SBarry Smith 
2693264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2694264ace61SBarry Smith 
2695264ace61SBarry Smith #undef __FUNCT__
2696264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2697264ace61SBarry Smith /*@C
26981c84c290SBarry Smith   DMRegister -  Adds a new DM component implementation
26991c84c290SBarry Smith 
27001c84c290SBarry Smith   Not Collective
27011c84c290SBarry Smith 
27021c84c290SBarry Smith   Input Parameters:
27031c84c290SBarry Smith + name        - The name of a new user-defined creation routine
27041c84c290SBarry Smith - create_func - The creation routine itself
27051c84c290SBarry Smith 
27061c84c290SBarry Smith   Notes:
27071c84c290SBarry Smith   DMRegister() may be called multiple times to add several user-defined DMs
27081c84c290SBarry Smith 
27091c84c290SBarry Smith 
27101c84c290SBarry Smith   Sample usage:
27111c84c290SBarry Smith .vb
2712bdf89e91SBarry Smith     DMRegister("my_da", MyDMCreate);
27131c84c290SBarry Smith .ve
27141c84c290SBarry Smith 
27151c84c290SBarry Smith   Then, your DM type can be chosen with the procedural interface via
27161c84c290SBarry Smith .vb
27171c84c290SBarry Smith     DMCreate(MPI_Comm, DM *);
27181c84c290SBarry Smith     DMSetType(DM,"my_da");
27191c84c290SBarry Smith .ve
27201c84c290SBarry Smith    or at runtime via the option
27211c84c290SBarry Smith .vb
27221c84c290SBarry Smith     -da_type my_da
27231c84c290SBarry Smith .ve
2724264ace61SBarry Smith 
2725264ace61SBarry Smith   Level: advanced
27261c84c290SBarry Smith 
27271c84c290SBarry Smith .keywords: DM, register
2728bdf89e91SBarry Smith .seealso: DMRegisterAll(), DMRegisterDestroy()
27291c84c290SBarry Smith 
2730264ace61SBarry Smith @*/
2731bdf89e91SBarry Smith PetscErrorCode  DMRegister(const char sname[],PetscErrorCode (*function)(DM))
2732264ace61SBarry Smith {
2733264ace61SBarry Smith   PetscErrorCode ierr;
2734264ace61SBarry Smith 
2735264ace61SBarry Smith   PetscFunctionBegin;
2736a240a19fSJed Brown   ierr = PetscFunctionListAdd(&DMList,sname,function);CHKERRQ(ierr);
2737264ace61SBarry Smith   PetscFunctionReturn(0);
2738264ace61SBarry Smith }
2739264ace61SBarry Smith 
2740b859378eSBarry Smith #undef __FUNCT__
2741b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2742b859378eSBarry Smith /*@C
274355849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
2744b859378eSBarry Smith 
2745b859378eSBarry Smith   Collective on PetscViewer
2746b859378eSBarry Smith 
2747b859378eSBarry Smith   Input Parameters:
2748b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2749b859378eSBarry Smith            some related function before a call to DMLoad().
2750b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2751b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2752b859378eSBarry Smith 
2753b859378eSBarry Smith    Level: intermediate
2754b859378eSBarry Smith 
2755b859378eSBarry Smith   Notes:
275655849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
2757b859378eSBarry Smith 
2758b859378eSBarry Smith   Notes for advanced users:
2759b859378eSBarry Smith   Most users should not need to know the details of the binary storage
2760b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
2761b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
2762b859378eSBarry Smith   format is
2763b859378eSBarry Smith .vb
2764b859378eSBarry Smith      has not yet been determined
2765b859378eSBarry Smith .ve
2766b859378eSBarry Smith 
2767b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2768b859378eSBarry Smith @*/
2769b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2770b859378eSBarry Smith {
27719331c7a4SMatthew G. Knepley   PetscBool      isbinary, ishdf5;
2772b859378eSBarry Smith   PetscErrorCode ierr;
2773b859378eSBarry Smith 
2774b859378eSBarry Smith   PetscFunctionBegin;
2775b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2776b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
277732c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
27789331c7a4SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
27799331c7a4SMatthew G. Knepley   if (isbinary) {
27809331c7a4SMatthew G. Knepley     PetscInt classid;
27819331c7a4SMatthew G. Knepley     char     type[256];
2782b859378eSBarry Smith 
278332c0f0efSBarry Smith     ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
27849200755eSBarry Smith     if (classid != DM_FILE_CLASSID) SETERRQ1(PetscObjectComm((PetscObject)newdm),PETSC_ERR_ARG_WRONG,"Not DM next in file, classid found %d",(int)classid);
278532c0f0efSBarry Smith     ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
278632c0f0efSBarry Smith     ierr = DMSetType(newdm, type);CHKERRQ(ierr);
27879331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
27889331c7a4SMatthew G. Knepley   } else if (ishdf5) {
27899331c7a4SMatthew G. Knepley     if (newdm->ops->load) {ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);}
27909331c7a4SMatthew G. Knepley   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen() or PetscViewerHDF5Open()");
2791b859378eSBarry Smith   PetscFunctionReturn(0);
2792b859378eSBarry Smith }
2793b859378eSBarry Smith 
27947da65231SMatthew G Knepley /******************************** FEM Support **********************************/
27957da65231SMatthew G Knepley 
27967da65231SMatthew G Knepley #undef __FUNCT__
27977da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
2798a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[])
2799a6dfd86eSKarl Rupp {
28001d47ebbbSSatish Balay   PetscInt       f;
28011b30c384SMatthew G Knepley   PetscErrorCode ierr;
28021b30c384SMatthew G Knepley 
28037da65231SMatthew G Knepley   PetscFunctionBegin;
280474778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
28051d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
280657622a8eSBarry Smith     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %g |\n", (double)PetscRealPart(x[f]));CHKERRQ(ierr);
28077da65231SMatthew G Knepley   }
28087da65231SMatthew G Knepley   PetscFunctionReturn(0);
28097da65231SMatthew G Knepley }
28107da65231SMatthew G Knepley 
28117da65231SMatthew G Knepley #undef __FUNCT__
28127da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
2813a6dfd86eSKarl Rupp PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[])
2814a6dfd86eSKarl Rupp {
28151b30c384SMatthew G Knepley   PetscInt       f, g;
28167da65231SMatthew G Knepley   PetscErrorCode ierr;
28177da65231SMatthew G Knepley 
28187da65231SMatthew G Knepley   PetscFunctionBegin;
281974778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
28201d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
282174778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
28221d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
2823e3556bceSMatthew G. Knepley       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5g", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
28247da65231SMatthew G Knepley     }
282574778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
28267da65231SMatthew G Knepley   }
28277da65231SMatthew G Knepley   PetscFunctionReturn(0);
28287da65231SMatthew G Knepley }
2829e7c4fc90SDmitry Karpeev 
2830970e74d5SMatthew G Knepley #undef __FUNCT__
2831e759306cSMatthew G. Knepley #define __FUNCT__ "DMPrintLocalVec"
28326113b454SMatthew G. Knepley PetscErrorCode DMPrintLocalVec(DM dm, const char name[], PetscReal tol, Vec X)
2833e759306cSMatthew G. Knepley {
2834e759306cSMatthew G. Knepley   PetscMPIInt    rank, numProcs;
2835e759306cSMatthew G. Knepley   PetscInt       p;
2836e759306cSMatthew G. Knepley   PetscErrorCode ierr;
2837e759306cSMatthew G. Knepley 
2838e759306cSMatthew G. Knepley   PetscFunctionBegin;
2839e759306cSMatthew G. Knepley   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr);
2840e759306cSMatthew G. Knepley   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr);
2841e759306cSMatthew G. Knepley   ierr = PetscPrintf(PetscObjectComm((PetscObject) dm), "%s:\n", name);CHKERRQ(ierr);
2842e759306cSMatthew G. Knepley   for (p = 0; p < numProcs; ++p) {
2843e759306cSMatthew G. Knepley     if (p == rank) {
2844e759306cSMatthew G. Knepley       Vec x;
2845e759306cSMatthew G. Knepley 
2846e759306cSMatthew G. Knepley       ierr = VecDuplicate(X, &x);CHKERRQ(ierr);
2847e759306cSMatthew G. Knepley       ierr = VecCopy(X, x);CHKERRQ(ierr);
28486113b454SMatthew G. Knepley       ierr = VecChop(x, tol);CHKERRQ(ierr);
2849e759306cSMatthew G. Knepley       ierr = VecView(x, PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);
2850e759306cSMatthew G. Knepley       ierr = VecDestroy(&x);CHKERRQ(ierr);
2851e759306cSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr);
2852e759306cSMatthew G. Knepley     }
2853e759306cSMatthew G. Knepley     ierr = PetscBarrier((PetscObject) dm);CHKERRQ(ierr);
2854e759306cSMatthew G. Knepley   }
2855e759306cSMatthew G. Knepley   PetscFunctionReturn(0);
2856e759306cSMatthew G. Knepley }
2857e759306cSMatthew G. Knepley 
2858e759306cSMatthew G. Knepley #undef __FUNCT__
285988ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
286088ed4aceSMatthew G Knepley /*@
286188ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
286288ed4aceSMatthew G Knepley 
286388ed4aceSMatthew G Knepley   Input Parameter:
286488ed4aceSMatthew G Knepley . dm - The DM
286588ed4aceSMatthew G Knepley 
286688ed4aceSMatthew G Knepley   Output Parameter:
286788ed4aceSMatthew G Knepley . section - The PetscSection
286888ed4aceSMatthew G Knepley 
286988ed4aceSMatthew G Knepley   Level: intermediate
287088ed4aceSMatthew G Knepley 
287188ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
287288ed4aceSMatthew G Knepley 
287388ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
287488ed4aceSMatthew G Knepley @*/
28750adebc6cSBarry Smith PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section)
28760adebc6cSBarry Smith {
2877fd59a867SMatthew G. Knepley   PetscErrorCode ierr;
2878fd59a867SMatthew G. Knepley 
287988ed4aceSMatthew G Knepley   PetscFunctionBegin;
288088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
288188ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
2882fd59a867SMatthew G. Knepley   if (!dm->defaultSection && dm->ops->createdefaultsection) {ierr = (*dm->ops->createdefaultsection)(dm);CHKERRQ(ierr);}
288388ed4aceSMatthew G Knepley   *section = dm->defaultSection;
288488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
288588ed4aceSMatthew G Knepley }
288688ed4aceSMatthew G Knepley 
288788ed4aceSMatthew G Knepley #undef __FUNCT__
288888ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
288988ed4aceSMatthew G Knepley /*@
289088ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
289188ed4aceSMatthew G Knepley 
289288ed4aceSMatthew G Knepley   Input Parameters:
289388ed4aceSMatthew G Knepley + dm - The DM
289488ed4aceSMatthew G Knepley - section - The PetscSection
289588ed4aceSMatthew G Knepley 
289688ed4aceSMatthew G Knepley   Level: intermediate
289788ed4aceSMatthew G Knepley 
289888ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
289988ed4aceSMatthew G Knepley 
290088ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
290188ed4aceSMatthew G Knepley @*/
29020adebc6cSBarry Smith PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section)
29030adebc6cSBarry Smith {
2904af122d2aSMatthew G Knepley   PetscInt       numFields;
2905af122d2aSMatthew G Knepley   PetscInt       f;
290688ed4aceSMatthew G Knepley   PetscErrorCode ierr;
290788ed4aceSMatthew G Knepley 
290888ed4aceSMatthew G Knepley   PetscFunctionBegin;
290988ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
29101d799100SJed Brown   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
29111d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
291288ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
291388ed4aceSMatthew G Knepley   dm->defaultSection = section;
2914af122d2aSMatthew G Knepley   ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);
2915af122d2aSMatthew G Knepley   if (numFields) {
2916af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
2917af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
2918af122d2aSMatthew G Knepley       const char *name;
2919af122d2aSMatthew G Knepley 
2920af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
2921decb47aaSMatthew G. Knepley       ierr = PetscObjectSetName((PetscObject) dm->fields[f], name);CHKERRQ(ierr);
2922af122d2aSMatthew G Knepley     }
2923af122d2aSMatthew G Knepley   }
29241d799100SJed Brown   /* The global section will be rebuilt in the next call to DMGetDefaultGlobalSection(). */
29251d799100SJed Brown   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
292688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
292788ed4aceSMatthew G Knepley }
292888ed4aceSMatthew G Knepley 
292988ed4aceSMatthew G Knepley #undef __FUNCT__
293088ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
293188ed4aceSMatthew G Knepley /*@
293288ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
293388ed4aceSMatthew G Knepley 
29348b1ab98fSJed Brown   Collective on DM
29358b1ab98fSJed Brown 
293688ed4aceSMatthew G Knepley   Input Parameter:
293788ed4aceSMatthew G Knepley . dm - The DM
293888ed4aceSMatthew G Knepley 
293988ed4aceSMatthew G Knepley   Output Parameter:
294088ed4aceSMatthew G Knepley . section - The PetscSection
294188ed4aceSMatthew G Knepley 
294288ed4aceSMatthew G Knepley   Level: intermediate
294388ed4aceSMatthew G Knepley 
294488ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
294588ed4aceSMatthew G Knepley 
294688ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
294788ed4aceSMatthew G Knepley @*/
29480adebc6cSBarry Smith PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section)
29490adebc6cSBarry Smith {
295088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
295188ed4aceSMatthew G Knepley 
295288ed4aceSMatthew G Knepley   PetscFunctionBegin;
295388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
295488ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
295588ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
2956fd59a867SMatthew G. Knepley     PetscSection s;
2957fd59a867SMatthew G. Knepley 
2958fd59a867SMatthew G. Knepley     ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
2959fd59a867SMatthew 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");
2960fd59a867SMatthew 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");
2961fd59a867SMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(s, dm->sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
2962cf06b437SMatthew G. Knepley     ierr = PetscLayoutDestroy(&dm->map);CHKERRQ(ierr);
2963ce94432eSBarry Smith     ierr = PetscSectionGetValueLayout(PetscObjectComm((PetscObject)dm), dm->defaultGlobalSection, &dm->map);CHKERRQ(ierr);
296488ed4aceSMatthew G Knepley   }
296588ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
296688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
296788ed4aceSMatthew G Knepley }
296888ed4aceSMatthew G Knepley 
296988ed4aceSMatthew G Knepley #undef __FUNCT__
2970b21d0597SMatthew G Knepley #define __FUNCT__ "DMSetDefaultGlobalSection"
2971b21d0597SMatthew G Knepley /*@
2972b21d0597SMatthew G Knepley   DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM.
2973b21d0597SMatthew G Knepley 
2974b21d0597SMatthew G Knepley   Input Parameters:
2975b21d0597SMatthew G Knepley + dm - The DM
29765080bbdbSMatthew G Knepley - section - The PetscSection, or NULL
2977b21d0597SMatthew G Knepley 
2978b21d0597SMatthew G Knepley   Level: intermediate
2979b21d0597SMatthew G Knepley 
2980b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
2981b21d0597SMatthew G Knepley 
2982b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection()
2983b21d0597SMatthew G Knepley @*/
29840adebc6cSBarry Smith PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section)
29850adebc6cSBarry Smith {
2986b21d0597SMatthew G Knepley   PetscErrorCode ierr;
2987b21d0597SMatthew G Knepley 
2988b21d0597SMatthew G Knepley   PetscFunctionBegin;
2989b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
29905080bbdbSMatthew G Knepley   if (section) PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
29911d799100SJed Brown   ierr = PetscObjectReference((PetscObject)section);CHKERRQ(ierr);
2992b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
2993b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
2994b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
2995b21d0597SMatthew G Knepley }
2996b21d0597SMatthew G Knepley 
2997b21d0597SMatthew G Knepley #undef __FUNCT__
299888ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
299988ed4aceSMatthew G Knepley /*@
300088ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
300188ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
300288ed4aceSMatthew G Knepley 
300388ed4aceSMatthew G Knepley   Input Parameter:
300488ed4aceSMatthew G Knepley . dm - The DM
300588ed4aceSMatthew G Knepley 
300688ed4aceSMatthew G Knepley   Output Parameter:
300788ed4aceSMatthew G Knepley . sf - The PetscSF
300888ed4aceSMatthew G Knepley 
300988ed4aceSMatthew G Knepley   Level: intermediate
301088ed4aceSMatthew G Knepley 
301188ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
301288ed4aceSMatthew G Knepley 
301388ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
301488ed4aceSMatthew G Knepley @*/
30150adebc6cSBarry Smith PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf)
30160adebc6cSBarry Smith {
301788ed4aceSMatthew G Knepley   PetscInt       nroots;
301888ed4aceSMatthew G Knepley   PetscErrorCode ierr;
301988ed4aceSMatthew G Knepley 
302088ed4aceSMatthew G Knepley   PetscFunctionBegin;
302188ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
302288ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
30230298fd71SBarry Smith   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
302488ed4aceSMatthew G Knepley   if (nroots < 0) {
302588ed4aceSMatthew G Knepley     PetscSection section, gSection;
302688ed4aceSMatthew G Knepley 
302788ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
302831ea6d37SMatthew G Knepley     if (section) {
302988ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
303088ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
303131ea6d37SMatthew G Knepley     } else {
30320298fd71SBarry Smith       *sf = NULL;
303331ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
303431ea6d37SMatthew G Knepley     }
303588ed4aceSMatthew G Knepley   }
303688ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
303788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
303888ed4aceSMatthew G Knepley }
303988ed4aceSMatthew G Knepley 
304088ed4aceSMatthew G Knepley #undef __FUNCT__
304188ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
304288ed4aceSMatthew G Knepley /*@
304388ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
304488ed4aceSMatthew G Knepley 
304588ed4aceSMatthew G Knepley   Input Parameters:
304688ed4aceSMatthew G Knepley + dm - The DM
304788ed4aceSMatthew G Knepley - sf - The PetscSF
304888ed4aceSMatthew G Knepley 
304988ed4aceSMatthew G Knepley   Level: intermediate
305088ed4aceSMatthew G Knepley 
305188ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
305288ed4aceSMatthew G Knepley 
305388ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
305488ed4aceSMatthew G Knepley @*/
30550adebc6cSBarry Smith PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf)
30560adebc6cSBarry Smith {
305788ed4aceSMatthew G Knepley   PetscErrorCode ierr;
305888ed4aceSMatthew G Knepley 
305988ed4aceSMatthew G Knepley   PetscFunctionBegin;
306088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
306188ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
306288ed4aceSMatthew G Knepley   ierr          = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
306388ed4aceSMatthew G Knepley   dm->defaultSF = sf;
306488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
306588ed4aceSMatthew G Knepley }
306688ed4aceSMatthew G Knepley 
306788ed4aceSMatthew G Knepley #undef __FUNCT__
306888ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
306988ed4aceSMatthew G Knepley /*@C
307088ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
307188ed4aceSMatthew G Knepley   describing the data layout.
307288ed4aceSMatthew G Knepley 
307388ed4aceSMatthew G Knepley   Input Parameters:
307488ed4aceSMatthew G Knepley + dm - The DM
307588ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
307688ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
307788ed4aceSMatthew G Knepley 
307888ed4aceSMatthew G Knepley   Level: intermediate
307988ed4aceSMatthew G Knepley 
308088ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
308188ed4aceSMatthew G Knepley @*/
308288ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
308388ed4aceSMatthew G Knepley {
308482f516ccSBarry Smith   MPI_Comm       comm;
308588ed4aceSMatthew G Knepley   PetscLayout    layout;
308688ed4aceSMatthew G Knepley   const PetscInt *ranges;
308788ed4aceSMatthew G Knepley   PetscInt       *local;
308888ed4aceSMatthew G Knepley   PetscSFNode    *remote;
3089ecd73843SMatthew G. Knepley   PetscInt       pStart, pEnd, p, nroots, nleaves = 0, l;
309088ed4aceSMatthew G Knepley   PetscMPIInt    size, rank;
309188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
309288ed4aceSMatthew G Knepley 
309388ed4aceSMatthew G Knepley   PetscFunctionBegin;
309482f516ccSBarry Smith   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
309588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
309688ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
309788ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
309888ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
309988ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
310088ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
310188ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
310288ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
310388ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
310488ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
3105ecd73843SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
31066636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
310788ed4aceSMatthew G Knepley 
31086636e97aSMatthew G Knepley     ierr     = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
31096636e97aSMatthew G Knepley     ierr     = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
31106636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
311188ed4aceSMatthew G Knepley   }
3112785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &local);CHKERRQ(ierr);
3113785e854fSJed Brown   ierr = PetscMalloc1(nleaves, &remote);CHKERRQ(ierr);
311488ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
31151f588964SMatthew G Knepley     const PetscInt *cind;
31166636e97aSMatthew G Knepley     PetscInt       dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
311788ed4aceSMatthew G Knepley 
311888ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
311988ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
312088ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
312188ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
312288ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
31236636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
312488ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
31256636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
31266636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
31276636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
3128057b4bcdSMatthew 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);
31296636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
31306636e97aSMatthew G Knepley     }
313188ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
313288ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
313388ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
313488ed4aceSMatthew G Knepley     }
313588ed4aceSMatthew G Knepley     if (gdof < 0) {
31366636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
313788ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
313888ed4aceSMatthew G Knepley 
313905376888SMatthew G. Knepley         ierr = PetscFindInt(offset,size+1,ranges,&r);CHKERRQ(ierr);
314031d3f06eSJed Brown         if (r < 0) r = -(r+2);
314105376888SMatthew 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);
314288ed4aceSMatthew G Knepley         remote[l].rank  = r;
314388ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
314488ed4aceSMatthew G Knepley       }
314588ed4aceSMatthew G Knepley     } else {
31466636e97aSMatthew G Knepley       for (d = 0; d < gsize; ++d, ++l) {
314788ed4aceSMatthew G Knepley         remote[l].rank  = rank;
314888ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
314988ed4aceSMatthew G Knepley       }
315088ed4aceSMatthew G Knepley     }
315188ed4aceSMatthew G Knepley   }
31526636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
315388ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
315488ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
315588ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
315688ed4aceSMatthew G Knepley }
3157af122d2aSMatthew G Knepley 
3158af122d2aSMatthew G Knepley #undef __FUNCT__
3159b21d0597SMatthew G Knepley #define __FUNCT__ "DMGetPointSF"
3160b21d0597SMatthew G Knepley /*@
3161b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
3162b21d0597SMatthew G Knepley 
3163b21d0597SMatthew G Knepley   Input Parameter:
3164b21d0597SMatthew G Knepley . dm - The DM
3165b21d0597SMatthew G Knepley 
3166b21d0597SMatthew G Knepley   Output Parameter:
3167b21d0597SMatthew G Knepley . sf - The PetscSF
3168b21d0597SMatthew G Knepley 
3169b21d0597SMatthew G Knepley   Level: intermediate
3170b21d0597SMatthew G Knepley 
3171b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
3172b21d0597SMatthew G Knepley 
3173057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3174b21d0597SMatthew G Knepley @*/
31750adebc6cSBarry Smith PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf)
31760adebc6cSBarry Smith {
3177b21d0597SMatthew G Knepley   PetscFunctionBegin;
3178b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3179b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
3180b21d0597SMatthew G Knepley   *sf = dm->sf;
3181b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3182b21d0597SMatthew G Knepley }
3183b21d0597SMatthew G Knepley 
3184b21d0597SMatthew G Knepley #undef __FUNCT__
3185057b4bcdSMatthew G Knepley #define __FUNCT__ "DMSetPointSF"
3186057b4bcdSMatthew G Knepley /*@
3187057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
3188057b4bcdSMatthew G Knepley 
3189057b4bcdSMatthew G Knepley   Input Parameters:
3190057b4bcdSMatthew G Knepley + dm - The DM
3191057b4bcdSMatthew G Knepley - sf - The PetscSF
3192057b4bcdSMatthew G Knepley 
3193057b4bcdSMatthew G Knepley   Level: intermediate
3194057b4bcdSMatthew G Knepley 
3195057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3196057b4bcdSMatthew G Knepley @*/
31970adebc6cSBarry Smith PetscErrorCode DMSetPointSF(DM dm, PetscSF sf)
31980adebc6cSBarry Smith {
3199057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
3200057b4bcdSMatthew G Knepley 
3201057b4bcdSMatthew G Knepley   PetscFunctionBegin;
3202057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3203057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1);
3204057b4bcdSMatthew G Knepley   ierr   = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
3205057b4bcdSMatthew G Knepley   ierr   = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
3206057b4bcdSMatthew G Knepley   dm->sf = sf;
3207057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
3208057b4bcdSMatthew G Knepley }
3209057b4bcdSMatthew G Knepley 
3210057b4bcdSMatthew G Knepley #undef __FUNCT__
3211af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetNumFields"
3212af122d2aSMatthew G Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
3213af122d2aSMatthew G Knepley {
3214af122d2aSMatthew G Knepley   PetscFunctionBegin;
3215af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3216af122d2aSMatthew G Knepley   PetscValidPointer(numFields, 2);
3217af122d2aSMatthew G Knepley   *numFields = dm->numFields;
3218af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3219af122d2aSMatthew G Knepley }
3220af122d2aSMatthew G Knepley 
3221af122d2aSMatthew G Knepley #undef __FUNCT__
3222af122d2aSMatthew G Knepley #define __FUNCT__ "DMSetNumFields"
3223af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
3224af122d2aSMatthew G Knepley {
3225af122d2aSMatthew G Knepley   PetscInt       f;
3226af122d2aSMatthew G Knepley   PetscErrorCode ierr;
3227af122d2aSMatthew G Knepley 
3228af122d2aSMatthew G Knepley   PetscFunctionBegin;
3229af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3230decb47aaSMatthew G. Knepley   if (dm->numFields == numFields) PetscFunctionReturn(0);
3231af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3232decb47aaSMatthew G. Knepley     ierr = PetscObjectDestroy((PetscObject *) &dm->fields[f]);CHKERRQ(ierr);
3233af122d2aSMatthew G Knepley   }
3234af122d2aSMatthew G Knepley   ierr          = PetscFree(dm->fields);CHKERRQ(ierr);
3235af122d2aSMatthew G Knepley   dm->numFields = numFields;
3236785e854fSJed Brown   ierr          = PetscMalloc1(dm->numFields, &dm->fields);CHKERRQ(ierr);
3237af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
323882f516ccSBarry Smith     ierr = PetscContainerCreate(PetscObjectComm((PetscObject) dm), (PetscContainer *) &dm->fields[f]);CHKERRQ(ierr);
3239af122d2aSMatthew G Knepley   }
3240af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3241af122d2aSMatthew G Knepley }
3242af122d2aSMatthew G Knepley 
3243af122d2aSMatthew G Knepley #undef __FUNCT__
3244af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetField"
3245af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field)
3246af122d2aSMatthew G Knepley {
3247af122d2aSMatthew G Knepley   PetscFunctionBegin;
3248af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3249decb47aaSMatthew G. Knepley   PetscValidPointer(field, 3);
325082f516ccSBarry Smith   if (!dm->fields) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Fields have not been setup in this DM. Call DMSetNumFields()");
325182f516ccSBarry Smith   if ((f < 0) || (f >= dm->numFields)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Field %d should be in [%d,%d)", f, 0, dm->numFields);
3252decb47aaSMatthew G. Knepley   *field = (PetscObject) dm->fields[f];
3253decb47aaSMatthew G. Knepley   PetscFunctionReturn(0);
3254decb47aaSMatthew G. Knepley }
3255decb47aaSMatthew G. Knepley 
3256decb47aaSMatthew G. Knepley #undef __FUNCT__
3257decb47aaSMatthew G. Knepley #define __FUNCT__ "DMSetField"
3258decb47aaSMatthew G. Knepley PetscErrorCode DMSetField(DM dm, PetscInt f, PetscObject field)
3259decb47aaSMatthew G. Knepley {
3260decb47aaSMatthew G. Knepley   PetscErrorCode ierr;
3261decb47aaSMatthew G. Knepley 
3262decb47aaSMatthew G. Knepley   PetscFunctionBegin;
3263decb47aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3264decb47aaSMatthew G. Knepley   if (!dm->fields) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONGSTATE, "Fields have not been setup in this DM. Call DMSetNumFields()");
3265decb47aaSMatthew G. Knepley   if ((f < 0) || (f >= dm->numFields)) SETERRQ3(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Field %d should be in [%d,%d)", f, 0, dm->numFields);
32669e8c3d3aSMatthew G. Knepley   if (((PetscObject) dm->fields[f]) == field) PetscFunctionReturn(0);
3267decb47aaSMatthew G. Knepley   ierr = PetscObjectDestroy((PetscObject *) &dm->fields[f]);CHKERRQ(ierr);
3268decb47aaSMatthew G. Knepley   dm->fields[f] = (PetscFE) field;
3269decb47aaSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) dm->fields[f]);CHKERRQ(ierr);
3270af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3271af122d2aSMatthew G Knepley }
32726636e97aSMatthew G Knepley 
32736636e97aSMatthew G Knepley #undef __FUNCT__
3274b64e0483SPeter Brune #define __FUNCT__ "DMRestrictHook_Coordinates"
3275b64e0483SPeter Brune PetscErrorCode DMRestrictHook_Coordinates(DM dm,DM dmc,void *ctx)
3276b64e0483SPeter Brune {
3277b64e0483SPeter Brune   DM dm_coord,dmc_coord;
3278b64e0483SPeter Brune   PetscErrorCode ierr;
3279b64e0483SPeter Brune   Vec coords,ccoords;
3280b64e0483SPeter Brune   VecScatter scat;
3281b64e0483SPeter Brune   PetscFunctionBegin;
3282b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
3283b64e0483SPeter Brune   ierr = DMGetCoordinateDM(dmc,&dmc_coord);CHKERRQ(ierr);
3284b64e0483SPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
3285b64e0483SPeter Brune   ierr = DMGetCoordinates(dmc,&ccoords);CHKERRQ(ierr);
3286b64e0483SPeter Brune   if (coords && !ccoords) {
3287b64e0483SPeter Brune     ierr = DMCreateGlobalVector(dmc_coord,&ccoords);CHKERRQ(ierr);
3288b64e0483SPeter Brune     ierr = DMCreateInjection(dmc_coord,dm_coord,&scat);CHKERRQ(ierr);
3289b64e0483SPeter Brune     ierr = VecScatterBegin(scat,coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
3290b64e0483SPeter Brune     ierr = VecScatterEnd(scat,coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
3291b64e0483SPeter Brune     ierr = DMSetCoordinates(dmc,ccoords);CHKERRQ(ierr);
3292b64e0483SPeter Brune     ierr = VecScatterDestroy(&scat);CHKERRQ(ierr);
3293b64e0483SPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
3294b64e0483SPeter Brune   }
3295b64e0483SPeter Brune   PetscFunctionReturn(0);
3296b64e0483SPeter Brune }
3297b64e0483SPeter Brune 
3298b64e0483SPeter Brune #undef __FUNCT__
329903dadc2fSPeter Brune #define __FUNCT__ "DMSubDomainHook_Coordinates"
330003dadc2fSPeter Brune static PetscErrorCode DMSubDomainHook_Coordinates(DM dm,DM subdm,void *ctx)
330103dadc2fSPeter Brune {
330203dadc2fSPeter Brune   DM dm_coord,subdm_coord;
330303dadc2fSPeter Brune   PetscErrorCode ierr;
330403dadc2fSPeter Brune   Vec coords,ccoords,clcoords;
330503dadc2fSPeter Brune   VecScatter *scat_i,*scat_g;
330603dadc2fSPeter Brune   PetscFunctionBegin;
330703dadc2fSPeter Brune   ierr = DMGetCoordinateDM(dm,&dm_coord);CHKERRQ(ierr);
330803dadc2fSPeter Brune   ierr = DMGetCoordinateDM(subdm,&subdm_coord);CHKERRQ(ierr);
330903dadc2fSPeter Brune   ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr);
331003dadc2fSPeter Brune   ierr = DMGetCoordinates(subdm,&ccoords);CHKERRQ(ierr);
331103dadc2fSPeter Brune   if (coords && !ccoords) {
331203dadc2fSPeter Brune     ierr = DMCreateGlobalVector(subdm_coord,&ccoords);CHKERRQ(ierr);
331303dadc2fSPeter Brune     ierr = DMCreateLocalVector(subdm_coord,&clcoords);CHKERRQ(ierr);
331403dadc2fSPeter Brune     ierr = DMCreateDomainDecompositionScatters(dm_coord,1,&subdm_coord,NULL,&scat_i,&scat_g);CHKERRQ(ierr);
331503dadc2fSPeter Brune     ierr = VecScatterBegin(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
331603dadc2fSPeter Brune     ierr = VecScatterBegin(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
331703dadc2fSPeter Brune     ierr = VecScatterEnd(scat_i[0],coords,ccoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
331803dadc2fSPeter Brune     ierr = VecScatterEnd(scat_g[0],coords,clcoords,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
331903dadc2fSPeter Brune     ierr = DMSetCoordinates(subdm,ccoords);CHKERRQ(ierr);
332003dadc2fSPeter Brune     ierr = DMSetCoordinatesLocal(subdm,clcoords);CHKERRQ(ierr);
332103dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_i[0]);CHKERRQ(ierr);
332203dadc2fSPeter Brune     ierr = VecScatterDestroy(&scat_g[0]);CHKERRQ(ierr);
332303dadc2fSPeter Brune     ierr = VecDestroy(&ccoords);CHKERRQ(ierr);
332403dadc2fSPeter Brune     ierr = VecDestroy(&clcoords);CHKERRQ(ierr);
332503dadc2fSPeter Brune     ierr = PetscFree(scat_i);CHKERRQ(ierr);
332603dadc2fSPeter Brune     ierr = PetscFree(scat_g);CHKERRQ(ierr);
332703dadc2fSPeter Brune   }
332803dadc2fSPeter Brune   PetscFunctionReturn(0);
332903dadc2fSPeter Brune }
333003dadc2fSPeter Brune 
333103dadc2fSPeter Brune #undef __FUNCT__
33326636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinates"
33336636e97aSMatthew G Knepley /*@
33346636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
33356636e97aSMatthew G Knepley 
33366636e97aSMatthew G Knepley   Collective on DM
33376636e97aSMatthew G Knepley 
33386636e97aSMatthew G Knepley   Input Parameters:
33396636e97aSMatthew G Knepley + dm - the DM
33406636e97aSMatthew G Knepley - c - coordinate vector
33416636e97aSMatthew G Knepley 
33426636e97aSMatthew G Knepley   Note:
33436636e97aSMatthew G Knepley   The coordinates do include those for ghost points, which are in the local vector
33446636e97aSMatthew G Knepley 
33456636e97aSMatthew G Knepley   Level: intermediate
33466636e97aSMatthew G Knepley 
33476636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
33486636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM()
33496636e97aSMatthew G Knepley @*/
33506636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
33516636e97aSMatthew G Knepley {
33526636e97aSMatthew G Knepley   PetscErrorCode ierr;
33536636e97aSMatthew G Knepley 
33546636e97aSMatthew G Knepley   PetscFunctionBegin;
33556636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
33566636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
33576636e97aSMatthew G Knepley   ierr            = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
33586636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
33596636e97aSMatthew G Knepley   dm->coordinates = c;
33606636e97aSMatthew G Knepley   ierr            = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
3361b64e0483SPeter Brune   ierr            = DMCoarsenHookAdd(dm,DMRestrictHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
336203dadc2fSPeter Brune   ierr            = DMSubDomainHookAdd(dm,DMSubDomainHook_Coordinates,NULL,NULL);CHKERRQ(ierr);
33636636e97aSMatthew G Knepley   PetscFunctionReturn(0);
33646636e97aSMatthew G Knepley }
33656636e97aSMatthew G Knepley 
33666636e97aSMatthew G Knepley #undef __FUNCT__
33676636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinatesLocal"
33686636e97aSMatthew G Knepley /*@
33696636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
33706636e97aSMatthew G Knepley 
33716636e97aSMatthew G Knepley   Collective on DM
33726636e97aSMatthew G Knepley 
33736636e97aSMatthew G Knepley    Input Parameters:
33746636e97aSMatthew G Knepley +  dm - the DM
33756636e97aSMatthew G Knepley -  c - coordinate vector
33766636e97aSMatthew G Knepley 
33776636e97aSMatthew G Knepley   Note:
33786636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
33796636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
33806636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
33816636e97aSMatthew G Knepley 
33826636e97aSMatthew G Knepley   Level: intermediate
33836636e97aSMatthew G Knepley 
33846636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
33856636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
33866636e97aSMatthew G Knepley @*/
33876636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
33886636e97aSMatthew G Knepley {
33896636e97aSMatthew G Knepley   PetscErrorCode ierr;
33906636e97aSMatthew G Knepley 
33916636e97aSMatthew G Knepley   PetscFunctionBegin;
33926636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
33936636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
33946636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
33956636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
33968865f1eaSKarl Rupp 
33976636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
33988865f1eaSKarl Rupp 
33996636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
34006636e97aSMatthew G Knepley   PetscFunctionReturn(0);
34016636e97aSMatthew G Knepley }
34026636e97aSMatthew G Knepley 
34036636e97aSMatthew G Knepley #undef __FUNCT__
34046636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinates"
34056636e97aSMatthew G Knepley /*@
34066636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
34076636e97aSMatthew G Knepley 
34086636e97aSMatthew G Knepley   Not Collective
34096636e97aSMatthew G Knepley 
34106636e97aSMatthew G Knepley   Input Parameter:
34116636e97aSMatthew G Knepley . dm - the DM
34126636e97aSMatthew G Knepley 
34136636e97aSMatthew G Knepley   Output Parameter:
34146636e97aSMatthew G Knepley . c - global coordinate vector
34156636e97aSMatthew G Knepley 
34166636e97aSMatthew G Knepley   Note:
34176636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
34186636e97aSMatthew G Knepley 
34196636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
34206636e97aSMatthew G Knepley 
34216636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
34226636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
34236636e97aSMatthew G Knepley 
34246636e97aSMatthew G Knepley   Level: intermediate
34256636e97aSMatthew G Knepley 
34266636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
34276636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
34286636e97aSMatthew G Knepley @*/
34296636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
34306636e97aSMatthew G Knepley {
34316636e97aSMatthew G Knepley   PetscErrorCode ierr;
34326636e97aSMatthew G Knepley 
34336636e97aSMatthew G Knepley   PetscFunctionBegin;
34346636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
34356636e97aSMatthew G Knepley   PetscValidPointer(c,2);
34361f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
34370298fd71SBarry Smith     DM cdm = NULL;
34386636e97aSMatthew G Knepley 
34396636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
34406636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
34416636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
34426636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
34436636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
34446636e97aSMatthew G Knepley   }
34456636e97aSMatthew G Knepley   *c = dm->coordinates;
34466636e97aSMatthew G Knepley   PetscFunctionReturn(0);
34476636e97aSMatthew G Knepley }
34486636e97aSMatthew G Knepley 
34496636e97aSMatthew G Knepley #undef __FUNCT__
34506636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinatesLocal"
34516636e97aSMatthew G Knepley /*@
34526636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
34536636e97aSMatthew G Knepley 
34546636e97aSMatthew G Knepley   Collective on DM
34556636e97aSMatthew G Knepley 
34566636e97aSMatthew G Knepley   Input Parameter:
34576636e97aSMatthew G Knepley . dm - the DM
34586636e97aSMatthew G Knepley 
34596636e97aSMatthew G Knepley   Output Parameter:
34606636e97aSMatthew G Knepley . c - coordinate vector
34616636e97aSMatthew G Knepley 
34626636e97aSMatthew G Knepley   Note:
34636636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
34646636e97aSMatthew G Knepley 
34656636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
34666636e97aSMatthew G Knepley 
34676636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
34686636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
34696636e97aSMatthew G Knepley 
34706636e97aSMatthew G Knepley   Level: intermediate
34716636e97aSMatthew G Knepley 
34726636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
34736636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
34746636e97aSMatthew G Knepley @*/
34756636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
34766636e97aSMatthew G Knepley {
34776636e97aSMatthew G Knepley   PetscErrorCode ierr;
34786636e97aSMatthew G Knepley 
34796636e97aSMatthew G Knepley   PetscFunctionBegin;
34806636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
34816636e97aSMatthew G Knepley   PetscValidPointer(c,2);
34821f588964SMatthew G Knepley   if (!dm->coordinatesLocal && dm->coordinates) {
34830298fd71SBarry Smith     DM cdm = NULL;
34846636e97aSMatthew G Knepley 
34856636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
34866636e97aSMatthew G Knepley     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
34876636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
34886636e97aSMatthew G Knepley     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
34896636e97aSMatthew G Knepley     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
34906636e97aSMatthew G Knepley   }
34916636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
34926636e97aSMatthew G Knepley   PetscFunctionReturn(0);
34936636e97aSMatthew G Knepley }
34946636e97aSMatthew G Knepley 
34956636e97aSMatthew G Knepley #undef __FUNCT__
34966636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinateDM"
34976636e97aSMatthew G Knepley /*@
34981cfe2091SMatthew G. Knepley   DMGetCoordinateDM - Gets the DM that prescribes coordinate layout and scatters between global and local coordinates
34996636e97aSMatthew G Knepley 
35006636e97aSMatthew G Knepley   Collective on DM
35016636e97aSMatthew G Knepley 
35026636e97aSMatthew G Knepley   Input Parameter:
35036636e97aSMatthew G Knepley . dm - the DM
35046636e97aSMatthew G Knepley 
35056636e97aSMatthew G Knepley   Output Parameter:
35066636e97aSMatthew G Knepley . cdm - coordinate DM
35076636e97aSMatthew G Knepley 
35086636e97aSMatthew G Knepley   Level: intermediate
35096636e97aSMatthew G Knepley 
35106636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
35111cfe2091SMatthew G. Knepley .seealso: DMSetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
35126636e97aSMatthew G Knepley @*/
35136636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
35146636e97aSMatthew G Knepley {
35156636e97aSMatthew G Knepley   PetscErrorCode ierr;
35166636e97aSMatthew G Knepley 
35176636e97aSMatthew G Knepley   PetscFunctionBegin;
35186636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
35196636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
35206636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
352182f516ccSBarry Smith     if (!dm->ops->createcoordinatedm) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Unable to create coordinates for this DM");
35226636e97aSMatthew G Knepley     ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr);
35236636e97aSMatthew G Knepley   }
35246636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
35256636e97aSMatthew G Knepley   PetscFunctionReturn(0);
35266636e97aSMatthew G Knepley }
3527e87bb0d3SMatthew G Knepley 
3528e87bb0d3SMatthew G Knepley #undef __FUNCT__
35291cfe2091SMatthew G. Knepley #define __FUNCT__ "DMSetCoordinateDM"
35301cfe2091SMatthew G. Knepley /*@
35311cfe2091SMatthew G. Knepley   DMSetCoordinateDM - Sets the DM that prescribes coordinate layout and scatters between global and local coordinates
35321cfe2091SMatthew G. Knepley 
35331cfe2091SMatthew G. Knepley   Logically Collective on DM
35341cfe2091SMatthew G. Knepley 
35351cfe2091SMatthew G. Knepley   Input Parameters:
35361cfe2091SMatthew G. Knepley + dm - the DM
35371cfe2091SMatthew G. Knepley - cdm - coordinate DM
35381cfe2091SMatthew G. Knepley 
35391cfe2091SMatthew G. Knepley   Level: intermediate
35401cfe2091SMatthew G. Knepley 
35411cfe2091SMatthew G. Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
35421cfe2091SMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
35431cfe2091SMatthew G. Knepley @*/
35441cfe2091SMatthew G. Knepley PetscErrorCode DMSetCoordinateDM(DM dm, DM cdm)
35451cfe2091SMatthew G. Knepley {
35461cfe2091SMatthew G. Knepley   PetscErrorCode ierr;
35471cfe2091SMatthew G. Knepley 
35481cfe2091SMatthew G. Knepley   PetscFunctionBegin;
35491cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
35501cfe2091SMatthew G. Knepley   PetscValidHeaderSpecific(cdm,DM_CLASSID,2);
35511cfe2091SMatthew G. Knepley   ierr = DMDestroy(&dm->coordinateDM);CHKERRQ(ierr);
35521cfe2091SMatthew G. Knepley   dm->coordinateDM = cdm;
35531cfe2091SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) dm->coordinateDM);CHKERRQ(ierr);
35541cfe2091SMatthew G. Knepley   PetscFunctionReturn(0);
35551cfe2091SMatthew G. Knepley }
35561cfe2091SMatthew G. Knepley 
35571cfe2091SMatthew G. Knepley #undef __FUNCT__
3558e8abe2deSMatthew G. Knepley #define __FUNCT__ "DMGetCoordinateSection"
3559e8abe2deSMatthew G. Knepley /*@
3560e8abe2deSMatthew G. Knepley   DMGetCoordinateSection - Retrieve the layout of coordinate values over the mesh.
3561e8abe2deSMatthew G. Knepley 
3562e8abe2deSMatthew G. Knepley   Not Collective
3563e8abe2deSMatthew G. Knepley 
3564e8abe2deSMatthew G. Knepley   Input Parameter:
3565e8abe2deSMatthew G. Knepley . dm - The DM object
3566e8abe2deSMatthew G. Knepley 
3567e8abe2deSMatthew G. Knepley   Output Parameter:
3568e8abe2deSMatthew G. Knepley . section - The PetscSection object
3569e8abe2deSMatthew G. Knepley 
3570e8abe2deSMatthew G. Knepley   Level: intermediate
3571e8abe2deSMatthew G. Knepley 
3572e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates
3573e8abe2deSMatthew G. Knepley .seealso: DMGetCoordinateDM(), DMGetDefaultSection(), DMSetDefaultSection()
3574e8abe2deSMatthew G. Knepley @*/
3575e8abe2deSMatthew G. Knepley PetscErrorCode DMGetCoordinateSection(DM dm, PetscSection *section)
3576e8abe2deSMatthew G. Knepley {
3577e8abe2deSMatthew G. Knepley   DM             cdm;
3578e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
3579e8abe2deSMatthew G. Knepley 
3580e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
3581e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3582e8abe2deSMatthew G. Knepley   PetscValidPointer(section, 2);
3583e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
3584e8abe2deSMatthew G. Knepley   ierr = DMGetDefaultSection(cdm, section);CHKERRQ(ierr);
3585e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
3586e8abe2deSMatthew G. Knepley }
3587e8abe2deSMatthew G. Knepley 
3588e8abe2deSMatthew G. Knepley #undef __FUNCT__
3589e8abe2deSMatthew G. Knepley #define __FUNCT__ "DMSetCoordinateSection"
3590e8abe2deSMatthew G. Knepley /*@
3591e8abe2deSMatthew G. Knepley   DMSetCoordinateSection - Set the layout of coordinate values over the mesh.
3592e8abe2deSMatthew G. Knepley 
3593e8abe2deSMatthew G. Knepley   Not Collective
3594e8abe2deSMatthew G. Knepley 
3595e8abe2deSMatthew G. Knepley   Input Parameters:
3596e8abe2deSMatthew G. Knepley + dm      - The DM object
3597e8abe2deSMatthew G. Knepley - section - The PetscSection object
3598e8abe2deSMatthew G. Knepley 
3599e8abe2deSMatthew G. Knepley   Level: intermediate
3600e8abe2deSMatthew G. Knepley 
3601e8abe2deSMatthew G. Knepley .keywords: mesh, coordinates
3602e8abe2deSMatthew G. Knepley .seealso: DMGetCoordinateSection(), DMGetDefaultSection(), DMSetDefaultSection()
3603e8abe2deSMatthew G. Knepley @*/
3604e8abe2deSMatthew G. Knepley PetscErrorCode DMSetCoordinateSection(DM dm, PetscSection section)
3605e8abe2deSMatthew G. Knepley {
3606e8abe2deSMatthew G. Knepley   DM             cdm;
3607e8abe2deSMatthew G. Knepley   PetscErrorCode ierr;
3608e8abe2deSMatthew G. Knepley 
3609e8abe2deSMatthew G. Knepley   PetscFunctionBegin;
3610e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3611e8abe2deSMatthew G. Knepley   PetscValidHeaderSpecific(section,PETSC_SECTION_CLASSID,2);
3612e8abe2deSMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
3613e8abe2deSMatthew G. Knepley   ierr = DMSetDefaultSection(cdm, section);CHKERRQ(ierr);
3614e8abe2deSMatthew G. Knepley   PetscFunctionReturn(0);
3615e8abe2deSMatthew G. Knepley }
3616e8abe2deSMatthew G. Knepley 
3617e8abe2deSMatthew G. Knepley #undef __FUNCT__
3618c6b900c6SMatthew G. Knepley #define __FUNCT__ "DMGetPeriodicity"
3619c6b900c6SMatthew G. Knepley PetscErrorCode DMGetPeriodicity(DM dm, const PetscReal **maxCell, const PetscReal **L)
3620c6b900c6SMatthew G. Knepley {
3621c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
3622c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3623c6b900c6SMatthew G. Knepley   if (L)       *L       = dm->L;
3624c6b900c6SMatthew G. Knepley   if (maxCell) *maxCell = dm->maxCell;
3625c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
3626c6b900c6SMatthew G. Knepley }
3627c6b900c6SMatthew G. Knepley 
3628c6b900c6SMatthew G. Knepley #undef __FUNCT__
3629c6b900c6SMatthew G. Knepley #define __FUNCT__ "DMSetPeriodicity"
3630c6b900c6SMatthew G. Knepley PetscErrorCode DMSetPeriodicity(DM dm, const PetscReal maxCell[], const PetscReal L[])
3631c6b900c6SMatthew G. Knepley {
3632c6b900c6SMatthew G. Knepley   Vec            coordinates;
3633c6b900c6SMatthew G. Knepley   PetscInt       dim, d;
3634c6b900c6SMatthew G. Knepley   PetscErrorCode ierr;
3635c6b900c6SMatthew G. Knepley 
3636c6b900c6SMatthew G. Knepley   PetscFunctionBegin;
3637c6b900c6SMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3638c6b900c6SMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
3639c6b900c6SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &dim);CHKERRQ(ierr);
3640c6b900c6SMatthew G. Knepley   ierr = PetscMalloc1(dim,&dm->L);CHKERRQ(ierr);
3641c6b900c6SMatthew G. Knepley   ierr = PetscMalloc1(dim,&dm->maxCell);CHKERRQ(ierr);
3642c6b900c6SMatthew G. Knepley   for (d = 0; d < dim; ++d) {dm->L[d] = L[d]; dm->maxCell[d] = maxCell[d];}
3643c6b900c6SMatthew G. Knepley   PetscFunctionReturn(0);
3644c6b900c6SMatthew G. Knepley }
3645c6b900c6SMatthew G. Knepley 
3646c6b900c6SMatthew G. Knepley #undef __FUNCT__
3647e87bb0d3SMatthew G Knepley #define __FUNCT__ "DMLocatePoints"
3648e87bb0d3SMatthew G Knepley /*@
3649e87bb0d3SMatthew G Knepley   DMLocatePoints - Locate the points in v in the mesh and return an IS of the containing cells
3650e87bb0d3SMatthew G Knepley 
3651e87bb0d3SMatthew G Knepley   Not collective
3652e87bb0d3SMatthew G Knepley 
3653e87bb0d3SMatthew G Knepley   Input Parameters:
3654e87bb0d3SMatthew G Knepley + dm - The DM
3655e87bb0d3SMatthew G Knepley - v - The Vec of points
3656e87bb0d3SMatthew G Knepley 
365761e3bb9bSMatthew G Knepley   Output Parameter:
3658e87bb0d3SMatthew G Knepley . cells - The local cell numbers for cells which contain the points
3659e87bb0d3SMatthew G Knepley 
3660e87bb0d3SMatthew G Knepley   Level: developer
366161e3bb9bSMatthew G Knepley 
366261e3bb9bSMatthew G Knepley .keywords: point location, mesh
366361e3bb9bSMatthew G Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
366461e3bb9bSMatthew G Knepley @*/
3665e87bb0d3SMatthew G Knepley PetscErrorCode DMLocatePoints(DM dm, Vec v, IS *cells)
3666e87bb0d3SMatthew G Knepley {
3667735aa83eSMatthew G Knepley   PetscErrorCode ierr;
3668735aa83eSMatthew G Knepley 
3669e87bb0d3SMatthew G Knepley   PetscFunctionBegin;
3670e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3671e87bb0d3SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
3672e87bb0d3SMatthew G Knepley   PetscValidPointer(cells,3);
3673735aa83eSMatthew G Knepley   if (dm->ops->locatepoints) {
3674735aa83eSMatthew G Knepley     ierr = (*dm->ops->locatepoints)(dm,v,cells);CHKERRQ(ierr);
367582f516ccSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Point location not available for this DM");
3676e87bb0d3SMatthew G Knepley   PetscFunctionReturn(0);
3677e87bb0d3SMatthew G Knepley }
367814f150ffSMatthew G. Knepley 
367914f150ffSMatthew G. Knepley #undef __FUNCT__
368014f150ffSMatthew G. Knepley #define __FUNCT__ "DMGetOutputDM"
3681f4d763aaSMatthew G. Knepley /*@
3682f4d763aaSMatthew G. Knepley   DMGetOutputDM - Retrieve the DM associated with the layout for output
3683f4d763aaSMatthew G. Knepley 
3684f4d763aaSMatthew G. Knepley   Input Parameter:
3685f4d763aaSMatthew G. Knepley . dm - The original DM
3686f4d763aaSMatthew G. Knepley 
3687f4d763aaSMatthew G. Knepley   Output Parameter:
3688f4d763aaSMatthew G. Knepley . odm - The DM which provides the layout for output
3689f4d763aaSMatthew G. Knepley 
3690f4d763aaSMatthew G. Knepley   Level: intermediate
3691f4d763aaSMatthew G. Knepley 
3692f4d763aaSMatthew G. Knepley .seealso: VecView(), DMGetDefaultGlobalSection()
3693f4d763aaSMatthew G. Knepley @*/
369414f150ffSMatthew G. Knepley PetscErrorCode DMGetOutputDM(DM dm, DM *odm)
369514f150ffSMatthew G. Knepley {
3696c26acbdeSMatthew G. Knepley   PetscSection   section;
3697c26acbdeSMatthew G. Knepley   PetscBool      hasConstraints;
369814f150ffSMatthew G. Knepley   PetscErrorCode ierr;
369914f150ffSMatthew G. Knepley 
370014f150ffSMatthew G. Knepley   PetscFunctionBegin;
370114f150ffSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
370214f150ffSMatthew G. Knepley   PetscValidPointer(odm,2);
3703c26acbdeSMatthew G. Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
3704c26acbdeSMatthew G. Knepley   ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr);
3705c26acbdeSMatthew G. Knepley   if (!hasConstraints) {
3706c26acbdeSMatthew G. Knepley     *odm = dm;
3707c26acbdeSMatthew G. Knepley     PetscFunctionReturn(0);
3708c26acbdeSMatthew G. Knepley   }
370914f150ffSMatthew G. Knepley   if (!dm->dmBC) {
3710c26acbdeSMatthew G. Knepley     PetscSection newSection, gsection;
371114f150ffSMatthew G. Knepley     PetscSF      sf;
371214f150ffSMatthew G. Knepley 
371314f150ffSMatthew G. Knepley     ierr = DMClone(dm, &dm->dmBC);CHKERRQ(ierr);
371414f150ffSMatthew G. Knepley     ierr = PetscSectionClone(section, &newSection);CHKERRQ(ierr);
371514f150ffSMatthew G. Knepley     ierr = DMSetDefaultSection(dm->dmBC, newSection);CHKERRQ(ierr);
371614f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);
371714f150ffSMatthew G. Knepley     ierr = DMGetPointSF(dm->dmBC, &sf);CHKERRQ(ierr);
371814f150ffSMatthew G. Knepley     ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_TRUE, &gsection);CHKERRQ(ierr);
371914f150ffSMatthew G. Knepley     ierr = DMSetDefaultGlobalSection(dm->dmBC, gsection);CHKERRQ(ierr);
372014f150ffSMatthew G. Knepley     ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr);
372114f150ffSMatthew G. Knepley   }
372214f150ffSMatthew G. Knepley   *odm = dm->dmBC;
372314f150ffSMatthew G. Knepley   PetscFunctionReturn(0);
372414f150ffSMatthew G. Knepley }
3725f4d763aaSMatthew G. Knepley 
3726f4d763aaSMatthew G. Knepley #undef __FUNCT__
3727f4d763aaSMatthew G. Knepley #define __FUNCT__ "DMGetOutputSequenceNumber"
3728f4d763aaSMatthew G. Knepley /*@
3729f4d763aaSMatthew G. Knepley   DMGetOutputSequenceNumber - Retrieve the sequence number for output
3730f4d763aaSMatthew G. Knepley 
3731f4d763aaSMatthew G. Knepley   Input Parameter:
3732f4d763aaSMatthew G. Knepley . dm - The original DM
3733f4d763aaSMatthew G. Knepley 
3734f4d763aaSMatthew G. Knepley   Output Parameter:
3735f4d763aaSMatthew G. Knepley . num - The output sequence number
3736f4d763aaSMatthew G. Knepley 
3737f4d763aaSMatthew G. Knepley   Level: intermediate
3738f4d763aaSMatthew G. Knepley 
3739f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
3740f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
3741f4d763aaSMatthew G. Knepley 
3742f4d763aaSMatthew G. Knepley .seealso: VecView()
3743f4d763aaSMatthew G. Knepley @*/
3744f4d763aaSMatthew G. Knepley PetscErrorCode DMGetOutputSequenceNumber(DM dm, PetscInt *num)
3745f4d763aaSMatthew G. Knepley {
3746f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
3747f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3748f4d763aaSMatthew G. Knepley   PetscValidPointer(num,2);
3749f4d763aaSMatthew G. Knepley   *num = dm->outputSequenceNum;
3750f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
3751f4d763aaSMatthew G. Knepley }
3752f4d763aaSMatthew G. Knepley 
3753f4d763aaSMatthew G. Knepley #undef __FUNCT__
3754f4d763aaSMatthew G. Knepley #define __FUNCT__ "DMSetOutputSequenceNumber"
3755f4d763aaSMatthew G. Knepley /*@
3756f4d763aaSMatthew G. Knepley   DMSetOutputSequenceNumber - Set the sequence number for output
3757f4d763aaSMatthew G. Knepley 
3758f4d763aaSMatthew G. Knepley   Input Parameters:
3759f4d763aaSMatthew G. Knepley + dm - The original DM
3760f4d763aaSMatthew G. Knepley - num - The output sequence number
3761f4d763aaSMatthew G. Knepley 
3762f4d763aaSMatthew G. Knepley   Level: intermediate
3763f4d763aaSMatthew G. Knepley 
3764f4d763aaSMatthew G. Knepley   Note: This is intended for output that should appear in sequence, for instance
3765f4d763aaSMatthew G. Knepley   a set of timesteps in an HDF5 file, or a set of realizations of a stochastic system.
3766f4d763aaSMatthew G. Knepley 
3767f4d763aaSMatthew G. Knepley .seealso: VecView()
3768f4d763aaSMatthew G. Knepley @*/
3769f4d763aaSMatthew G. Knepley PetscErrorCode DMSetOutputSequenceNumber(DM dm, PetscInt num)
3770f4d763aaSMatthew G. Knepley {
3771f4d763aaSMatthew G. Knepley   PetscFunctionBegin;
3772f4d763aaSMatthew G. Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3773f4d763aaSMatthew G. Knepley   dm->outputSequenceNum = num;
3774f4d763aaSMatthew G. Knepley   PetscFunctionReturn(0);
3775f4d763aaSMatthew G. Knepley }
3776