xref: /petsc/src/dm/interface/dm.c (revision 19fd82e9cecaa743f7d770680f25ee0b5a8ad815)
108da532bSDmitry Karpeev #include <petscsnes.h>
2b45d2f2cSJed Brown #include <petsc-private/dmimpl.h>     /*I      "petscdm.h"     I*/
347c6ae99SBarry Smith 
4732e2eb9SMatthew G Knepley PetscClassId  DM_CLASSID;
567a56275SMatthew G Knepley PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal;
667a56275SMatthew G Knepley 
747c6ae99SBarry Smith #undef __FUNCT__
8a4121054SBarry Smith #define __FUNCT__ "DMCreate"
9a4121054SBarry Smith /*@
10de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
11a4121054SBarry Smith 
12a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
13a4121054SBarry Smith    error when you try to use the vector.
14a4121054SBarry Smith 
15a4121054SBarry Smith   Collective on MPI_Comm
16a4121054SBarry Smith 
17a4121054SBarry Smith   Input Parameter:
18a4121054SBarry Smith . comm - The communicator for the DM object
19a4121054SBarry Smith 
20a4121054SBarry Smith   Output Parameter:
21a4121054SBarry Smith . dm - The DM object
22a4121054SBarry Smith 
23a4121054SBarry Smith   Level: beginner
24a4121054SBarry Smith 
25a4121054SBarry Smith .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE
26a4121054SBarry Smith @*/
277087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
28a4121054SBarry Smith {
29a4121054SBarry Smith   DM             v;
30a4121054SBarry Smith   PetscErrorCode ierr;
31a4121054SBarry Smith 
32a4121054SBarry Smith   PetscFunctionBegin;
331411c6eeSJed Brown   PetscValidPointer(dm,2);
341411c6eeSJed Brown   *dm = PETSC_NULL;
35a4121054SBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
36b84caa0eSBarry Smith   ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr);
37b84caa0eSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
38a4121054SBarry Smith   ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr);
39a4121054SBarry Smith #endif
40a4121054SBarry Smith 
413194b578SJed Brown   ierr = PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, -1, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
42a4121054SBarry Smith   ierr = PetscMemzero(v->ops, sizeof(struct _DMOps));CHKERRQ(ierr);
431411c6eeSJed Brown 
44e7c4fc90SDmitry Karpeev 
451411c6eeSJed Brown   v->ltogmap      = PETSC_NULL;
461411c6eeSJed Brown   v->ltogmapb     = PETSC_NULL;
471411c6eeSJed Brown   v->bs           = 1;
48171400e9SBarry Smith   v->coloringtype = IS_COLORING_GLOBAL;
49970e74d5SMatthew G Knepley   v->lf           = PETSC_NULL;
50970e74d5SMatthew G Knepley   v->lj           = PETSC_NULL;
5188ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
5288ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
5388ed4aceSMatthew G Knepley   v->defaultSection       = PETSC_NULL;
5488ed4aceSMatthew G Knepley   v->defaultGlobalSection = PETSC_NULL;
55435a35e8SMatthew G Knepley   {
56435a35e8SMatthew G Knepley     PetscInt i;
57435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
58435a35e8SMatthew G Knepley       v->nullspaceConstructors[i] = PETSC_NULL;
59435a35e8SMatthew G Knepley     }
60435a35e8SMatthew G Knepley   }
61af122d2aSMatthew G Knepley   v->numFields = 0;
62af122d2aSMatthew G Knepley   v->fields    = PETSC_NULL;
631411c6eeSJed Brown 
641411c6eeSJed Brown   *dm = v;
65a4121054SBarry Smith   PetscFunctionReturn(0);
66a4121054SBarry Smith }
67a4121054SBarry Smith 
68a4121054SBarry Smith 
69a4121054SBarry Smith #undef __FUNCT__
709a42bb27SBarry Smith #define __FUNCT__ "DMSetVecType"
719a42bb27SBarry Smith /*@C
72564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
739a42bb27SBarry Smith 
74aa219208SBarry Smith    Logically Collective on DMDA
759a42bb27SBarry Smith 
769a42bb27SBarry Smith    Input Parameter:
779a42bb27SBarry Smith +  da - initial distributed array
788154be41SBarry Smith .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
799a42bb27SBarry Smith 
809a42bb27SBarry Smith    Options Database:
81dd85299cSBarry Smith .   -dm_vec_type ctype
829a42bb27SBarry Smith 
839a42bb27SBarry Smith    Level: intermediate
849a42bb27SBarry Smith 
85aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
869a42bb27SBarry Smith @*/
87*19fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
889a42bb27SBarry Smith {
899a42bb27SBarry Smith   PetscErrorCode ierr;
909a42bb27SBarry Smith 
919a42bb27SBarry Smith   PetscFunctionBegin;
929a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
939a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
94*19fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
959a42bb27SBarry Smith   PetscFunctionReturn(0);
969a42bb27SBarry Smith }
979a42bb27SBarry Smith 
989a42bb27SBarry Smith #undef __FUNCT__
99521d9a4cSLisandro Dalcin #define __FUNCT__ "DMSetMatType"
100521d9a4cSLisandro Dalcin /*@C
101521d9a4cSLisandro Dalcin        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
102521d9a4cSLisandro Dalcin 
103521d9a4cSLisandro Dalcin    Logically Collective on DM
104521d9a4cSLisandro Dalcin 
105521d9a4cSLisandro Dalcin    Input Parameter:
106521d9a4cSLisandro Dalcin +  dm - the DM context
107521d9a4cSLisandro Dalcin .  ctype - the matrix type
108521d9a4cSLisandro Dalcin 
109521d9a4cSLisandro Dalcin    Options Database:
110521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
111521d9a4cSLisandro Dalcin 
112521d9a4cSLisandro Dalcin    Level: intermediate
113521d9a4cSLisandro Dalcin 
114521d9a4cSLisandro Dalcin .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType
115521d9a4cSLisandro Dalcin @*/
116*19fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
117521d9a4cSLisandro Dalcin {
118521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
119521d9a4cSLisandro Dalcin   PetscFunctionBegin;
120521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
121521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
122*19fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
123521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
124521d9a4cSLisandro Dalcin }
125521d9a4cSLisandro Dalcin 
126521d9a4cSLisandro Dalcin #undef __FUNCT__
1279a42bb27SBarry Smith #define __FUNCT__ "DMSetOptionsPrefix"
1289a42bb27SBarry Smith /*@C
1299a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
130aa219208SBarry Smith    DMDA options in the database.
1319a42bb27SBarry Smith 
132aa219208SBarry Smith    Logically Collective on DMDA
1339a42bb27SBarry Smith 
1349a42bb27SBarry Smith    Input Parameter:
135aa219208SBarry Smith +  da - the DMDA context
1369a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
1379a42bb27SBarry Smith 
1389a42bb27SBarry Smith    Notes:
1399a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
1409a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
1419a42bb27SBarry Smith 
1429a42bb27SBarry Smith    Level: advanced
1439a42bb27SBarry Smith 
144aa219208SBarry Smith .keywords: DMDA, set, options, prefix, database
1459a42bb27SBarry Smith 
1469a42bb27SBarry Smith .seealso: DMSetFromOptions()
1479a42bb27SBarry Smith @*/
1487087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
1499a42bb27SBarry Smith {
1509a42bb27SBarry Smith   PetscErrorCode ierr;
1519a42bb27SBarry Smith 
1529a42bb27SBarry Smith   PetscFunctionBegin;
1539a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1549a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
1559a42bb27SBarry Smith   PetscFunctionReturn(0);
1569a42bb27SBarry Smith }
1579a42bb27SBarry Smith 
1589a42bb27SBarry Smith #undef __FUNCT__
15947c6ae99SBarry Smith #define __FUNCT__ "DMDestroy"
16047c6ae99SBarry Smith /*@
161aa219208SBarry Smith     DMDestroy - Destroys a vector packer or DMDA.
16247c6ae99SBarry Smith 
16347c6ae99SBarry Smith     Collective on DM
16447c6ae99SBarry Smith 
16547c6ae99SBarry Smith     Input Parameter:
16647c6ae99SBarry Smith .   dm - the DM object to destroy
16747c6ae99SBarry Smith 
16847c6ae99SBarry Smith     Level: developer
16947c6ae99SBarry Smith 
170e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
17147c6ae99SBarry Smith 
17247c6ae99SBarry Smith @*/
173fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
17447c6ae99SBarry Smith {
175af122d2aSMatthew G Knepley   PetscInt       i, cnt = 0, f;
176dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
17747c6ae99SBarry Smith   PetscErrorCode ierr;
17847c6ae99SBarry Smith 
17947c6ae99SBarry Smith   PetscFunctionBegin;
1806bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
1816bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
18287e657c6SBarry Smith 
18387e657c6SBarry Smith   /* count all the circular references of DM and its contained Vecs */
184732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
1856bf464f9SBarry Smith     if ((*dm)->localin[i])  {cnt++;}
1866bf464f9SBarry Smith     if ((*dm)->globalin[i]) {cnt++;}
187732e2eb9SMatthew G Knepley   }
188dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++;
18971cd77b2SBarry Smith   if ((*dm)->x) {
19071cd77b2SBarry Smith     PetscObject obj;
19171cd77b2SBarry Smith     ierr = PetscObjectQuery((PetscObject)(*dm)->x,"DM",&obj);CHKERRQ(ierr);
19271cd77b2SBarry Smith     if (obj == (PetscObject)*dm) cnt++;
19371cd77b2SBarry Smith   }
194732e2eb9SMatthew G Knepley 
1956bf464f9SBarry Smith   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
196732e2eb9SMatthew G Knepley   /*
197732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
198732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
199732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
200732e2eb9SMatthew G Knepley   */
2016bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
2026bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
203732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
2046bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
2056bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
206732e2eb9SMatthew G Knepley   }
207dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nnext) { /* Destroy the named vectors */
208dfe15315SJed Brown     nnext = nlink->next;
209dfe15315SJed Brown     if (nlink->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)*dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"DM still has Vec named '%s' checked out",nlink->name);
210dfe15315SJed Brown     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
211dfe15315SJed Brown     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
212dfe15315SJed Brown     ierr = PetscFree(nlink);CHKERRQ(ierr);
213dfe15315SJed Brown   }
214dfe15315SJed Brown   (*dm)->namedglobal = PETSC_NULL;
2151a266240SBarry Smith 
216b17ce1afSJed Brown   /* Destroy the list of hooks */
217c833c3b5SJed Brown   {
218c833c3b5SJed Brown     DMCoarsenHookLink link,next;
219b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
220b17ce1afSJed Brown       next = link->next;
221b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
222b17ce1afSJed Brown     }
223b17ce1afSJed Brown     (*dm)->coarsenhook = PETSC_NULL;
224c833c3b5SJed Brown   }
225c833c3b5SJed Brown   {
226c833c3b5SJed Brown     DMRefineHookLink link,next;
227c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
228c833c3b5SJed Brown       next = link->next;
229c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
230c833c3b5SJed Brown     }
231c833c3b5SJed Brown     (*dm)->refinehook = PETSC_NULL;
232c833c3b5SJed Brown   }
233aa1993deSMatthew G Knepley   /* Destroy the work arrays */
234aa1993deSMatthew G Knepley   {
235aa1993deSMatthew G Knepley     DMWorkLink link,next;
236aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
237aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
238aa1993deSMatthew G Knepley       next = link->next;
239aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
240aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
241aa1993deSMatthew G Knepley     }
242aa1993deSMatthew G Knepley     (*dm)->workin = PETSC_NULL;
243aa1993deSMatthew G Knepley   }
244b17ce1afSJed Brown 
2451a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
2461a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
2471a266240SBarry Smith   }
24887e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
24971cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
2504dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
2516bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
2526bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr);
2536bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
254073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
25588ed4aceSMatthew G Knepley 
25688ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
25788ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
25888ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
25988ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
260af122d2aSMatthew G Knepley 
2616636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
2626636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
2636636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
2646636e97aSMatthew G Knepley 
265af122d2aSMatthew G Knepley   for (f = 0; f < (*dm)->numFields; ++f) {
266af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&(*dm)->fields[f]);CHKERRQ(ierr);
267af122d2aSMatthew G Knepley   }
268af122d2aSMatthew G Knepley   ierr = PetscFree((*dm)->fields);CHKERRQ(ierr);
269732e2eb9SMatthew G Knepley   /* if memory was published with AMS then destroy it */
2706bf464f9SBarry Smith   ierr = PetscObjectDepublish(*dm);CHKERRQ(ierr);
271732e2eb9SMatthew G Knepley 
2726bf464f9SBarry Smith   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
273435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
274732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
27547c6ae99SBarry Smith   PetscFunctionReturn(0);
27647c6ae99SBarry Smith }
27747c6ae99SBarry Smith 
27847c6ae99SBarry Smith #undef __FUNCT__
279d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp"
280d7bf68aeSBarry Smith /*@
281d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
282d7bf68aeSBarry Smith 
283d7bf68aeSBarry Smith     Collective on DM
284d7bf68aeSBarry Smith 
285d7bf68aeSBarry Smith     Input Parameter:
286d7bf68aeSBarry Smith .   dm - the DM object to setup
287d7bf68aeSBarry Smith 
288d7bf68aeSBarry Smith     Level: developer
289d7bf68aeSBarry Smith 
290e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
291d7bf68aeSBarry Smith 
292d7bf68aeSBarry Smith @*/
2937087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
294d7bf68aeSBarry Smith {
295d7bf68aeSBarry Smith   PetscErrorCode ierr;
296d7bf68aeSBarry Smith 
297d7bf68aeSBarry Smith   PetscFunctionBegin;
298171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2998387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
300d7bf68aeSBarry Smith   if (dm->ops->setup) {
301d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
302d7bf68aeSBarry Smith   }
3038387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
304d7bf68aeSBarry Smith   PetscFunctionReturn(0);
305d7bf68aeSBarry Smith }
306d7bf68aeSBarry Smith 
307d7bf68aeSBarry Smith #undef __FUNCT__
308d7bf68aeSBarry Smith #define __FUNCT__ "DMSetFromOptions"
309d7bf68aeSBarry Smith /*@
310d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
311d7bf68aeSBarry Smith 
312d7bf68aeSBarry Smith     Collective on DM
313d7bf68aeSBarry Smith 
314d7bf68aeSBarry Smith     Input Parameter:
315d7bf68aeSBarry Smith .   dm - the DM object to set options for
316d7bf68aeSBarry Smith 
317732e2eb9SMatthew G Knepley     Options Database:
318dd85299cSBarry Smith +   -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
319dd85299cSBarry Smith .   -dm_vec_type <type>  type of vector to create inside DM
320171400e9SBarry Smith .   -dm_mat_type <type>  type of matrix to create inside DM
321171400e9SBarry Smith -   -dm_coloring_type <global or ghosted>
322732e2eb9SMatthew G Knepley 
323d7bf68aeSBarry Smith     Level: developer
324d7bf68aeSBarry Smith 
325e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
326d7bf68aeSBarry Smith 
327d7bf68aeSBarry Smith @*/
3287087cfbeSBarry Smith PetscErrorCode  DMSetFromOptions(DM dm)
329d7bf68aeSBarry Smith {
33067ad5babSMatthew G Knepley   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg;
331d7bf68aeSBarry Smith   PetscErrorCode ierr;
332f9ba7244SBarry Smith   char           typeName[256] = MATAIJ;
333d7bf68aeSBarry Smith 
334d7bf68aeSBarry Smith   PetscFunctionBegin;
335171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3363194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
33782fcb398SMatthew G Knepley     ierr = PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);CHKERRQ(ierr);
338c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_detail", "Exhaustive mesh description", "DMView", flg2, &flg2, PETSC_NULL);CHKERRQ(ierr);
339c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_vtk", "Output mesh in VTK format", "DMView", flg3, &flg3, PETSC_NULL);CHKERRQ(ierr);
34067ad5babSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_latex", "Output mesh in LaTeX TikZ format", "DMView", flg4, &flg4, PETSC_NULL);CHKERRQ(ierr);
341073dac72SJed Brown     ierr = PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,PETSC_NULL);CHKERRQ(ierr);
342f9ba7244SBarry Smith     ierr = PetscOptionsList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
343f9ba7244SBarry Smith     if (flg) {
344f9ba7244SBarry Smith       ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
345f9ba7244SBarry Smith     }
3468caf3d72SBarry Smith     ierr = PetscOptionsList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype?dm->mattype:typeName,typeName,sizeof(typeName),&flg);CHKERRQ(ierr);
347073dac72SJed Brown     if (flg) {
348521d9a4cSLisandro Dalcin       ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
349073dac72SJed Brown     }
3501b89239cSHong Zhang     ierr = PetscOptionsEnum("-dm_is_coloring_type","Global or local coloring of Jacobian","ISColoringType",ISColoringTypes,(PetscEnum)dm->coloringtype,(PetscEnum*)&dm->coloringtype,PETSC_NULL);CHKERRQ(ierr);
351f9ba7244SBarry Smith     if (dm->ops->setfromoptions) {
352f9ba7244SBarry Smith       ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr);
353f9ba7244SBarry Smith     }
354f9ba7244SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
355f9ba7244SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
35682fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
35782fcb398SMatthew G Knepley   if (flg1) {
35882fcb398SMatthew G Knepley     ierr = DMView(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
35982fcb398SMatthew G Knepley   }
360c4721b0eSMatthew G Knepley   if (flg2) {
361c4721b0eSMatthew G Knepley     PetscViewer viewer;
362c4721b0eSMatthew G Knepley 
363c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
364c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
365c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
366c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
367c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
368c4721b0eSMatthew G Knepley   }
369c4721b0eSMatthew G Knepley   if (flg3) {
370c4721b0eSMatthew G Knepley     PetscViewer viewer;
371c4721b0eSMatthew G Knepley 
372c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
373c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
374c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);
375c4721b0eSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.vtk");CHKERRQ(ierr);
376c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
377c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
378c4721b0eSMatthew G Knepley   }
37967ad5babSMatthew G Knepley   if (flg4) {
38067ad5babSMatthew G Knepley     PetscViewer viewer;
38167ad5babSMatthew G Knepley 
38267ad5babSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
38367ad5babSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
38467ad5babSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_LATEX);CHKERRQ(ierr);
38567ad5babSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.tex");CHKERRQ(ierr);
38667ad5babSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
38767ad5babSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
38867ad5babSMatthew G Knepley   }
389d7bf68aeSBarry Smith   PetscFunctionReturn(0);
390d7bf68aeSBarry Smith }
391d7bf68aeSBarry Smith 
392d7bf68aeSBarry Smith #undef __FUNCT__
39347c6ae99SBarry Smith #define __FUNCT__ "DMView"
394fc9bc008SSatish Balay /*@C
395aa219208SBarry Smith     DMView - Views a vector packer or DMDA.
39647c6ae99SBarry Smith 
39747c6ae99SBarry Smith     Collective on DM
39847c6ae99SBarry Smith 
39947c6ae99SBarry Smith     Input Parameter:
40047c6ae99SBarry Smith +   dm - the DM object to view
40147c6ae99SBarry Smith -   v - the viewer
40247c6ae99SBarry Smith 
40347c6ae99SBarry Smith     Level: developer
40447c6ae99SBarry Smith 
405e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
40647c6ae99SBarry Smith 
40747c6ae99SBarry Smith @*/
4087087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
40947c6ae99SBarry Smith {
41047c6ae99SBarry Smith   PetscErrorCode ierr;
41147c6ae99SBarry Smith 
41247c6ae99SBarry Smith   PetscFunctionBegin;
413171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4143014e516SBarry Smith  if (!v) {
4153014e516SBarry Smith     ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr);
4163014e516SBarry Smith   }
4170c010503SBarry Smith   if (dm->ops->view) {
4180c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
41947c6ae99SBarry Smith   }
42047c6ae99SBarry Smith   PetscFunctionReturn(0);
42147c6ae99SBarry Smith }
42247c6ae99SBarry Smith 
42347c6ae99SBarry Smith #undef __FUNCT__
42447c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
42547c6ae99SBarry Smith /*@
426aa219208SBarry Smith     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
42747c6ae99SBarry Smith 
42847c6ae99SBarry Smith     Collective on DM
42947c6ae99SBarry Smith 
43047c6ae99SBarry Smith     Input Parameter:
43147c6ae99SBarry Smith .   dm - the DM object
43247c6ae99SBarry Smith 
43347c6ae99SBarry Smith     Output Parameter:
43447c6ae99SBarry Smith .   vec - the global vector
43547c6ae99SBarry Smith 
436073dac72SJed Brown     Level: beginner
43747c6ae99SBarry Smith 
438e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
43947c6ae99SBarry Smith 
44047c6ae99SBarry Smith @*/
4417087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
44247c6ae99SBarry Smith {
44347c6ae99SBarry Smith   PetscErrorCode ierr;
44447c6ae99SBarry Smith 
44547c6ae99SBarry Smith   PetscFunctionBegin;
446171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
44788ed4aceSMatthew G Knepley   if (dm->defaultSection) {
44888ed4aceSMatthew G Knepley     PetscSection gSection;
44988ed4aceSMatthew G Knepley     PetscInt     localSize;
45088ed4aceSMatthew G Knepley 
45188ed4aceSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
45288ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr);
45388ed4aceSMatthew G Knepley     ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr);
45488ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
45588ed4aceSMatthew G Knepley     /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */
45688ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
45788ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
45888ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */
45988ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */
46088ed4aceSMatthew G Knepley     /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */
46188ed4aceSMatthew G Knepley   } else {
46247c6ae99SBarry Smith     ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
46388ed4aceSMatthew G Knepley   }
46447c6ae99SBarry Smith   PetscFunctionReturn(0);
46547c6ae99SBarry Smith }
46647c6ae99SBarry Smith 
46747c6ae99SBarry Smith #undef __FUNCT__
46847c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
46947c6ae99SBarry Smith /*@
470aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
47147c6ae99SBarry Smith 
47247c6ae99SBarry Smith     Not Collective
47347c6ae99SBarry Smith 
47447c6ae99SBarry Smith     Input Parameter:
47547c6ae99SBarry Smith .   dm - the DM object
47647c6ae99SBarry Smith 
47747c6ae99SBarry Smith     Output Parameter:
47847c6ae99SBarry Smith .   vec - the local vector
47947c6ae99SBarry Smith 
480073dac72SJed Brown     Level: beginner
48147c6ae99SBarry Smith 
482e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
48347c6ae99SBarry Smith 
48447c6ae99SBarry Smith @*/
4857087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
48647c6ae99SBarry Smith {
48747c6ae99SBarry Smith   PetscErrorCode ierr;
48847c6ae99SBarry Smith 
48947c6ae99SBarry Smith   PetscFunctionBegin;
490171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
49188ed4aceSMatthew G Knepley   if (dm->defaultSection) {
49288ed4aceSMatthew G Knepley     PetscInt localSize;
49388ed4aceSMatthew G Knepley 
49488ed4aceSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr);
49588ed4aceSMatthew G Knepley     ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr);
49688ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr);
49788ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
49888ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
49988ed4aceSMatthew G Knepley   } else {
50047c6ae99SBarry Smith     ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
50188ed4aceSMatthew G Knepley   }
50247c6ae99SBarry Smith   PetscFunctionReturn(0);
50347c6ae99SBarry Smith }
50447c6ae99SBarry Smith 
50547c6ae99SBarry Smith #undef __FUNCT__
5061411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
5071411c6eeSJed Brown /*@
5081411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
5091411c6eeSJed Brown 
5101411c6eeSJed Brown    Collective on DM
5111411c6eeSJed Brown 
5121411c6eeSJed Brown    Input Parameter:
5131411c6eeSJed Brown .  dm - the DM that provides the mapping
5141411c6eeSJed Brown 
5151411c6eeSJed Brown    Output Parameter:
5161411c6eeSJed Brown .  ltog - the mapping
5171411c6eeSJed Brown 
5181411c6eeSJed Brown    Level: intermediate
5191411c6eeSJed Brown 
5201411c6eeSJed Brown    Notes:
5211411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
5221411c6eeSJed Brown    MatSetLocalToGlobalMapping().
5231411c6eeSJed Brown 
5241411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
5251411c6eeSJed Brown @*/
5267087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
5271411c6eeSJed Brown {
5281411c6eeSJed Brown   PetscErrorCode ierr;
5291411c6eeSJed Brown 
5301411c6eeSJed Brown   PetscFunctionBegin;
5311411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5321411c6eeSJed Brown   PetscValidPointer(ltog,2);
5331411c6eeSJed Brown   if (!dm->ltogmap) {
53437d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
53537d0c07bSMatthew G Knepley 
53637d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
53737d0c07bSMatthew G Knepley     if (section) {
53837d0c07bSMatthew G Knepley       PetscInt      *ltog;
53937d0c07bSMatthew G Knepley       PetscInt       pStart, pEnd, size, p, l;
54037d0c07bSMatthew G Knepley 
54137d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
54237d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
54337d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
54437d0c07bSMatthew G Knepley       ierr = PetscMalloc(size * sizeof(PetscInt), &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
54537d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
54637d0c07bSMatthew G Knepley         PetscInt dof, off, c;
54737d0c07bSMatthew G Knepley 
54837d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
54937d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
55037d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
55137d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
55237d0c07bSMatthew G Knepley           ltog[l] = off+c;
55337d0c07bSMatthew G Knepley         }
55437d0c07bSMatthew G Knepley       }
55537d0c07bSMatthew G Knepley       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
55637d0c07bSMatthew G Knepley       ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr);
55737d0c07bSMatthew G Knepley     } else {
5581411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
5591411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
5601411c6eeSJed Brown     }
56137d0c07bSMatthew G Knepley   }
5621411c6eeSJed Brown   *ltog = dm->ltogmap;
5631411c6eeSJed Brown   PetscFunctionReturn(0);
5641411c6eeSJed Brown }
5651411c6eeSJed Brown 
5661411c6eeSJed Brown #undef __FUNCT__
5671411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
5681411c6eeSJed Brown /*@
5691411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
5701411c6eeSJed Brown 
5711411c6eeSJed Brown    Collective on DM
5721411c6eeSJed Brown 
5731411c6eeSJed Brown    Input Parameter:
5741411c6eeSJed Brown .  da - the distributed array that provides the mapping
5751411c6eeSJed Brown 
5761411c6eeSJed Brown    Output Parameter:
5771411c6eeSJed Brown .  ltog - the block mapping
5781411c6eeSJed Brown 
5791411c6eeSJed Brown    Level: intermediate
5801411c6eeSJed Brown 
5811411c6eeSJed Brown    Notes:
5821411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
5831411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
5841411c6eeSJed Brown 
5851411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
5861411c6eeSJed Brown @*/
5877087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
5881411c6eeSJed Brown {
5891411c6eeSJed Brown   PetscErrorCode ierr;
5901411c6eeSJed Brown 
5911411c6eeSJed Brown   PetscFunctionBegin;
5921411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5931411c6eeSJed Brown   PetscValidPointer(ltog,2);
5941411c6eeSJed Brown   if (!dm->ltogmapb) {
5951411c6eeSJed Brown     PetscInt bs;
5961411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
5971411c6eeSJed Brown     if (bs > 1) {
5981411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
5991411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
6001411c6eeSJed Brown     } else {
6011411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
6021411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
6031411c6eeSJed Brown     }
6041411c6eeSJed Brown   }
6051411c6eeSJed Brown   *ltog = dm->ltogmapb;
6061411c6eeSJed Brown   PetscFunctionReturn(0);
6071411c6eeSJed Brown }
6081411c6eeSJed Brown 
6091411c6eeSJed Brown #undef __FUNCT__
6101411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
6111411c6eeSJed Brown /*@
6121411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
6131411c6eeSJed Brown 
6141411c6eeSJed Brown    Not Collective
6151411c6eeSJed Brown 
6161411c6eeSJed Brown    Input Parameter:
6171411c6eeSJed Brown .  dm - the DM with block structure
6181411c6eeSJed Brown 
6191411c6eeSJed Brown    Output Parameter:
6201411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
6211411c6eeSJed Brown 
6221411c6eeSJed Brown    Level: intermediate
6231411c6eeSJed Brown 
6241411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
6251411c6eeSJed Brown @*/
6267087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
6271411c6eeSJed Brown {
6281411c6eeSJed Brown   PetscFunctionBegin;
6291411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6301411c6eeSJed Brown   PetscValidPointer(bs,2);
6311411c6eeSJed 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");
6321411c6eeSJed Brown   *bs = dm->bs;
6331411c6eeSJed Brown   PetscFunctionReturn(0);
6341411c6eeSJed Brown }
6351411c6eeSJed Brown 
6361411c6eeSJed Brown #undef __FUNCT__
637e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
63847c6ae99SBarry Smith /*@
639e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
64047c6ae99SBarry Smith 
64147c6ae99SBarry Smith     Collective on DM
64247c6ae99SBarry Smith 
64347c6ae99SBarry Smith     Input Parameter:
64447c6ae99SBarry Smith +   dm1 - the DM object
64547c6ae99SBarry Smith -   dm2 - the second, finer DM object
64647c6ae99SBarry Smith 
64747c6ae99SBarry Smith     Output Parameter:
64847c6ae99SBarry Smith +  mat - the interpolation
64947c6ae99SBarry Smith -  vec - the scaling (optional)
65047c6ae99SBarry Smith 
65147c6ae99SBarry Smith     Level: developer
65247c6ae99SBarry Smith 
65385afcc9aSBarry 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
65485afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
655d52bd9f3SBarry Smith 
656d52bd9f3SBarry Smith         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMDAGetCoordinateDA()) to interpolate the mesh coordinate vectors
657d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
65885afcc9aSBarry Smith 
65985afcc9aSBarry Smith 
660e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
66147c6ae99SBarry Smith 
66247c6ae99SBarry Smith @*/
663e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
66447c6ae99SBarry Smith {
66547c6ae99SBarry Smith   PetscErrorCode ierr;
66647c6ae99SBarry Smith 
66747c6ae99SBarry Smith   PetscFunctionBegin;
668171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
669171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
67025296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
67147c6ae99SBarry Smith   PetscFunctionReturn(0);
67247c6ae99SBarry Smith }
67347c6ae99SBarry Smith 
67447c6ae99SBarry Smith #undef __FUNCT__
675e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
67647c6ae99SBarry Smith /*@
677e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
67847c6ae99SBarry Smith 
67947c6ae99SBarry Smith     Collective on DM
68047c6ae99SBarry Smith 
68147c6ae99SBarry Smith     Input Parameter:
68247c6ae99SBarry Smith +   dm1 - the DM object
68347c6ae99SBarry Smith -   dm2 - the second, finer DM object
68447c6ae99SBarry Smith 
68547c6ae99SBarry Smith     Output Parameter:
68647c6ae99SBarry Smith .   ctx - the injection
68747c6ae99SBarry Smith 
68847c6ae99SBarry Smith     Level: developer
68947c6ae99SBarry Smith 
69085afcc9aSBarry 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
69185afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
69285afcc9aSBarry Smith 
693e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
69447c6ae99SBarry Smith 
69547c6ae99SBarry Smith @*/
696e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
69747c6ae99SBarry Smith {
69847c6ae99SBarry Smith   PetscErrorCode ierr;
69947c6ae99SBarry Smith 
70047c6ae99SBarry Smith   PetscFunctionBegin;
701171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
702171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
70347c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
70447c6ae99SBarry Smith   PetscFunctionReturn(0);
70547c6ae99SBarry Smith }
70647c6ae99SBarry Smith 
70747c6ae99SBarry Smith #undef __FUNCT__
708e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
709d1e2c406SBarry Smith /*@C
710e727c939SJed Brown     DMCreateColoring - Gets coloring for a DMDA or DMComposite
71147c6ae99SBarry Smith 
71247c6ae99SBarry Smith     Collective on DM
71347c6ae99SBarry Smith 
71447c6ae99SBarry Smith     Input Parameter:
71547c6ae99SBarry Smith +   dm - the DM object
71647c6ae99SBarry Smith .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
71747c6ae99SBarry Smith -   matype - either MATAIJ or MATBAIJ
71847c6ae99SBarry Smith 
71947c6ae99SBarry Smith     Output Parameter:
72047c6ae99SBarry Smith .   coloring - the coloring
72147c6ae99SBarry Smith 
72247c6ae99SBarry Smith     Level: developer
72347c6ae99SBarry Smith 
724e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
72547c6ae99SBarry Smith 
726aab9d709SJed Brown @*/
727*19fd82e9SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
72847c6ae99SBarry Smith {
72947c6ae99SBarry Smith   PetscErrorCode ierr;
73047c6ae99SBarry Smith 
73147c6ae99SBarry Smith   PetscFunctionBegin;
732171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
73347c6ae99SBarry Smith   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
73447c6ae99SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
73547c6ae99SBarry Smith   PetscFunctionReturn(0);
73647c6ae99SBarry Smith }
73747c6ae99SBarry Smith 
73847c6ae99SBarry Smith #undef __FUNCT__
739950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
74047c6ae99SBarry Smith /*@C
741950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
74247c6ae99SBarry Smith 
74347c6ae99SBarry Smith     Collective on DM
74447c6ae99SBarry Smith 
74547c6ae99SBarry Smith     Input Parameter:
74647c6ae99SBarry Smith +   dm - the DM object
74747c6ae99SBarry Smith -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
74894013140SBarry Smith             any type which inherits from one of these (such as MATAIJ)
74947c6ae99SBarry Smith 
75047c6ae99SBarry Smith     Output Parameter:
75147c6ae99SBarry Smith .   mat - the empty Jacobian
75247c6ae99SBarry Smith 
753073dac72SJed Brown     Level: beginner
75447c6ae99SBarry Smith 
75594013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
75694013140SBarry Smith        do not need to do it yourself.
75794013140SBarry Smith 
75894013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
759aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
76094013140SBarry Smith 
76194013140SBarry 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
76294013140SBarry Smith        internally by PETSc.
76394013140SBarry Smith 
76494013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
765aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
76694013140SBarry Smith 
767e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
76847c6ae99SBarry Smith 
769aab9d709SJed Brown @*/
770*19fd82e9SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,MatType mtype,Mat *mat)
77147c6ae99SBarry Smith {
77247c6ae99SBarry Smith   PetscErrorCode ierr;
77347c6ae99SBarry Smith 
77447c6ae99SBarry Smith   PetscFunctionBegin;
775171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
776235683edSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
777235683edSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
778235683edSBarry Smith #endif
779c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
780c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
781073dac72SJed Brown   if (dm->mattype) {
78225296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
783073dac72SJed Brown   } else {
78425296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
785c7b7c8a4SJed Brown   }
78647c6ae99SBarry Smith   PetscFunctionReturn(0);
78747c6ae99SBarry Smith }
78847c6ae99SBarry Smith 
78947c6ae99SBarry Smith #undef __FUNCT__
790732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
791732e2eb9SMatthew G Knepley /*@
792950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
793732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
794732e2eb9SMatthew G Knepley 
795732e2eb9SMatthew G Knepley   Logically Collective on DMDA
796732e2eb9SMatthew G Knepley 
797732e2eb9SMatthew G Knepley   Input Parameter:
798732e2eb9SMatthew G Knepley + dm - the DM
799732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
800732e2eb9SMatthew G Knepley 
801732e2eb9SMatthew G Knepley   Level: developer
802950540a4SJed Brown .seealso DMCreateMatrix()
803732e2eb9SMatthew G Knepley @*/
804732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
805732e2eb9SMatthew G Knepley {
806732e2eb9SMatthew G Knepley   PetscFunctionBegin;
807732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
808732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
809732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
810732e2eb9SMatthew G Knepley }
811732e2eb9SMatthew G Knepley 
812732e2eb9SMatthew G Knepley #undef __FUNCT__
813a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
814a89ea682SMatthew G Knepley /*@C
815aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
816a89ea682SMatthew G Knepley 
817a89ea682SMatthew G Knepley   Not Collective
818a89ea682SMatthew G Knepley 
819a89ea682SMatthew G Knepley   Input Parameters:
820a89ea682SMatthew G Knepley + dm - the DM object
821aa1993deSMatthew G Knepley . count - The minium size
822aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
823a89ea682SMatthew G Knepley 
824a89ea682SMatthew G Knepley   Output Parameter:
825a89ea682SMatthew G Knepley . array - the work array
826a89ea682SMatthew G Knepley 
827a89ea682SMatthew G Knepley   Level: developer
828a89ea682SMatthew G Knepley 
829a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
830a89ea682SMatthew G Knepley @*/
831aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
832a89ea682SMatthew G Knepley {
833a89ea682SMatthew G Knepley   PetscErrorCode ierr;
834aa1993deSMatthew G Knepley   DMWorkLink link;
835aa1993deSMatthew G Knepley   size_t size;
836a89ea682SMatthew G Knepley 
837a89ea682SMatthew G Knepley   PetscFunctionBegin;
838a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
839aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
840aa1993deSMatthew G Knepley   if (dm->workin) {
841aa1993deSMatthew G Knepley     link = dm->workin;
842aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
843aa1993deSMatthew G Knepley   } else {
844aa1993deSMatthew G Knepley     ierr = PetscNewLog(dm,struct _DMWorkLink,&link);CHKERRQ(ierr);
845a89ea682SMatthew G Knepley   }
846aa1993deSMatthew G Knepley   ierr = PetscDataTypeGetSize(dtype,&size);CHKERRQ(ierr);
847aa1993deSMatthew G Knepley   if (size*count > link->bytes) {
848aa1993deSMatthew G Knepley     ierr = PetscFree(link->mem);CHKERRQ(ierr);
849aa1993deSMatthew G Knepley     ierr = PetscMalloc(size*count,&link->mem);CHKERRQ(ierr);
850aa1993deSMatthew G Knepley     link->bytes = size*count;
851aa1993deSMatthew G Knepley   }
852aa1993deSMatthew G Knepley   link->next = dm->workout;
853aa1993deSMatthew G Knepley   dm->workout = link;
854aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
855a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
856a89ea682SMatthew G Knepley }
857a89ea682SMatthew G Knepley 
858aa1993deSMatthew G Knepley #undef __FUNCT__
859aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
860aa1993deSMatthew G Knepley /*@C
861aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
862aa1993deSMatthew G Knepley 
863aa1993deSMatthew G Knepley   Not Collective
864aa1993deSMatthew G Knepley 
865aa1993deSMatthew G Knepley   Input Parameters:
866aa1993deSMatthew G Knepley + dm - the DM object
867aa1993deSMatthew G Knepley . count - The minium size
868aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
869aa1993deSMatthew G Knepley 
870aa1993deSMatthew G Knepley   Output Parameter:
871aa1993deSMatthew G Knepley . array - the work array
872aa1993deSMatthew G Knepley 
873aa1993deSMatthew G Knepley   Level: developer
874aa1993deSMatthew G Knepley 
875aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
876aa1993deSMatthew G Knepley @*/
877aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
878aa1993deSMatthew G Knepley {
879aa1993deSMatthew G Knepley   DMWorkLink *p,link;
880aa1993deSMatthew G Knepley 
881aa1993deSMatthew G Knepley   PetscFunctionBegin;
882aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
883aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
884aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
885aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
886aa1993deSMatthew G Knepley       *p = link->next;
887aa1993deSMatthew G Knepley       link->next = dm->workin;
888aa1993deSMatthew G Knepley       dm->workin = link;
889aa1993deSMatthew G Knepley       *(void**)mem = PETSC_NULL;
890aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
891aa1993deSMatthew G Knepley     }
892aa1993deSMatthew G Knepley   }
893aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
894aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
895aa1993deSMatthew G Knepley }
896e7c4fc90SDmitry Karpeev 
897e7c4fc90SDmitry Karpeev #undef __FUNCT__
898435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
899435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
900435a35e8SMatthew G Knepley {
901435a35e8SMatthew G Knepley   PetscFunctionBegin;
902435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
903435a35e8SMatthew G Knepley   if (field >= 10) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
904435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
905435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
906435a35e8SMatthew G Knepley }
907435a35e8SMatthew G Knepley 
908435a35e8SMatthew G Knepley #undef __FUNCT__
9094d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
9104f3b5142SJed Brown /*@C
9114d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
9124d343eeaSMatthew G Knepley 
9134d343eeaSMatthew G Knepley   Not collective
9144d343eeaSMatthew G Knepley 
9154d343eeaSMatthew G Knepley   Input Parameter:
9164d343eeaSMatthew G Knepley . dm - the DM object
9174d343eeaSMatthew G Knepley 
9184d343eeaSMatthew G Knepley   Output Parameters:
91921c9b008SJed Brown + numFields  - The number of fields (or PETSC_NULL if not requested)
92037d0c07bSMatthew G Knepley . fieldNames - The name for each field (or PETSC_NULL if not requested)
92121c9b008SJed Brown - fields     - The global indices for each field (or PETSC_NULL if not requested)
9224d343eeaSMatthew G Knepley 
9234d343eeaSMatthew G Knepley   Level: intermediate
9244d343eeaSMatthew G Knepley 
92521c9b008SJed Brown   Notes:
92621c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
92721c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
92821c9b008SJed Brown   PetscFree().
92921c9b008SJed Brown 
9304d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
9314d343eeaSMatthew G Knepley @*/
93237d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
9334d343eeaSMatthew G Knepley {
93437d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
9354d343eeaSMatthew G Knepley   PetscErrorCode ierr;
9364d343eeaSMatthew G Knepley 
9374d343eeaSMatthew G Knepley   PetscFunctionBegin;
9384d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
93969ca1f37SDmitry Karpeev   if (numFields) {
94069ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
94169ca1f37SDmitry Karpeev     *numFields = 0;
94269ca1f37SDmitry Karpeev   }
94337d0c07bSMatthew G Knepley   if (fieldNames) {
94437d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
94537d0c07bSMatthew G Knepley     *fieldNames = PETSC_NULL;
94669ca1f37SDmitry Karpeev   }
94769ca1f37SDmitry Karpeev   if (fields) {
94869ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
94969ca1f37SDmitry Karpeev     *fields = PETSC_NULL;
95069ca1f37SDmitry Karpeev   }
95137d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
95237d0c07bSMatthew G Knepley   if (section) {
95337d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
95437d0c07bSMatthew G Knepley     PetscInt  nF, f, pStart, pEnd, p;
95537d0c07bSMatthew G Knepley 
95637d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
95737d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
95837d0c07bSMatthew G Knepley     ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr);
95937d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
96037d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
96137d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
96237d0c07bSMatthew G Knepley     }
96337d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
96437d0c07bSMatthew G Knepley       PetscInt gdof;
96537d0c07bSMatthew G Knepley 
96637d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
96737d0c07bSMatthew G Knepley       if (gdof > 0) {
96837d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
96937d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
97037d0c07bSMatthew G Knepley 
97137d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
97237d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
97337d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
97437d0c07bSMatthew G Knepley         }
97537d0c07bSMatthew G Knepley       }
97637d0c07bSMatthew G Knepley     }
97737d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
97837d0c07bSMatthew G Knepley       ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr);
97937d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
98037d0c07bSMatthew G Knepley     }
98137d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
98237d0c07bSMatthew G Knepley       PetscInt gdof, goff;
98337d0c07bSMatthew G Knepley 
98437d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
98537d0c07bSMatthew G Knepley       if (gdof > 0) {
98637d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
98737d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
98837d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
98937d0c07bSMatthew G Knepley 
99037d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
99137d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
99237d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
99337d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
99437d0c07bSMatthew G Knepley           }
99537d0c07bSMatthew G Knepley         }
99637d0c07bSMatthew G Knepley       }
99737d0c07bSMatthew G Knepley     }
99837d0c07bSMatthew G Knepley     if (numFields) {*numFields = nF;}
99937d0c07bSMatthew G Knepley     if (fieldNames) {
100037d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr);
100137d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
100237d0c07bSMatthew G Knepley         const char *fieldName;
100337d0c07bSMatthew G Knepley 
100437d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
100537d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr);
100637d0c07bSMatthew G Knepley       }
100737d0c07bSMatthew G Knepley     }
100837d0c07bSMatthew G Knepley     if (fields) {
100937d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr);
101037d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
101137d0c07bSMatthew G Knepley         ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
101237d0c07bSMatthew G Knepley       }
101337d0c07bSMatthew G Knepley     }
101437d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
101537d0c07bSMatthew G Knepley   } else {
101637d0c07bSMatthew G Knepley     if (dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);}
101769ca1f37SDmitry Karpeev   }
10184d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
10194d343eeaSMatthew G Knepley }
10204d343eeaSMatthew G Knepley 
1021a89ea682SMatthew G Knepley #undef __FUNCT__
102216621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecompositionDM"
1023e7c4fc90SDmitry Karpeev /*@C
102416621825SDmitry Karpeev   DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields.
102516621825SDmitry Karpeev 
102616621825SDmitry Karpeev   Not Collective
102716621825SDmitry Karpeev 
102816621825SDmitry Karpeev   Input Parameters:
102916621825SDmitry Karpeev + dm   - the DM object
103016621825SDmitry Karpeev - name - the name of the field decomposition
103116621825SDmitry Karpeev 
103216621825SDmitry Karpeev   Output Parameter:
103316621825SDmitry Karpeev . ddm  - the field decomposition DM (PETSC_NULL, if no such decomposition is known)
103416621825SDmitry Karpeev 
103516621825SDmitry Karpeev   Level: advanced
103616621825SDmitry Karpeev 
103716621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
103816621825SDmitry Karpeev @*/
103916621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm)
104016621825SDmitry Karpeev {
104116621825SDmitry Karpeev   PetscErrorCode ierr;
104216621825SDmitry Karpeev 
104316621825SDmitry Karpeev   PetscFunctionBegin;
104416621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
104516621825SDmitry Karpeev   PetscValidCharPointer(name,2);
104616621825SDmitry Karpeev   PetscValidPointer(ddm,3);
104716621825SDmitry Karpeev   *ddm = PETSC_NULL;
1048731c8d9eSDmitry Karpeev   if (dm->ops->createfielddecompositiondm) {
104916621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
105016621825SDmitry Karpeev   }
105116621825SDmitry Karpeev   PetscFunctionReturn(0);
105216621825SDmitry Karpeev }
105316621825SDmitry Karpeev 
105416621825SDmitry Karpeev #undef __FUNCT__
105516621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
105616621825SDmitry Karpeev /*@C
105716621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
105816621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
105916621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1060e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1061e7c4fc90SDmitry Karpeev 
1062e7c4fc90SDmitry Karpeev   Not collective
1063e7c4fc90SDmitry Karpeev 
1064e7c4fc90SDmitry Karpeev   Input Parameter:
1065e7c4fc90SDmitry Karpeev . dm - the DM object
1066e7c4fc90SDmitry Karpeev 
1067e7c4fc90SDmitry Karpeev   Output Parameters:
106816621825SDmitry Karpeev + len       - The number of subproblems in the field decomposition (or PETSC_NULL if not requested)
106916621825SDmitry Karpeev . namelist  - The name for each field (or PETSC_NULL if not requested)
107016621825SDmitry Karpeev . islist    - The global indices for each field (or PETSC_NULL if not requested)
107116621825SDmitry Karpeev - dmlist    - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
1072e7c4fc90SDmitry Karpeev 
1073e7c4fc90SDmitry Karpeev   Level: intermediate
1074e7c4fc90SDmitry Karpeev 
1075e7c4fc90SDmitry Karpeev   Notes:
1076e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1077e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1078e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1079e7c4fc90SDmitry Karpeev 
1080e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1081e7c4fc90SDmitry Karpeev @*/
108216621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1083e7c4fc90SDmitry Karpeev {
1084e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1085e7c4fc90SDmitry Karpeev 
1086e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1087e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1088731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);      *len      = 0;}
1089731c8d9eSDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;}
1090731c8d9eSDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);   *islist   = 0;}
1091731c8d9eSDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);   *dmlist   = 0;}
109216621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1093435a35e8SMatthew G Knepley     PetscSection section;
1094435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1095435a35e8SMatthew G Knepley 
1096435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1097435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1098435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1099435a35e8SMatthew G Knepley       *len = numFields;
1100435a35e8SMatthew G Knepley       ierr = PetscMalloc3(numFields,char*,namelist,numFields,IS,islist,numFields,DM,dmlist);CHKERRQ(ierr);
1101435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1102435a35e8SMatthew G Knepley         const char *fieldName;
1103435a35e8SMatthew G Knepley 
1104435a35e8SMatthew G Knepley         ierr = DMCreateSubDM(dm, 1, &f, &(*islist)[f], &(*dmlist)[f]);CHKERRQ(ierr);
1105435a35e8SMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1106435a35e8SMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*namelist)[f]);CHKERRQ(ierr);
1107435a35e8SMatthew G Knepley       }
1108435a35e8SMatthew G Knepley     } else {
110969ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1110e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
1111e7c4fc90SDmitry Karpeev       if (dmlist) *dmlist = PETSC_NULL;
1112e7c4fc90SDmitry Karpeev     }
1113435a35e8SMatthew G Knepley   }
1114e7c4fc90SDmitry Karpeev   else {
111516621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
111616621825SDmitry Karpeev   }
111716621825SDmitry Karpeev   PetscFunctionReturn(0);
111816621825SDmitry Karpeev }
111916621825SDmitry Karpeev 
112016621825SDmitry Karpeev #undef __FUNCT__
1121435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1122435a35e8SMatthew G Knepley /*@C
1123435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1124435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1125435a35e8SMatthew G Knepley 
1126435a35e8SMatthew G Knepley   Not collective
1127435a35e8SMatthew G Knepley 
1128435a35e8SMatthew G Knepley   Input Parameters:
1129435a35e8SMatthew G Knepley + dm - the DM object
1130435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
1131435a35e8SMatthew G Knepley - len       - The number of subproblems in the decomposition (or PETSC_NULL if not requested)
1132435a35e8SMatthew G Knepley 
1133435a35e8SMatthew G Knepley   Output Parameters:
1134435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1135435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1136435a35e8SMatthew G Knepley 
1137435a35e8SMatthew G Knepley   Level: intermediate
1138435a35e8SMatthew G Knepley 
1139435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1140435a35e8SMatthew G Knepley @*/
1141435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1142435a35e8SMatthew G Knepley {
1143435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1144435a35e8SMatthew G Knepley 
1145435a35e8SMatthew G Knepley   PetscFunctionBegin;
1146435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1147435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
1148435a35e8SMatthew G Knepley   if (is) {PetscValidPointer(is,4);}
1149435a35e8SMatthew G Knepley   if (subdm) {PetscValidPointer(subdm,5);}
1150435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1151435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm); CHKERRQ(ierr);
1152435a35e8SMatthew G Knepley   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1153435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1154435a35e8SMatthew G Knepley }
1155435a35e8SMatthew G Knepley 
1156435a35e8SMatthew G Knepley #undef __FUNCT__
115716621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecompositionDM"
115816621825SDmitry Karpeev /*@C
115916621825SDmitry Karpeev   DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains.
116016621825SDmitry Karpeev 
116116621825SDmitry Karpeev   Not Collective
116216621825SDmitry Karpeev 
116316621825SDmitry Karpeev   Input Parameters:
116416621825SDmitry Karpeev + dm   - the DM object
116516621825SDmitry Karpeev - name - the name of the subdomain decomposition
116616621825SDmitry Karpeev 
116716621825SDmitry Karpeev   Output Parameter:
116816621825SDmitry Karpeev . ddm  - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known)
116916621825SDmitry Karpeev 
117016621825SDmitry Karpeev   Level: advanced
117116621825SDmitry Karpeev 
117216621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
117316621825SDmitry Karpeev @*/
117416621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm)
117516621825SDmitry Karpeev {
117616621825SDmitry Karpeev   PetscErrorCode ierr;
117716621825SDmitry Karpeev 
117816621825SDmitry Karpeev   PetscFunctionBegin;
117916621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
118016621825SDmitry Karpeev   PetscValidCharPointer(name,2);
118116621825SDmitry Karpeev   PetscValidPointer(ddm,3);
118216621825SDmitry Karpeev   *ddm = PETSC_NULL;
1183731c8d9eSDmitry Karpeev   if (dm->ops->createdomaindecompositiondm) {
118416621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
118516621825SDmitry Karpeev   }
118616621825SDmitry Karpeev   PetscFunctionReturn(0);
118716621825SDmitry Karpeev }
118816621825SDmitry Karpeev 
118916621825SDmitry Karpeev #undef __FUNCT__
119016621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
119116621825SDmitry Karpeev /*@C
11928d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
11938d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
11948d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
11958d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
11968d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
119716621825SDmitry Karpeev 
119816621825SDmitry Karpeev   Not collective
119916621825SDmitry Karpeev 
120016621825SDmitry Karpeev   Input Parameter:
120116621825SDmitry Karpeev . dm - the DM object
120216621825SDmitry Karpeev 
120316621825SDmitry Karpeev   Output Parameters:
120416621825SDmitry Karpeev + len         - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested)
120516621825SDmitry Karpeev . namelist    - The name for each subdomain (or PETSC_NULL if not requested)
12068d4ac253SDmitry Karpeev . innerislist - The global indices for each inner subdomain (or PETSC_NULL, if not requested)
12078d4ac253SDmitry Karpeev . outerislist - The global indices for each outer subdomain (or PETSC_NULL, if not requested)
120816621825SDmitry Karpeev - dmlist      - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
120916621825SDmitry Karpeev 
121016621825SDmitry Karpeev   Level: intermediate
121116621825SDmitry Karpeev 
121216621825SDmitry Karpeev   Notes:
121316621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
121416621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
121516621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
121616621825SDmitry Karpeev 
12178d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
121816621825SDmitry Karpeev @*/
12198d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
122016621825SDmitry Karpeev {
122116621825SDmitry Karpeev   PetscErrorCode ierr;
122216621825SDmitry Karpeev 
122316621825SDmitry Karpeev   PetscFunctionBegin;
122416621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1225731c8d9eSDmitry Karpeev   if (len)           {PetscValidPointer(len,2);            *len         = PETSC_NULL;}
122616621825SDmitry Karpeev   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = PETSC_NULL;}
12278d4ac253SDmitry Karpeev   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = PETSC_NULL;}
12288d4ac253SDmitry Karpeev   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = PETSC_NULL;}
12298d4ac253SDmitry Karpeev   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = PETSC_NULL;}
123016621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
12318d4ac253SDmitry Karpeev     ierr = (*dm->ops->createdomaindecomposition)(dm,len,namelist,innerislist,outerislist,dmlist); CHKERRQ(ierr);
1232e7c4fc90SDmitry Karpeev   }
1233e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1234e7c4fc90SDmitry Karpeev }
1235e7c4fc90SDmitry Karpeev 
1236731c8d9eSDmitry Karpeev #undef __FUNCT__
123747c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
123847c6ae99SBarry Smith /*@
123947c6ae99SBarry Smith   DMRefine - Refines a DM object
124047c6ae99SBarry Smith 
124147c6ae99SBarry Smith   Collective on DM
124247c6ae99SBarry Smith 
124347c6ae99SBarry Smith   Input Parameter:
124447c6ae99SBarry Smith + dm   - the DM object
124591d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
124647c6ae99SBarry Smith 
124747c6ae99SBarry Smith   Output Parameter:
1248ae0a1c52SMatthew G Knepley . dmf - the refined DM, or PETSC_NULL
1249ae0a1c52SMatthew G Knepley 
1250ae0a1c52SMatthew G Knepley   Note: If no refinement was done, the return value is PETSC_NULL
125147c6ae99SBarry Smith 
125247c6ae99SBarry Smith   Level: developer
125347c6ae99SBarry Smith 
1254e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
125547c6ae99SBarry Smith @*/
12567087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
125747c6ae99SBarry Smith {
125847c6ae99SBarry Smith   PetscErrorCode ierr;
1259c833c3b5SJed Brown   DMRefineHookLink link;
126047c6ae99SBarry Smith 
126147c6ae99SBarry Smith   PetscFunctionBegin;
1262732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
126347c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
12644057135bSMatthew G Knepley   if (*dmf) {
126543842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
1266644e2e5bSBarry Smith     (*dmf)->ops->initialguess = dm->ops->initialguess;
1267644e2e5bSBarry Smith     (*dmf)->ops->function     = dm->ops->function;
1268644e2e5bSBarry Smith     (*dmf)->ops->functionj    = dm->ops->functionj;
1269644e2e5bSBarry Smith     if (dm->ops->jacobian != DMComputeJacobianDefault) {
1270644e2e5bSBarry Smith       (*dmf)->ops->jacobian     = dm->ops->jacobian;
1271644e2e5bSBarry Smith     }
12728cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
1273644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
12740598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1275656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
1276e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1277c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
1278c833c3b5SJed Brown       if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);}
1279c833c3b5SJed Brown     }
1280c833c3b5SJed Brown   }
1281c833c3b5SJed Brown   PetscFunctionReturn(0);
1282c833c3b5SJed Brown }
1283c833c3b5SJed Brown 
1284c833c3b5SJed Brown #undef __FUNCT__
1285c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1286c833c3b5SJed Brown /*@
1287c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1288c833c3b5SJed Brown 
1289c833c3b5SJed Brown    Logically Collective
1290c833c3b5SJed Brown 
1291c833c3b5SJed Brown    Input Arguments:
1292c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1293c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1294c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
1295c833c3b5SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1296c833c3b5SJed Brown 
1297c833c3b5SJed Brown    Calling sequence of refinehook:
1298c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1299c833c3b5SJed Brown 
1300c833c3b5SJed Brown +  coarse - coarse level DM
1301c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1302c833c3b5SJed Brown -  ctx - optional user-defined function context
1303c833c3b5SJed Brown 
1304c833c3b5SJed Brown    Calling sequence for interphook:
1305c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1306c833c3b5SJed Brown 
1307c833c3b5SJed Brown +  coarse - coarse level DM
1308c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1309c833c3b5SJed Brown .  fine - fine level DM to update
1310c833c3b5SJed Brown -  ctx - optional user-defined function context
1311c833c3b5SJed Brown 
1312c833c3b5SJed Brown    Level: advanced
1313c833c3b5SJed Brown 
1314c833c3b5SJed Brown    Notes:
1315c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1316c833c3b5SJed Brown 
1317c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1318c833c3b5SJed Brown 
1319c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1320c833c3b5SJed Brown @*/
1321c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1322c833c3b5SJed Brown {
1323c833c3b5SJed Brown   PetscErrorCode ierr;
1324c833c3b5SJed Brown   DMRefineHookLink link,*p;
1325c833c3b5SJed Brown 
1326c833c3b5SJed Brown   PetscFunctionBegin;
1327c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1328c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1329c833c3b5SJed Brown   ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1330c833c3b5SJed Brown   link->refinehook = refinehook;
1331c833c3b5SJed Brown   link->interphook = interphook;
1332c833c3b5SJed Brown   link->ctx = ctx;
1333c833c3b5SJed Brown   link->next = PETSC_NULL;
1334c833c3b5SJed Brown   *p = link;
1335c833c3b5SJed Brown   PetscFunctionReturn(0);
1336c833c3b5SJed Brown }
1337c833c3b5SJed Brown 
1338c833c3b5SJed Brown #undef __FUNCT__
1339c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1340c833c3b5SJed Brown /*@
1341c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1342c833c3b5SJed Brown 
1343c833c3b5SJed Brown    Collective if any hooks are
1344c833c3b5SJed Brown 
1345c833c3b5SJed Brown    Input Arguments:
1346c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1347c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1348c833c3b5SJed Brown -  fine - finer DM to update
1349c833c3b5SJed Brown 
1350c833c3b5SJed Brown    Level: developer
1351c833c3b5SJed Brown 
1352c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1353c833c3b5SJed Brown @*/
1354c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1355c833c3b5SJed Brown {
1356c833c3b5SJed Brown   PetscErrorCode ierr;
1357c833c3b5SJed Brown   DMRefineHookLink link;
1358c833c3b5SJed Brown 
1359c833c3b5SJed Brown   PetscFunctionBegin;
1360c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
1361c833c3b5SJed Brown     if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);}
13624057135bSMatthew G Knepley   }
136347c6ae99SBarry Smith   PetscFunctionReturn(0);
136447c6ae99SBarry Smith }
136547c6ae99SBarry Smith 
136647c6ae99SBarry Smith #undef __FUNCT__
1367eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1368eb3f98d2SBarry Smith /*@
1369eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1370eb3f98d2SBarry Smith 
1371eb3f98d2SBarry Smith     Not Collective
1372eb3f98d2SBarry Smith 
1373eb3f98d2SBarry Smith     Input Parameter:
1374eb3f98d2SBarry Smith .   dm - the DM object
1375eb3f98d2SBarry Smith 
1376eb3f98d2SBarry Smith     Output Parameter:
1377eb3f98d2SBarry Smith .   level - number of refinements
1378eb3f98d2SBarry Smith 
1379eb3f98d2SBarry Smith     Level: developer
1380eb3f98d2SBarry Smith 
13816a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1382eb3f98d2SBarry Smith 
1383eb3f98d2SBarry Smith @*/
1384eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1385eb3f98d2SBarry Smith {
1386eb3f98d2SBarry Smith   PetscFunctionBegin;
1387eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1388eb3f98d2SBarry Smith   *level = dm->levelup;
1389eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1390eb3f98d2SBarry Smith }
1391eb3f98d2SBarry Smith 
1392eb3f98d2SBarry Smith #undef __FUNCT__
139347c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
139447c6ae99SBarry Smith /*@
139547c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
139647c6ae99SBarry Smith 
139747c6ae99SBarry Smith     Neighbor-wise Collective on DM
139847c6ae99SBarry Smith 
139947c6ae99SBarry Smith     Input Parameters:
140047c6ae99SBarry Smith +   dm - the DM object
140147c6ae99SBarry Smith .   g - the global vector
140247c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
140347c6ae99SBarry Smith -   l - the local vector
140447c6ae99SBarry Smith 
140547c6ae99SBarry Smith 
140647c6ae99SBarry Smith     Level: beginner
140747c6ae99SBarry Smith 
1408e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
140947c6ae99SBarry Smith 
141047c6ae99SBarry Smith @*/
14117087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
141247c6ae99SBarry Smith {
14137128ae9fSMatthew G Knepley   PetscSF        sf;
141447c6ae99SBarry Smith   PetscErrorCode ierr;
141547c6ae99SBarry Smith 
141647c6ae99SBarry Smith   PetscFunctionBegin;
1417171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14187128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14197128ae9fSMatthew G Knepley   if (sf) {
14207128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
14217128ae9fSMatthew G Knepley 
14227128ae9fSMatthew G Knepley     if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14237128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14247128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14257128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14267128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14277128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14287128ae9fSMatthew G Knepley   } else {
1429843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14307128ae9fSMatthew G Knepley   }
143147c6ae99SBarry Smith   PetscFunctionReturn(0);
143247c6ae99SBarry Smith }
143347c6ae99SBarry Smith 
143447c6ae99SBarry Smith #undef __FUNCT__
143547c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
143647c6ae99SBarry Smith /*@
143747c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
143847c6ae99SBarry Smith 
143947c6ae99SBarry Smith     Neighbor-wise Collective on DM
144047c6ae99SBarry Smith 
144147c6ae99SBarry Smith     Input Parameters:
144247c6ae99SBarry Smith +   dm - the DM object
144347c6ae99SBarry Smith .   g - the global vector
144447c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
144547c6ae99SBarry Smith -   l - the local vector
144647c6ae99SBarry Smith 
144747c6ae99SBarry Smith 
144847c6ae99SBarry Smith     Level: beginner
144947c6ae99SBarry Smith 
1450e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
145147c6ae99SBarry Smith 
145247c6ae99SBarry Smith @*/
14537087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
145447c6ae99SBarry Smith {
14557128ae9fSMatthew G Knepley   PetscSF        sf;
145647c6ae99SBarry Smith   PetscErrorCode ierr;
145761a3c1faSSatish Balay   PetscScalar    *lArray, *gArray;
145847c6ae99SBarry Smith 
145947c6ae99SBarry Smith   PetscFunctionBegin;
1460171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14617128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14627128ae9fSMatthew G Knepley   if (sf) {
14637128ae9fSMatthew G Knepley   if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14647128ae9fSMatthew G Knepley 
14657128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14667128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14677128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14687128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14697128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14707128ae9fSMatthew G Knepley   } else {
1471843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14727128ae9fSMatthew G Knepley   }
147347c6ae99SBarry Smith   PetscFunctionReturn(0);
147447c6ae99SBarry Smith }
147547c6ae99SBarry Smith 
147647c6ae99SBarry Smith #undef __FUNCT__
14779a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
147847c6ae99SBarry Smith /*@
14799a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
14809a42bb27SBarry Smith 
14819a42bb27SBarry Smith     Neighbor-wise Collective on DM
14829a42bb27SBarry Smith 
14839a42bb27SBarry Smith     Input Parameters:
14849a42bb27SBarry Smith +   dm - the DM object
1485f6813fd5SJed Brown .   l - the local vector
14869a42bb27SBarry 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
14879a42bb27SBarry Smith            base point.
1488f6813fd5SJed Brown - - the global vector
14899a42bb27SBarry Smith 
14909a42bb27SBarry 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
14919a42bb27SBarry 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
14929a42bb27SBarry Smith            global array to the final global array with VecAXPY().
14939a42bb27SBarry Smith 
14949a42bb27SBarry Smith     Level: beginner
14959a42bb27SBarry Smith 
1496e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
14979a42bb27SBarry Smith 
14989a42bb27SBarry Smith @*/
14997087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
15009a42bb27SBarry Smith {
15017128ae9fSMatthew G Knepley   PetscSF        sf;
15029a42bb27SBarry Smith   PetscErrorCode ierr;
15039a42bb27SBarry Smith 
15049a42bb27SBarry Smith   PetscFunctionBegin;
1505171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15067128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
15077128ae9fSMatthew G Knepley   if (sf) {
15087128ae9fSMatthew G Knepley     MPI_Op       op;
15097128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
15107128ae9fSMatthew G Knepley 
15117128ae9fSMatthew G Knepley     switch(mode) {
15127128ae9fSMatthew G Knepley     case INSERT_VALUES:
15137128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
15147128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
15157128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
15167128ae9fSMatthew G Knepley #else
15177128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
15187128ae9fSMatthew G Knepley #endif
15197128ae9fSMatthew G Knepley     case ADD_VALUES:
15207128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
15217128ae9fSMatthew G Knepley       op = MPI_SUM; break;
15227128ae9fSMatthew G Knepley   default:
15237128ae9fSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15247128ae9fSMatthew G Knepley     }
15257128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15267128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15277128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
15287128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15297128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15307128ae9fSMatthew G Knepley   } else {
1531843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
15327128ae9fSMatthew G Knepley   }
15339a42bb27SBarry Smith   PetscFunctionReturn(0);
15349a42bb27SBarry Smith }
15359a42bb27SBarry Smith 
15369a42bb27SBarry Smith #undef __FUNCT__
15379a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
15389a42bb27SBarry Smith /*@
15399a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
154047c6ae99SBarry Smith 
154147c6ae99SBarry Smith     Neighbor-wise Collective on DM
154247c6ae99SBarry Smith 
154347c6ae99SBarry Smith     Input Parameters:
154447c6ae99SBarry Smith +   dm - the DM object
1545f6813fd5SJed Brown .   l - the local vector
154647c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1547f6813fd5SJed Brown -   g - the global vector
154847c6ae99SBarry Smith 
154947c6ae99SBarry Smith 
155047c6ae99SBarry Smith     Level: beginner
155147c6ae99SBarry Smith 
1552e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
155347c6ae99SBarry Smith 
155447c6ae99SBarry Smith @*/
15557087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
155647c6ae99SBarry Smith {
15577128ae9fSMatthew G Knepley   PetscSF        sf;
155847c6ae99SBarry Smith   PetscErrorCode ierr;
155947c6ae99SBarry Smith 
156047c6ae99SBarry Smith   PetscFunctionBegin;
1561171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15627128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
15637128ae9fSMatthew G Knepley   if (sf) {
15647128ae9fSMatthew G Knepley     MPI_Op       op;
15657128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
15667128ae9fSMatthew G Knepley 
15677128ae9fSMatthew G Knepley     switch(mode) {
15687128ae9fSMatthew G Knepley     case INSERT_VALUES:
15697128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
15707128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
15717128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
15727128ae9fSMatthew G Knepley #else
15737128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
15747128ae9fSMatthew G Knepley #endif
15757128ae9fSMatthew G Knepley     case ADD_VALUES:
15767128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
15777128ae9fSMatthew G Knepley       op = MPI_SUM; break;
15787128ae9fSMatthew G Knepley     default:
15797128ae9fSMatthew G Knepley       SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15807128ae9fSMatthew G Knepley     }
15817128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15827128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15837128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
15847128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15857128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15867128ae9fSMatthew G Knepley   } else {
1587843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
15887128ae9fSMatthew G Knepley   }
158947c6ae99SBarry Smith   PetscFunctionReturn(0);
159047c6ae99SBarry Smith }
159147c6ae99SBarry Smith 
159247c6ae99SBarry Smith #undef __FUNCT__
159347c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobianDefault"
159447c6ae99SBarry Smith /*@
159547c6ae99SBarry Smith     DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided
159647c6ae99SBarry Smith 
159747c6ae99SBarry Smith     Collective on DM
159847c6ae99SBarry Smith 
159947c6ae99SBarry Smith     Input Parameter:
160047c6ae99SBarry Smith +   dm - the DM object
160147c6ae99SBarry Smith .   x - location to compute Jacobian at; may be ignored for linear problems
160247c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
160347c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
160447c6ae99SBarry Smith 
160547c6ae99SBarry Smith     Level: developer
160647c6ae99SBarry Smith 
1607e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
160847c6ae99SBarry Smith          DMSetFunction()
160947c6ae99SBarry Smith 
161047c6ae99SBarry Smith @*/
16117087cfbeSBarry Smith PetscErrorCode  DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
161247c6ae99SBarry Smith {
161347c6ae99SBarry Smith   PetscErrorCode ierr;
1614171400e9SBarry Smith 
161547c6ae99SBarry Smith   PetscFunctionBegin;
1616171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
161747c6ae99SBarry Smith   *stflag = SAME_NONZERO_PATTERN;
161847c6ae99SBarry Smith   ierr  = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr);
161947c6ae99SBarry Smith   if (A != B) {
162047c6ae99SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
162147c6ae99SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
162247c6ae99SBarry Smith   }
162347c6ae99SBarry Smith   PetscFunctionReturn(0);
162447c6ae99SBarry Smith }
162547c6ae99SBarry Smith 
162647c6ae99SBarry Smith #undef __FUNCT__
162747c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
162847c6ae99SBarry Smith /*@
162947c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
163047c6ae99SBarry Smith 
163147c6ae99SBarry Smith     Collective on DM
163247c6ae99SBarry Smith 
163347c6ae99SBarry Smith     Input Parameter:
163447c6ae99SBarry Smith +   dm - the DM object
163591d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
163647c6ae99SBarry Smith 
163747c6ae99SBarry Smith     Output Parameter:
163847c6ae99SBarry Smith .   dmc - the coarsened DM
163947c6ae99SBarry Smith 
164047c6ae99SBarry Smith     Level: developer
164147c6ae99SBarry Smith 
1642e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
164347c6ae99SBarry Smith 
164447c6ae99SBarry Smith @*/
16457087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
164647c6ae99SBarry Smith {
164747c6ae99SBarry Smith   PetscErrorCode ierr;
1648b17ce1afSJed Brown   DMCoarsenHookLink link;
164947c6ae99SBarry Smith 
165047c6ae99SBarry Smith   PetscFunctionBegin;
1651171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
165247c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
165343842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
165447c6ae99SBarry Smith   (*dmc)->ops->initialguess = dm->ops->initialguess;
165547c6ae99SBarry Smith   (*dmc)->ops->function     = dm->ops->function;
165647c6ae99SBarry Smith   (*dmc)->ops->functionj    = dm->ops->functionj;
165747c6ae99SBarry Smith   if (dm->ops->jacobian != DMComputeJacobianDefault) {
165847c6ae99SBarry Smith     (*dmc)->ops->jacobian     = dm->ops->jacobian;
165947c6ae99SBarry Smith   }
16608cd211a4SJed Brown   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1661644e2e5bSBarry Smith   (*dmc)->ctx       = dm->ctx;
16620598a293SJed Brown   (*dmc)->levelup   = dm->levelup;
1663656b349aSBarry Smith   (*dmc)->leveldown = dm->leveldown + 1;
1664e4b4b23bSJed Brown   ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
1665b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1666b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1667b17ce1afSJed Brown   }
1668b17ce1afSJed Brown   PetscFunctionReturn(0);
1669b17ce1afSJed Brown }
1670b17ce1afSJed Brown 
1671b17ce1afSJed Brown #undef __FUNCT__
1672b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1673b17ce1afSJed Brown /*@
1674b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1675b17ce1afSJed Brown 
1676b17ce1afSJed Brown    Logically Collective
1677b17ce1afSJed Brown 
1678b17ce1afSJed Brown    Input Arguments:
1679b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1680b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1681b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
1682b17ce1afSJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1683b17ce1afSJed Brown 
1684b17ce1afSJed Brown    Calling sequence of coarsenhook:
1685b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1686b17ce1afSJed Brown 
1687b17ce1afSJed Brown +  fine - fine level DM
1688b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1689b17ce1afSJed Brown -  ctx - optional user-defined function context
1690b17ce1afSJed Brown 
1691b17ce1afSJed Brown    Calling sequence for restricthook:
1692c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
1693b17ce1afSJed Brown 
1694b17ce1afSJed Brown +  fine - fine level DM
1695b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
1696c833c3b5SJed Brown .  rscale - scaling vector for restriction
1697c833c3b5SJed Brown .  inject - matrix restricting by injection
1698b17ce1afSJed Brown .  coarse - coarse level DM to update
1699b17ce1afSJed Brown -  ctx - optional user-defined function context
1700b17ce1afSJed Brown 
1701b17ce1afSJed Brown    Level: advanced
1702b17ce1afSJed Brown 
1703b17ce1afSJed Brown    Notes:
1704b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
1705b17ce1afSJed Brown 
1706b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1707b17ce1afSJed Brown 
1708b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1709b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
1710b17ce1afSJed Brown 
1711c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1712b17ce1afSJed Brown @*/
1713b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1714b17ce1afSJed Brown {
1715b17ce1afSJed Brown   PetscErrorCode ierr;
1716b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
1717b17ce1afSJed Brown 
1718b17ce1afSJed Brown   PetscFunctionBegin;
1719b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
17206bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1721b17ce1afSJed Brown   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1722b17ce1afSJed Brown   link->coarsenhook = coarsenhook;
1723b17ce1afSJed Brown   link->restricthook = restricthook;
1724b17ce1afSJed Brown   link->ctx = ctx;
17256cab3a1bSJed Brown   link->next = PETSC_NULL;
1726b17ce1afSJed Brown   *p = link;
1727b17ce1afSJed Brown   PetscFunctionReturn(0);
1728b17ce1afSJed Brown }
1729b17ce1afSJed Brown 
1730b17ce1afSJed Brown #undef __FUNCT__
1731b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
1732b17ce1afSJed Brown /*@
1733b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1734b17ce1afSJed Brown 
1735b17ce1afSJed Brown    Collective if any hooks are
1736b17ce1afSJed Brown 
1737b17ce1afSJed Brown    Input Arguments:
1738b17ce1afSJed Brown +  fine - finer DM to use as a base
1739b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
1740b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
1741b17ce1afSJed Brown -  coarse - coarer DM to update
1742b17ce1afSJed Brown 
1743b17ce1afSJed Brown    Level: developer
1744b17ce1afSJed Brown 
1745b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
1746b17ce1afSJed Brown @*/
1747b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1748b17ce1afSJed Brown {
1749b17ce1afSJed Brown   PetscErrorCode ierr;
1750b17ce1afSJed Brown   DMCoarsenHookLink link;
1751b17ce1afSJed Brown 
1752b17ce1afSJed Brown   PetscFunctionBegin;
1753b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
1754b17ce1afSJed Brown     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1755b17ce1afSJed Brown   }
175647c6ae99SBarry Smith   PetscFunctionReturn(0);
175747c6ae99SBarry Smith }
175847c6ae99SBarry Smith 
175947c6ae99SBarry Smith #undef __FUNCT__
17605dbd56e3SPeter Brune #define __FUNCT__ "DMBlockRestrictHookAdd"
17615dbd56e3SPeter Brune /*@
17625dbd56e3SPeter Brune    DMBlockRestrictHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
17635dbd56e3SPeter Brune 
17645dbd56e3SPeter Brune    Logically Collective
17655dbd56e3SPeter Brune 
17665dbd56e3SPeter Brune    Input Arguments:
17675dbd56e3SPeter Brune +  global - global DM
17685dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
17695dbd56e3SPeter Brune -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
17705dbd56e3SPeter Brune 
17715dbd56e3SPeter Brune    Calling sequence for restricthook:
17725dbd56e3SPeter Brune $    restricthook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
17735dbd56e3SPeter Brune 
17745dbd56e3SPeter Brune +  global - global DM
17755dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
17765dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
17775dbd56e3SPeter Brune .  block  - block DM (may just be a shell if the global DM is passed in correctly)
17785dbd56e3SPeter Brune -  ctx - optional user-defined function context
17795dbd56e3SPeter Brune 
17805dbd56e3SPeter Brune    Level: advanced
17815dbd56e3SPeter Brune 
17825dbd56e3SPeter Brune    Notes:
17835dbd56e3SPeter Brune    This function is only needed if auxiliary data needs to be set up on coarse grids.
17845dbd56e3SPeter Brune 
17855dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
17865dbd56e3SPeter Brune 
17875dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
17885dbd56e3SPeter Brune    extract the finest level information from its context (instead of from the SNES).
17895dbd56e3SPeter Brune 
17905dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
17915dbd56e3SPeter Brune @*/
17925dbd56e3SPeter Brune PetscErrorCode DMBlockRestrictHookAdd(DM global,PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
17935dbd56e3SPeter Brune {
17945dbd56e3SPeter Brune   PetscErrorCode ierr;
17955dbd56e3SPeter Brune   DMBlockRestrictHookLink link,*p;
17965dbd56e3SPeter Brune 
17975dbd56e3SPeter Brune   PetscFunctionBegin;
17985dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
17995dbd56e3SPeter Brune   for (p=&global->blockrestricthook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
18005dbd56e3SPeter Brune   ierr = PetscMalloc(sizeof(struct _DMBlockRestrictHookLink),&link);CHKERRQ(ierr);
18015dbd56e3SPeter Brune   link->restricthook = restricthook;
18025dbd56e3SPeter Brune   link->ctx = ctx;
18035dbd56e3SPeter Brune   link->next = PETSC_NULL;
18045dbd56e3SPeter Brune   *p = link;
18055dbd56e3SPeter Brune   PetscFunctionReturn(0);
18065dbd56e3SPeter Brune }
18075dbd56e3SPeter Brune 
18085dbd56e3SPeter Brune #undef __FUNCT__
18095dbd56e3SPeter Brune #define __FUNCT__ "DMBlockRestrict"
18105dbd56e3SPeter Brune /*@
18115dbd56e3SPeter Brune    DMBlockRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMBlockRestrictHookAdd()
18125dbd56e3SPeter Brune 
18135dbd56e3SPeter Brune    Collective if any hooks are
18145dbd56e3SPeter Brune 
18155dbd56e3SPeter Brune    Input Arguments:
18165dbd56e3SPeter Brune +  fine - finer DM to use as a base
18175dbd56e3SPeter Brune .  restrct - restriction matrix, apply using MatRestrict()
18185dbd56e3SPeter Brune .  inject - injection matrix, also use MatRestrict()
18195dbd56e3SPeter Brune -  coarse - coarer DM to update
18205dbd56e3SPeter Brune 
18215dbd56e3SPeter Brune    Level: developer
18225dbd56e3SPeter Brune 
18235dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
18245dbd56e3SPeter Brune @*/
18255dbd56e3SPeter Brune PetscErrorCode DMBlockRestrict(DM global,VecScatter in,VecScatter out,DM block)
18265dbd56e3SPeter Brune {
18275dbd56e3SPeter Brune   PetscErrorCode ierr;
18285dbd56e3SPeter Brune   DMBlockRestrictHookLink link;
18295dbd56e3SPeter Brune 
18305dbd56e3SPeter Brune   PetscFunctionBegin;
18315dbd56e3SPeter Brune   for (link=global->blockrestricthook; link; link=link->next) {
18325dbd56e3SPeter Brune     if (link->restricthook) {ierr = (*link->restricthook)(global,in,out,block,link->ctx);CHKERRQ(ierr);}
18335dbd56e3SPeter Brune   }
18345dbd56e3SPeter Brune   PetscFunctionReturn(0);
18355dbd56e3SPeter Brune }
18365dbd56e3SPeter Brune 
18375dbd56e3SPeter Brune #undef __FUNCT__
18385fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
18395fe1f584SPeter Brune /*@
18406a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
18415fe1f584SPeter Brune 
18425fe1f584SPeter Brune     Not Collective
18435fe1f584SPeter Brune 
18445fe1f584SPeter Brune     Input Parameter:
18455fe1f584SPeter Brune .   dm - the DM object
18465fe1f584SPeter Brune 
18475fe1f584SPeter Brune     Output Parameter:
18486a7d9d85SPeter Brune .   level - number of coarsenings
18495fe1f584SPeter Brune 
18505fe1f584SPeter Brune     Level: developer
18515fe1f584SPeter Brune 
18526a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
18535fe1f584SPeter Brune 
18545fe1f584SPeter Brune @*/
18555fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
18565fe1f584SPeter Brune {
18575fe1f584SPeter Brune   PetscFunctionBegin;
18585fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18595fe1f584SPeter Brune   *level = dm->leveldown;
18605fe1f584SPeter Brune   PetscFunctionReturn(0);
18615fe1f584SPeter Brune }
18625fe1f584SPeter Brune 
18635fe1f584SPeter Brune 
18645fe1f584SPeter Brune 
18655fe1f584SPeter Brune #undef __FUNCT__
186647c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
186747c6ae99SBarry Smith /*@C
186847c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
186947c6ae99SBarry Smith 
187047c6ae99SBarry Smith     Collective on DM
187147c6ae99SBarry Smith 
187247c6ae99SBarry Smith     Input Parameter:
187347c6ae99SBarry Smith +   dm - the DM object
187447c6ae99SBarry Smith -   nlevels - the number of levels of refinement
187547c6ae99SBarry Smith 
187647c6ae99SBarry Smith     Output Parameter:
187747c6ae99SBarry Smith .   dmf - the refined DM hierarchy
187847c6ae99SBarry Smith 
187947c6ae99SBarry Smith     Level: developer
188047c6ae99SBarry Smith 
1881e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
188247c6ae99SBarry Smith 
188347c6ae99SBarry Smith @*/
18847087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
188547c6ae99SBarry Smith {
188647c6ae99SBarry Smith   PetscErrorCode ierr;
188747c6ae99SBarry Smith 
188847c6ae99SBarry Smith   PetscFunctionBegin;
1889171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
189047c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
189147c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
189247c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
189347c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
189447c6ae99SBarry Smith   } else if (dm->ops->refine) {
189547c6ae99SBarry Smith     PetscInt i;
189647c6ae99SBarry Smith 
189747c6ae99SBarry Smith     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
189847c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
189947c6ae99SBarry Smith       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
190047c6ae99SBarry Smith     }
190147c6ae99SBarry Smith   } else {
190247c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
190347c6ae99SBarry Smith   }
190447c6ae99SBarry Smith   PetscFunctionReturn(0);
190547c6ae99SBarry Smith }
190647c6ae99SBarry Smith 
190747c6ae99SBarry Smith #undef __FUNCT__
190847c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
190947c6ae99SBarry Smith /*@C
191047c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
191147c6ae99SBarry Smith 
191247c6ae99SBarry Smith     Collective on DM
191347c6ae99SBarry Smith 
191447c6ae99SBarry Smith     Input Parameter:
191547c6ae99SBarry Smith +   dm - the DM object
191647c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
191747c6ae99SBarry Smith 
191847c6ae99SBarry Smith     Output Parameter:
191947c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
192047c6ae99SBarry Smith 
192147c6ae99SBarry Smith     Level: developer
192247c6ae99SBarry Smith 
1923e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
192447c6ae99SBarry Smith 
192547c6ae99SBarry Smith @*/
19267087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
192747c6ae99SBarry Smith {
192847c6ae99SBarry Smith   PetscErrorCode ierr;
192947c6ae99SBarry Smith 
193047c6ae99SBarry Smith   PetscFunctionBegin;
1931171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
193247c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
193347c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
193447c6ae99SBarry Smith   PetscValidPointer(dmc,3);
193547c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
193647c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
193747c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
193847c6ae99SBarry Smith     PetscInt i;
193947c6ae99SBarry Smith 
194047c6ae99SBarry Smith     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
194147c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
194247c6ae99SBarry Smith       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
194347c6ae99SBarry Smith     }
194447c6ae99SBarry Smith   } else {
194547c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
194647c6ae99SBarry Smith   }
194747c6ae99SBarry Smith   PetscFunctionReturn(0);
194847c6ae99SBarry Smith }
194947c6ae99SBarry Smith 
195047c6ae99SBarry Smith #undef __FUNCT__
1951e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
195247c6ae99SBarry Smith /*@
1953e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
195447c6ae99SBarry Smith    grids associated with two DMs.
195547c6ae99SBarry Smith 
195647c6ae99SBarry Smith    Collective on DM
195747c6ae99SBarry Smith 
195847c6ae99SBarry Smith    Input Parameters:
195947c6ae99SBarry Smith +  dmc - the coarse grid DM
196047c6ae99SBarry Smith -  dmf - the fine grid DM
196147c6ae99SBarry Smith 
196247c6ae99SBarry Smith    Output Parameters:
196347c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
196447c6ae99SBarry Smith 
196547c6ae99SBarry Smith    Level: intermediate
196647c6ae99SBarry Smith 
196747c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
196847c6ae99SBarry Smith 
1969e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
197047c6ae99SBarry Smith @*/
1971e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
197247c6ae99SBarry Smith {
197347c6ae99SBarry Smith   PetscErrorCode ierr;
197447c6ae99SBarry Smith 
197547c6ae99SBarry Smith   PetscFunctionBegin;
1976171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
1977171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
197847c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
197947c6ae99SBarry Smith   PetscFunctionReturn(0);
198047c6ae99SBarry Smith }
198147c6ae99SBarry Smith 
198247c6ae99SBarry Smith #undef __FUNCT__
19831a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
19841a266240SBarry Smith /*@C
19851a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
19861a266240SBarry Smith 
19871a266240SBarry Smith     Not Collective
19881a266240SBarry Smith 
19891a266240SBarry Smith     Input Parameters:
19901a266240SBarry Smith +   dm - the DM object
19911a266240SBarry Smith -   destroy - the destroy function
19921a266240SBarry Smith 
19931a266240SBarry Smith     Level: intermediate
19941a266240SBarry Smith 
1995e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
19961a266240SBarry Smith 
1997f07f9ceaSJed Brown @*/
19981a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
19991a266240SBarry Smith {
20001a266240SBarry Smith   PetscFunctionBegin;
2001171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
20021a266240SBarry Smith   dm->ctxdestroy = destroy;
20031a266240SBarry Smith   PetscFunctionReturn(0);
20041a266240SBarry Smith }
20051a266240SBarry Smith 
20061a266240SBarry Smith #undef __FUNCT__
20071b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
2008b07ff414SBarry Smith /*@
20091b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
201047c6ae99SBarry Smith 
201147c6ae99SBarry Smith     Not Collective
201247c6ae99SBarry Smith 
201347c6ae99SBarry Smith     Input Parameters:
201447c6ae99SBarry Smith +   dm - the DM object
201547c6ae99SBarry Smith -   ctx - the user context
201647c6ae99SBarry Smith 
201747c6ae99SBarry Smith     Level: intermediate
201847c6ae99SBarry Smith 
2019e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
202047c6ae99SBarry Smith 
202147c6ae99SBarry Smith @*/
20221b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
202347c6ae99SBarry Smith {
202447c6ae99SBarry Smith   PetscFunctionBegin;
2025171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
202647c6ae99SBarry Smith   dm->ctx = ctx;
202747c6ae99SBarry Smith   PetscFunctionReturn(0);
202847c6ae99SBarry Smith }
202947c6ae99SBarry Smith 
203047c6ae99SBarry Smith #undef __FUNCT__
20311b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
203247c6ae99SBarry Smith /*@
20331b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
203447c6ae99SBarry Smith 
203547c6ae99SBarry Smith     Not Collective
203647c6ae99SBarry Smith 
203747c6ae99SBarry Smith     Input Parameter:
203847c6ae99SBarry Smith .   dm - the DM object
203947c6ae99SBarry Smith 
204047c6ae99SBarry Smith     Output Parameter:
204147c6ae99SBarry Smith .   ctx - the user context
204247c6ae99SBarry Smith 
204347c6ae99SBarry Smith     Level: intermediate
204447c6ae99SBarry Smith 
2045e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
204647c6ae99SBarry Smith 
204747c6ae99SBarry Smith @*/
20481b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
204947c6ae99SBarry Smith {
205047c6ae99SBarry Smith   PetscFunctionBegin;
2051171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
20521b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
205347c6ae99SBarry Smith   PetscFunctionReturn(0);
205447c6ae99SBarry Smith }
205547c6ae99SBarry Smith 
205647c6ae99SBarry Smith #undef __FUNCT__
205747c6ae99SBarry Smith #define __FUNCT__ "DMSetInitialGuess"
20587e833e3aSBarry Smith /*@C
205947c6ae99SBarry Smith     DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers
206047c6ae99SBarry Smith 
206147c6ae99SBarry Smith     Logically Collective on DM
206247c6ae99SBarry Smith 
206347c6ae99SBarry Smith     Input Parameter:
206447c6ae99SBarry Smith +   dm - the DM object to destroy
206547c6ae99SBarry Smith -   f - the function to compute the initial guess
206647c6ae99SBarry Smith 
206747c6ae99SBarry Smith     Level: intermediate
206847c6ae99SBarry Smith 
2069e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
207047c6ae99SBarry Smith 
2071f07f9ceaSJed Brown @*/
20727087cfbeSBarry Smith PetscErrorCode  DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec))
207347c6ae99SBarry Smith {
207447c6ae99SBarry Smith   PetscFunctionBegin;
2075171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
207647c6ae99SBarry Smith   dm->ops->initialguess = f;
207747c6ae99SBarry Smith   PetscFunctionReturn(0);
207847c6ae99SBarry Smith }
207947c6ae99SBarry Smith 
208047c6ae99SBarry Smith #undef __FUNCT__
208147c6ae99SBarry Smith #define __FUNCT__ "DMSetFunction"
20827e833e3aSBarry Smith /*@C
208347c6ae99SBarry Smith     DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES
208447c6ae99SBarry Smith 
208547c6ae99SBarry Smith     Logically Collective on DM
208647c6ae99SBarry Smith 
208747c6ae99SBarry Smith     Input Parameter:
208847c6ae99SBarry Smith +   dm - the DM object
208947c6ae99SBarry Smith -   f - the function to compute (use PETSC_NULL to cancel a previous function that was set)
209047c6ae99SBarry Smith 
209147c6ae99SBarry Smith     Level: intermediate
209247c6ae99SBarry Smith 
209347c6ae99SBarry Smith     Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian
209447c6ae99SBarry Smith            computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian.
209547c6ae99SBarry Smith 
2096e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
209747c6ae99SBarry Smith          DMSetJacobian()
209847c6ae99SBarry Smith 
2099f07f9ceaSJed Brown @*/
21007087cfbeSBarry Smith PetscErrorCode  DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
210147c6ae99SBarry Smith {
210247c6ae99SBarry Smith   PetscFunctionBegin;
2103171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
210447c6ae99SBarry Smith   dm->ops->function = f;
210547c6ae99SBarry Smith   if (f) {
210647c6ae99SBarry Smith     dm->ops->functionj = f;
210747c6ae99SBarry Smith   }
210847c6ae99SBarry Smith   PetscFunctionReturn(0);
210947c6ae99SBarry Smith }
211047c6ae99SBarry Smith 
211147c6ae99SBarry Smith #undef __FUNCT__
211247c6ae99SBarry Smith #define __FUNCT__ "DMSetJacobian"
21137e833e3aSBarry Smith /*@C
211447c6ae99SBarry Smith     DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES
211547c6ae99SBarry Smith 
211647c6ae99SBarry Smith     Logically Collective on DM
211747c6ae99SBarry Smith 
211847c6ae99SBarry Smith     Input Parameter:
211947c6ae99SBarry Smith +   dm - the DM object to destroy
212047c6ae99SBarry Smith -   f - the function to compute the matrix entries
212147c6ae99SBarry Smith 
212247c6ae99SBarry Smith     Level: intermediate
212347c6ae99SBarry Smith 
2124e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
212547c6ae99SBarry Smith          DMSetFunction()
212647c6ae99SBarry Smith 
2127f07f9ceaSJed Brown @*/
21287087cfbeSBarry Smith PetscErrorCode  DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*))
212947c6ae99SBarry Smith {
213047c6ae99SBarry Smith   PetscFunctionBegin;
2131171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
213247c6ae99SBarry Smith   dm->ops->jacobian = f;
213347c6ae99SBarry Smith   PetscFunctionReturn(0);
213447c6ae99SBarry Smith }
213547c6ae99SBarry Smith 
213647c6ae99SBarry Smith #undef __FUNCT__
213708da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
213808da532bSDmitry Karpeev /*@C
213908da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
214008da532bSDmitry Karpeev 
214108da532bSDmitry Karpeev     Logically Collective on DM
214208da532bSDmitry Karpeev 
214308da532bSDmitry Karpeev     Input Parameter:
214408da532bSDmitry Karpeev +   dm - the DM object
214508da532bSDmitry Karpeev -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
214608da532bSDmitry Karpeev 
214708da532bSDmitry Karpeev     Level: intermediate
214808da532bSDmitry Karpeev 
2149e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
215008da532bSDmitry Karpeev          DMSetJacobian()
215108da532bSDmitry Karpeev 
215208da532bSDmitry Karpeev @*/
215308da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
215408da532bSDmitry Karpeev {
215508da532bSDmitry Karpeev   PetscFunctionBegin;
215608da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
215708da532bSDmitry Karpeev   PetscFunctionReturn(0);
215808da532bSDmitry Karpeev }
215908da532bSDmitry Karpeev 
216008da532bSDmitry Karpeev #undef __FUNCT__
216108da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
216208da532bSDmitry Karpeev /*@
216308da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
216408da532bSDmitry Karpeev 
216508da532bSDmitry Karpeev     Not Collective
216608da532bSDmitry Karpeev 
216708da532bSDmitry Karpeev     Input Parameter:
216808da532bSDmitry Karpeev .   dm - the DM object to destroy
216908da532bSDmitry Karpeev 
217008da532bSDmitry Karpeev     Output Parameter:
217108da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
217208da532bSDmitry Karpeev 
217308da532bSDmitry Karpeev     Level: developer
217408da532bSDmitry Karpeev 
2175e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
217608da532bSDmitry Karpeev 
217708da532bSDmitry Karpeev @*/
217808da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
217908da532bSDmitry Karpeev {
218008da532bSDmitry Karpeev   PetscFunctionBegin;
218108da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
218208da532bSDmitry Karpeev   PetscFunctionReturn(0);
218308da532bSDmitry Karpeev }
218408da532bSDmitry Karpeev 
218508da532bSDmitry Karpeev #undef __FUNCT__
218608da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
218708da532bSDmitry Karpeev /*@C
218808da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
218908da532bSDmitry Karpeev 
219008da532bSDmitry Karpeev     Logically Collective on DM
219108da532bSDmitry Karpeev 
219208da532bSDmitry Karpeev     Input Parameters:
219308da532bSDmitry Karpeev +   dm - the DM object to destroy
219408da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
219508da532bSDmitry Karpeev 
219608da532bSDmitry Karpeev     Output parameters:
219708da532bSDmitry Karpeev +   xl - lower bound
219808da532bSDmitry Karpeev -   xu - upper bound
219908da532bSDmitry Karpeev 
220008da532bSDmitry Karpeev     Level: intermediate
220108da532bSDmitry Karpeev 
2202e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
220308da532bSDmitry Karpeev          DMSetFunction(), DMSetVariableBounds()
220408da532bSDmitry Karpeev 
220508da532bSDmitry Karpeev @*/
220608da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
220708da532bSDmitry Karpeev {
220808da532bSDmitry Karpeev   PetscErrorCode ierr;
220908da532bSDmitry Karpeev   PetscFunctionBegin;
221008da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
221108da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
221208da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
221308da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
221408da532bSDmitry Karpeev   }
2215a201590fSDmitry Karpeev   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
221608da532bSDmitry Karpeev   PetscFunctionReturn(0);
221708da532bSDmitry Karpeev }
221808da532bSDmitry Karpeev 
221908da532bSDmitry Karpeev #undef __FUNCT__
222047c6ae99SBarry Smith #define __FUNCT__ "DMComputeInitialGuess"
222147c6ae99SBarry Smith /*@
222247c6ae99SBarry Smith     DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers
222347c6ae99SBarry Smith 
222447c6ae99SBarry Smith     Collective on DM
222547c6ae99SBarry Smith 
222647c6ae99SBarry Smith     Input Parameter:
222747c6ae99SBarry Smith +   dm - the DM object to destroy
222847c6ae99SBarry Smith -   x - the vector to hold the initial guess values
222947c6ae99SBarry Smith 
223047c6ae99SBarry Smith     Level: developer
223147c6ae99SBarry Smith 
2232e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat()
223347c6ae99SBarry Smith 
223447c6ae99SBarry Smith @*/
22357087cfbeSBarry Smith PetscErrorCode  DMComputeInitialGuess(DM dm,Vec x)
223647c6ae99SBarry Smith {
223747c6ae99SBarry Smith   PetscErrorCode ierr;
223847c6ae99SBarry Smith   PetscFunctionBegin;
2239171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
224047c6ae99SBarry Smith   if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()");
224147c6ae99SBarry Smith   ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr);
224247c6ae99SBarry Smith   PetscFunctionReturn(0);
224347c6ae99SBarry Smith }
224447c6ae99SBarry Smith 
224547c6ae99SBarry Smith #undef __FUNCT__
224647c6ae99SBarry Smith #define __FUNCT__ "DMHasInitialGuess"
224747c6ae99SBarry Smith /*@
224847c6ae99SBarry Smith     DMHasInitialGuess - does the DM object have an initial guess function
224947c6ae99SBarry Smith 
225047c6ae99SBarry Smith     Not Collective
225147c6ae99SBarry Smith 
225247c6ae99SBarry Smith     Input Parameter:
225347c6ae99SBarry Smith .   dm - the DM object to destroy
225447c6ae99SBarry Smith 
225547c6ae99SBarry Smith     Output Parameter:
225647c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
225747c6ae99SBarry Smith 
225847c6ae99SBarry Smith     Level: developer
225947c6ae99SBarry Smith 
2260e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
226147c6ae99SBarry Smith 
226247c6ae99SBarry Smith @*/
22637087cfbeSBarry Smith PetscErrorCode  DMHasInitialGuess(DM dm,PetscBool  *flg)
226447c6ae99SBarry Smith {
226547c6ae99SBarry Smith   PetscFunctionBegin;
2266171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
226747c6ae99SBarry Smith   *flg =  (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE;
226847c6ae99SBarry Smith   PetscFunctionReturn(0);
226947c6ae99SBarry Smith }
227047c6ae99SBarry Smith 
227147c6ae99SBarry Smith #undef __FUNCT__
227247c6ae99SBarry Smith #define __FUNCT__ "DMHasFunction"
227347c6ae99SBarry Smith /*@
227447c6ae99SBarry Smith     DMHasFunction - does the DM object have a function
227547c6ae99SBarry Smith 
227647c6ae99SBarry Smith     Not Collective
227747c6ae99SBarry Smith 
227847c6ae99SBarry Smith     Input Parameter:
227947c6ae99SBarry Smith .   dm - the DM object to destroy
228047c6ae99SBarry Smith 
228147c6ae99SBarry Smith     Output Parameter:
228247c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
228347c6ae99SBarry Smith 
228447c6ae99SBarry Smith     Level: developer
228547c6ae99SBarry Smith 
2286e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
228747c6ae99SBarry Smith 
228847c6ae99SBarry Smith @*/
22897087cfbeSBarry Smith PetscErrorCode  DMHasFunction(DM dm,PetscBool  *flg)
229047c6ae99SBarry Smith {
229147c6ae99SBarry Smith   PetscFunctionBegin;
2292171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
229347c6ae99SBarry Smith   *flg =  (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE;
229447c6ae99SBarry Smith   PetscFunctionReturn(0);
229547c6ae99SBarry Smith }
229647c6ae99SBarry Smith 
229747c6ae99SBarry Smith #undef __FUNCT__
229847c6ae99SBarry Smith #define __FUNCT__ "DMHasJacobian"
229947c6ae99SBarry Smith /*@
230047c6ae99SBarry Smith     DMHasJacobian - does the DM object have a matrix function
230147c6ae99SBarry Smith 
230247c6ae99SBarry Smith     Not Collective
230347c6ae99SBarry Smith 
230447c6ae99SBarry Smith     Input Parameter:
230547c6ae99SBarry Smith .   dm - the DM object to destroy
230647c6ae99SBarry Smith 
230747c6ae99SBarry Smith     Output Parameter:
230847c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
230947c6ae99SBarry Smith 
231047c6ae99SBarry Smith     Level: developer
231147c6ae99SBarry Smith 
2312e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
231347c6ae99SBarry Smith 
231447c6ae99SBarry Smith @*/
23157087cfbeSBarry Smith PetscErrorCode  DMHasJacobian(DM dm,PetscBool  *flg)
231647c6ae99SBarry Smith {
231747c6ae99SBarry Smith   PetscFunctionBegin;
2318171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
231947c6ae99SBarry Smith   *flg =  (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE;
232047c6ae99SBarry Smith   PetscFunctionReturn(0);
232147c6ae99SBarry Smith }
232247c6ae99SBarry Smith 
232347c6ae99SBarry Smith #undef __FUNCT__
2324b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2325b0ae01b7SPeter Brune /*@
2326b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2327b0ae01b7SPeter Brune 
2328b0ae01b7SPeter Brune     Not Collective
2329b0ae01b7SPeter Brune 
2330b0ae01b7SPeter Brune     Input Parameter:
2331b0ae01b7SPeter Brune .   dm - the DM object
2332b0ae01b7SPeter Brune 
2333b0ae01b7SPeter Brune     Output Parameter:
2334b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2335b0ae01b7SPeter Brune 
2336b0ae01b7SPeter Brune     Level: developer
2337b0ae01b7SPeter Brune 
2338b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2339b0ae01b7SPeter Brune 
2340b0ae01b7SPeter Brune @*/
2341b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2342b0ae01b7SPeter Brune {
2343b0ae01b7SPeter Brune   PetscFunctionBegin;
2344b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2345b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2346b0ae01b7SPeter Brune }
2347b0ae01b7SPeter Brune 
2348b0ae01b7SPeter Brune #undef  __FUNCT__
234908da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2350748fac09SDmitry Karpeev /*@C
235108da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
235208da532bSDmitry Karpeev 
235308da532bSDmitry Karpeev     Collective on DM
235408da532bSDmitry Karpeev 
235508da532bSDmitry Karpeev     Input Parameter:
235608da532bSDmitry Karpeev +   dm - the DM object
2357e88d7f4bSDmitry Karpeev -   x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems.
235808da532bSDmitry Karpeev 
235908da532bSDmitry Karpeev     Level: developer
236008da532bSDmitry Karpeev 
2361e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
236208da532bSDmitry Karpeev          DMSetFunction(), DMSetJacobian(), DMSetVariableBounds()
236308da532bSDmitry Karpeev 
236408da532bSDmitry Karpeev @*/
236508da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
236608da532bSDmitry Karpeev {
236708da532bSDmitry Karpeev   PetscErrorCode ierr;
236808da532bSDmitry Karpeev   PetscFunctionBegin;
236908da532bSDmitry Karpeev   if (x) {
237008da532bSDmitry Karpeev     if (!dm->x) {
237108da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
237208da532bSDmitry Karpeev     }
237308da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
237408da532bSDmitry Karpeev   }
237508da532bSDmitry Karpeev   else if (dm->x) {
237608da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
237708da532bSDmitry Karpeev   }
237808da532bSDmitry Karpeev   PetscFunctionReturn(0);
237908da532bSDmitry Karpeev }
238008da532bSDmitry Karpeev 
238108da532bSDmitry Karpeev 
238208da532bSDmitry Karpeev #undef __FUNCT__
238347c6ae99SBarry Smith #define __FUNCT__ "DMComputeFunction"
238447c6ae99SBarry Smith /*@
238547c6ae99SBarry Smith     DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES
238647c6ae99SBarry Smith 
238747c6ae99SBarry Smith     Collective on DM
238847c6ae99SBarry Smith 
238947c6ae99SBarry Smith     Input Parameter:
239047c6ae99SBarry Smith +   dm - the DM object to destroy
239147c6ae99SBarry Smith .   x - the location where the function is evaluationed, may be ignored for linear problems
239247c6ae99SBarry Smith -   b - the vector to hold the right hand side entries
239347c6ae99SBarry Smith 
239447c6ae99SBarry Smith     Level: developer
239547c6ae99SBarry Smith 
2396e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
239747c6ae99SBarry Smith          DMSetJacobian()
239847c6ae99SBarry Smith 
239947c6ae99SBarry Smith @*/
24007087cfbeSBarry Smith PetscErrorCode  DMComputeFunction(DM dm,Vec x,Vec b)
240147c6ae99SBarry Smith {
240247c6ae99SBarry Smith   PetscErrorCode ierr;
240347c6ae99SBarry Smith   PetscFunctionBegin;
2404171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
240547c6ae99SBarry Smith   if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()");
2406644e2e5bSBarry Smith   PetscStackPush("DM user function");
240747c6ae99SBarry Smith   ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr);
2408644e2e5bSBarry Smith   PetscStackPop;
240947c6ae99SBarry Smith   PetscFunctionReturn(0);
241047c6ae99SBarry Smith }
241147c6ae99SBarry Smith 
241247c6ae99SBarry Smith 
241308da532bSDmitry Karpeev 
241447c6ae99SBarry Smith #undef __FUNCT__
241547c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobian"
241647c6ae99SBarry Smith /*@
241747c6ae99SBarry Smith     DMComputeJacobian - compute the matrix entries for the solver
241847c6ae99SBarry Smith 
241947c6ae99SBarry Smith     Collective on DM
242047c6ae99SBarry Smith 
242147c6ae99SBarry Smith     Input Parameter:
242247c6ae99SBarry Smith +   dm - the DM object
2423cab2e9ccSBarry Smith .   x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM
242447c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
242547c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
242647c6ae99SBarry Smith 
242747c6ae99SBarry Smith     Level: developer
242847c6ae99SBarry Smith 
2429e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
243047c6ae99SBarry Smith          DMSetFunction()
243147c6ae99SBarry Smith 
243247c6ae99SBarry Smith @*/
24337087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
243447c6ae99SBarry Smith {
243547c6ae99SBarry Smith   PetscErrorCode ierr;
243647c6ae99SBarry Smith 
243747c6ae99SBarry Smith   PetscFunctionBegin;
2438171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
243947c6ae99SBarry Smith   if (!dm->ops->jacobian) {
244047c6ae99SBarry Smith     ISColoring     coloring;
244147c6ae99SBarry Smith     MatFDColoring  fd;
2442*19fd82e9SBarry Smith     MatType  mtype;
244347c6ae99SBarry Smith 
24442c9966d7SBarry Smith     ierr = PetscObjectGetType((PetscObject)B,&mtype);CHKERRQ(ierr);
24452c9966d7SBarry Smith     ierr = DMCreateColoring(dm,dm->coloringtype,mtype,&coloring);CHKERRQ(ierr);
244647c6ae99SBarry Smith     ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr);
2447fcfd50ebSBarry Smith     ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
244847c6ae99SBarry Smith     ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr);
24490bdded8aSJed Brown     ierr = PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);CHKERRQ(ierr);
24500bdded8aSJed Brown     ierr = MatFDColoringSetFromOptions(fd);CHKERRQ(ierr);
245171cd77b2SBarry Smith 
245247c6ae99SBarry Smith     dm->fd = fd;
245347c6ae99SBarry Smith     dm->ops->jacobian = DMComputeJacobianDefault;
24542533e041SBarry Smith 
245571cd77b2SBarry Smith     /* don't know why this is needed */
245671cd77b2SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
245747c6ae99SBarry Smith   }
245847c6ae99SBarry Smith   if (!x) x = dm->x;
245947c6ae99SBarry Smith   ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr);
2460cab2e9ccSBarry Smith 
246171cd77b2SBarry Smith   /* if matrix depends on x; i.e. nonlinear problem, keep copy of input vector since needed by multigrid methods to generate coarse grid matrices */
2462649052a6SBarry Smith   if (x) {
2463cab2e9ccSBarry Smith     if (!dm->x) {
246471cd77b2SBarry Smith       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
2465cab2e9ccSBarry Smith     }
2466cab2e9ccSBarry Smith     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
2467649052a6SBarry Smith   }
2468a8248277SBarry Smith   if (A != B) {
2469a8248277SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2470a8248277SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2471a8248277SBarry Smith   }
247247c6ae99SBarry Smith   PetscFunctionReturn(0);
247347c6ae99SBarry Smith }
2474264ace61SBarry Smith 
2475cab2e9ccSBarry Smith 
2476264ace61SBarry Smith PetscFList DMList                       = PETSC_NULL;
2477264ace61SBarry Smith PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
2478264ace61SBarry Smith 
2479264ace61SBarry Smith #undef __FUNCT__
2480264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2481264ace61SBarry Smith /*@C
2482264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2483264ace61SBarry Smith 
2484264ace61SBarry Smith   Collective on DM
2485264ace61SBarry Smith 
2486264ace61SBarry Smith   Input Parameters:
2487264ace61SBarry Smith + dm     - The DM object
2488264ace61SBarry Smith - method - The name of the DM type
2489264ace61SBarry Smith 
2490264ace61SBarry Smith   Options Database Key:
2491264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2492264ace61SBarry Smith 
2493264ace61SBarry Smith   Notes:
2494e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2495264ace61SBarry Smith 
2496264ace61SBarry Smith   Level: intermediate
2497264ace61SBarry Smith 
2498264ace61SBarry Smith .keywords: DM, set, type
2499264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2500264ace61SBarry Smith @*/
2501*19fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
2502264ace61SBarry Smith {
2503264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2504264ace61SBarry Smith   PetscBool      match;
2505264ace61SBarry Smith   PetscErrorCode ierr;
2506264ace61SBarry Smith 
2507264ace61SBarry Smith   PetscFunctionBegin;
2508264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2509251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2510264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2511264ace61SBarry Smith 
2512264ace61SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
25134b91b6eaSBarry Smith   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2514264ace61SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2515264ace61SBarry Smith 
2516264ace61SBarry Smith   if (dm->ops->destroy) {
2517264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
2518b5c23020SJed Brown     dm->ops->destroy = PETSC_NULL;
2519264ace61SBarry Smith   }
2520264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2521264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2522264ace61SBarry Smith   PetscFunctionReturn(0);
2523264ace61SBarry Smith }
2524264ace61SBarry Smith 
2525264ace61SBarry Smith #undef __FUNCT__
2526264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2527264ace61SBarry Smith /*@C
2528264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2529264ace61SBarry Smith 
2530264ace61SBarry Smith   Not Collective
2531264ace61SBarry Smith 
2532264ace61SBarry Smith   Input Parameter:
2533264ace61SBarry Smith . dm  - The DM
2534264ace61SBarry Smith 
2535264ace61SBarry Smith   Output Parameter:
2536264ace61SBarry Smith . type - The DM type name
2537264ace61SBarry Smith 
2538264ace61SBarry Smith   Level: intermediate
2539264ace61SBarry Smith 
2540264ace61SBarry Smith .keywords: DM, get, type, name
2541264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2542264ace61SBarry Smith @*/
2543*19fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
2544264ace61SBarry Smith {
2545264ace61SBarry Smith   PetscErrorCode ierr;
2546264ace61SBarry Smith 
2547264ace61SBarry Smith   PetscFunctionBegin;
2548264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2549264ace61SBarry Smith   PetscValidCharPointer(type,2);
2550264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2551264ace61SBarry Smith     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2552264ace61SBarry Smith   }
2553264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2554264ace61SBarry Smith   PetscFunctionReturn(0);
2555264ace61SBarry Smith }
2556264ace61SBarry Smith 
255767a56275SMatthew G Knepley #undef __FUNCT__
255867a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
255967a56275SMatthew G Knepley /*@C
256067a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
256167a56275SMatthew G Knepley 
256267a56275SMatthew G Knepley   Collective on DM
256367a56275SMatthew G Knepley 
256467a56275SMatthew G Knepley   Input Parameters:
256567a56275SMatthew G Knepley + dm - the DM
256667a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
256767a56275SMatthew G Knepley 
256867a56275SMatthew G Knepley   Output Parameter:
256967a56275SMatthew G Knepley . M - pointer to new DM
257067a56275SMatthew G Knepley 
257167a56275SMatthew G Knepley   Notes:
257267a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
257367a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
257467a56275SMatthew G Knepley   of the input DM.
257567a56275SMatthew G Knepley 
257667a56275SMatthew G Knepley   Level: intermediate
257767a56275SMatthew G Knepley 
257867a56275SMatthew G Knepley .seealso: DMCreate()
257967a56275SMatthew G Knepley @*/
2580*19fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
258167a56275SMatthew G Knepley {
258267a56275SMatthew G Knepley   DM             B;
258367a56275SMatthew G Knepley   char           convname[256];
258467a56275SMatthew G Knepley   PetscBool      sametype, issame;
258567a56275SMatthew G Knepley   PetscErrorCode ierr;
258667a56275SMatthew G Knepley 
258767a56275SMatthew G Knepley   PetscFunctionBegin;
258867a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
258967a56275SMatthew G Knepley   PetscValidType(dm,1);
259067a56275SMatthew G Knepley   PetscValidPointer(M,3);
2591251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
259267a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
259367a56275SMatthew G Knepley   {
2594*19fd82e9SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM *) = PETSC_NULL;
259567a56275SMatthew G Knepley 
259667a56275SMatthew G Knepley     /*
259767a56275SMatthew G Knepley        Order of precedence:
259867a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
259967a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
260067a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
260167a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
260267a56275SMatthew G Knepley        5) Use a really basic converter.
260367a56275SMatthew G Knepley     */
260467a56275SMatthew G Knepley 
260567a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
260667a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
260767a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
260867a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
260967a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
261067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
261167a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
261267a56275SMatthew G Knepley     if (conv) goto foundconv;
261367a56275SMatthew G Knepley 
261467a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
261567a56275SMatthew G Knepley     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
261667a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
261767a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
261867a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
261967a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
262067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
262167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
262267a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
262367a56275SMatthew G Knepley     if (conv) {
2624fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
262567a56275SMatthew G Knepley       goto foundconv;
262667a56275SMatthew G Knepley     }
262767a56275SMatthew G Knepley 
262867a56275SMatthew G Knepley #if 0
262967a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
263067a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2631fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
263267a56275SMatthew G Knepley     if (conv) goto foundconv;
263367a56275SMatthew G Knepley 
263467a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
263567a56275SMatthew G Knepley     if (dm->ops->convert) {
263667a56275SMatthew G Knepley       conv = dm->ops->convert;
263767a56275SMatthew G Knepley     }
263867a56275SMatthew G Knepley     if (conv) goto foundconv;
263967a56275SMatthew G Knepley #endif
264067a56275SMatthew G Knepley 
264167a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
264267a56275SMatthew G Knepley     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
264367a56275SMatthew G Knepley 
264467a56275SMatthew G Knepley     foundconv:
264567a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
264667a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
264767a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
264867a56275SMatthew G Knepley   }
264967a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
265067a56275SMatthew G Knepley   PetscFunctionReturn(0);
265167a56275SMatthew G Knepley }
2652264ace61SBarry Smith 
2653264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2654264ace61SBarry Smith 
2655264ace61SBarry Smith #undef __FUNCT__
2656264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2657264ace61SBarry Smith /*@C
2658264ace61SBarry Smith   DMRegister - See DMRegisterDynamic()
2659264ace61SBarry Smith 
2660264ace61SBarry Smith   Level: advanced
2661264ace61SBarry Smith @*/
26627087cfbeSBarry Smith PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
2663264ace61SBarry Smith {
2664264ace61SBarry Smith   char fullname[PETSC_MAX_PATH_LEN];
2665264ace61SBarry Smith   PetscErrorCode ierr;
2666264ace61SBarry Smith 
2667264ace61SBarry Smith   PetscFunctionBegin;
2668264ace61SBarry Smith   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
2669264ace61SBarry Smith   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
2670264ace61SBarry Smith   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
2671264ace61SBarry Smith   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
2672264ace61SBarry Smith   PetscFunctionReturn(0);
2673264ace61SBarry Smith }
2674264ace61SBarry Smith 
2675264ace61SBarry Smith 
2676264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2677264ace61SBarry Smith #undef __FUNCT__
2678264ace61SBarry Smith #define __FUNCT__ "DMRegisterDestroy"
2679264ace61SBarry Smith /*@C
2680264ace61SBarry Smith    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
2681264ace61SBarry Smith 
2682264ace61SBarry Smith    Not Collective
2683264ace61SBarry Smith 
2684264ace61SBarry Smith    Level: advanced
2685264ace61SBarry Smith 
2686264ace61SBarry Smith .keywords: DM, register, destroy
2687264ace61SBarry Smith .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
2688264ace61SBarry Smith @*/
26897087cfbeSBarry Smith PetscErrorCode  DMRegisterDestroy(void)
2690264ace61SBarry Smith {
2691264ace61SBarry Smith   PetscErrorCode ierr;
2692264ace61SBarry Smith 
2693264ace61SBarry Smith   PetscFunctionBegin;
2694264ace61SBarry Smith   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
2695264ace61SBarry Smith   DMRegisterAllCalled = PETSC_FALSE;
2696264ace61SBarry Smith   PetscFunctionReturn(0);
2697264ace61SBarry Smith }
269823f975d1SBarry Smith 
269923f975d1SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2700c6db04a5SJed Brown #include <mex.h>
270123f975d1SBarry Smith 
27023014e516SBarry Smith typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext;
270323f975d1SBarry Smith 
270423f975d1SBarry Smith #undef __FUNCT__
270523f975d1SBarry Smith #define __FUNCT__ "DMComputeFunction_Matlab"
270623f975d1SBarry Smith /*
270723f975d1SBarry Smith    DMComputeFunction_Matlab - Calls the function that has been set with
270823f975d1SBarry Smith                          DMSetFunctionMatlab().
270923f975d1SBarry Smith 
271023f975d1SBarry Smith    For linear problems x is null
271123f975d1SBarry Smith 
271223f975d1SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
271323f975d1SBarry Smith */
27147087cfbeSBarry Smith PetscErrorCode  DMComputeFunction_Matlab(DM dm,Vec x,Vec y)
271523f975d1SBarry Smith {
271623f975d1SBarry Smith   PetscErrorCode    ierr;
271723f975d1SBarry Smith   DMMatlabContext   *sctx;
271823f975d1SBarry Smith   int               nlhs = 1,nrhs = 4;
271923f975d1SBarry Smith   mxArray	    *plhs[1],*prhs[4];
272023f975d1SBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
272123f975d1SBarry Smith 
272223f975d1SBarry Smith   PetscFunctionBegin;
272323f975d1SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
272423f975d1SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
272523f975d1SBarry Smith   PetscCheckSameComm(dm,1,y,3);
272623f975d1SBarry Smith 
272723f975d1SBarry Smith   /* call Matlab function in ctx with arguments x and y */
27281b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
272923f975d1SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
273023f975d1SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
27313014e516SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr);
273223f975d1SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
273323f975d1SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
273423f975d1SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
273523f975d1SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
2736b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr);
273723f975d1SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
273823f975d1SBarry Smith   mxDestroyArray(prhs[0]);
273923f975d1SBarry Smith   mxDestroyArray(prhs[1]);
274023f975d1SBarry Smith   mxDestroyArray(prhs[2]);
274123f975d1SBarry Smith   mxDestroyArray(prhs[3]);
274223f975d1SBarry Smith   mxDestroyArray(plhs[0]);
274323f975d1SBarry Smith   PetscFunctionReturn(0);
274423f975d1SBarry Smith }
274523f975d1SBarry Smith 
274623f975d1SBarry Smith 
274723f975d1SBarry Smith #undef __FUNCT__
274823f975d1SBarry Smith #define __FUNCT__ "DMSetFunctionMatlab"
274923f975d1SBarry Smith /*
275023f975d1SBarry Smith    DMSetFunctionMatlab - Sets the function evaluation routine
275123f975d1SBarry Smith 
275223f975d1SBarry Smith */
27537087cfbeSBarry Smith PetscErrorCode  DMSetFunctionMatlab(DM dm,const char *func)
275423f975d1SBarry Smith {
275523f975d1SBarry Smith   PetscErrorCode    ierr;
275623f975d1SBarry Smith   DMMatlabContext   *sctx;
275723f975d1SBarry Smith 
275823f975d1SBarry Smith   PetscFunctionBegin;
2759171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
276023f975d1SBarry Smith   /* currently sctx is memory bleed */
27611b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
27623014e516SBarry Smith   if (!sctx) {
276323f975d1SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
27643014e516SBarry Smith   }
276523f975d1SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
27661b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
276723f975d1SBarry Smith   ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr);
276823f975d1SBarry Smith   PetscFunctionReturn(0);
276923f975d1SBarry Smith }
27703014e516SBarry Smith 
27713014e516SBarry Smith #undef __FUNCT__
27723014e516SBarry Smith #define __FUNCT__ "DMComputeJacobian_Matlab"
27733014e516SBarry Smith /*
27743014e516SBarry Smith    DMComputeJacobian_Matlab - Calls the function that has been set with
27753014e516SBarry Smith                          DMSetJacobianMatlab().
27763014e516SBarry Smith 
27773014e516SBarry Smith    For linear problems x is null
27783014e516SBarry Smith 
27793014e516SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
27803014e516SBarry Smith */
27817087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str)
27823014e516SBarry Smith {
27833014e516SBarry Smith   PetscErrorCode    ierr;
27843014e516SBarry Smith   DMMatlabContext   *sctx;
27853014e516SBarry Smith   int               nlhs = 2,nrhs = 5;
27863014e516SBarry Smith   mxArray	    *plhs[2],*prhs[5];
27873014e516SBarry Smith   long long int     lx = 0,lA = 0,lB = 0,ls = 0;
27883014e516SBarry Smith 
27893014e516SBarry Smith   PetscFunctionBegin;
27903014e516SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
27913014e516SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
27923014e516SBarry Smith 
2793e3c5b3baSBarry Smith   /* call MATLAB function in ctx with arguments x, A, and B */
27941b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
27953014e516SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
27963014e516SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
27973014e516SBarry Smith   ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr);
27983014e516SBarry Smith   ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr);
27993014e516SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
28003014e516SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
28013014e516SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
28023014e516SBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
28033014e516SBarry Smith   prhs[4] =  mxCreateString(sctx->jacname);
2804b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr);
2805c980e822SBarry Smith   *str    =  (MatStructure) mxGetScalar(plhs[0]);
2806c088a8dcSBarry Smith   ierr    =  (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr);
28073014e516SBarry Smith   mxDestroyArray(prhs[0]);
28083014e516SBarry Smith   mxDestroyArray(prhs[1]);
28093014e516SBarry Smith   mxDestroyArray(prhs[2]);
28103014e516SBarry Smith   mxDestroyArray(prhs[3]);
28113014e516SBarry Smith   mxDestroyArray(prhs[4]);
28123014e516SBarry Smith   mxDestroyArray(plhs[0]);
28133014e516SBarry Smith   mxDestroyArray(plhs[1]);
28143014e516SBarry Smith   PetscFunctionReturn(0);
28153014e516SBarry Smith }
28163014e516SBarry Smith 
28173014e516SBarry Smith 
28183014e516SBarry Smith #undef __FUNCT__
28193014e516SBarry Smith #define __FUNCT__ "DMSetJacobianMatlab"
28203014e516SBarry Smith /*
28213014e516SBarry Smith    DMSetJacobianMatlab - Sets the Jacobian function evaluation routine
28223014e516SBarry Smith 
28233014e516SBarry Smith */
28247087cfbeSBarry Smith PetscErrorCode  DMSetJacobianMatlab(DM dm,const char *func)
28253014e516SBarry Smith {
28263014e516SBarry Smith   PetscErrorCode    ierr;
28273014e516SBarry Smith   DMMatlabContext   *sctx;
28283014e516SBarry Smith 
28293014e516SBarry Smith   PetscFunctionBegin;
2830171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
28313014e516SBarry Smith   /* currently sctx is memory bleed */
28321b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
28333014e516SBarry Smith   if (!sctx) {
28343014e516SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
28353014e516SBarry Smith   }
28363014e516SBarry Smith   ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr);
28371b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
28383014e516SBarry Smith   ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr);
28393014e516SBarry Smith   PetscFunctionReturn(0);
28403014e516SBarry Smith }
284123f975d1SBarry Smith #endif
2842b859378eSBarry Smith 
2843b859378eSBarry Smith #undef __FUNCT__
2844b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2845b859378eSBarry Smith /*@C
2846b859378eSBarry Smith   DMLoad - Loads a DM that has been stored in binary or HDF5 format
2847b859378eSBarry Smith   with DMView().
2848b859378eSBarry Smith 
2849b859378eSBarry Smith   Collective on PetscViewer
2850b859378eSBarry Smith 
2851b859378eSBarry Smith   Input Parameters:
2852b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2853b859378eSBarry Smith            some related function before a call to DMLoad().
2854b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2855b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2856b859378eSBarry Smith 
2857b859378eSBarry Smith    Level: intermediate
2858b859378eSBarry Smith 
2859b859378eSBarry Smith   Notes:
2860b859378eSBarry Smith   Defaults to the DM DA.
2861b859378eSBarry Smith 
2862b859378eSBarry Smith   Notes for advanced users:
2863b859378eSBarry Smith   Most users should not need to know the details of the binary storage
2864b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
2865b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
2866b859378eSBarry Smith   format is
2867b859378eSBarry Smith .vb
2868b859378eSBarry Smith      has not yet been determined
2869b859378eSBarry Smith .ve
2870b859378eSBarry Smith 
2871b859378eSBarry Smith    In addition, PETSc automatically does the byte swapping for
2872b859378eSBarry Smith machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
2873b859378eSBarry Smith linux, Windows and the paragon; thus if you write your own binary
2874b859378eSBarry Smith read/write routines you have to swap the bytes; see PetscBinaryRead()
2875b859378eSBarry Smith and PetscBinaryWrite() to see how this may be done.
2876b859378eSBarry Smith 
2877b859378eSBarry Smith   Concepts: vector^loading from file
2878b859378eSBarry Smith 
2879b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2880b859378eSBarry Smith @*/
2881b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2882b859378eSBarry Smith {
2883b859378eSBarry Smith   PetscErrorCode ierr;
2884b859378eSBarry Smith 
2885b859378eSBarry Smith   PetscFunctionBegin;
2886b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2887b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
2888b859378eSBarry Smith 
2889b859378eSBarry Smith   if (!((PetscObject)newdm)->type_name) {
2890b859378eSBarry Smith     ierr = DMSetType(newdm, DMDA);CHKERRQ(ierr);
2891b859378eSBarry Smith   }
2892b859378eSBarry Smith   ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
2893b859378eSBarry Smith   PetscFunctionReturn(0);
2894b859378eSBarry Smith }
2895b859378eSBarry Smith 
28967da65231SMatthew G Knepley /******************************** FEM Support **********************************/
28977da65231SMatthew G Knepley 
28987da65231SMatthew G Knepley #undef __FUNCT__
28997da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
29007da65231SMatthew G Knepley PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
29011d47ebbbSSatish Balay   PetscInt       f;
29021b30c384SMatthew G Knepley   PetscErrorCode ierr;
29031b30c384SMatthew G Knepley 
29047da65231SMatthew G Knepley   PetscFunctionBegin;
290574778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
29061d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
290774778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
29087da65231SMatthew G Knepley   }
29097da65231SMatthew G Knepley   PetscFunctionReturn(0);
29107da65231SMatthew G Knepley }
29117da65231SMatthew G Knepley 
29127da65231SMatthew G Knepley #undef __FUNCT__
29137da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
29147da65231SMatthew G Knepley PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
29151b30c384SMatthew G Knepley   PetscInt       f, g;
29167da65231SMatthew G Knepley   PetscErrorCode ierr;
29177da65231SMatthew G Knepley 
29187da65231SMatthew G Knepley   PetscFunctionBegin;
291974778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
29201d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
292174778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
29221d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
292374778d6cSJed Brown       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
29247da65231SMatthew G Knepley     }
292574778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
29267da65231SMatthew G Knepley   }
29277da65231SMatthew G Knepley   PetscFunctionReturn(0);
29287da65231SMatthew G Knepley }
2929e7c4fc90SDmitry Karpeev 
2930970e74d5SMatthew G Knepley #undef __FUNCT__
2931970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalFunction"
2932970e74d5SMatthew G Knepley /*@C
2933970e74d5SMatthew G Knepley   DMGetLocalFunction - Get the local residual function from this DM
2934970e74d5SMatthew G Knepley 
2935970e74d5SMatthew G Knepley   Not collective
2936970e74d5SMatthew G Knepley 
2937970e74d5SMatthew G Knepley   Input Parameter:
2938970e74d5SMatthew G Knepley . dm - The DM
2939970e74d5SMatthew G Knepley 
2940970e74d5SMatthew G Knepley   Output Parameter:
2941970e74d5SMatthew G Knepley . lf - The local residual function
2942970e74d5SMatthew G Knepley 
2943970e74d5SMatthew G Knepley    Calling sequence of lf:
2944970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
2945970e74d5SMatthew G Knepley 
2946970e74d5SMatthew G Knepley +  snes - the SNES context
2947970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2948970e74d5SMatthew G Knepley .  f - local vector to put residual in
2949970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2950970e74d5SMatthew G Knepley 
2951970e74d5SMatthew G Knepley   Level: intermediate
2952970e74d5SMatthew G Knepley 
2953970e74d5SMatthew G Knepley .seealso DMSetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
2954970e74d5SMatthew G Knepley @*/
2955970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalFunction(DM dm, PetscErrorCode (**lf)(DM, Vec, Vec, void *))
2956970e74d5SMatthew G Knepley {
2957970e74d5SMatthew G Knepley   PetscFunctionBegin;
2958970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2959970e74d5SMatthew G Knepley   if (lf) *lf = dm->lf;
2960970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2961970e74d5SMatthew G Knepley }
2962970e74d5SMatthew G Knepley 
2963970e74d5SMatthew G Knepley #undef __FUNCT__
2964970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalFunction"
2965970e74d5SMatthew G Knepley /*@C
2966970e74d5SMatthew G Knepley   DMSetLocalFunction - Set the local residual function from this DM
2967970e74d5SMatthew G Knepley 
2968970e74d5SMatthew G Knepley   Not collective
2969970e74d5SMatthew G Knepley 
2970970e74d5SMatthew G Knepley   Input Parameters:
2971970e74d5SMatthew G Knepley + dm - The DM
2972970e74d5SMatthew G Knepley - lf - The local residual function
2973970e74d5SMatthew G Knepley 
2974970e74d5SMatthew G Knepley    Calling sequence of lf:
2975970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
2976970e74d5SMatthew G Knepley 
2977970e74d5SMatthew G Knepley +  snes - the SNES context
2978970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2979970e74d5SMatthew G Knepley .  f - local vector to put residual in
2980970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2981970e74d5SMatthew G Knepley 
2982970e74d5SMatthew G Knepley   Level: intermediate
2983970e74d5SMatthew G Knepley 
2984970e74d5SMatthew G Knepley .seealso DMGetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
2985970e74d5SMatthew G Knepley @*/
2986970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalFunction(DM dm, PetscErrorCode (*lf)(DM, Vec, Vec, void *))
2987970e74d5SMatthew G Knepley {
2988970e74d5SMatthew G Knepley   PetscFunctionBegin;
2989970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2990970e74d5SMatthew G Knepley   dm->lf = lf;
2991970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2992970e74d5SMatthew G Knepley }
2993970e74d5SMatthew G Knepley 
2994970e74d5SMatthew G Knepley #undef __FUNCT__
2995970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalJacobian"
2996970e74d5SMatthew G Knepley /*@C
2997970e74d5SMatthew G Knepley   DMGetLocalJacobian - Get the local Jacobian function from this DM
2998970e74d5SMatthew G Knepley 
2999970e74d5SMatthew G Knepley   Not collective
3000970e74d5SMatthew G Knepley 
3001970e74d5SMatthew G Knepley   Input Parameter:
3002970e74d5SMatthew G Knepley . dm - The DM
3003970e74d5SMatthew G Knepley 
3004970e74d5SMatthew G Knepley   Output Parameter:
3005970e74d5SMatthew G Knepley . lj - The local Jacobian function
3006970e74d5SMatthew G Knepley 
3007970e74d5SMatthew G Knepley    Calling sequence of lj:
3008970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
3009970e74d5SMatthew G Knepley 
3010970e74d5SMatthew G Knepley +  snes - the SNES context
3011970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3012970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
3013970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
3014970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3015970e74d5SMatthew G Knepley 
3016970e74d5SMatthew G Knepley   Level: intermediate
3017970e74d5SMatthew G Knepley 
3018970e74d5SMatthew G Knepley .seealso DMSetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
3019970e74d5SMatthew G Knepley @*/
3020970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalJacobian(DM dm, PetscErrorCode (**lj)(DM, Vec, Mat, Mat, void *))
3021970e74d5SMatthew G Knepley {
3022970e74d5SMatthew G Knepley   PetscFunctionBegin;
3023970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3024970e74d5SMatthew G Knepley   if (lj) *lj = dm->lj;
3025970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3026970e74d5SMatthew G Knepley }
3027970e74d5SMatthew G Knepley 
3028970e74d5SMatthew G Knepley #undef __FUNCT__
3029970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalJacobian"
3030970e74d5SMatthew G Knepley /*@C
3031970e74d5SMatthew G Knepley   DMSetLocalJacobian - Set the local Jacobian function from this DM
3032970e74d5SMatthew G Knepley 
3033970e74d5SMatthew G Knepley   Not collective
3034970e74d5SMatthew G Knepley 
3035970e74d5SMatthew G Knepley   Input Parameters:
3036970e74d5SMatthew G Knepley + dm - The DM
3037970e74d5SMatthew G Knepley - lj - The local Jacobian function
3038970e74d5SMatthew G Knepley 
3039970e74d5SMatthew G Knepley    Calling sequence of lj:
3040970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
3041970e74d5SMatthew G Knepley 
3042970e74d5SMatthew G Knepley +  snes - the SNES context
3043970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3044970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
3045970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
3046970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3047970e74d5SMatthew G Knepley 
3048970e74d5SMatthew G Knepley   Level: intermediate
3049970e74d5SMatthew G Knepley 
3050970e74d5SMatthew G Knepley .seealso DMGetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
3051970e74d5SMatthew G Knepley @*/
3052970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalJacobian(DM dm, PetscErrorCode (*lj)(DM, Vec, Mat,  Mat, void *))
3053970e74d5SMatthew G Knepley {
3054970e74d5SMatthew G Knepley   PetscFunctionBegin;
3055970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3056970e74d5SMatthew G Knepley   dm->lj = lj;
3057970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3058970e74d5SMatthew G Knepley }
305988ed4aceSMatthew G Knepley 
306088ed4aceSMatthew G Knepley #undef __FUNCT__
306188ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
306288ed4aceSMatthew G Knepley /*@
306388ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
306488ed4aceSMatthew G Knepley 
306588ed4aceSMatthew G Knepley   Input Parameter:
306688ed4aceSMatthew G Knepley . dm - The DM
306788ed4aceSMatthew G Knepley 
306888ed4aceSMatthew G Knepley   Output Parameter:
306988ed4aceSMatthew G Knepley . section - The PetscSection
307088ed4aceSMatthew G Knepley 
307188ed4aceSMatthew G Knepley   Level: intermediate
307288ed4aceSMatthew G Knepley 
307388ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
307488ed4aceSMatthew G Knepley 
307588ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
307688ed4aceSMatthew G Knepley @*/
307788ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) {
307888ed4aceSMatthew G Knepley   PetscFunctionBegin;
307988ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
308088ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
308188ed4aceSMatthew G Knepley   *section = dm->defaultSection;
308288ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
308388ed4aceSMatthew G Knepley }
308488ed4aceSMatthew G Knepley 
308588ed4aceSMatthew G Knepley #undef __FUNCT__
308688ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
308788ed4aceSMatthew G Knepley /*@
308888ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
308988ed4aceSMatthew G Knepley 
309088ed4aceSMatthew G Knepley   Input Parameters:
309188ed4aceSMatthew G Knepley + dm - The DM
309288ed4aceSMatthew G Knepley - section - The PetscSection
309388ed4aceSMatthew G Knepley 
309488ed4aceSMatthew G Knepley   Level: intermediate
309588ed4aceSMatthew G Knepley 
309688ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
309788ed4aceSMatthew G Knepley 
309888ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
309988ed4aceSMatthew G Knepley @*/
310088ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) {
3101af122d2aSMatthew G Knepley   PetscInt       numFields;
3102af122d2aSMatthew G Knepley   PetscInt       f;
310388ed4aceSMatthew G Knepley   PetscErrorCode ierr;
310488ed4aceSMatthew G Knepley 
310588ed4aceSMatthew G Knepley   PetscFunctionBegin;
310688ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
310788ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
310888ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
310988ed4aceSMatthew G Knepley   dm->defaultSection = section;
3110af122d2aSMatthew G Knepley   ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);
3111af122d2aSMatthew G Knepley   if (numFields) {
3112af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
3113af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
3114af122d2aSMatthew G Knepley       const char *name;
3115af122d2aSMatthew G Knepley 
3116af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
3117af122d2aSMatthew G Knepley       ierr = PetscObjectSetName(dm->fields[f], name);CHKERRQ(ierr);
3118af122d2aSMatthew G Knepley     }
3119af122d2aSMatthew G Knepley   }
312088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
312188ed4aceSMatthew G Knepley }
312288ed4aceSMatthew G Knepley 
312388ed4aceSMatthew G Knepley #undef __FUNCT__
312488ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
312588ed4aceSMatthew G Knepley /*@
312688ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
312788ed4aceSMatthew G Knepley 
312888ed4aceSMatthew G Knepley   Input Parameter:
312988ed4aceSMatthew G Knepley . dm - The DM
313088ed4aceSMatthew G Knepley 
313188ed4aceSMatthew G Knepley   Output Parameter:
313288ed4aceSMatthew G Knepley . section - The PetscSection
313388ed4aceSMatthew G Knepley 
313488ed4aceSMatthew G Knepley   Level: intermediate
313588ed4aceSMatthew G Knepley 
313688ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
313788ed4aceSMatthew G Knepley 
313888ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
313988ed4aceSMatthew G Knepley @*/
314088ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) {
314188ed4aceSMatthew G Knepley   PetscErrorCode ierr;
314288ed4aceSMatthew G Knepley 
314388ed4aceSMatthew G Knepley   PetscFunctionBegin;
314488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
314588ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
314688ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
3147b21d0597SMatthew G Knepley     ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
314888ed4aceSMatthew G Knepley   }
314988ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
315088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
315188ed4aceSMatthew G Knepley }
315288ed4aceSMatthew G Knepley 
315388ed4aceSMatthew G Knepley #undef __FUNCT__
3154b21d0597SMatthew G Knepley #define __FUNCT__ "DMSetDefaultGlobalSection"
3155b21d0597SMatthew G Knepley /*@
3156b21d0597SMatthew G Knepley   DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM.
3157b21d0597SMatthew G Knepley 
3158b21d0597SMatthew G Knepley   Input Parameters:
3159b21d0597SMatthew G Knepley + dm - The DM
3160b21d0597SMatthew G Knepley - section - The PetscSection
3161b21d0597SMatthew G Knepley 
3162b21d0597SMatthew G Knepley   Level: intermediate
3163b21d0597SMatthew G Knepley 
3164b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
3165b21d0597SMatthew G Knepley 
3166b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection()
3167b21d0597SMatthew G Knepley @*/
3168b21d0597SMatthew G Knepley PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section) {
3169b21d0597SMatthew G Knepley   PetscErrorCode ierr;
3170b21d0597SMatthew G Knepley 
3171b21d0597SMatthew G Knepley   PetscFunctionBegin;
3172b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3173b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
3174b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
3175b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3176b21d0597SMatthew G Knepley }
3177b21d0597SMatthew G Knepley 
3178b21d0597SMatthew G Knepley #undef __FUNCT__
317988ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
318088ed4aceSMatthew G Knepley /*@
318188ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
318288ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
318388ed4aceSMatthew G Knepley 
318488ed4aceSMatthew G Knepley   Input Parameter:
318588ed4aceSMatthew G Knepley . dm - The DM
318688ed4aceSMatthew G Knepley 
318788ed4aceSMatthew G Knepley   Output Parameter:
318888ed4aceSMatthew G Knepley . sf - The PetscSF
318988ed4aceSMatthew G Knepley 
319088ed4aceSMatthew G Knepley   Level: intermediate
319188ed4aceSMatthew G Knepley 
319288ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
319388ed4aceSMatthew G Knepley 
319488ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
319588ed4aceSMatthew G Knepley @*/
319688ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) {
319788ed4aceSMatthew G Knepley   PetscInt       nroots;
319888ed4aceSMatthew G Knepley   PetscErrorCode ierr;
319988ed4aceSMatthew G Knepley 
320088ed4aceSMatthew G Knepley   PetscFunctionBegin;
320188ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
320288ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
320388ed4aceSMatthew G Knepley   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
320488ed4aceSMatthew G Knepley   if (nroots < 0) {
320588ed4aceSMatthew G Knepley     PetscSection section, gSection;
320688ed4aceSMatthew G Knepley 
320788ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
320831ea6d37SMatthew G Knepley     if (section) {
320988ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
321088ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
321131ea6d37SMatthew G Knepley     } else {
321231ea6d37SMatthew G Knepley       *sf = PETSC_NULL;
321331ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
321431ea6d37SMatthew G Knepley     }
321588ed4aceSMatthew G Knepley   }
321688ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
321788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
321888ed4aceSMatthew G Knepley }
321988ed4aceSMatthew G Knepley 
322088ed4aceSMatthew G Knepley #undef __FUNCT__
322188ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
322288ed4aceSMatthew G Knepley /*@
322388ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
322488ed4aceSMatthew G Knepley 
322588ed4aceSMatthew G Knepley   Input Parameters:
322688ed4aceSMatthew G Knepley + dm - The DM
322788ed4aceSMatthew G Knepley - sf - The PetscSF
322888ed4aceSMatthew G Knepley 
322988ed4aceSMatthew G Knepley   Level: intermediate
323088ed4aceSMatthew G Knepley 
323188ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
323288ed4aceSMatthew G Knepley 
323388ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
323488ed4aceSMatthew G Knepley @*/
323588ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) {
323688ed4aceSMatthew G Knepley   PetscErrorCode ierr;
323788ed4aceSMatthew G Knepley 
323888ed4aceSMatthew G Knepley   PetscFunctionBegin;
323988ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
324088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
324188ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
324288ed4aceSMatthew G Knepley   dm->defaultSF = sf;
324388ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
324488ed4aceSMatthew G Knepley }
324588ed4aceSMatthew G Knepley 
324688ed4aceSMatthew G Knepley #undef __FUNCT__
324788ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
324888ed4aceSMatthew G Knepley /*@C
324988ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
325088ed4aceSMatthew G Knepley   describing the data layout.
325188ed4aceSMatthew G Knepley 
325288ed4aceSMatthew G Knepley   Input Parameters:
325388ed4aceSMatthew G Knepley + dm - The DM
325488ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
325588ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
325688ed4aceSMatthew G Knepley 
325788ed4aceSMatthew G Knepley   Level: intermediate
325888ed4aceSMatthew G Knepley 
325988ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
326088ed4aceSMatthew G Knepley @*/
326188ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
326288ed4aceSMatthew G Knepley {
326388ed4aceSMatthew G Knepley   MPI_Comm        comm = ((PetscObject) dm)->comm;
326488ed4aceSMatthew G Knepley   PetscLayout     layout;
326588ed4aceSMatthew G Knepley   const PetscInt *ranges;
326688ed4aceSMatthew G Knepley   PetscInt       *local;
326788ed4aceSMatthew G Knepley   PetscSFNode    *remote;
326888ed4aceSMatthew G Knepley   PetscInt        pStart, pEnd, p, nroots, nleaves, l;
326988ed4aceSMatthew G Knepley   PetscMPIInt     size, rank;
327088ed4aceSMatthew G Knepley   PetscErrorCode  ierr;
327188ed4aceSMatthew G Knepley 
327288ed4aceSMatthew G Knepley   PetscFunctionBegin;
327388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
327488ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
327588ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
327688ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
327788ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
327888ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
327988ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
328088ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
328188ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
328288ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
328388ed4aceSMatthew G Knepley   for (p = pStart, nleaves = 0; p < pEnd; ++p) {
32846636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
328588ed4aceSMatthew G Knepley 
32866636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
32876636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
32886636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
328988ed4aceSMatthew G Knepley   }
329088ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr);
329188ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr);
329288ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
329388ed4aceSMatthew G Knepley     PetscInt *cind;
32946636e97aSMatthew G Knepley     PetscInt  dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
329588ed4aceSMatthew G Knepley 
329688ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
329788ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
329888ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
329988ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
330088ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
33016636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
330288ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
33036636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
33046636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
33056636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
33066636e97aSMatthew 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", size, p, dof-cdof, dof);
33076636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
33086636e97aSMatthew G Knepley     }
330988ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
331088ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
331188ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
331288ed4aceSMatthew G Knepley     }
331388ed4aceSMatthew G Knepley     if (gdof < 0) {
33146636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
331588ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
331688ed4aceSMatthew G Knepley 
331788ed4aceSMatthew G Knepley         for (r = 0; r < size; ++r) {
331888ed4aceSMatthew G Knepley           if ((offset >= ranges[r]) && (offset < ranges[r+1])) break;
331988ed4aceSMatthew G Knepley         }
332088ed4aceSMatthew G Knepley         remote[l].rank  = r;
332188ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
332288ed4aceSMatthew G Knepley       }
332388ed4aceSMatthew G Knepley     } else {
33246636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
332588ed4aceSMatthew G Knepley         remote[l].rank  = rank;
332688ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
332788ed4aceSMatthew G Knepley       }
332888ed4aceSMatthew G Knepley     }
332988ed4aceSMatthew G Knepley   }
33306636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
333188ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
333288ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
333388ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
333488ed4aceSMatthew G Knepley }
3335af122d2aSMatthew G Knepley 
3336af122d2aSMatthew G Knepley #undef __FUNCT__
3337b21d0597SMatthew G Knepley #define __FUNCT__ "DMGetPointSF"
3338b21d0597SMatthew G Knepley /*@
3339b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
3340b21d0597SMatthew G Knepley 
3341b21d0597SMatthew G Knepley   Input Parameter:
3342b21d0597SMatthew G Knepley . dm - The DM
3343b21d0597SMatthew G Knepley 
3344b21d0597SMatthew G Knepley   Output Parameter:
3345b21d0597SMatthew G Knepley . sf - The PetscSF
3346b21d0597SMatthew G Knepley 
3347b21d0597SMatthew G Knepley   Level: intermediate
3348b21d0597SMatthew G Knepley 
3349b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
3350b21d0597SMatthew G Knepley 
3351b21d0597SMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3352b21d0597SMatthew G Knepley @*/
3353b21d0597SMatthew G Knepley PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) {
3354b21d0597SMatthew G Knepley   PetscFunctionBegin;
3355b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3356b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
3357b21d0597SMatthew G Knepley   *sf = dm->sf;
3358b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3359b21d0597SMatthew G Knepley }
3360b21d0597SMatthew G Knepley 
3361b21d0597SMatthew G Knepley #undef __FUNCT__
3362af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetNumFields"
3363af122d2aSMatthew G Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
3364af122d2aSMatthew G Knepley {
3365af122d2aSMatthew G Knepley   PetscFunctionBegin;
3366af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3367af122d2aSMatthew G Knepley   PetscValidPointer(numFields, 2);
3368af122d2aSMatthew G Knepley   *numFields = dm->numFields;
3369af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3370af122d2aSMatthew G Knepley }
3371af122d2aSMatthew G Knepley 
3372af122d2aSMatthew G Knepley #undef __FUNCT__
3373af122d2aSMatthew G Knepley #define __FUNCT__ "DMSetNumFields"
3374af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
3375af122d2aSMatthew G Knepley {
3376af122d2aSMatthew G Knepley   PetscInt       f;
3377af122d2aSMatthew G Knepley   PetscErrorCode ierr;
3378af122d2aSMatthew G Knepley 
3379af122d2aSMatthew G Knepley   PetscFunctionBegin;
3380af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3381af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3382af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&dm->fields[f]);CHKERRQ(ierr);
3383af122d2aSMatthew G Knepley   }
3384af122d2aSMatthew G Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
3385af122d2aSMatthew G Knepley   dm->numFields = numFields;
3386af122d2aSMatthew G Knepley   ierr = PetscMalloc(dm->numFields * sizeof(PetscObject), &dm->fields);CHKERRQ(ierr);
3387af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3388af122d2aSMatthew G Knepley     ierr = PetscContainerCreate(((PetscObject) dm)->comm, (PetscContainer *) &dm->fields[f]);CHKERRQ(ierr);
3389af122d2aSMatthew G Knepley   }
3390af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3391af122d2aSMatthew G Knepley }
3392af122d2aSMatthew G Knepley 
3393af122d2aSMatthew G Knepley #undef __FUNCT__
3394af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetField"
3395af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field)
3396af122d2aSMatthew G Knepley {
3397af122d2aSMatthew G Knepley   PetscFunctionBegin;
3398af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3399af122d2aSMatthew G Knepley   PetscValidPointer(field, 2);
3400af122d2aSMatthew G Knepley   if (!dm->fields) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Fields have not been setup in this DM. Call DMSetNumFields()");
3401af122d2aSMatthew G Knepley   if ((f < 0) || (f >= dm->numFields)) SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Field %d should be in [%d,%d)", f, 0, dm->numFields);
3402af122d2aSMatthew G Knepley   *field = dm->fields[f];
3403af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3404af122d2aSMatthew G Knepley }
34056636e97aSMatthew G Knepley 
34066636e97aSMatthew G Knepley #undef __FUNCT__
34076636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinates"
34086636e97aSMatthew G Knepley /*@
34096636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
34106636e97aSMatthew G Knepley 
34116636e97aSMatthew G Knepley   Collective on DM
34126636e97aSMatthew G Knepley 
34136636e97aSMatthew G Knepley   Input Parameters:
34146636e97aSMatthew G Knepley + dm - the DM
34156636e97aSMatthew G Knepley - c - coordinate vector
34166636e97aSMatthew G Knepley 
34176636e97aSMatthew G Knepley   Note:
34186636e97aSMatthew G Knepley   The coordinates do include those for ghost points, which are in the local vector
34196636e97aSMatthew G Knepley 
34206636e97aSMatthew G Knepley   Level: intermediate
34216636e97aSMatthew G Knepley 
34226636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
34236636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM()
34246636e97aSMatthew G Knepley @*/
34256636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
34266636e97aSMatthew G Knepley {
34276636e97aSMatthew G Knepley   PetscErrorCode ierr;
34286636e97aSMatthew G Knepley 
34296636e97aSMatthew G Knepley   PetscFunctionBegin;
34306636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
34316636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
34326636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
34336636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
34346636e97aSMatthew G Knepley   dm->coordinates = c;
34356636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
34366636e97aSMatthew G Knepley   PetscFunctionReturn(0);
34376636e97aSMatthew G Knepley }
34386636e97aSMatthew G Knepley 
34396636e97aSMatthew G Knepley #undef __FUNCT__
34406636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinatesLocal"
34416636e97aSMatthew G Knepley /*@
34426636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
34436636e97aSMatthew G Knepley 
34446636e97aSMatthew G Knepley   Collective on DM
34456636e97aSMatthew G Knepley 
34466636e97aSMatthew G Knepley    Input Parameters:
34476636e97aSMatthew G Knepley +  dm - the DM
34486636e97aSMatthew G Knepley -  c - coordinate vector
34496636e97aSMatthew G Knepley 
34506636e97aSMatthew G Knepley   Note:
34516636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
34526636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
34536636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
34546636e97aSMatthew G Knepley 
34556636e97aSMatthew G Knepley   Level: intermediate
34566636e97aSMatthew G Knepley 
34576636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
34586636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
34596636e97aSMatthew G Knepley @*/
34606636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
34616636e97aSMatthew G Knepley {
34626636e97aSMatthew G Knepley   PetscErrorCode ierr;
34636636e97aSMatthew G Knepley 
34646636e97aSMatthew G Knepley   PetscFunctionBegin;
34656636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
34666636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
34676636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
34686636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
34696636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
34706636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
34716636e97aSMatthew G Knepley   PetscFunctionReturn(0);
34726636e97aSMatthew G Knepley }
34736636e97aSMatthew G Knepley 
34746636e97aSMatthew G Knepley #undef __FUNCT__
34756636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinates"
34766636e97aSMatthew G Knepley /*@
34776636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
34786636e97aSMatthew G Knepley 
34796636e97aSMatthew G Knepley   Not Collective
34806636e97aSMatthew G Knepley 
34816636e97aSMatthew G Knepley   Input Parameter:
34826636e97aSMatthew G Knepley . dm - the DM
34836636e97aSMatthew G Knepley 
34846636e97aSMatthew G Knepley   Output Parameter:
34856636e97aSMatthew G Knepley . c - global coordinate vector
34866636e97aSMatthew G Knepley 
34876636e97aSMatthew G Knepley   Note:
34886636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
34896636e97aSMatthew G Knepley 
34906636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
34916636e97aSMatthew G Knepley 
34926636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
34936636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
34946636e97aSMatthew G Knepley 
34956636e97aSMatthew G Knepley   Level: intermediate
34966636e97aSMatthew G Knepley 
34976636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
34986636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
34996636e97aSMatthew G Knepley @*/
35006636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
35016636e97aSMatthew G Knepley {
35026636e97aSMatthew G Knepley   PetscErrorCode ierr;
35036636e97aSMatthew G Knepley 
35046636e97aSMatthew G Knepley   PetscFunctionBegin;
35056636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
35066636e97aSMatthew G Knepley   PetscValidPointer(c,2);
35076636e97aSMatthew G Knepley   if (!dm->coordinates) {
35086636e97aSMatthew G Knepley     DM cdm;
35096636e97aSMatthew G Knepley 
35106636e97aSMatthew G Knepley     if (!dm->coordinatesLocal) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ORDER, "You must call DMSetCoordinates() or DMSetCoordinatesLocal() before this call");
35116636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
35126636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
35136636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
35146636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
35156636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
35166636e97aSMatthew G Knepley   }
35176636e97aSMatthew G Knepley   *c = dm->coordinates;
35186636e97aSMatthew G Knepley   PetscFunctionReturn(0);
35196636e97aSMatthew G Knepley }
35206636e97aSMatthew G Knepley 
35216636e97aSMatthew G Knepley #undef __FUNCT__
35226636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinatesLocal"
35236636e97aSMatthew G Knepley /*@
35246636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
35256636e97aSMatthew G Knepley 
35266636e97aSMatthew G Knepley   Collective on DM
35276636e97aSMatthew G Knepley 
35286636e97aSMatthew G Knepley   Input Parameter:
35296636e97aSMatthew G Knepley . dm - the DM
35306636e97aSMatthew G Knepley 
35316636e97aSMatthew G Knepley   Output Parameter:
35326636e97aSMatthew G Knepley . c - coordinate vector
35336636e97aSMatthew G Knepley 
35346636e97aSMatthew G Knepley   Note:
35356636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
35366636e97aSMatthew G Knepley 
35376636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
35386636e97aSMatthew G Knepley 
35396636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
35406636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
35416636e97aSMatthew G Knepley 
35426636e97aSMatthew G Knepley   Level: intermediate
35436636e97aSMatthew G Knepley 
35446636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
35456636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
35466636e97aSMatthew G Knepley @*/
35476636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
35486636e97aSMatthew G Knepley {
35496636e97aSMatthew G Knepley   PetscErrorCode ierr;
35506636e97aSMatthew G Knepley 
35516636e97aSMatthew G Knepley   PetscFunctionBegin;
35526636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
35536636e97aSMatthew G Knepley   PetscValidPointer(c,2);
35546636e97aSMatthew G Knepley   if (!dm->coordinatesLocal) {
35556636e97aSMatthew G Knepley     DM cdm;
35566636e97aSMatthew G Knepley 
35576636e97aSMatthew G Knepley     if (!dm->coordinates) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ORDER, "You must call DMSetCoordinates() or DMSetCoordinatesLocal() before this call");
35586636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
35596636e97aSMatthew G Knepley     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
35606636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
35616636e97aSMatthew G Knepley     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
35626636e97aSMatthew G Knepley     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
35636636e97aSMatthew G Knepley   }
35646636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
35656636e97aSMatthew G Knepley   PetscFunctionReturn(0);
35666636e97aSMatthew G Knepley }
35676636e97aSMatthew G Knepley 
35686636e97aSMatthew G Knepley #undef __FUNCT__
35696636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinateDM"
35706636e97aSMatthew G Knepley /*@
35716636e97aSMatthew G Knepley   DMGetCoordinateDM - Gets the DM that scatters between global and local coordinates
35726636e97aSMatthew G Knepley 
35736636e97aSMatthew G Knepley   Collective on DM
35746636e97aSMatthew G Knepley 
35756636e97aSMatthew G Knepley   Input Parameter:
35766636e97aSMatthew G Knepley . dm - the DM
35776636e97aSMatthew G Knepley 
35786636e97aSMatthew G Knepley   Output Parameter:
35796636e97aSMatthew G Knepley . cdm - coordinate DM
35806636e97aSMatthew G Knepley 
35816636e97aSMatthew G Knepley   Level: intermediate
35826636e97aSMatthew G Knepley 
35836636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
35846636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
35856636e97aSMatthew G Knepley @*/
35866636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
35876636e97aSMatthew G Knepley {
35886636e97aSMatthew G Knepley   PetscErrorCode ierr;
35896636e97aSMatthew G Knepley 
35906636e97aSMatthew G Knepley   PetscFunctionBegin;
35916636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
35926636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
35936636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
35946636e97aSMatthew G Knepley     if (!dm->ops->createcoordinatedm) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Unable to create coordinates for this DM");
35956636e97aSMatthew G Knepley     ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr);
35966636e97aSMatthew G Knepley   }
35976636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
35986636e97aSMatthew G Knepley   PetscFunctionReturn(0);
35996636e97aSMatthew G Knepley }
3600