xref: /petsc/src/dm/interface/dm.c (revision 40e8a239252cd2a4eb258775ad94638664d144ac)
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 @*/
8719fd82e9SBarry 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);
9419fd82e9SBarry 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 @*/
11619fd82e9SBarry 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);
12219fd82e9SBarry 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;
4491f588964SMatthew G Knepley     PetscInt     localSize, blockSize = -1, pStart, pEnd, p;
45088ed4aceSMatthew G Knepley 
45188ed4aceSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
4521f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
4531f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
4541f588964SMatthew G Knepley       PetscInt dof, cdof;
4551f588964SMatthew G Knepley 
4561f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
4571f588964SMatthew G Knepley       ierr = PetscSectionGetConstraintDof(dm->defaultSection, p, &cdof);CHKERRQ(ierr);
4581f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof-cdof;
4591f588964SMatthew G Knepley       if ((dof > 0) && (dof-cdof != blockSize)) {
4601f588964SMatthew G Knepley         blockSize = 1;
4611f588964SMatthew G Knepley         break;
4621f588964SMatthew G Knepley       }
4631f588964SMatthew G Knepley     }
46488ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr);
4651f588964SMatthew G Knepley     if (localSize%blockSize) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONG, "Mismatch between blocksize %d and local storage size %d", blockSize, localSize);
46688ed4aceSMatthew G Knepley     ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr);
46788ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
4681f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
46988ed4aceSMatthew G Knepley     /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */
47088ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
47188ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
47288ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */
47388ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */
47488ed4aceSMatthew G Knepley     /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */
47588ed4aceSMatthew G Knepley   } else {
47647c6ae99SBarry Smith     ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
47788ed4aceSMatthew G Knepley   }
47847c6ae99SBarry Smith   PetscFunctionReturn(0);
47947c6ae99SBarry Smith }
48047c6ae99SBarry Smith 
48147c6ae99SBarry Smith #undef __FUNCT__
48247c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
48347c6ae99SBarry Smith /*@
484aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
48547c6ae99SBarry Smith 
48647c6ae99SBarry Smith     Not Collective
48747c6ae99SBarry Smith 
48847c6ae99SBarry Smith     Input Parameter:
48947c6ae99SBarry Smith .   dm - the DM object
49047c6ae99SBarry Smith 
49147c6ae99SBarry Smith     Output Parameter:
49247c6ae99SBarry Smith .   vec - the local vector
49347c6ae99SBarry Smith 
494073dac72SJed Brown     Level: beginner
49547c6ae99SBarry Smith 
496e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
49747c6ae99SBarry Smith 
49847c6ae99SBarry Smith @*/
4997087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
50047c6ae99SBarry Smith {
50147c6ae99SBarry Smith   PetscErrorCode ierr;
50247c6ae99SBarry Smith 
50347c6ae99SBarry Smith   PetscFunctionBegin;
504171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
50588ed4aceSMatthew G Knepley   if (dm->defaultSection) {
5061f588964SMatthew G Knepley     PetscInt localSize, blockSize = -1, pStart, pEnd, p;
50788ed4aceSMatthew G Knepley 
5081f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
5091f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
5101f588964SMatthew G Knepley       PetscInt dof;
5111f588964SMatthew G Knepley 
5121f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
5131f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof;
5141f588964SMatthew G Knepley       if ((dof > 0) && (dof != blockSize)) {
5151f588964SMatthew G Knepley         blockSize = 1;
5161f588964SMatthew G Knepley         break;
5171f588964SMatthew G Knepley       }
5181f588964SMatthew G Knepley     }
51988ed4aceSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr);
52088ed4aceSMatthew G Knepley     ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr);
52188ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr);
5221f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
52388ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
52488ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
52588ed4aceSMatthew G Knepley   } else {
52647c6ae99SBarry Smith     ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
52788ed4aceSMatthew G Knepley   }
52847c6ae99SBarry Smith   PetscFunctionReturn(0);
52947c6ae99SBarry Smith }
53047c6ae99SBarry Smith 
53147c6ae99SBarry Smith #undef __FUNCT__
5321411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
5331411c6eeSJed Brown /*@
5341411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
5351411c6eeSJed Brown 
5361411c6eeSJed Brown    Collective on DM
5371411c6eeSJed Brown 
5381411c6eeSJed Brown    Input Parameter:
5391411c6eeSJed Brown .  dm - the DM that provides the mapping
5401411c6eeSJed Brown 
5411411c6eeSJed Brown    Output Parameter:
5421411c6eeSJed Brown .  ltog - the mapping
5431411c6eeSJed Brown 
5441411c6eeSJed Brown    Level: intermediate
5451411c6eeSJed Brown 
5461411c6eeSJed Brown    Notes:
5471411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
5481411c6eeSJed Brown    MatSetLocalToGlobalMapping().
5491411c6eeSJed Brown 
5501411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
5511411c6eeSJed Brown @*/
5527087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
5531411c6eeSJed Brown {
5541411c6eeSJed Brown   PetscErrorCode ierr;
5551411c6eeSJed Brown 
5561411c6eeSJed Brown   PetscFunctionBegin;
5571411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5581411c6eeSJed Brown   PetscValidPointer(ltog,2);
5591411c6eeSJed Brown   if (!dm->ltogmap) {
56037d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
56137d0c07bSMatthew G Knepley 
56237d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
56337d0c07bSMatthew G Knepley     if (section) {
56437d0c07bSMatthew G Knepley       PetscInt      *ltog;
56537d0c07bSMatthew G Knepley       PetscInt       pStart, pEnd, size, p, l;
56637d0c07bSMatthew G Knepley 
56737d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
56837d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
56937d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
57037d0c07bSMatthew G Knepley       ierr = PetscMalloc(size * sizeof(PetscInt), &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
57137d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
57237d0c07bSMatthew G Knepley         PetscInt dof, off, c;
57337d0c07bSMatthew G Knepley 
57437d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
57537d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
57637d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
57737d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
57837d0c07bSMatthew G Knepley           ltog[l] = off+c;
57937d0c07bSMatthew G Knepley         }
58037d0c07bSMatthew G Knepley       }
58137d0c07bSMatthew G Knepley       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
58237d0c07bSMatthew G Knepley       ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr);
58337d0c07bSMatthew G Knepley     } else {
5841411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
5851411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
5861411c6eeSJed Brown     }
58737d0c07bSMatthew G Knepley   }
5881411c6eeSJed Brown   *ltog = dm->ltogmap;
5891411c6eeSJed Brown   PetscFunctionReturn(0);
5901411c6eeSJed Brown }
5911411c6eeSJed Brown 
5921411c6eeSJed Brown #undef __FUNCT__
5931411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
5941411c6eeSJed Brown /*@
5951411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
5961411c6eeSJed Brown 
5971411c6eeSJed Brown    Collective on DM
5981411c6eeSJed Brown 
5991411c6eeSJed Brown    Input Parameter:
6001411c6eeSJed Brown .  da - the distributed array that provides the mapping
6011411c6eeSJed Brown 
6021411c6eeSJed Brown    Output Parameter:
6031411c6eeSJed Brown .  ltog - the block mapping
6041411c6eeSJed Brown 
6051411c6eeSJed Brown    Level: intermediate
6061411c6eeSJed Brown 
6071411c6eeSJed Brown    Notes:
6081411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
6091411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
6101411c6eeSJed Brown 
6111411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
6121411c6eeSJed Brown @*/
6137087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
6141411c6eeSJed Brown {
6151411c6eeSJed Brown   PetscErrorCode ierr;
6161411c6eeSJed Brown 
6171411c6eeSJed Brown   PetscFunctionBegin;
6181411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6191411c6eeSJed Brown   PetscValidPointer(ltog,2);
6201411c6eeSJed Brown   if (!dm->ltogmapb) {
6211411c6eeSJed Brown     PetscInt bs;
6221411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
6231411c6eeSJed Brown     if (bs > 1) {
6241411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
6251411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
6261411c6eeSJed Brown     } else {
6271411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
6281411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
6291411c6eeSJed Brown     }
6301411c6eeSJed Brown   }
6311411c6eeSJed Brown   *ltog = dm->ltogmapb;
6321411c6eeSJed Brown   PetscFunctionReturn(0);
6331411c6eeSJed Brown }
6341411c6eeSJed Brown 
6351411c6eeSJed Brown #undef __FUNCT__
6361411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
6371411c6eeSJed Brown /*@
6381411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
6391411c6eeSJed Brown 
6401411c6eeSJed Brown    Not Collective
6411411c6eeSJed Brown 
6421411c6eeSJed Brown    Input Parameter:
6431411c6eeSJed Brown .  dm - the DM with block structure
6441411c6eeSJed Brown 
6451411c6eeSJed Brown    Output Parameter:
6461411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
6471411c6eeSJed Brown 
6481411c6eeSJed Brown    Level: intermediate
6491411c6eeSJed Brown 
6501411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
6511411c6eeSJed Brown @*/
6527087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
6531411c6eeSJed Brown {
6541411c6eeSJed Brown   PetscFunctionBegin;
6551411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6561411c6eeSJed Brown   PetscValidPointer(bs,2);
6571411c6eeSJed 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");
6581411c6eeSJed Brown   *bs = dm->bs;
6591411c6eeSJed Brown   PetscFunctionReturn(0);
6601411c6eeSJed Brown }
6611411c6eeSJed Brown 
6621411c6eeSJed Brown #undef __FUNCT__
663e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
66447c6ae99SBarry Smith /*@
665e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
66647c6ae99SBarry Smith 
66747c6ae99SBarry Smith     Collective on DM
66847c6ae99SBarry Smith 
66947c6ae99SBarry Smith     Input Parameter:
67047c6ae99SBarry Smith +   dm1 - the DM object
67147c6ae99SBarry Smith -   dm2 - the second, finer DM object
67247c6ae99SBarry Smith 
67347c6ae99SBarry Smith     Output Parameter:
67447c6ae99SBarry Smith +  mat - the interpolation
67547c6ae99SBarry Smith -  vec - the scaling (optional)
67647c6ae99SBarry Smith 
67747c6ae99SBarry Smith     Level: developer
67847c6ae99SBarry Smith 
67985afcc9aSBarry 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
68085afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
681d52bd9f3SBarry Smith 
6821f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
683d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
68485afcc9aSBarry Smith 
68585afcc9aSBarry Smith 
686e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
68747c6ae99SBarry Smith 
68847c6ae99SBarry Smith @*/
689e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
69047c6ae99SBarry Smith {
69147c6ae99SBarry Smith   PetscErrorCode ierr;
69247c6ae99SBarry Smith 
69347c6ae99SBarry Smith   PetscFunctionBegin;
694171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
695171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
69625296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
69747c6ae99SBarry Smith   PetscFunctionReturn(0);
69847c6ae99SBarry Smith }
69947c6ae99SBarry Smith 
70047c6ae99SBarry Smith #undef __FUNCT__
701e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
70247c6ae99SBarry Smith /*@
703e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
70447c6ae99SBarry Smith 
70547c6ae99SBarry Smith     Collective on DM
70647c6ae99SBarry Smith 
70747c6ae99SBarry Smith     Input Parameter:
70847c6ae99SBarry Smith +   dm1 - the DM object
70947c6ae99SBarry Smith -   dm2 - the second, finer DM object
71047c6ae99SBarry Smith 
71147c6ae99SBarry Smith     Output Parameter:
71247c6ae99SBarry Smith .   ctx - the injection
71347c6ae99SBarry Smith 
71447c6ae99SBarry Smith     Level: developer
71547c6ae99SBarry Smith 
71685afcc9aSBarry 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
71785afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
71885afcc9aSBarry Smith 
719e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
72047c6ae99SBarry Smith 
72147c6ae99SBarry Smith @*/
722e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
72347c6ae99SBarry Smith {
72447c6ae99SBarry Smith   PetscErrorCode ierr;
72547c6ae99SBarry Smith 
72647c6ae99SBarry Smith   PetscFunctionBegin;
727171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
728171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
72947c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
73047c6ae99SBarry Smith   PetscFunctionReturn(0);
73147c6ae99SBarry Smith }
73247c6ae99SBarry Smith 
73347c6ae99SBarry Smith #undef __FUNCT__
734e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
735d1e2c406SBarry Smith /*@C
736e727c939SJed Brown     DMCreateColoring - Gets coloring for a DMDA or DMComposite
73747c6ae99SBarry Smith 
73847c6ae99SBarry Smith     Collective on DM
73947c6ae99SBarry Smith 
74047c6ae99SBarry Smith     Input Parameter:
74147c6ae99SBarry Smith +   dm - the DM object
74247c6ae99SBarry Smith .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
74347c6ae99SBarry Smith -   matype - either MATAIJ or MATBAIJ
74447c6ae99SBarry Smith 
74547c6ae99SBarry Smith     Output Parameter:
74647c6ae99SBarry Smith .   coloring - the coloring
74747c6ae99SBarry Smith 
74847c6ae99SBarry Smith     Level: developer
74947c6ae99SBarry Smith 
750e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
75147c6ae99SBarry Smith 
752aab9d709SJed Brown @*/
75319fd82e9SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
75447c6ae99SBarry Smith {
75547c6ae99SBarry Smith   PetscErrorCode ierr;
75647c6ae99SBarry Smith 
75747c6ae99SBarry Smith   PetscFunctionBegin;
758171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
75947c6ae99SBarry Smith   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
76047c6ae99SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
76147c6ae99SBarry Smith   PetscFunctionReturn(0);
76247c6ae99SBarry Smith }
76347c6ae99SBarry Smith 
76447c6ae99SBarry Smith #undef __FUNCT__
765950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
76647c6ae99SBarry Smith /*@C
767950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
76847c6ae99SBarry Smith 
76947c6ae99SBarry Smith     Collective on DM
77047c6ae99SBarry Smith 
77147c6ae99SBarry Smith     Input Parameter:
77247c6ae99SBarry Smith +   dm - the DM object
77347c6ae99SBarry Smith -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
77494013140SBarry Smith             any type which inherits from one of these (such as MATAIJ)
77547c6ae99SBarry Smith 
77647c6ae99SBarry Smith     Output Parameter:
77747c6ae99SBarry Smith .   mat - the empty Jacobian
77847c6ae99SBarry Smith 
779073dac72SJed Brown     Level: beginner
78047c6ae99SBarry Smith 
78194013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
78294013140SBarry Smith        do not need to do it yourself.
78394013140SBarry Smith 
78494013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
785aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
78694013140SBarry Smith 
78794013140SBarry 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
78894013140SBarry Smith        internally by PETSc.
78994013140SBarry Smith 
79094013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
791aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
79294013140SBarry Smith 
793e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
79447c6ae99SBarry Smith 
795aab9d709SJed Brown @*/
79619fd82e9SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,MatType mtype,Mat *mat)
79747c6ae99SBarry Smith {
79847c6ae99SBarry Smith   PetscErrorCode ierr;
79947c6ae99SBarry Smith 
80047c6ae99SBarry Smith   PetscFunctionBegin;
801171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
802235683edSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
803235683edSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
804235683edSBarry Smith #endif
805c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
806c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
807073dac72SJed Brown   if (dm->mattype) {
80825296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
809073dac72SJed Brown   } else {
81025296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
811c7b7c8a4SJed Brown   }
81247c6ae99SBarry Smith   PetscFunctionReturn(0);
81347c6ae99SBarry Smith }
81447c6ae99SBarry Smith 
81547c6ae99SBarry Smith #undef __FUNCT__
816732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
817732e2eb9SMatthew G Knepley /*@
818950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
819732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
820732e2eb9SMatthew G Knepley 
821732e2eb9SMatthew G Knepley   Logically Collective on DMDA
822732e2eb9SMatthew G Knepley 
823732e2eb9SMatthew G Knepley   Input Parameter:
824732e2eb9SMatthew G Knepley + dm - the DM
825732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
826732e2eb9SMatthew G Knepley 
827732e2eb9SMatthew G Knepley   Level: developer
828950540a4SJed Brown .seealso DMCreateMatrix()
829732e2eb9SMatthew G Knepley @*/
830732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
831732e2eb9SMatthew G Knepley {
832732e2eb9SMatthew G Knepley   PetscFunctionBegin;
833732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
834732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
835732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
836732e2eb9SMatthew G Knepley }
837732e2eb9SMatthew G Knepley 
838732e2eb9SMatthew G Knepley #undef __FUNCT__
839a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
840a89ea682SMatthew G Knepley /*@C
841aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
842a89ea682SMatthew G Knepley 
843a89ea682SMatthew G Knepley   Not Collective
844a89ea682SMatthew G Knepley 
845a89ea682SMatthew G Knepley   Input Parameters:
846a89ea682SMatthew G Knepley + dm - the DM object
847aa1993deSMatthew G Knepley . count - The minium size
848aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
849a89ea682SMatthew G Knepley 
850a89ea682SMatthew G Knepley   Output Parameter:
851a89ea682SMatthew G Knepley . array - the work array
852a89ea682SMatthew G Knepley 
853a89ea682SMatthew G Knepley   Level: developer
854a89ea682SMatthew G Knepley 
855a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
856a89ea682SMatthew G Knepley @*/
857aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
858a89ea682SMatthew G Knepley {
859a89ea682SMatthew G Knepley   PetscErrorCode ierr;
860aa1993deSMatthew G Knepley   DMWorkLink link;
861aa1993deSMatthew G Knepley   size_t size;
862a89ea682SMatthew G Knepley 
863a89ea682SMatthew G Knepley   PetscFunctionBegin;
864a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
865aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
866aa1993deSMatthew G Knepley   if (dm->workin) {
867aa1993deSMatthew G Knepley     link = dm->workin;
868aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
869aa1993deSMatthew G Knepley   } else {
870aa1993deSMatthew G Knepley     ierr = PetscNewLog(dm,struct _DMWorkLink,&link);CHKERRQ(ierr);
871a89ea682SMatthew G Knepley   }
872aa1993deSMatthew G Knepley   ierr = PetscDataTypeGetSize(dtype,&size);CHKERRQ(ierr);
873aa1993deSMatthew G Knepley   if (size*count > link->bytes) {
874aa1993deSMatthew G Knepley     ierr = PetscFree(link->mem);CHKERRQ(ierr);
875aa1993deSMatthew G Knepley     ierr = PetscMalloc(size*count,&link->mem);CHKERRQ(ierr);
876aa1993deSMatthew G Knepley     link->bytes = size*count;
877aa1993deSMatthew G Knepley   }
878aa1993deSMatthew G Knepley   link->next = dm->workout;
879aa1993deSMatthew G Knepley   dm->workout = link;
880aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
881a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
882a89ea682SMatthew G Knepley }
883a89ea682SMatthew G Knepley 
884aa1993deSMatthew G Knepley #undef __FUNCT__
885aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
886aa1993deSMatthew G Knepley /*@C
887aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
888aa1993deSMatthew G Knepley 
889aa1993deSMatthew G Knepley   Not Collective
890aa1993deSMatthew G Knepley 
891aa1993deSMatthew G Knepley   Input Parameters:
892aa1993deSMatthew G Knepley + dm - the DM object
893aa1993deSMatthew G Knepley . count - The minium size
894aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
895aa1993deSMatthew G Knepley 
896aa1993deSMatthew G Knepley   Output Parameter:
897aa1993deSMatthew G Knepley . array - the work array
898aa1993deSMatthew G Knepley 
899aa1993deSMatthew G Knepley   Level: developer
900aa1993deSMatthew G Knepley 
901aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
902aa1993deSMatthew G Knepley @*/
903aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
904aa1993deSMatthew G Knepley {
905aa1993deSMatthew G Knepley   DMWorkLink *p,link;
906aa1993deSMatthew G Knepley 
907aa1993deSMatthew G Knepley   PetscFunctionBegin;
908aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
909aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
910aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
911aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
912aa1993deSMatthew G Knepley       *p = link->next;
913aa1993deSMatthew G Knepley       link->next = dm->workin;
914aa1993deSMatthew G Knepley       dm->workin = link;
915aa1993deSMatthew G Knepley       *(void**)mem = PETSC_NULL;
916aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
917aa1993deSMatthew G Knepley     }
918aa1993deSMatthew G Knepley   }
919aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
920aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
921aa1993deSMatthew G Knepley }
922e7c4fc90SDmitry Karpeev 
923e7c4fc90SDmitry Karpeev #undef __FUNCT__
924435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
925435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
926435a35e8SMatthew G Knepley {
927435a35e8SMatthew G Knepley   PetscFunctionBegin;
928435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
929435a35e8SMatthew G Knepley   if (field >= 10) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
930435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
931435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
932435a35e8SMatthew G Knepley }
933435a35e8SMatthew G Knepley 
934435a35e8SMatthew G Knepley #undef __FUNCT__
9354d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
9364f3b5142SJed Brown /*@C
9374d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
9384d343eeaSMatthew G Knepley 
9394d343eeaSMatthew G Knepley   Not collective
9404d343eeaSMatthew G Knepley 
9414d343eeaSMatthew G Knepley   Input Parameter:
9424d343eeaSMatthew G Knepley . dm - the DM object
9434d343eeaSMatthew G Knepley 
9444d343eeaSMatthew G Knepley   Output Parameters:
94521c9b008SJed Brown + numFields  - The number of fields (or PETSC_NULL if not requested)
94637d0c07bSMatthew G Knepley . fieldNames - The name for each field (or PETSC_NULL if not requested)
94721c9b008SJed Brown - fields     - The global indices for each field (or PETSC_NULL if not requested)
9484d343eeaSMatthew G Knepley 
9494d343eeaSMatthew G Knepley   Level: intermediate
9504d343eeaSMatthew G Knepley 
95121c9b008SJed Brown   Notes:
95221c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
95321c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
95421c9b008SJed Brown   PetscFree().
95521c9b008SJed Brown 
9564d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
9574d343eeaSMatthew G Knepley @*/
95837d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
9594d343eeaSMatthew G Knepley {
96037d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
9614d343eeaSMatthew G Knepley   PetscErrorCode ierr;
9624d343eeaSMatthew G Knepley 
9634d343eeaSMatthew G Knepley   PetscFunctionBegin;
9644d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
96569ca1f37SDmitry Karpeev   if (numFields) {
96669ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
96769ca1f37SDmitry Karpeev     *numFields = 0;
96869ca1f37SDmitry Karpeev   }
96937d0c07bSMatthew G Knepley   if (fieldNames) {
97037d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
97137d0c07bSMatthew G Knepley     *fieldNames = PETSC_NULL;
97269ca1f37SDmitry Karpeev   }
97369ca1f37SDmitry Karpeev   if (fields) {
97469ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
97569ca1f37SDmitry Karpeev     *fields = PETSC_NULL;
97669ca1f37SDmitry Karpeev   }
97737d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
97837d0c07bSMatthew G Knepley   if (section) {
97937d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
98037d0c07bSMatthew G Knepley     PetscInt  nF, f, pStart, pEnd, p;
98137d0c07bSMatthew G Knepley 
98237d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
98337d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
98437d0c07bSMatthew G Knepley     ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr);
98537d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
98637d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
98737d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
98837d0c07bSMatthew G Knepley     }
98937d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
99037d0c07bSMatthew G Knepley       PetscInt gdof;
99137d0c07bSMatthew G Knepley 
99237d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
99337d0c07bSMatthew G Knepley       if (gdof > 0) {
99437d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
99537d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
99637d0c07bSMatthew G Knepley 
99737d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
99837d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
99937d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
100037d0c07bSMatthew G Knepley         }
100137d0c07bSMatthew G Knepley       }
100237d0c07bSMatthew G Knepley     }
100337d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
100437d0c07bSMatthew G Knepley       ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr);
100537d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
100637d0c07bSMatthew G Knepley     }
100737d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
100837d0c07bSMatthew G Knepley       PetscInt gdof, goff;
100937d0c07bSMatthew G Knepley 
101037d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
101137d0c07bSMatthew G Knepley       if (gdof > 0) {
101237d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
101337d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
101437d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
101537d0c07bSMatthew G Knepley 
101637d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
101737d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
101837d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
101937d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
102037d0c07bSMatthew G Knepley           }
102137d0c07bSMatthew G Knepley         }
102237d0c07bSMatthew G Knepley       }
102337d0c07bSMatthew G Knepley     }
102437d0c07bSMatthew G Knepley     if (numFields) {*numFields = nF;}
102537d0c07bSMatthew G Knepley     if (fieldNames) {
102637d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr);
102737d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
102837d0c07bSMatthew G Knepley         const char *fieldName;
102937d0c07bSMatthew G Knepley 
103037d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
103137d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr);
103237d0c07bSMatthew G Knepley       }
103337d0c07bSMatthew G Knepley     }
103437d0c07bSMatthew G Knepley     if (fields) {
103537d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr);
103637d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
103737d0c07bSMatthew G Knepley         ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
103837d0c07bSMatthew G Knepley       }
103937d0c07bSMatthew G Knepley     }
104037d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
104137d0c07bSMatthew G Knepley   } else {
104237d0c07bSMatthew G Knepley     if (dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);}
104369ca1f37SDmitry Karpeev   }
10444d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
10454d343eeaSMatthew G Knepley }
10464d343eeaSMatthew G Knepley 
1047a89ea682SMatthew G Knepley #undef __FUNCT__
104816621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecompositionDM"
1049e7c4fc90SDmitry Karpeev /*@C
105016621825SDmitry Karpeev   DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields.
105116621825SDmitry Karpeev 
105216621825SDmitry Karpeev   Not Collective
105316621825SDmitry Karpeev 
105416621825SDmitry Karpeev   Input Parameters:
105516621825SDmitry Karpeev + dm   - the DM object
105616621825SDmitry Karpeev - name - the name of the field decomposition
105716621825SDmitry Karpeev 
105816621825SDmitry Karpeev   Output Parameter:
105916621825SDmitry Karpeev . ddm  - the field decomposition DM (PETSC_NULL, if no such decomposition is known)
106016621825SDmitry Karpeev 
106116621825SDmitry Karpeev   Level: advanced
106216621825SDmitry Karpeev 
106316621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
106416621825SDmitry Karpeev @*/
106516621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm)
106616621825SDmitry Karpeev {
106716621825SDmitry Karpeev   PetscErrorCode ierr;
106816621825SDmitry Karpeev 
106916621825SDmitry Karpeev   PetscFunctionBegin;
107016621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
107116621825SDmitry Karpeev   PetscValidCharPointer(name,2);
107216621825SDmitry Karpeev   PetscValidPointer(ddm,3);
107316621825SDmitry Karpeev   *ddm = PETSC_NULL;
1074731c8d9eSDmitry Karpeev   if (dm->ops->createfielddecompositiondm) {
107516621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
107616621825SDmitry Karpeev   }
107716621825SDmitry Karpeev   PetscFunctionReturn(0);
107816621825SDmitry Karpeev }
107916621825SDmitry Karpeev 
108016621825SDmitry Karpeev #undef __FUNCT__
108116621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
108216621825SDmitry Karpeev /*@C
108316621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
108416621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
108516621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1086e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1087e7c4fc90SDmitry Karpeev 
1088e7c4fc90SDmitry Karpeev   Not collective
1089e7c4fc90SDmitry Karpeev 
1090e7c4fc90SDmitry Karpeev   Input Parameter:
1091e7c4fc90SDmitry Karpeev . dm - the DM object
1092e7c4fc90SDmitry Karpeev 
1093e7c4fc90SDmitry Karpeev   Output Parameters:
109416621825SDmitry Karpeev + len       - The number of subproblems in the field decomposition (or PETSC_NULL if not requested)
109516621825SDmitry Karpeev . namelist  - The name for each field (or PETSC_NULL if not requested)
109616621825SDmitry Karpeev . islist    - The global indices for each field (or PETSC_NULL if not requested)
109716621825SDmitry Karpeev - dmlist    - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
1098e7c4fc90SDmitry Karpeev 
1099e7c4fc90SDmitry Karpeev   Level: intermediate
1100e7c4fc90SDmitry Karpeev 
1101e7c4fc90SDmitry Karpeev   Notes:
1102e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1103e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1104e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1105e7c4fc90SDmitry Karpeev 
1106e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1107e7c4fc90SDmitry Karpeev @*/
110816621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1109e7c4fc90SDmitry Karpeev {
1110e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1111e7c4fc90SDmitry Karpeev 
1112e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1113e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1114731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);      *len      = 0;}
1115731c8d9eSDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;}
1116731c8d9eSDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);   *islist   = 0;}
1117731c8d9eSDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);   *dmlist   = 0;}
111816621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1119435a35e8SMatthew G Knepley     PetscSection section;
1120435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1121435a35e8SMatthew G Knepley 
1122435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1123435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1124435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1125435a35e8SMatthew G Knepley       *len = numFields;
1126435a35e8SMatthew G Knepley       ierr = PetscMalloc3(numFields,char*,namelist,numFields,IS,islist,numFields,DM,dmlist);CHKERRQ(ierr);
1127435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1128435a35e8SMatthew G Knepley         const char *fieldName;
1129435a35e8SMatthew G Knepley 
1130435a35e8SMatthew G Knepley         ierr = DMCreateSubDM(dm, 1, &f, &(*islist)[f], &(*dmlist)[f]);CHKERRQ(ierr);
1131435a35e8SMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1132435a35e8SMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*namelist)[f]);CHKERRQ(ierr);
1133435a35e8SMatthew G Knepley       }
1134435a35e8SMatthew G Knepley     } else {
113569ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1136e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
1137e7c4fc90SDmitry Karpeev       if (dmlist) *dmlist = PETSC_NULL;
1138e7c4fc90SDmitry Karpeev     }
1139435a35e8SMatthew G Knepley   }
1140e7c4fc90SDmitry Karpeev   else {
114116621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
114216621825SDmitry Karpeev   }
114316621825SDmitry Karpeev   PetscFunctionReturn(0);
114416621825SDmitry Karpeev }
114516621825SDmitry Karpeev 
114616621825SDmitry Karpeev #undef __FUNCT__
1147435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1148435a35e8SMatthew G Knepley /*@C
1149435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1150435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1151435a35e8SMatthew G Knepley 
1152435a35e8SMatthew G Knepley   Not collective
1153435a35e8SMatthew G Knepley 
1154435a35e8SMatthew G Knepley   Input Parameters:
1155435a35e8SMatthew G Knepley + dm - the DM object
1156435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
1157435a35e8SMatthew G Knepley - len       - The number of subproblems in the decomposition (or PETSC_NULL if not requested)
1158435a35e8SMatthew G Knepley 
1159435a35e8SMatthew G Knepley   Output Parameters:
1160435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1161435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1162435a35e8SMatthew G Knepley 
1163435a35e8SMatthew G Knepley   Level: intermediate
1164435a35e8SMatthew G Knepley 
1165435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1166435a35e8SMatthew G Knepley @*/
1167435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1168435a35e8SMatthew G Knepley {
1169435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1170435a35e8SMatthew G Knepley 
1171435a35e8SMatthew G Knepley   PetscFunctionBegin;
1172435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1173435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
1174435a35e8SMatthew G Knepley   if (is) {PetscValidPointer(is,4);}
1175435a35e8SMatthew G Knepley   if (subdm) {PetscValidPointer(subdm,5);}
1176435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1177435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm); CHKERRQ(ierr);
1178435a35e8SMatthew G Knepley   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1179435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1180435a35e8SMatthew G Knepley }
1181435a35e8SMatthew G Knepley 
1182435a35e8SMatthew G Knepley #undef __FUNCT__
118316621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecompositionDM"
118416621825SDmitry Karpeev /*@C
118516621825SDmitry Karpeev   DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains.
118616621825SDmitry Karpeev 
118716621825SDmitry Karpeev   Not Collective
118816621825SDmitry Karpeev 
118916621825SDmitry Karpeev   Input Parameters:
119016621825SDmitry Karpeev + dm   - the DM object
119116621825SDmitry Karpeev - name - the name of the subdomain decomposition
119216621825SDmitry Karpeev 
119316621825SDmitry Karpeev   Output Parameter:
119416621825SDmitry Karpeev . ddm  - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known)
119516621825SDmitry Karpeev 
119616621825SDmitry Karpeev   Level: advanced
119716621825SDmitry Karpeev 
119816621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
119916621825SDmitry Karpeev @*/
120016621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm)
120116621825SDmitry Karpeev {
120216621825SDmitry Karpeev   PetscErrorCode ierr;
120316621825SDmitry Karpeev 
120416621825SDmitry Karpeev   PetscFunctionBegin;
120516621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
120616621825SDmitry Karpeev   PetscValidCharPointer(name,2);
120716621825SDmitry Karpeev   PetscValidPointer(ddm,3);
120816621825SDmitry Karpeev   *ddm = PETSC_NULL;
1209731c8d9eSDmitry Karpeev   if (dm->ops->createdomaindecompositiondm) {
121016621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
121116621825SDmitry Karpeev   }
121216621825SDmitry Karpeev   PetscFunctionReturn(0);
121316621825SDmitry Karpeev }
121416621825SDmitry Karpeev 
121516621825SDmitry Karpeev #undef __FUNCT__
121616621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
121716621825SDmitry Karpeev /*@C
12188d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
12198d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
12208d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
12218d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
12228d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
122316621825SDmitry Karpeev 
122416621825SDmitry Karpeev   Not collective
122516621825SDmitry Karpeev 
122616621825SDmitry Karpeev   Input Parameter:
122716621825SDmitry Karpeev . dm - the DM object
122816621825SDmitry Karpeev 
122916621825SDmitry Karpeev   Output Parameters:
123016621825SDmitry Karpeev + len         - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested)
123116621825SDmitry Karpeev . namelist    - The name for each subdomain (or PETSC_NULL if not requested)
12328d4ac253SDmitry Karpeev . innerislist - The global indices for each inner subdomain (or PETSC_NULL, if not requested)
12338d4ac253SDmitry Karpeev . outerislist - The global indices for each outer subdomain (or PETSC_NULL, if not requested)
123416621825SDmitry Karpeev - dmlist      - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
123516621825SDmitry Karpeev 
123616621825SDmitry Karpeev   Level: intermediate
123716621825SDmitry Karpeev 
123816621825SDmitry Karpeev   Notes:
123916621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
124016621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
124116621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
124216621825SDmitry Karpeev 
12438d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
124416621825SDmitry Karpeev @*/
12458d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
124616621825SDmitry Karpeev {
124716621825SDmitry Karpeev   PetscErrorCode ierr;
124816621825SDmitry Karpeev 
124916621825SDmitry Karpeev   PetscFunctionBegin;
125016621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1251731c8d9eSDmitry Karpeev   if (len)           {PetscValidPointer(len,2);            *len         = PETSC_NULL;}
125216621825SDmitry Karpeev   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = PETSC_NULL;}
12538d4ac253SDmitry Karpeev   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = PETSC_NULL;}
12548d4ac253SDmitry Karpeev   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = PETSC_NULL;}
12558d4ac253SDmitry Karpeev   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = PETSC_NULL;}
125616621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
12578d4ac253SDmitry Karpeev     ierr = (*dm->ops->createdomaindecomposition)(dm,len,namelist,innerislist,outerislist,dmlist); CHKERRQ(ierr);
1258e7c4fc90SDmitry Karpeev   }
1259e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1260e7c4fc90SDmitry Karpeev }
1261e7c4fc90SDmitry Karpeev 
1262731c8d9eSDmitry Karpeev #undef __FUNCT__
126347c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
126447c6ae99SBarry Smith /*@
126547c6ae99SBarry Smith   DMRefine - Refines a DM object
126647c6ae99SBarry Smith 
126747c6ae99SBarry Smith   Collective on DM
126847c6ae99SBarry Smith 
126947c6ae99SBarry Smith   Input Parameter:
127047c6ae99SBarry Smith + dm   - the DM object
127191d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
127247c6ae99SBarry Smith 
127347c6ae99SBarry Smith   Output Parameter:
1274ae0a1c52SMatthew G Knepley . dmf - the refined DM, or PETSC_NULL
1275ae0a1c52SMatthew G Knepley 
1276ae0a1c52SMatthew G Knepley   Note: If no refinement was done, the return value is PETSC_NULL
127747c6ae99SBarry Smith 
127847c6ae99SBarry Smith   Level: developer
127947c6ae99SBarry Smith 
1280e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
128147c6ae99SBarry Smith @*/
12827087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
128347c6ae99SBarry Smith {
128447c6ae99SBarry Smith   PetscErrorCode ierr;
1285c833c3b5SJed Brown   DMRefineHookLink link;
128647c6ae99SBarry Smith 
128747c6ae99SBarry Smith   PetscFunctionBegin;
1288732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
128947c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
12904057135bSMatthew G Knepley   if (*dmf) {
129143842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
1292644e2e5bSBarry Smith     (*dmf)->ops->initialguess = dm->ops->initialguess;
1293644e2e5bSBarry Smith     (*dmf)->ops->function     = dm->ops->function;
1294644e2e5bSBarry Smith     (*dmf)->ops->functionj    = dm->ops->functionj;
1295644e2e5bSBarry Smith     if (dm->ops->jacobian != DMComputeJacobianDefault) {
1296644e2e5bSBarry Smith       (*dmf)->ops->jacobian     = dm->ops->jacobian;
1297644e2e5bSBarry Smith     }
12988cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
1299644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
13000598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1301656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
1302e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1303c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
1304c833c3b5SJed Brown       if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);}
1305c833c3b5SJed Brown     }
1306c833c3b5SJed Brown   }
1307c833c3b5SJed Brown   PetscFunctionReturn(0);
1308c833c3b5SJed Brown }
1309c833c3b5SJed Brown 
1310c833c3b5SJed Brown #undef __FUNCT__
1311c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1312c833c3b5SJed Brown /*@
1313c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1314c833c3b5SJed Brown 
1315c833c3b5SJed Brown    Logically Collective
1316c833c3b5SJed Brown 
1317c833c3b5SJed Brown    Input Arguments:
1318c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1319c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1320c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
1321c833c3b5SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1322c833c3b5SJed Brown 
1323c833c3b5SJed Brown    Calling sequence of refinehook:
1324c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1325c833c3b5SJed Brown 
1326c833c3b5SJed Brown +  coarse - coarse level DM
1327c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1328c833c3b5SJed Brown -  ctx - optional user-defined function context
1329c833c3b5SJed Brown 
1330c833c3b5SJed Brown    Calling sequence for interphook:
1331c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1332c833c3b5SJed Brown 
1333c833c3b5SJed Brown +  coarse - coarse level DM
1334c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1335c833c3b5SJed Brown .  fine - fine level DM to update
1336c833c3b5SJed Brown -  ctx - optional user-defined function context
1337c833c3b5SJed Brown 
1338c833c3b5SJed Brown    Level: advanced
1339c833c3b5SJed Brown 
1340c833c3b5SJed Brown    Notes:
1341c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1342c833c3b5SJed Brown 
1343c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1344c833c3b5SJed Brown 
1345c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1346c833c3b5SJed Brown @*/
1347c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1348c833c3b5SJed Brown {
1349c833c3b5SJed Brown   PetscErrorCode ierr;
1350c833c3b5SJed Brown   DMRefineHookLink link,*p;
1351c833c3b5SJed Brown 
1352c833c3b5SJed Brown   PetscFunctionBegin;
1353c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1354c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1355c833c3b5SJed Brown   ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1356c833c3b5SJed Brown   link->refinehook = refinehook;
1357c833c3b5SJed Brown   link->interphook = interphook;
1358c833c3b5SJed Brown   link->ctx = ctx;
1359c833c3b5SJed Brown   link->next = PETSC_NULL;
1360c833c3b5SJed Brown   *p = link;
1361c833c3b5SJed Brown   PetscFunctionReturn(0);
1362c833c3b5SJed Brown }
1363c833c3b5SJed Brown 
1364c833c3b5SJed Brown #undef __FUNCT__
1365c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1366c833c3b5SJed Brown /*@
1367c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1368c833c3b5SJed Brown 
1369c833c3b5SJed Brown    Collective if any hooks are
1370c833c3b5SJed Brown 
1371c833c3b5SJed Brown    Input Arguments:
1372c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1373c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1374c833c3b5SJed Brown -  fine - finer DM to update
1375c833c3b5SJed Brown 
1376c833c3b5SJed Brown    Level: developer
1377c833c3b5SJed Brown 
1378c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1379c833c3b5SJed Brown @*/
1380c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1381c833c3b5SJed Brown {
1382c833c3b5SJed Brown   PetscErrorCode ierr;
1383c833c3b5SJed Brown   DMRefineHookLink link;
1384c833c3b5SJed Brown 
1385c833c3b5SJed Brown   PetscFunctionBegin;
1386c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
1387c833c3b5SJed Brown     if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);}
13884057135bSMatthew G Knepley   }
138947c6ae99SBarry Smith   PetscFunctionReturn(0);
139047c6ae99SBarry Smith }
139147c6ae99SBarry Smith 
139247c6ae99SBarry Smith #undef __FUNCT__
1393eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1394eb3f98d2SBarry Smith /*@
1395eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1396eb3f98d2SBarry Smith 
1397eb3f98d2SBarry Smith     Not Collective
1398eb3f98d2SBarry Smith 
1399eb3f98d2SBarry Smith     Input Parameter:
1400eb3f98d2SBarry Smith .   dm - the DM object
1401eb3f98d2SBarry Smith 
1402eb3f98d2SBarry Smith     Output Parameter:
1403eb3f98d2SBarry Smith .   level - number of refinements
1404eb3f98d2SBarry Smith 
1405eb3f98d2SBarry Smith     Level: developer
1406eb3f98d2SBarry Smith 
14076a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1408eb3f98d2SBarry Smith 
1409eb3f98d2SBarry Smith @*/
1410eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1411eb3f98d2SBarry Smith {
1412eb3f98d2SBarry Smith   PetscFunctionBegin;
1413eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1414eb3f98d2SBarry Smith   *level = dm->levelup;
1415eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1416eb3f98d2SBarry Smith }
1417eb3f98d2SBarry Smith 
1418eb3f98d2SBarry Smith #undef __FUNCT__
141947c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
142047c6ae99SBarry Smith /*@
142147c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
142247c6ae99SBarry Smith 
142347c6ae99SBarry Smith     Neighbor-wise Collective on DM
142447c6ae99SBarry Smith 
142547c6ae99SBarry Smith     Input Parameters:
142647c6ae99SBarry Smith +   dm - the DM object
142747c6ae99SBarry Smith .   g - the global vector
142847c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
142947c6ae99SBarry Smith -   l - the local vector
143047c6ae99SBarry Smith 
143147c6ae99SBarry Smith 
143247c6ae99SBarry Smith     Level: beginner
143347c6ae99SBarry Smith 
1434e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
143547c6ae99SBarry Smith 
143647c6ae99SBarry Smith @*/
14377087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
143847c6ae99SBarry Smith {
14397128ae9fSMatthew G Knepley   PetscSF        sf;
144047c6ae99SBarry Smith   PetscErrorCode ierr;
144147c6ae99SBarry Smith 
144247c6ae99SBarry Smith   PetscFunctionBegin;
1443171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14447128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14457128ae9fSMatthew G Knepley   if (sf) {
14467128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
14477128ae9fSMatthew G Knepley 
14487128ae9fSMatthew G Knepley     if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14497128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14507128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14517128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14527128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14537128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14547128ae9fSMatthew G Knepley   } else {
1455843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14567128ae9fSMatthew G Knepley   }
145747c6ae99SBarry Smith   PetscFunctionReturn(0);
145847c6ae99SBarry Smith }
145947c6ae99SBarry Smith 
146047c6ae99SBarry Smith #undef __FUNCT__
146147c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
146247c6ae99SBarry Smith /*@
146347c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
146447c6ae99SBarry Smith 
146547c6ae99SBarry Smith     Neighbor-wise Collective on DM
146647c6ae99SBarry Smith 
146747c6ae99SBarry Smith     Input Parameters:
146847c6ae99SBarry Smith +   dm - the DM object
146947c6ae99SBarry Smith .   g - the global vector
147047c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
147147c6ae99SBarry Smith -   l - the local vector
147247c6ae99SBarry Smith 
147347c6ae99SBarry Smith 
147447c6ae99SBarry Smith     Level: beginner
147547c6ae99SBarry Smith 
1476e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
147747c6ae99SBarry Smith 
147847c6ae99SBarry Smith @*/
14797087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
148047c6ae99SBarry Smith {
14817128ae9fSMatthew G Knepley   PetscSF        sf;
148247c6ae99SBarry Smith   PetscErrorCode ierr;
148361a3c1faSSatish Balay   PetscScalar    *lArray, *gArray;
148447c6ae99SBarry Smith 
148547c6ae99SBarry Smith   PetscFunctionBegin;
1486171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14877128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14887128ae9fSMatthew G Knepley   if (sf) {
14897128ae9fSMatthew G Knepley   if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14907128ae9fSMatthew G Knepley 
14917128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14927128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14937128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14947128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14957128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14967128ae9fSMatthew G Knepley   } else {
1497843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14987128ae9fSMatthew G Knepley   }
149947c6ae99SBarry Smith   PetscFunctionReturn(0);
150047c6ae99SBarry Smith }
150147c6ae99SBarry Smith 
150247c6ae99SBarry Smith #undef __FUNCT__
15039a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
150447c6ae99SBarry Smith /*@
15059a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
15069a42bb27SBarry Smith 
15079a42bb27SBarry Smith     Neighbor-wise Collective on DM
15089a42bb27SBarry Smith 
15099a42bb27SBarry Smith     Input Parameters:
15109a42bb27SBarry Smith +   dm - the DM object
1511f6813fd5SJed Brown .   l - the local vector
15129a42bb27SBarry 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
15139a42bb27SBarry Smith            base point.
1514f6813fd5SJed Brown - - the global vector
15159a42bb27SBarry Smith 
15169a42bb27SBarry 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
15179a42bb27SBarry 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
15189a42bb27SBarry Smith            global array to the final global array with VecAXPY().
15199a42bb27SBarry Smith 
15209a42bb27SBarry Smith     Level: beginner
15219a42bb27SBarry Smith 
1522e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
15239a42bb27SBarry Smith 
15249a42bb27SBarry Smith @*/
15257087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
15269a42bb27SBarry Smith {
15277128ae9fSMatthew G Knepley   PetscSF        sf;
15289a42bb27SBarry Smith   PetscErrorCode ierr;
15299a42bb27SBarry Smith 
15309a42bb27SBarry Smith   PetscFunctionBegin;
1531171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15327128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
15337128ae9fSMatthew G Knepley   if (sf) {
15347128ae9fSMatthew G Knepley     MPI_Op       op;
15357128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
15367128ae9fSMatthew G Knepley 
15377128ae9fSMatthew G Knepley     switch(mode) {
15387128ae9fSMatthew G Knepley     case INSERT_VALUES:
15397128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
15407128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
15417128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
15427128ae9fSMatthew G Knepley #else
15437128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
15447128ae9fSMatthew G Knepley #endif
15457128ae9fSMatthew G Knepley     case ADD_VALUES:
15467128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
15477128ae9fSMatthew G Knepley       op = MPI_SUM; break;
15487128ae9fSMatthew G Knepley   default:
15497128ae9fSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15507128ae9fSMatthew G Knepley     }
15517128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15527128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15537128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
15547128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15557128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15567128ae9fSMatthew G Knepley   } else {
1557843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
15587128ae9fSMatthew G Knepley   }
15599a42bb27SBarry Smith   PetscFunctionReturn(0);
15609a42bb27SBarry Smith }
15619a42bb27SBarry Smith 
15629a42bb27SBarry Smith #undef __FUNCT__
15639a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
15649a42bb27SBarry Smith /*@
15659a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
156647c6ae99SBarry Smith 
156747c6ae99SBarry Smith     Neighbor-wise Collective on DM
156847c6ae99SBarry Smith 
156947c6ae99SBarry Smith     Input Parameters:
157047c6ae99SBarry Smith +   dm - the DM object
1571f6813fd5SJed Brown .   l - the local vector
157247c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1573f6813fd5SJed Brown -   g - the global vector
157447c6ae99SBarry Smith 
157547c6ae99SBarry Smith 
157647c6ae99SBarry Smith     Level: beginner
157747c6ae99SBarry Smith 
1578e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
157947c6ae99SBarry Smith 
158047c6ae99SBarry Smith @*/
15817087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
158247c6ae99SBarry Smith {
15837128ae9fSMatthew G Knepley   PetscSF        sf;
158447c6ae99SBarry Smith   PetscErrorCode ierr;
158547c6ae99SBarry Smith 
158647c6ae99SBarry Smith   PetscFunctionBegin;
1587171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15887128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
15897128ae9fSMatthew G Knepley   if (sf) {
15907128ae9fSMatthew G Knepley     MPI_Op       op;
15917128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
15927128ae9fSMatthew G Knepley 
15937128ae9fSMatthew G Knepley     switch(mode) {
15947128ae9fSMatthew G Knepley     case INSERT_VALUES:
15957128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
15967128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
15977128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
15987128ae9fSMatthew G Knepley #else
15997128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
16007128ae9fSMatthew G Knepley #endif
16017128ae9fSMatthew G Knepley     case ADD_VALUES:
16027128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
16037128ae9fSMatthew G Knepley       op = MPI_SUM; break;
16047128ae9fSMatthew G Knepley     default:
16057128ae9fSMatthew G Knepley       SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
16067128ae9fSMatthew G Knepley     }
16077128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
16087128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
16097128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
16107128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
16117128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
16127128ae9fSMatthew G Knepley   } else {
1613843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
16147128ae9fSMatthew G Knepley   }
161547c6ae99SBarry Smith   PetscFunctionReturn(0);
161647c6ae99SBarry Smith }
161747c6ae99SBarry Smith 
161847c6ae99SBarry Smith #undef __FUNCT__
161947c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobianDefault"
162047c6ae99SBarry Smith /*@
162147c6ae99SBarry Smith     DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided
162247c6ae99SBarry Smith 
162347c6ae99SBarry Smith     Collective on DM
162447c6ae99SBarry Smith 
162547c6ae99SBarry Smith     Input Parameter:
162647c6ae99SBarry Smith +   dm - the DM object
162747c6ae99SBarry Smith .   x - location to compute Jacobian at; may be ignored for linear problems
162847c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
162947c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
163047c6ae99SBarry Smith 
163147c6ae99SBarry Smith     Level: developer
163247c6ae99SBarry Smith 
1633e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
163447c6ae99SBarry Smith          DMSetFunction()
163547c6ae99SBarry Smith 
163647c6ae99SBarry Smith @*/
16377087cfbeSBarry Smith PetscErrorCode  DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
163847c6ae99SBarry Smith {
163947c6ae99SBarry Smith   PetscErrorCode ierr;
1640171400e9SBarry Smith 
164147c6ae99SBarry Smith   PetscFunctionBegin;
1642171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
164347c6ae99SBarry Smith   *stflag = SAME_NONZERO_PATTERN;
164447c6ae99SBarry Smith   ierr  = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr);
164547c6ae99SBarry Smith   if (A != B) {
164647c6ae99SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
164747c6ae99SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
164847c6ae99SBarry Smith   }
164947c6ae99SBarry Smith   PetscFunctionReturn(0);
165047c6ae99SBarry Smith }
165147c6ae99SBarry Smith 
165247c6ae99SBarry Smith #undef __FUNCT__
165347c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
165447c6ae99SBarry Smith /*@
165547c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
165647c6ae99SBarry Smith 
165747c6ae99SBarry Smith     Collective on DM
165847c6ae99SBarry Smith 
165947c6ae99SBarry Smith     Input Parameter:
166047c6ae99SBarry Smith +   dm - the DM object
166191d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
166247c6ae99SBarry Smith 
166347c6ae99SBarry Smith     Output Parameter:
166447c6ae99SBarry Smith .   dmc - the coarsened DM
166547c6ae99SBarry Smith 
166647c6ae99SBarry Smith     Level: developer
166747c6ae99SBarry Smith 
1668e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
166947c6ae99SBarry Smith 
167047c6ae99SBarry Smith @*/
16717087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
167247c6ae99SBarry Smith {
167347c6ae99SBarry Smith   PetscErrorCode ierr;
1674b17ce1afSJed Brown   DMCoarsenHookLink link;
167547c6ae99SBarry Smith 
167647c6ae99SBarry Smith   PetscFunctionBegin;
1677171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
167847c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
167943842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
168047c6ae99SBarry Smith   (*dmc)->ops->initialguess = dm->ops->initialguess;
168147c6ae99SBarry Smith   (*dmc)->ops->function     = dm->ops->function;
168247c6ae99SBarry Smith   (*dmc)->ops->functionj    = dm->ops->functionj;
168347c6ae99SBarry Smith   if (dm->ops->jacobian != DMComputeJacobianDefault) {
168447c6ae99SBarry Smith     (*dmc)->ops->jacobian     = dm->ops->jacobian;
168547c6ae99SBarry Smith   }
16868cd211a4SJed Brown   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1687644e2e5bSBarry Smith   (*dmc)->ctx       = dm->ctx;
16880598a293SJed Brown   (*dmc)->levelup   = dm->levelup;
1689656b349aSBarry Smith   (*dmc)->leveldown = dm->leveldown + 1;
1690e4b4b23bSJed Brown   ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
1691b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1692b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1693b17ce1afSJed Brown   }
1694b17ce1afSJed Brown   PetscFunctionReturn(0);
1695b17ce1afSJed Brown }
1696b17ce1afSJed Brown 
1697b17ce1afSJed Brown #undef __FUNCT__
1698b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1699b17ce1afSJed Brown /*@
1700b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1701b17ce1afSJed Brown 
1702b17ce1afSJed Brown    Logically Collective
1703b17ce1afSJed Brown 
1704b17ce1afSJed Brown    Input Arguments:
1705b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1706b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1707b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
1708b17ce1afSJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1709b17ce1afSJed Brown 
1710b17ce1afSJed Brown    Calling sequence of coarsenhook:
1711b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1712b17ce1afSJed Brown 
1713b17ce1afSJed Brown +  fine - fine level DM
1714b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1715b17ce1afSJed Brown -  ctx - optional user-defined function context
1716b17ce1afSJed Brown 
1717b17ce1afSJed Brown    Calling sequence for restricthook:
1718c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
1719b17ce1afSJed Brown 
1720b17ce1afSJed Brown +  fine - fine level DM
1721b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
1722c833c3b5SJed Brown .  rscale - scaling vector for restriction
1723c833c3b5SJed Brown .  inject - matrix restricting by injection
1724b17ce1afSJed Brown .  coarse - coarse level DM to update
1725b17ce1afSJed Brown -  ctx - optional user-defined function context
1726b17ce1afSJed Brown 
1727b17ce1afSJed Brown    Level: advanced
1728b17ce1afSJed Brown 
1729b17ce1afSJed Brown    Notes:
1730b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
1731b17ce1afSJed Brown 
1732b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1733b17ce1afSJed Brown 
1734b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1735b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
1736b17ce1afSJed Brown 
1737c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1738b17ce1afSJed Brown @*/
1739b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1740b17ce1afSJed Brown {
1741b17ce1afSJed Brown   PetscErrorCode ierr;
1742b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
1743b17ce1afSJed Brown 
1744b17ce1afSJed Brown   PetscFunctionBegin;
1745b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
17466bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1747b17ce1afSJed Brown   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1748b17ce1afSJed Brown   link->coarsenhook = coarsenhook;
1749b17ce1afSJed Brown   link->restricthook = restricthook;
1750b17ce1afSJed Brown   link->ctx = ctx;
17516cab3a1bSJed Brown   link->next = PETSC_NULL;
1752b17ce1afSJed Brown   *p = link;
1753b17ce1afSJed Brown   PetscFunctionReturn(0);
1754b17ce1afSJed Brown }
1755b17ce1afSJed Brown 
1756b17ce1afSJed Brown #undef __FUNCT__
1757b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
1758b17ce1afSJed Brown /*@
1759b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1760b17ce1afSJed Brown 
1761b17ce1afSJed Brown    Collective if any hooks are
1762b17ce1afSJed Brown 
1763b17ce1afSJed Brown    Input Arguments:
1764b17ce1afSJed Brown +  fine - finer DM to use as a base
1765b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
1766b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
1767b17ce1afSJed Brown -  coarse - coarer DM to update
1768b17ce1afSJed Brown 
1769b17ce1afSJed Brown    Level: developer
1770b17ce1afSJed Brown 
1771b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
1772b17ce1afSJed Brown @*/
1773b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1774b17ce1afSJed Brown {
1775b17ce1afSJed Brown   PetscErrorCode ierr;
1776b17ce1afSJed Brown   DMCoarsenHookLink link;
1777b17ce1afSJed Brown 
1778b17ce1afSJed Brown   PetscFunctionBegin;
1779b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
1780b17ce1afSJed Brown     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1781b17ce1afSJed Brown   }
178247c6ae99SBarry Smith   PetscFunctionReturn(0);
178347c6ae99SBarry Smith }
178447c6ae99SBarry Smith 
178547c6ae99SBarry Smith #undef __FUNCT__
17865dbd56e3SPeter Brune #define __FUNCT__ "DMBlockRestrictHookAdd"
17875dbd56e3SPeter Brune /*@
17885dbd56e3SPeter Brune    DMBlockRestrictHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
17895dbd56e3SPeter Brune 
17905dbd56e3SPeter Brune    Logically Collective
17915dbd56e3SPeter Brune 
17925dbd56e3SPeter Brune    Input Arguments:
17935dbd56e3SPeter Brune +  global - global DM
17945dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
17955dbd56e3SPeter Brune -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
17965dbd56e3SPeter Brune 
17975dbd56e3SPeter Brune    Calling sequence for restricthook:
17985dbd56e3SPeter Brune $    restricthook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
17995dbd56e3SPeter Brune 
18005dbd56e3SPeter Brune +  global - global DM
18015dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
18025dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
18035dbd56e3SPeter Brune .  block  - block DM (may just be a shell if the global DM is passed in correctly)
18045dbd56e3SPeter Brune -  ctx - optional user-defined function context
18055dbd56e3SPeter Brune 
18065dbd56e3SPeter Brune    Level: advanced
18075dbd56e3SPeter Brune 
18085dbd56e3SPeter Brune    Notes:
18095dbd56e3SPeter Brune    This function is only needed if auxiliary data needs to be set up on coarse grids.
18105dbd56e3SPeter Brune 
18115dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
18125dbd56e3SPeter Brune 
18135dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
18145dbd56e3SPeter Brune    extract the finest level information from its context (instead of from the SNES).
18155dbd56e3SPeter Brune 
18165dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
18175dbd56e3SPeter Brune @*/
18185dbd56e3SPeter Brune PetscErrorCode DMBlockRestrictHookAdd(DM global,PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
18195dbd56e3SPeter Brune {
18205dbd56e3SPeter Brune   PetscErrorCode ierr;
18215dbd56e3SPeter Brune   DMBlockRestrictHookLink link,*p;
18225dbd56e3SPeter Brune 
18235dbd56e3SPeter Brune   PetscFunctionBegin;
18245dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
18255dbd56e3SPeter Brune   for (p=&global->blockrestricthook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
18265dbd56e3SPeter Brune   ierr = PetscMalloc(sizeof(struct _DMBlockRestrictHookLink),&link);CHKERRQ(ierr);
18275dbd56e3SPeter Brune   link->restricthook = restricthook;
18285dbd56e3SPeter Brune   link->ctx = ctx;
18295dbd56e3SPeter Brune   link->next = PETSC_NULL;
18305dbd56e3SPeter Brune   *p = link;
18315dbd56e3SPeter Brune   PetscFunctionReturn(0);
18325dbd56e3SPeter Brune }
18335dbd56e3SPeter Brune 
18345dbd56e3SPeter Brune #undef __FUNCT__
18355dbd56e3SPeter Brune #define __FUNCT__ "DMBlockRestrict"
18365dbd56e3SPeter Brune /*@
18375dbd56e3SPeter Brune    DMBlockRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMBlockRestrictHookAdd()
18385dbd56e3SPeter Brune 
18395dbd56e3SPeter Brune    Collective if any hooks are
18405dbd56e3SPeter Brune 
18415dbd56e3SPeter Brune    Input Arguments:
18425dbd56e3SPeter Brune +  fine - finer DM to use as a base
18435dbd56e3SPeter Brune .  restrct - restriction matrix, apply using MatRestrict()
18445dbd56e3SPeter Brune .  inject - injection matrix, also use MatRestrict()
18455dbd56e3SPeter Brune -  coarse - coarer DM to update
18465dbd56e3SPeter Brune 
18475dbd56e3SPeter Brune    Level: developer
18485dbd56e3SPeter Brune 
18495dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
18505dbd56e3SPeter Brune @*/
18515dbd56e3SPeter Brune PetscErrorCode DMBlockRestrict(DM global,VecScatter in,VecScatter out,DM block)
18525dbd56e3SPeter Brune {
18535dbd56e3SPeter Brune   PetscErrorCode ierr;
18545dbd56e3SPeter Brune   DMBlockRestrictHookLink link;
18555dbd56e3SPeter Brune 
18565dbd56e3SPeter Brune   PetscFunctionBegin;
18575dbd56e3SPeter Brune   for (link=global->blockrestricthook; link; link=link->next) {
18585dbd56e3SPeter Brune     if (link->restricthook) {ierr = (*link->restricthook)(global,in,out,block,link->ctx);CHKERRQ(ierr);}
18595dbd56e3SPeter Brune   }
18605dbd56e3SPeter Brune   PetscFunctionReturn(0);
18615dbd56e3SPeter Brune }
18625dbd56e3SPeter Brune 
18635dbd56e3SPeter Brune #undef __FUNCT__
18645fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
18655fe1f584SPeter Brune /*@
18666a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
18675fe1f584SPeter Brune 
18685fe1f584SPeter Brune     Not Collective
18695fe1f584SPeter Brune 
18705fe1f584SPeter Brune     Input Parameter:
18715fe1f584SPeter Brune .   dm - the DM object
18725fe1f584SPeter Brune 
18735fe1f584SPeter Brune     Output Parameter:
18746a7d9d85SPeter Brune .   level - number of coarsenings
18755fe1f584SPeter Brune 
18765fe1f584SPeter Brune     Level: developer
18775fe1f584SPeter Brune 
18786a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
18795fe1f584SPeter Brune 
18805fe1f584SPeter Brune @*/
18815fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
18825fe1f584SPeter Brune {
18835fe1f584SPeter Brune   PetscFunctionBegin;
18845fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18855fe1f584SPeter Brune   *level = dm->leveldown;
18865fe1f584SPeter Brune   PetscFunctionReturn(0);
18875fe1f584SPeter Brune }
18885fe1f584SPeter Brune 
18895fe1f584SPeter Brune 
18905fe1f584SPeter Brune 
18915fe1f584SPeter Brune #undef __FUNCT__
189247c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
189347c6ae99SBarry Smith /*@C
189447c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
189547c6ae99SBarry Smith 
189647c6ae99SBarry Smith     Collective on DM
189747c6ae99SBarry Smith 
189847c6ae99SBarry Smith     Input Parameter:
189947c6ae99SBarry Smith +   dm - the DM object
190047c6ae99SBarry Smith -   nlevels - the number of levels of refinement
190147c6ae99SBarry Smith 
190247c6ae99SBarry Smith     Output Parameter:
190347c6ae99SBarry Smith .   dmf - the refined DM hierarchy
190447c6ae99SBarry Smith 
190547c6ae99SBarry Smith     Level: developer
190647c6ae99SBarry Smith 
1907e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
190847c6ae99SBarry Smith 
190947c6ae99SBarry Smith @*/
19107087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
191147c6ae99SBarry Smith {
191247c6ae99SBarry Smith   PetscErrorCode ierr;
191347c6ae99SBarry Smith 
191447c6ae99SBarry Smith   PetscFunctionBegin;
1915171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
191647c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
191747c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
191847c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
191947c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
192047c6ae99SBarry Smith   } else if (dm->ops->refine) {
192147c6ae99SBarry Smith     PetscInt i;
192247c6ae99SBarry Smith 
192347c6ae99SBarry Smith     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
192447c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
192547c6ae99SBarry Smith       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
192647c6ae99SBarry Smith     }
192747c6ae99SBarry Smith   } else {
192847c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
192947c6ae99SBarry Smith   }
193047c6ae99SBarry Smith   PetscFunctionReturn(0);
193147c6ae99SBarry Smith }
193247c6ae99SBarry Smith 
193347c6ae99SBarry Smith #undef __FUNCT__
193447c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
193547c6ae99SBarry Smith /*@C
193647c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
193747c6ae99SBarry Smith 
193847c6ae99SBarry Smith     Collective on DM
193947c6ae99SBarry Smith 
194047c6ae99SBarry Smith     Input Parameter:
194147c6ae99SBarry Smith +   dm - the DM object
194247c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
194347c6ae99SBarry Smith 
194447c6ae99SBarry Smith     Output Parameter:
194547c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
194647c6ae99SBarry Smith 
194747c6ae99SBarry Smith     Level: developer
194847c6ae99SBarry Smith 
1949e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
195047c6ae99SBarry Smith 
195147c6ae99SBarry Smith @*/
19527087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
195347c6ae99SBarry Smith {
195447c6ae99SBarry Smith   PetscErrorCode ierr;
195547c6ae99SBarry Smith 
195647c6ae99SBarry Smith   PetscFunctionBegin;
1957171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
195847c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
195947c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
196047c6ae99SBarry Smith   PetscValidPointer(dmc,3);
196147c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
196247c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
196347c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
196447c6ae99SBarry Smith     PetscInt i;
196547c6ae99SBarry Smith 
196647c6ae99SBarry Smith     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
196747c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
196847c6ae99SBarry Smith       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
196947c6ae99SBarry Smith     }
197047c6ae99SBarry Smith   } else {
197147c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
197247c6ae99SBarry Smith   }
197347c6ae99SBarry Smith   PetscFunctionReturn(0);
197447c6ae99SBarry Smith }
197547c6ae99SBarry Smith 
197647c6ae99SBarry Smith #undef __FUNCT__
1977e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
197847c6ae99SBarry Smith /*@
1979e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
198047c6ae99SBarry Smith    grids associated with two DMs.
198147c6ae99SBarry Smith 
198247c6ae99SBarry Smith    Collective on DM
198347c6ae99SBarry Smith 
198447c6ae99SBarry Smith    Input Parameters:
198547c6ae99SBarry Smith +  dmc - the coarse grid DM
198647c6ae99SBarry Smith -  dmf - the fine grid DM
198747c6ae99SBarry Smith 
198847c6ae99SBarry Smith    Output Parameters:
198947c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
199047c6ae99SBarry Smith 
199147c6ae99SBarry Smith    Level: intermediate
199247c6ae99SBarry Smith 
199347c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
199447c6ae99SBarry Smith 
1995e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
199647c6ae99SBarry Smith @*/
1997e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
199847c6ae99SBarry Smith {
199947c6ae99SBarry Smith   PetscErrorCode ierr;
200047c6ae99SBarry Smith 
200147c6ae99SBarry Smith   PetscFunctionBegin;
2002171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
2003171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
200447c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
200547c6ae99SBarry Smith   PetscFunctionReturn(0);
200647c6ae99SBarry Smith }
200747c6ae99SBarry Smith 
200847c6ae99SBarry Smith #undef __FUNCT__
20091a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
20101a266240SBarry Smith /*@C
20111a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
20121a266240SBarry Smith 
20131a266240SBarry Smith     Not Collective
20141a266240SBarry Smith 
20151a266240SBarry Smith     Input Parameters:
20161a266240SBarry Smith +   dm - the DM object
20171a266240SBarry Smith -   destroy - the destroy function
20181a266240SBarry Smith 
20191a266240SBarry Smith     Level: intermediate
20201a266240SBarry Smith 
2021e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
20221a266240SBarry Smith 
2023f07f9ceaSJed Brown @*/
20241a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
20251a266240SBarry Smith {
20261a266240SBarry Smith   PetscFunctionBegin;
2027171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
20281a266240SBarry Smith   dm->ctxdestroy = destroy;
20291a266240SBarry Smith   PetscFunctionReturn(0);
20301a266240SBarry Smith }
20311a266240SBarry Smith 
20321a266240SBarry Smith #undef __FUNCT__
20331b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
2034b07ff414SBarry Smith /*@
20351b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
203647c6ae99SBarry Smith 
203747c6ae99SBarry Smith     Not Collective
203847c6ae99SBarry Smith 
203947c6ae99SBarry Smith     Input Parameters:
204047c6ae99SBarry Smith +   dm - the DM object
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  DMSetApplicationContext(DM dm,void *ctx)
204947c6ae99SBarry Smith {
205047c6ae99SBarry Smith   PetscFunctionBegin;
2051171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
205247c6ae99SBarry Smith   dm->ctx = ctx;
205347c6ae99SBarry Smith   PetscFunctionReturn(0);
205447c6ae99SBarry Smith }
205547c6ae99SBarry Smith 
205647c6ae99SBarry Smith #undef __FUNCT__
20571b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
205847c6ae99SBarry Smith /*@
20591b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
206047c6ae99SBarry Smith 
206147c6ae99SBarry Smith     Not Collective
206247c6ae99SBarry Smith 
206347c6ae99SBarry Smith     Input Parameter:
206447c6ae99SBarry Smith .   dm - the DM object
206547c6ae99SBarry Smith 
206647c6ae99SBarry Smith     Output Parameter:
206747c6ae99SBarry Smith .   ctx - the user context
206847c6ae99SBarry Smith 
206947c6ae99SBarry Smith     Level: intermediate
207047c6ae99SBarry Smith 
2071e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
207247c6ae99SBarry Smith 
207347c6ae99SBarry Smith @*/
20741b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
207547c6ae99SBarry Smith {
207647c6ae99SBarry Smith   PetscFunctionBegin;
2077171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
20781b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
207947c6ae99SBarry Smith   PetscFunctionReturn(0);
208047c6ae99SBarry Smith }
208147c6ae99SBarry Smith 
208247c6ae99SBarry Smith #undef __FUNCT__
208347c6ae99SBarry Smith #define __FUNCT__ "DMSetInitialGuess"
20847e833e3aSBarry Smith /*@C
208547c6ae99SBarry Smith     DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers
208647c6ae99SBarry Smith 
208747c6ae99SBarry Smith     Logically Collective on DM
208847c6ae99SBarry Smith 
208947c6ae99SBarry Smith     Input Parameter:
209047c6ae99SBarry Smith +   dm - the DM object to destroy
209147c6ae99SBarry Smith -   f - the function to compute the initial guess
209247c6ae99SBarry Smith 
209347c6ae99SBarry Smith     Level: intermediate
209447c6ae99SBarry Smith 
2095e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
209647c6ae99SBarry Smith 
2097f07f9ceaSJed Brown @*/
20987087cfbeSBarry Smith PetscErrorCode  DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec))
209947c6ae99SBarry Smith {
210047c6ae99SBarry Smith   PetscFunctionBegin;
2101171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
210247c6ae99SBarry Smith   dm->ops->initialguess = f;
210347c6ae99SBarry Smith   PetscFunctionReturn(0);
210447c6ae99SBarry Smith }
210547c6ae99SBarry Smith 
210647c6ae99SBarry Smith #undef __FUNCT__
210747c6ae99SBarry Smith #define __FUNCT__ "DMSetFunction"
21087e833e3aSBarry Smith /*@C
210947c6ae99SBarry Smith     DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES
211047c6ae99SBarry Smith 
211147c6ae99SBarry Smith     Logically Collective on DM
211247c6ae99SBarry Smith 
211347c6ae99SBarry Smith     Input Parameter:
211447c6ae99SBarry Smith +   dm - the DM object
211547c6ae99SBarry Smith -   f - the function to compute (use PETSC_NULL to cancel a previous function that was set)
211647c6ae99SBarry Smith 
211747c6ae99SBarry Smith     Level: intermediate
211847c6ae99SBarry Smith 
211947c6ae99SBarry Smith     Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian
212047c6ae99SBarry Smith            computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian.
212147c6ae99SBarry Smith 
2122e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
212347c6ae99SBarry Smith          DMSetJacobian()
212447c6ae99SBarry Smith 
2125f07f9ceaSJed Brown @*/
21267087cfbeSBarry Smith PetscErrorCode  DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
212747c6ae99SBarry Smith {
212847c6ae99SBarry Smith   PetscFunctionBegin;
2129171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
213047c6ae99SBarry Smith   dm->ops->function = f;
213147c6ae99SBarry Smith   if (f) {
213247c6ae99SBarry Smith     dm->ops->functionj = f;
213347c6ae99SBarry Smith   }
213447c6ae99SBarry Smith   PetscFunctionReturn(0);
213547c6ae99SBarry Smith }
213647c6ae99SBarry Smith 
213747c6ae99SBarry Smith #undef __FUNCT__
213847c6ae99SBarry Smith #define __FUNCT__ "DMSetJacobian"
21397e833e3aSBarry Smith /*@C
214047c6ae99SBarry Smith     DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES
214147c6ae99SBarry Smith 
214247c6ae99SBarry Smith     Logically Collective on DM
214347c6ae99SBarry Smith 
214447c6ae99SBarry Smith     Input Parameter:
214547c6ae99SBarry Smith +   dm - the DM object to destroy
214647c6ae99SBarry Smith -   f - the function to compute the matrix entries
214747c6ae99SBarry Smith 
214847c6ae99SBarry Smith     Level: intermediate
214947c6ae99SBarry Smith 
2150e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
215147c6ae99SBarry Smith          DMSetFunction()
215247c6ae99SBarry Smith 
2153f07f9ceaSJed Brown @*/
21547087cfbeSBarry Smith PetscErrorCode  DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*))
215547c6ae99SBarry Smith {
215647c6ae99SBarry Smith   PetscFunctionBegin;
2157171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
215847c6ae99SBarry Smith   dm->ops->jacobian = f;
215947c6ae99SBarry Smith   PetscFunctionReturn(0);
216047c6ae99SBarry Smith }
216147c6ae99SBarry Smith 
216247c6ae99SBarry Smith #undef __FUNCT__
216308da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
216408da532bSDmitry Karpeev /*@C
216508da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
216608da532bSDmitry Karpeev 
216708da532bSDmitry Karpeev     Logically Collective on DM
216808da532bSDmitry Karpeev 
216908da532bSDmitry Karpeev     Input Parameter:
217008da532bSDmitry Karpeev +   dm - the DM object
217108da532bSDmitry Karpeev -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
217208da532bSDmitry Karpeev 
217308da532bSDmitry Karpeev     Level: intermediate
217408da532bSDmitry Karpeev 
2175e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
217608da532bSDmitry Karpeev          DMSetJacobian()
217708da532bSDmitry Karpeev 
217808da532bSDmitry Karpeev @*/
217908da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
218008da532bSDmitry Karpeev {
218108da532bSDmitry Karpeev   PetscFunctionBegin;
218208da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
218308da532bSDmitry Karpeev   PetscFunctionReturn(0);
218408da532bSDmitry Karpeev }
218508da532bSDmitry Karpeev 
218608da532bSDmitry Karpeev #undef __FUNCT__
218708da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
218808da532bSDmitry Karpeev /*@
218908da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
219008da532bSDmitry Karpeev 
219108da532bSDmitry Karpeev     Not Collective
219208da532bSDmitry Karpeev 
219308da532bSDmitry Karpeev     Input Parameter:
219408da532bSDmitry Karpeev .   dm - the DM object to destroy
219508da532bSDmitry Karpeev 
219608da532bSDmitry Karpeev     Output Parameter:
219708da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
219808da532bSDmitry Karpeev 
219908da532bSDmitry Karpeev     Level: developer
220008da532bSDmitry Karpeev 
2201e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
220208da532bSDmitry Karpeev 
220308da532bSDmitry Karpeev @*/
220408da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
220508da532bSDmitry Karpeev {
220608da532bSDmitry Karpeev   PetscFunctionBegin;
220708da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
220808da532bSDmitry Karpeev   PetscFunctionReturn(0);
220908da532bSDmitry Karpeev }
221008da532bSDmitry Karpeev 
221108da532bSDmitry Karpeev #undef __FUNCT__
221208da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
221308da532bSDmitry Karpeev /*@C
221408da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
221508da532bSDmitry Karpeev 
221608da532bSDmitry Karpeev     Logically Collective on DM
221708da532bSDmitry Karpeev 
221808da532bSDmitry Karpeev     Input Parameters:
221908da532bSDmitry Karpeev +   dm - the DM object to destroy
222008da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
222108da532bSDmitry Karpeev 
222208da532bSDmitry Karpeev     Output parameters:
222308da532bSDmitry Karpeev +   xl - lower bound
222408da532bSDmitry Karpeev -   xu - upper bound
222508da532bSDmitry Karpeev 
222608da532bSDmitry Karpeev     Level: intermediate
222708da532bSDmitry Karpeev 
2228e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
222908da532bSDmitry Karpeev          DMSetFunction(), DMSetVariableBounds()
223008da532bSDmitry Karpeev 
223108da532bSDmitry Karpeev @*/
223208da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
223308da532bSDmitry Karpeev {
223408da532bSDmitry Karpeev   PetscErrorCode ierr;
223508da532bSDmitry Karpeev   PetscFunctionBegin;
223608da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
223708da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
223808da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
223908da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
224008da532bSDmitry Karpeev   }
2241a201590fSDmitry Karpeev   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
224208da532bSDmitry Karpeev   PetscFunctionReturn(0);
224308da532bSDmitry Karpeev }
224408da532bSDmitry Karpeev 
224508da532bSDmitry Karpeev #undef __FUNCT__
224647c6ae99SBarry Smith #define __FUNCT__ "DMComputeInitialGuess"
224747c6ae99SBarry Smith /*@
224847c6ae99SBarry Smith     DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers
224947c6ae99SBarry Smith 
225047c6ae99SBarry Smith     Collective on DM
225147c6ae99SBarry Smith 
225247c6ae99SBarry Smith     Input Parameter:
225347c6ae99SBarry Smith +   dm - the DM object to destroy
225447c6ae99SBarry Smith -   x - the vector to hold the initial guess values
225547c6ae99SBarry Smith 
225647c6ae99SBarry Smith     Level: developer
225747c6ae99SBarry Smith 
2258e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat()
225947c6ae99SBarry Smith 
226047c6ae99SBarry Smith @*/
22617087cfbeSBarry Smith PetscErrorCode  DMComputeInitialGuess(DM dm,Vec x)
226247c6ae99SBarry Smith {
226347c6ae99SBarry Smith   PetscErrorCode ierr;
226447c6ae99SBarry Smith   PetscFunctionBegin;
2265171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
226647c6ae99SBarry Smith   if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()");
226747c6ae99SBarry Smith   ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr);
226847c6ae99SBarry Smith   PetscFunctionReturn(0);
226947c6ae99SBarry Smith }
227047c6ae99SBarry Smith 
227147c6ae99SBarry Smith #undef __FUNCT__
227247c6ae99SBarry Smith #define __FUNCT__ "DMHasInitialGuess"
227347c6ae99SBarry Smith /*@
227447c6ae99SBarry Smith     DMHasInitialGuess - does the DM object have an initial guess 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  DMHasInitialGuess(DM dm,PetscBool  *flg)
229047c6ae99SBarry Smith {
229147c6ae99SBarry Smith   PetscFunctionBegin;
2292171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
229347c6ae99SBarry Smith   *flg =  (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE;
229447c6ae99SBarry Smith   PetscFunctionReturn(0);
229547c6ae99SBarry Smith }
229647c6ae99SBarry Smith 
229747c6ae99SBarry Smith #undef __FUNCT__
229847c6ae99SBarry Smith #define __FUNCT__ "DMHasFunction"
229947c6ae99SBarry Smith /*@
230047c6ae99SBarry Smith     DMHasFunction - does the DM object have a 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  DMHasFunction(DM dm,PetscBool  *flg)
231647c6ae99SBarry Smith {
231747c6ae99SBarry Smith   PetscFunctionBegin;
2318171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
231947c6ae99SBarry Smith   *flg =  (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE;
232047c6ae99SBarry Smith   PetscFunctionReturn(0);
232147c6ae99SBarry Smith }
232247c6ae99SBarry Smith 
232347c6ae99SBarry Smith #undef __FUNCT__
232447c6ae99SBarry Smith #define __FUNCT__ "DMHasJacobian"
232547c6ae99SBarry Smith /*@
232647c6ae99SBarry Smith     DMHasJacobian - does the DM object have a matrix function
232747c6ae99SBarry Smith 
232847c6ae99SBarry Smith     Not Collective
232947c6ae99SBarry Smith 
233047c6ae99SBarry Smith     Input Parameter:
233147c6ae99SBarry Smith .   dm - the DM object to destroy
233247c6ae99SBarry Smith 
233347c6ae99SBarry Smith     Output Parameter:
233447c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
233547c6ae99SBarry Smith 
233647c6ae99SBarry Smith     Level: developer
233747c6ae99SBarry Smith 
2338e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
233947c6ae99SBarry Smith 
234047c6ae99SBarry Smith @*/
23417087cfbeSBarry Smith PetscErrorCode  DMHasJacobian(DM dm,PetscBool  *flg)
234247c6ae99SBarry Smith {
234347c6ae99SBarry Smith   PetscFunctionBegin;
2344171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
234547c6ae99SBarry Smith   *flg =  (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE;
234647c6ae99SBarry Smith   PetscFunctionReturn(0);
234747c6ae99SBarry Smith }
234847c6ae99SBarry Smith 
234947c6ae99SBarry Smith #undef __FUNCT__
2350b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2351b0ae01b7SPeter Brune /*@
2352b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2353b0ae01b7SPeter Brune 
2354b0ae01b7SPeter Brune     Not Collective
2355b0ae01b7SPeter Brune 
2356b0ae01b7SPeter Brune     Input Parameter:
2357b0ae01b7SPeter Brune .   dm - the DM object
2358b0ae01b7SPeter Brune 
2359b0ae01b7SPeter Brune     Output Parameter:
2360b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2361b0ae01b7SPeter Brune 
2362b0ae01b7SPeter Brune     Level: developer
2363b0ae01b7SPeter Brune 
2364b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2365b0ae01b7SPeter Brune 
2366b0ae01b7SPeter Brune @*/
2367b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2368b0ae01b7SPeter Brune {
2369b0ae01b7SPeter Brune   PetscFunctionBegin;
2370b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2371b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2372b0ae01b7SPeter Brune }
2373b0ae01b7SPeter Brune 
2374b0ae01b7SPeter Brune #undef  __FUNCT__
237508da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2376748fac09SDmitry Karpeev /*@C
237708da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
237808da532bSDmitry Karpeev 
237908da532bSDmitry Karpeev     Collective on DM
238008da532bSDmitry Karpeev 
238108da532bSDmitry Karpeev     Input Parameter:
238208da532bSDmitry Karpeev +   dm - the DM object
2383e88d7f4bSDmitry Karpeev -   x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems.
238408da532bSDmitry Karpeev 
238508da532bSDmitry Karpeev     Level: developer
238608da532bSDmitry Karpeev 
2387e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
238808da532bSDmitry Karpeev          DMSetFunction(), DMSetJacobian(), DMSetVariableBounds()
238908da532bSDmitry Karpeev 
239008da532bSDmitry Karpeev @*/
239108da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
239208da532bSDmitry Karpeev {
239308da532bSDmitry Karpeev   PetscErrorCode ierr;
239408da532bSDmitry Karpeev   PetscFunctionBegin;
239508da532bSDmitry Karpeev   if (x) {
239608da532bSDmitry Karpeev     if (!dm->x) {
239708da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
239808da532bSDmitry Karpeev     }
239908da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
240008da532bSDmitry Karpeev   }
240108da532bSDmitry Karpeev   else if (dm->x) {
240208da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
240308da532bSDmitry Karpeev   }
240408da532bSDmitry Karpeev   PetscFunctionReturn(0);
240508da532bSDmitry Karpeev }
240608da532bSDmitry Karpeev 
240708da532bSDmitry Karpeev 
240808da532bSDmitry Karpeev #undef __FUNCT__
240947c6ae99SBarry Smith #define __FUNCT__ "DMComputeFunction"
241047c6ae99SBarry Smith /*@
241147c6ae99SBarry Smith     DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES
241247c6ae99SBarry Smith 
241347c6ae99SBarry Smith     Collective on DM
241447c6ae99SBarry Smith 
241547c6ae99SBarry Smith     Input Parameter:
241647c6ae99SBarry Smith +   dm - the DM object to destroy
241747c6ae99SBarry Smith .   x - the location where the function is evaluationed, may be ignored for linear problems
241847c6ae99SBarry Smith -   b - the vector to hold the right hand side entries
241947c6ae99SBarry Smith 
242047c6ae99SBarry Smith     Level: developer
242147c6ae99SBarry Smith 
2422e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
242347c6ae99SBarry Smith          DMSetJacobian()
242447c6ae99SBarry Smith 
242547c6ae99SBarry Smith @*/
24267087cfbeSBarry Smith PetscErrorCode  DMComputeFunction(DM dm,Vec x,Vec b)
242747c6ae99SBarry Smith {
242847c6ae99SBarry Smith   PetscErrorCode ierr;
242947c6ae99SBarry Smith   PetscFunctionBegin;
2430171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
243147c6ae99SBarry Smith   if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()");
2432644e2e5bSBarry Smith   PetscStackPush("DM user function");
243347c6ae99SBarry Smith   ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr);
2434644e2e5bSBarry Smith   PetscStackPop;
243547c6ae99SBarry Smith   PetscFunctionReturn(0);
243647c6ae99SBarry Smith }
243747c6ae99SBarry Smith 
243847c6ae99SBarry Smith 
243908da532bSDmitry Karpeev 
244047c6ae99SBarry Smith #undef __FUNCT__
244147c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobian"
244247c6ae99SBarry Smith /*@
244347c6ae99SBarry Smith     DMComputeJacobian - compute the matrix entries for the solver
244447c6ae99SBarry Smith 
244547c6ae99SBarry Smith     Collective on DM
244647c6ae99SBarry Smith 
244747c6ae99SBarry Smith     Input Parameter:
244847c6ae99SBarry Smith +   dm - the DM object
2449cab2e9ccSBarry Smith .   x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM
245047c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
245147c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
245247c6ae99SBarry Smith 
245347c6ae99SBarry Smith     Level: developer
245447c6ae99SBarry Smith 
2455e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
245647c6ae99SBarry Smith          DMSetFunction()
245747c6ae99SBarry Smith 
245847c6ae99SBarry Smith @*/
24597087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
246047c6ae99SBarry Smith {
246147c6ae99SBarry Smith   PetscErrorCode ierr;
246247c6ae99SBarry Smith 
246347c6ae99SBarry Smith   PetscFunctionBegin;
2464171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
246547c6ae99SBarry Smith   if (!dm->ops->jacobian) {
246647c6ae99SBarry Smith     ISColoring     coloring;
246747c6ae99SBarry Smith     MatFDColoring  fd;
246819fd82e9SBarry Smith     MatType        mtype;
246947c6ae99SBarry Smith 
24702c9966d7SBarry Smith     ierr = PetscObjectGetType((PetscObject)B,&mtype);CHKERRQ(ierr);
24712c9966d7SBarry Smith     ierr = DMCreateColoring(dm,dm->coloringtype,mtype,&coloring);CHKERRQ(ierr);
247247c6ae99SBarry Smith     ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr);
2473fcfd50ebSBarry Smith     ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
247447c6ae99SBarry Smith     ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr);
24750bdded8aSJed Brown     ierr = PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);CHKERRQ(ierr);
24760bdded8aSJed Brown     ierr = MatFDColoringSetFromOptions(fd);CHKERRQ(ierr);
247771cd77b2SBarry Smith 
247847c6ae99SBarry Smith     dm->fd = fd;
247947c6ae99SBarry Smith     dm->ops->jacobian = DMComputeJacobianDefault;
24802533e041SBarry Smith 
248171cd77b2SBarry Smith     /* don't know why this is needed */
248271cd77b2SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
248347c6ae99SBarry Smith   }
248447c6ae99SBarry Smith   if (!x) x = dm->x;
248547c6ae99SBarry Smith   ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr);
2486cab2e9ccSBarry Smith 
248771cd77b2SBarry 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 */
2488649052a6SBarry Smith   if (x) {
2489cab2e9ccSBarry Smith     if (!dm->x) {
249071cd77b2SBarry Smith       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
2491cab2e9ccSBarry Smith     }
2492cab2e9ccSBarry Smith     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
2493649052a6SBarry Smith   }
2494a8248277SBarry Smith   if (A != B) {
2495a8248277SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2496a8248277SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2497a8248277SBarry Smith   }
249847c6ae99SBarry Smith   PetscFunctionReturn(0);
249947c6ae99SBarry Smith }
2500264ace61SBarry Smith 
2501cab2e9ccSBarry Smith 
2502264ace61SBarry Smith PetscFList DMList                       = PETSC_NULL;
2503264ace61SBarry Smith PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
2504264ace61SBarry Smith 
2505264ace61SBarry Smith #undef __FUNCT__
2506264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2507264ace61SBarry Smith /*@C
2508264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2509264ace61SBarry Smith 
2510264ace61SBarry Smith   Collective on DM
2511264ace61SBarry Smith 
2512264ace61SBarry Smith   Input Parameters:
2513264ace61SBarry Smith + dm     - The DM object
2514264ace61SBarry Smith - method - The name of the DM type
2515264ace61SBarry Smith 
2516264ace61SBarry Smith   Options Database Key:
2517264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2518264ace61SBarry Smith 
2519264ace61SBarry Smith   Notes:
2520e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2521264ace61SBarry Smith 
2522264ace61SBarry Smith   Level: intermediate
2523264ace61SBarry Smith 
2524264ace61SBarry Smith .keywords: DM, set, type
2525264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2526264ace61SBarry Smith @*/
252719fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
2528264ace61SBarry Smith {
2529264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2530264ace61SBarry Smith   PetscBool      match;
2531264ace61SBarry Smith   PetscErrorCode ierr;
2532264ace61SBarry Smith 
2533264ace61SBarry Smith   PetscFunctionBegin;
2534264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2535251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2536264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2537264ace61SBarry Smith 
2538264ace61SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
25394b91b6eaSBarry Smith   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2540264ace61SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2541264ace61SBarry Smith 
2542264ace61SBarry Smith   if (dm->ops->destroy) {
2543264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
2544b5c23020SJed Brown     dm->ops->destroy = PETSC_NULL;
2545264ace61SBarry Smith   }
2546264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2547264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2548264ace61SBarry Smith   PetscFunctionReturn(0);
2549264ace61SBarry Smith }
2550264ace61SBarry Smith 
2551264ace61SBarry Smith #undef __FUNCT__
2552264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2553264ace61SBarry Smith /*@C
2554264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2555264ace61SBarry Smith 
2556264ace61SBarry Smith   Not Collective
2557264ace61SBarry Smith 
2558264ace61SBarry Smith   Input Parameter:
2559264ace61SBarry Smith . dm  - The DM
2560264ace61SBarry Smith 
2561264ace61SBarry Smith   Output Parameter:
2562264ace61SBarry Smith . type - The DM type name
2563264ace61SBarry Smith 
2564264ace61SBarry Smith   Level: intermediate
2565264ace61SBarry Smith 
2566264ace61SBarry Smith .keywords: DM, get, type, name
2567264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2568264ace61SBarry Smith @*/
256919fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
2570264ace61SBarry Smith {
2571264ace61SBarry Smith   PetscErrorCode ierr;
2572264ace61SBarry Smith 
2573264ace61SBarry Smith   PetscFunctionBegin;
2574264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2575264ace61SBarry Smith   PetscValidCharPointer(type,2);
2576264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2577264ace61SBarry Smith     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2578264ace61SBarry Smith   }
2579264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2580264ace61SBarry Smith   PetscFunctionReturn(0);
2581264ace61SBarry Smith }
2582264ace61SBarry Smith 
258367a56275SMatthew G Knepley #undef __FUNCT__
258467a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
258567a56275SMatthew G Knepley /*@C
258667a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
258767a56275SMatthew G Knepley 
258867a56275SMatthew G Knepley   Collective on DM
258967a56275SMatthew G Knepley 
259067a56275SMatthew G Knepley   Input Parameters:
259167a56275SMatthew G Knepley + dm - the DM
259267a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
259367a56275SMatthew G Knepley 
259467a56275SMatthew G Knepley   Output Parameter:
259567a56275SMatthew G Knepley . M - pointer to new DM
259667a56275SMatthew G Knepley 
259767a56275SMatthew G Knepley   Notes:
259867a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
259967a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
260067a56275SMatthew G Knepley   of the input DM.
260167a56275SMatthew G Knepley 
260267a56275SMatthew G Knepley   Level: intermediate
260367a56275SMatthew G Knepley 
260467a56275SMatthew G Knepley .seealso: DMCreate()
260567a56275SMatthew G Knepley @*/
260619fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
260767a56275SMatthew G Knepley {
260867a56275SMatthew G Knepley   DM             B;
260967a56275SMatthew G Knepley   char           convname[256];
261067a56275SMatthew G Knepley   PetscBool      sametype, issame;
261167a56275SMatthew G Knepley   PetscErrorCode ierr;
261267a56275SMatthew G Knepley 
261367a56275SMatthew G Knepley   PetscFunctionBegin;
261467a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
261567a56275SMatthew G Knepley   PetscValidType(dm,1);
261667a56275SMatthew G Knepley   PetscValidPointer(M,3);
2617251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
261867a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
261967a56275SMatthew G Knepley   {
262019fd82e9SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM *) = PETSC_NULL;
262167a56275SMatthew G Knepley 
262267a56275SMatthew G Knepley     /*
262367a56275SMatthew G Knepley        Order of precedence:
262467a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
262567a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
262667a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
262767a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
262867a56275SMatthew G Knepley        5) Use a really basic converter.
262967a56275SMatthew G Knepley     */
263067a56275SMatthew G Knepley 
263167a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
263267a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
263367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
263467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
263567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
263667a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
263767a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
263867a56275SMatthew G Knepley     if (conv) goto foundconv;
263967a56275SMatthew G Knepley 
264067a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
264167a56275SMatthew G Knepley     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
264267a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
264367a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
264467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
264567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
264667a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
264767a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
264867a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
264967a56275SMatthew G Knepley     if (conv) {
2650fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
265167a56275SMatthew G Knepley       goto foundconv;
265267a56275SMatthew G Knepley     }
265367a56275SMatthew G Knepley 
265467a56275SMatthew G Knepley #if 0
265567a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
265667a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2657fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
265867a56275SMatthew G Knepley     if (conv) goto foundconv;
265967a56275SMatthew G Knepley 
266067a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
266167a56275SMatthew G Knepley     if (dm->ops->convert) {
266267a56275SMatthew G Knepley       conv = dm->ops->convert;
266367a56275SMatthew G Knepley     }
266467a56275SMatthew G Knepley     if (conv) goto foundconv;
266567a56275SMatthew G Knepley #endif
266667a56275SMatthew G Knepley 
266767a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
266867a56275SMatthew G Knepley     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
266967a56275SMatthew G Knepley 
267067a56275SMatthew G Knepley     foundconv:
267167a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
267267a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
267367a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
267467a56275SMatthew G Knepley   }
267567a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
267667a56275SMatthew G Knepley   PetscFunctionReturn(0);
267767a56275SMatthew G Knepley }
2678264ace61SBarry Smith 
2679264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2680264ace61SBarry Smith 
2681264ace61SBarry Smith #undef __FUNCT__
2682264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2683264ace61SBarry Smith /*@C
2684264ace61SBarry Smith   DMRegister - See DMRegisterDynamic()
2685264ace61SBarry Smith 
2686264ace61SBarry Smith   Level: advanced
2687264ace61SBarry Smith @*/
26887087cfbeSBarry Smith PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
2689264ace61SBarry Smith {
2690264ace61SBarry Smith   char fullname[PETSC_MAX_PATH_LEN];
2691264ace61SBarry Smith   PetscErrorCode ierr;
2692264ace61SBarry Smith 
2693264ace61SBarry Smith   PetscFunctionBegin;
2694264ace61SBarry Smith   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
2695264ace61SBarry Smith   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
2696264ace61SBarry Smith   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
2697264ace61SBarry Smith   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
2698264ace61SBarry Smith   PetscFunctionReturn(0);
2699264ace61SBarry Smith }
2700264ace61SBarry Smith 
2701264ace61SBarry Smith 
2702264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2703264ace61SBarry Smith #undef __FUNCT__
2704264ace61SBarry Smith #define __FUNCT__ "DMRegisterDestroy"
2705264ace61SBarry Smith /*@C
2706264ace61SBarry Smith    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
2707264ace61SBarry Smith 
2708264ace61SBarry Smith    Not Collective
2709264ace61SBarry Smith 
2710264ace61SBarry Smith    Level: advanced
2711264ace61SBarry Smith 
2712264ace61SBarry Smith .keywords: DM, register, destroy
2713264ace61SBarry Smith .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
2714264ace61SBarry Smith @*/
27157087cfbeSBarry Smith PetscErrorCode  DMRegisterDestroy(void)
2716264ace61SBarry Smith {
2717264ace61SBarry Smith   PetscErrorCode ierr;
2718264ace61SBarry Smith 
2719264ace61SBarry Smith   PetscFunctionBegin;
2720264ace61SBarry Smith   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
2721264ace61SBarry Smith   DMRegisterAllCalled = PETSC_FALSE;
2722264ace61SBarry Smith   PetscFunctionReturn(0);
2723264ace61SBarry Smith }
272423f975d1SBarry Smith 
272523f975d1SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2726c6db04a5SJed Brown #include <mex.h>
272723f975d1SBarry Smith 
27283014e516SBarry Smith typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext;
272923f975d1SBarry Smith 
273023f975d1SBarry Smith #undef __FUNCT__
273123f975d1SBarry Smith #define __FUNCT__ "DMComputeFunction_Matlab"
273223f975d1SBarry Smith /*
273323f975d1SBarry Smith    DMComputeFunction_Matlab - Calls the function that has been set with
273423f975d1SBarry Smith                          DMSetFunctionMatlab().
273523f975d1SBarry Smith 
273623f975d1SBarry Smith    For linear problems x is null
273723f975d1SBarry Smith 
273823f975d1SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
273923f975d1SBarry Smith */
27407087cfbeSBarry Smith PetscErrorCode  DMComputeFunction_Matlab(DM dm,Vec x,Vec y)
274123f975d1SBarry Smith {
274223f975d1SBarry Smith   PetscErrorCode    ierr;
274323f975d1SBarry Smith   DMMatlabContext   *sctx;
274423f975d1SBarry Smith   int               nlhs = 1,nrhs = 4;
274523f975d1SBarry Smith   mxArray	    *plhs[1],*prhs[4];
274623f975d1SBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
274723f975d1SBarry Smith 
274823f975d1SBarry Smith   PetscFunctionBegin;
274923f975d1SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
275023f975d1SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
275123f975d1SBarry Smith   PetscCheckSameComm(dm,1,y,3);
275223f975d1SBarry Smith 
275323f975d1SBarry Smith   /* call Matlab function in ctx with arguments x and y */
27541b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
275523f975d1SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
275623f975d1SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
27573014e516SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr);
275823f975d1SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
275923f975d1SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
276023f975d1SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
276123f975d1SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
2762b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr);
276323f975d1SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
276423f975d1SBarry Smith   mxDestroyArray(prhs[0]);
276523f975d1SBarry Smith   mxDestroyArray(prhs[1]);
276623f975d1SBarry Smith   mxDestroyArray(prhs[2]);
276723f975d1SBarry Smith   mxDestroyArray(prhs[3]);
276823f975d1SBarry Smith   mxDestroyArray(plhs[0]);
276923f975d1SBarry Smith   PetscFunctionReturn(0);
277023f975d1SBarry Smith }
277123f975d1SBarry Smith 
277223f975d1SBarry Smith 
277323f975d1SBarry Smith #undef __FUNCT__
277423f975d1SBarry Smith #define __FUNCT__ "DMSetFunctionMatlab"
277523f975d1SBarry Smith /*
277623f975d1SBarry Smith    DMSetFunctionMatlab - Sets the function evaluation routine
277723f975d1SBarry Smith 
277823f975d1SBarry Smith */
27797087cfbeSBarry Smith PetscErrorCode  DMSetFunctionMatlab(DM dm,const char *func)
278023f975d1SBarry Smith {
278123f975d1SBarry Smith   PetscErrorCode    ierr;
278223f975d1SBarry Smith   DMMatlabContext   *sctx;
278323f975d1SBarry Smith 
278423f975d1SBarry Smith   PetscFunctionBegin;
2785171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
278623f975d1SBarry Smith   /* currently sctx is memory bleed */
27871b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
27883014e516SBarry Smith   if (!sctx) {
278923f975d1SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
27903014e516SBarry Smith   }
279123f975d1SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
27921b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
279323f975d1SBarry Smith   ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr);
279423f975d1SBarry Smith   PetscFunctionReturn(0);
279523f975d1SBarry Smith }
27963014e516SBarry Smith 
27973014e516SBarry Smith #undef __FUNCT__
27983014e516SBarry Smith #define __FUNCT__ "DMComputeJacobian_Matlab"
27993014e516SBarry Smith /*
28003014e516SBarry Smith    DMComputeJacobian_Matlab - Calls the function that has been set with
28013014e516SBarry Smith                          DMSetJacobianMatlab().
28023014e516SBarry Smith 
28033014e516SBarry Smith    For linear problems x is null
28043014e516SBarry Smith 
28053014e516SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
28063014e516SBarry Smith */
28077087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str)
28083014e516SBarry Smith {
28093014e516SBarry Smith   PetscErrorCode    ierr;
28103014e516SBarry Smith   DMMatlabContext   *sctx;
28113014e516SBarry Smith   int               nlhs = 2,nrhs = 5;
28123014e516SBarry Smith   mxArray	    *plhs[2],*prhs[5];
28133014e516SBarry Smith   long long int     lx = 0,lA = 0,lB = 0,ls = 0;
28143014e516SBarry Smith 
28153014e516SBarry Smith   PetscFunctionBegin;
28163014e516SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
28173014e516SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
28183014e516SBarry Smith 
2819e3c5b3baSBarry Smith   /* call MATLAB function in ctx with arguments x, A, and B */
28201b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
28213014e516SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
28223014e516SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
28233014e516SBarry Smith   ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr);
28243014e516SBarry Smith   ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr);
28253014e516SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
28263014e516SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
28273014e516SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
28283014e516SBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
28293014e516SBarry Smith   prhs[4] =  mxCreateString(sctx->jacname);
2830b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr);
2831c980e822SBarry Smith   *str    =  (MatStructure) mxGetScalar(plhs[0]);
2832c088a8dcSBarry Smith   ierr    =  (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr);
28333014e516SBarry Smith   mxDestroyArray(prhs[0]);
28343014e516SBarry Smith   mxDestroyArray(prhs[1]);
28353014e516SBarry Smith   mxDestroyArray(prhs[2]);
28363014e516SBarry Smith   mxDestroyArray(prhs[3]);
28373014e516SBarry Smith   mxDestroyArray(prhs[4]);
28383014e516SBarry Smith   mxDestroyArray(plhs[0]);
28393014e516SBarry Smith   mxDestroyArray(plhs[1]);
28403014e516SBarry Smith   PetscFunctionReturn(0);
28413014e516SBarry Smith }
28423014e516SBarry Smith 
28433014e516SBarry Smith 
28443014e516SBarry Smith #undef __FUNCT__
28453014e516SBarry Smith #define __FUNCT__ "DMSetJacobianMatlab"
28463014e516SBarry Smith /*
28473014e516SBarry Smith    DMSetJacobianMatlab - Sets the Jacobian function evaluation routine
28483014e516SBarry Smith 
28493014e516SBarry Smith */
28507087cfbeSBarry Smith PetscErrorCode  DMSetJacobianMatlab(DM dm,const char *func)
28513014e516SBarry Smith {
28523014e516SBarry Smith   PetscErrorCode    ierr;
28533014e516SBarry Smith   DMMatlabContext   *sctx;
28543014e516SBarry Smith 
28553014e516SBarry Smith   PetscFunctionBegin;
2856171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
28573014e516SBarry Smith   /* currently sctx is memory bleed */
28581b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
28593014e516SBarry Smith   if (!sctx) {
28603014e516SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
28613014e516SBarry Smith   }
28623014e516SBarry Smith   ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr);
28631b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
28643014e516SBarry Smith   ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr);
28653014e516SBarry Smith   PetscFunctionReturn(0);
28663014e516SBarry Smith }
286723f975d1SBarry Smith #endif
2868b859378eSBarry Smith 
2869b859378eSBarry Smith #undef __FUNCT__
2870b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2871b859378eSBarry Smith /*@C
2872b859378eSBarry Smith   DMLoad - Loads a DM that has been stored in binary or HDF5 format
2873b859378eSBarry Smith   with DMView().
2874b859378eSBarry Smith 
2875b859378eSBarry Smith   Collective on PetscViewer
2876b859378eSBarry Smith 
2877b859378eSBarry Smith   Input Parameters:
2878b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2879b859378eSBarry Smith            some related function before a call to DMLoad().
2880b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2881b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2882b859378eSBarry Smith 
2883b859378eSBarry Smith    Level: intermediate
2884b859378eSBarry Smith 
2885b859378eSBarry Smith   Notes:
2886b859378eSBarry Smith   Defaults to the DM DA.
2887b859378eSBarry Smith 
2888b859378eSBarry Smith   Notes for advanced users:
2889b859378eSBarry Smith   Most users should not need to know the details of the binary storage
2890b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
2891b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
2892b859378eSBarry Smith   format is
2893b859378eSBarry Smith .vb
2894b859378eSBarry Smith      has not yet been determined
2895b859378eSBarry Smith .ve
2896b859378eSBarry Smith 
2897b859378eSBarry Smith    In addition, PETSc automatically does the byte swapping for
2898b859378eSBarry Smith machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
2899b859378eSBarry Smith linux, Windows and the paragon; thus if you write your own binary
2900b859378eSBarry Smith read/write routines you have to swap the bytes; see PetscBinaryRead()
2901b859378eSBarry Smith and PetscBinaryWrite() to see how this may be done.
2902b859378eSBarry Smith 
2903b859378eSBarry Smith   Concepts: vector^loading from file
2904b859378eSBarry Smith 
2905b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2906b859378eSBarry Smith @*/
2907b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2908b859378eSBarry Smith {
2909b859378eSBarry Smith   PetscErrorCode ierr;
2910b859378eSBarry Smith 
2911b859378eSBarry Smith   PetscFunctionBegin;
2912b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2913b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
2914b859378eSBarry Smith 
2915b859378eSBarry Smith   if (!((PetscObject)newdm)->type_name) {
2916b859378eSBarry Smith     ierr = DMSetType(newdm, DMDA);CHKERRQ(ierr);
2917b859378eSBarry Smith   }
2918b859378eSBarry Smith   ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
2919b859378eSBarry Smith   PetscFunctionReturn(0);
2920b859378eSBarry Smith }
2921b859378eSBarry Smith 
29227da65231SMatthew G Knepley /******************************** FEM Support **********************************/
29237da65231SMatthew G Knepley 
29247da65231SMatthew G Knepley #undef __FUNCT__
29257da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
29267da65231SMatthew G Knepley PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
29271d47ebbbSSatish Balay   PetscInt       f;
29281b30c384SMatthew G Knepley   PetscErrorCode ierr;
29291b30c384SMatthew G Knepley 
29307da65231SMatthew G Knepley   PetscFunctionBegin;
293174778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
29321d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
293374778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
29347da65231SMatthew G Knepley   }
29357da65231SMatthew G Knepley   PetscFunctionReturn(0);
29367da65231SMatthew G Knepley }
29377da65231SMatthew G Knepley 
29387da65231SMatthew G Knepley #undef __FUNCT__
29397da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
29407da65231SMatthew G Knepley PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
29411b30c384SMatthew G Knepley   PetscInt       f, g;
29427da65231SMatthew G Knepley   PetscErrorCode ierr;
29437da65231SMatthew G Knepley 
29447da65231SMatthew G Knepley   PetscFunctionBegin;
294574778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
29461d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
294774778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
29481d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
294974778d6cSJed Brown       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
29507da65231SMatthew G Knepley     }
295174778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
29527da65231SMatthew G Knepley   }
29537da65231SMatthew G Knepley   PetscFunctionReturn(0);
29547da65231SMatthew G Knepley }
2955e7c4fc90SDmitry Karpeev 
2956970e74d5SMatthew G Knepley #undef __FUNCT__
2957970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalFunction"
2958970e74d5SMatthew G Knepley /*@C
2959970e74d5SMatthew G Knepley   DMGetLocalFunction - Get the local residual function from this DM
2960970e74d5SMatthew G Knepley 
2961970e74d5SMatthew G Knepley   Not collective
2962970e74d5SMatthew G Knepley 
2963970e74d5SMatthew G Knepley   Input Parameter:
2964970e74d5SMatthew G Knepley . dm - The DM
2965970e74d5SMatthew G Knepley 
2966970e74d5SMatthew G Knepley   Output Parameter:
2967970e74d5SMatthew G Knepley . lf - The local residual function
2968970e74d5SMatthew G Knepley 
2969970e74d5SMatthew G Knepley    Calling sequence of lf:
2970970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
2971970e74d5SMatthew G Knepley 
2972970e74d5SMatthew G Knepley +  snes - the SNES context
2973970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2974970e74d5SMatthew G Knepley .  f - local vector to put residual in
2975970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2976970e74d5SMatthew G Knepley 
2977970e74d5SMatthew G Knepley   Level: intermediate
2978970e74d5SMatthew G Knepley 
2979970e74d5SMatthew G Knepley .seealso DMSetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
2980970e74d5SMatthew G Knepley @*/
2981970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalFunction(DM dm, PetscErrorCode (**lf)(DM, Vec, Vec, void *))
2982970e74d5SMatthew G Knepley {
2983970e74d5SMatthew G Knepley   PetscFunctionBegin;
2984970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2985970e74d5SMatthew G Knepley   if (lf) *lf = dm->lf;
2986970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2987970e74d5SMatthew G Knepley }
2988970e74d5SMatthew G Knepley 
2989970e74d5SMatthew G Knepley #undef __FUNCT__
2990970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalFunction"
2991970e74d5SMatthew G Knepley /*@C
2992970e74d5SMatthew G Knepley   DMSetLocalFunction - Set the local residual function from this DM
2993970e74d5SMatthew G Knepley 
2994970e74d5SMatthew G Knepley   Not collective
2995970e74d5SMatthew G Knepley 
2996970e74d5SMatthew G Knepley   Input Parameters:
2997970e74d5SMatthew G Knepley + dm - The DM
2998970e74d5SMatthew G Knepley - lf - The local residual function
2999970e74d5SMatthew G Knepley 
3000970e74d5SMatthew G Knepley    Calling sequence of lf:
3001970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
3002970e74d5SMatthew G Knepley 
3003970e74d5SMatthew G Knepley +  snes - the SNES context
3004970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3005970e74d5SMatthew G Knepley .  f - local vector to put residual in
3006970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3007970e74d5SMatthew G Knepley 
3008970e74d5SMatthew G Knepley   Level: intermediate
3009970e74d5SMatthew G Knepley 
3010970e74d5SMatthew G Knepley .seealso DMGetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
3011970e74d5SMatthew G Knepley @*/
3012970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalFunction(DM dm, PetscErrorCode (*lf)(DM, Vec, Vec, void *))
3013970e74d5SMatthew G Knepley {
3014970e74d5SMatthew G Knepley   PetscFunctionBegin;
3015970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3016970e74d5SMatthew G Knepley   dm->lf = lf;
3017970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3018970e74d5SMatthew G Knepley }
3019970e74d5SMatthew G Knepley 
3020970e74d5SMatthew G Knepley #undef __FUNCT__
3021970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalJacobian"
3022970e74d5SMatthew G Knepley /*@C
3023970e74d5SMatthew G Knepley   DMGetLocalJacobian - Get the local Jacobian function from this DM
3024970e74d5SMatthew G Knepley 
3025970e74d5SMatthew G Knepley   Not collective
3026970e74d5SMatthew G Knepley 
3027970e74d5SMatthew G Knepley   Input Parameter:
3028970e74d5SMatthew G Knepley . dm - The DM
3029970e74d5SMatthew G Knepley 
3030970e74d5SMatthew G Knepley   Output Parameter:
3031970e74d5SMatthew G Knepley . lj - The local Jacobian function
3032970e74d5SMatthew G Knepley 
3033970e74d5SMatthew G Knepley    Calling sequence of lj:
3034970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
3035970e74d5SMatthew G Knepley 
3036970e74d5SMatthew G Knepley +  snes - the SNES context
3037970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3038970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
3039970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
3040970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3041970e74d5SMatthew G Knepley 
3042970e74d5SMatthew G Knepley   Level: intermediate
3043970e74d5SMatthew G Knepley 
3044970e74d5SMatthew G Knepley .seealso DMSetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
3045970e74d5SMatthew G Knepley @*/
3046970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalJacobian(DM dm, PetscErrorCode (**lj)(DM, Vec, Mat, Mat, void *))
3047970e74d5SMatthew G Knepley {
3048970e74d5SMatthew G Knepley   PetscFunctionBegin;
3049970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3050970e74d5SMatthew G Knepley   if (lj) *lj = dm->lj;
3051970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3052970e74d5SMatthew G Knepley }
3053970e74d5SMatthew G Knepley 
3054970e74d5SMatthew G Knepley #undef __FUNCT__
3055970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalJacobian"
3056970e74d5SMatthew G Knepley /*@C
3057970e74d5SMatthew G Knepley   DMSetLocalJacobian - Set the local Jacobian function from this DM
3058970e74d5SMatthew G Knepley 
3059970e74d5SMatthew G Knepley   Not collective
3060970e74d5SMatthew G Knepley 
3061970e74d5SMatthew G Knepley   Input Parameters:
3062970e74d5SMatthew G Knepley + dm - The DM
3063970e74d5SMatthew G Knepley - lj - The local Jacobian function
3064970e74d5SMatthew G Knepley 
3065970e74d5SMatthew G Knepley    Calling sequence of lj:
3066970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
3067970e74d5SMatthew G Knepley 
3068970e74d5SMatthew G Knepley +  snes - the SNES context
3069970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3070970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
3071970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
3072970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3073970e74d5SMatthew G Knepley 
3074970e74d5SMatthew G Knepley   Level: intermediate
3075970e74d5SMatthew G Knepley 
3076970e74d5SMatthew G Knepley .seealso DMGetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
3077970e74d5SMatthew G Knepley @*/
3078970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalJacobian(DM dm, PetscErrorCode (*lj)(DM, Vec, Mat,  Mat, void *))
3079970e74d5SMatthew G Knepley {
3080970e74d5SMatthew G Knepley   PetscFunctionBegin;
3081970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3082970e74d5SMatthew G Knepley   dm->lj = lj;
3083970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3084970e74d5SMatthew G Knepley }
308588ed4aceSMatthew G Knepley 
308688ed4aceSMatthew G Knepley #undef __FUNCT__
308788ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
308888ed4aceSMatthew G Knepley /*@
308988ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
309088ed4aceSMatthew G Knepley 
309188ed4aceSMatthew G Knepley   Input Parameter:
309288ed4aceSMatthew G Knepley . dm - The DM
309388ed4aceSMatthew G Knepley 
309488ed4aceSMatthew G Knepley   Output Parameter:
309588ed4aceSMatthew G Knepley . section - The PetscSection
309688ed4aceSMatthew G Knepley 
309788ed4aceSMatthew G Knepley   Level: intermediate
309888ed4aceSMatthew G Knepley 
309988ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
310088ed4aceSMatthew G Knepley 
310188ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
310288ed4aceSMatthew G Knepley @*/
310388ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) {
310488ed4aceSMatthew G Knepley   PetscFunctionBegin;
310588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
310688ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
310788ed4aceSMatthew G Knepley   *section = dm->defaultSection;
310888ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
310988ed4aceSMatthew G Knepley }
311088ed4aceSMatthew G Knepley 
311188ed4aceSMatthew G Knepley #undef __FUNCT__
311288ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
311388ed4aceSMatthew G Knepley /*@
311488ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
311588ed4aceSMatthew G Knepley 
311688ed4aceSMatthew G Knepley   Input Parameters:
311788ed4aceSMatthew G Knepley + dm - The DM
311888ed4aceSMatthew G Knepley - section - The PetscSection
311988ed4aceSMatthew G Knepley 
312088ed4aceSMatthew G Knepley   Level: intermediate
312188ed4aceSMatthew G Knepley 
312288ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
312388ed4aceSMatthew G Knepley 
312488ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
312588ed4aceSMatthew G Knepley @*/
312688ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) {
3127af122d2aSMatthew G Knepley   PetscInt       numFields;
3128af122d2aSMatthew G Knepley   PetscInt       f;
312988ed4aceSMatthew G Knepley   PetscErrorCode ierr;
313088ed4aceSMatthew G Knepley 
313188ed4aceSMatthew G Knepley   PetscFunctionBegin;
313288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
313388ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
313488ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
313588ed4aceSMatthew G Knepley   dm->defaultSection = section;
3136af122d2aSMatthew G Knepley   ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);
3137af122d2aSMatthew G Knepley   if (numFields) {
3138af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
3139af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
3140af122d2aSMatthew G Knepley       const char *name;
3141af122d2aSMatthew G Knepley 
3142af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
3143af122d2aSMatthew G Knepley       ierr = PetscObjectSetName(dm->fields[f], name);CHKERRQ(ierr);
3144af122d2aSMatthew G Knepley     }
3145af122d2aSMatthew G Knepley   }
314688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
314788ed4aceSMatthew G Knepley }
314888ed4aceSMatthew G Knepley 
314988ed4aceSMatthew G Knepley #undef __FUNCT__
315088ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
315188ed4aceSMatthew G Knepley /*@
315288ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
315388ed4aceSMatthew G Knepley 
315488ed4aceSMatthew G Knepley   Input Parameter:
315588ed4aceSMatthew G Knepley . dm - The DM
315688ed4aceSMatthew G Knepley 
315788ed4aceSMatthew G Knepley   Output Parameter:
315888ed4aceSMatthew G Knepley . section - The PetscSection
315988ed4aceSMatthew G Knepley 
316088ed4aceSMatthew G Knepley   Level: intermediate
316188ed4aceSMatthew G Knepley 
316288ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
316388ed4aceSMatthew G Knepley 
316488ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
316588ed4aceSMatthew G Knepley @*/
316688ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) {
316788ed4aceSMatthew G Knepley   PetscErrorCode ierr;
316888ed4aceSMatthew G Knepley 
316988ed4aceSMatthew G Knepley   PetscFunctionBegin;
317088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
317188ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
317288ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
3173*40e8a239SMatthew G Knepley     if (!dm->defaultSection || !dm->sf) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection and PetscSF in order to create a global PetscSection");
3174b21d0597SMatthew G Knepley     ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
317588ed4aceSMatthew G Knepley   }
317688ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
317788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
317888ed4aceSMatthew G Knepley }
317988ed4aceSMatthew G Knepley 
318088ed4aceSMatthew G Knepley #undef __FUNCT__
3181b21d0597SMatthew G Knepley #define __FUNCT__ "DMSetDefaultGlobalSection"
3182b21d0597SMatthew G Knepley /*@
3183b21d0597SMatthew G Knepley   DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM.
3184b21d0597SMatthew G Knepley 
3185b21d0597SMatthew G Knepley   Input Parameters:
3186b21d0597SMatthew G Knepley + dm - The DM
3187b21d0597SMatthew G Knepley - section - The PetscSection
3188b21d0597SMatthew G Knepley 
3189b21d0597SMatthew G Knepley   Level: intermediate
3190b21d0597SMatthew G Knepley 
3191b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
3192b21d0597SMatthew G Knepley 
3193b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection()
3194b21d0597SMatthew G Knepley @*/
3195b21d0597SMatthew G Knepley PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section) {
3196b21d0597SMatthew G Knepley   PetscErrorCode ierr;
3197b21d0597SMatthew G Knepley 
3198b21d0597SMatthew G Knepley   PetscFunctionBegin;
3199b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3200b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
3201b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
3202b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3203b21d0597SMatthew G Knepley }
3204b21d0597SMatthew G Knepley 
3205b21d0597SMatthew G Knepley #undef __FUNCT__
320688ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
320788ed4aceSMatthew G Knepley /*@
320888ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
320988ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
321088ed4aceSMatthew G Knepley 
321188ed4aceSMatthew G Knepley   Input Parameter:
321288ed4aceSMatthew G Knepley . dm - The DM
321388ed4aceSMatthew G Knepley 
321488ed4aceSMatthew G Knepley   Output Parameter:
321588ed4aceSMatthew G Knepley . sf - The PetscSF
321688ed4aceSMatthew G Knepley 
321788ed4aceSMatthew G Knepley   Level: intermediate
321888ed4aceSMatthew G Knepley 
321988ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
322088ed4aceSMatthew G Knepley 
322188ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
322288ed4aceSMatthew G Knepley @*/
322388ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) {
322488ed4aceSMatthew G Knepley   PetscInt       nroots;
322588ed4aceSMatthew G Knepley   PetscErrorCode ierr;
322688ed4aceSMatthew G Knepley 
322788ed4aceSMatthew G Knepley   PetscFunctionBegin;
322888ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
322988ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
323088ed4aceSMatthew G Knepley   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
323188ed4aceSMatthew G Knepley   if (nroots < 0) {
323288ed4aceSMatthew G Knepley     PetscSection section, gSection;
323388ed4aceSMatthew G Knepley 
323488ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
323531ea6d37SMatthew G Knepley     if (section) {
323688ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
323788ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
323831ea6d37SMatthew G Knepley     } else {
323931ea6d37SMatthew G Knepley       *sf = PETSC_NULL;
324031ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
324131ea6d37SMatthew G Knepley     }
324288ed4aceSMatthew G Knepley   }
324388ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
324488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
324588ed4aceSMatthew G Knepley }
324688ed4aceSMatthew G Knepley 
324788ed4aceSMatthew G Knepley #undef __FUNCT__
324888ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
324988ed4aceSMatthew G Knepley /*@
325088ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
325188ed4aceSMatthew G Knepley 
325288ed4aceSMatthew G Knepley   Input Parameters:
325388ed4aceSMatthew G Knepley + dm - The DM
325488ed4aceSMatthew G Knepley - sf - The PetscSF
325588ed4aceSMatthew G Knepley 
325688ed4aceSMatthew G Knepley   Level: intermediate
325788ed4aceSMatthew G Knepley 
325888ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
325988ed4aceSMatthew G Knepley 
326088ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
326188ed4aceSMatthew G Knepley @*/
326288ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) {
326388ed4aceSMatthew G Knepley   PetscErrorCode ierr;
326488ed4aceSMatthew G Knepley 
326588ed4aceSMatthew G Knepley   PetscFunctionBegin;
326688ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
326788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
326888ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
326988ed4aceSMatthew G Knepley   dm->defaultSF = sf;
327088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
327188ed4aceSMatthew G Knepley }
327288ed4aceSMatthew G Knepley 
327388ed4aceSMatthew G Knepley #undef __FUNCT__
327488ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
327588ed4aceSMatthew G Knepley /*@C
327688ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
327788ed4aceSMatthew G Knepley   describing the data layout.
327888ed4aceSMatthew G Knepley 
327988ed4aceSMatthew G Knepley   Input Parameters:
328088ed4aceSMatthew G Knepley + dm - The DM
328188ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
328288ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
328388ed4aceSMatthew G Knepley 
328488ed4aceSMatthew G Knepley   Level: intermediate
328588ed4aceSMatthew G Knepley 
328688ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
328788ed4aceSMatthew G Knepley @*/
328888ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
328988ed4aceSMatthew G Knepley {
329088ed4aceSMatthew G Knepley   MPI_Comm        comm = ((PetscObject) dm)->comm;
329188ed4aceSMatthew G Knepley   PetscLayout     layout;
329288ed4aceSMatthew G Knepley   const PetscInt *ranges;
329388ed4aceSMatthew G Knepley   PetscInt       *local;
329488ed4aceSMatthew G Knepley   PetscSFNode    *remote;
329588ed4aceSMatthew G Knepley   PetscInt        pStart, pEnd, p, nroots, nleaves, l;
329688ed4aceSMatthew G Knepley   PetscMPIInt     size, rank;
329788ed4aceSMatthew G Knepley   PetscErrorCode  ierr;
329888ed4aceSMatthew G Knepley 
329988ed4aceSMatthew G Knepley   PetscFunctionBegin;
330088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
330188ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
330288ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
330388ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
330488ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
330588ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
330688ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
330788ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
330888ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
330988ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
331088ed4aceSMatthew G Knepley   for (p = pStart, nleaves = 0; p < pEnd; ++p) {
33116636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
331288ed4aceSMatthew G Knepley 
33136636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
33146636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
33156636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
331688ed4aceSMatthew G Knepley   }
331788ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr);
331888ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr);
331988ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
33201f588964SMatthew G Knepley     const PetscInt *cind;
33216636e97aSMatthew G Knepley     PetscInt        dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
332288ed4aceSMatthew G Knepley 
332388ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
332488ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
332588ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
332688ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
332788ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
33286636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
332988ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
33306636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
33316636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
33326636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
33336636e97aSMatthew 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);
33346636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
33356636e97aSMatthew G Knepley     }
333688ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
333788ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
333888ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
333988ed4aceSMatthew G Knepley     }
334088ed4aceSMatthew G Knepley     if (gdof < 0) {
33416636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
334288ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
334388ed4aceSMatthew G Knepley 
334488ed4aceSMatthew G Knepley         for (r = 0; r < size; ++r) {
334588ed4aceSMatthew G Knepley           if ((offset >= ranges[r]) && (offset < ranges[r+1])) break;
334688ed4aceSMatthew G Knepley         }
334788ed4aceSMatthew G Knepley         remote[l].rank  = r;
334888ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
334988ed4aceSMatthew G Knepley       }
335088ed4aceSMatthew G Knepley     } else {
33516636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
335288ed4aceSMatthew G Knepley         remote[l].rank  = rank;
335388ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
335488ed4aceSMatthew G Knepley       }
335588ed4aceSMatthew G Knepley     }
335688ed4aceSMatthew G Knepley   }
33576636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
335888ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
335988ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
336088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
336188ed4aceSMatthew G Knepley }
3362af122d2aSMatthew G Knepley 
3363af122d2aSMatthew G Knepley #undef __FUNCT__
3364b21d0597SMatthew G Knepley #define __FUNCT__ "DMGetPointSF"
3365b21d0597SMatthew G Knepley /*@
3366b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
3367b21d0597SMatthew G Knepley 
3368b21d0597SMatthew G Knepley   Input Parameter:
3369b21d0597SMatthew G Knepley . dm - The DM
3370b21d0597SMatthew G Knepley 
3371b21d0597SMatthew G Knepley   Output Parameter:
3372b21d0597SMatthew G Knepley . sf - The PetscSF
3373b21d0597SMatthew G Knepley 
3374b21d0597SMatthew G Knepley   Level: intermediate
3375b21d0597SMatthew G Knepley 
3376b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
3377b21d0597SMatthew G Knepley 
3378b21d0597SMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3379b21d0597SMatthew G Knepley @*/
3380b21d0597SMatthew G Knepley PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) {
3381b21d0597SMatthew G Knepley   PetscFunctionBegin;
3382b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3383b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
3384b21d0597SMatthew G Knepley   *sf = dm->sf;
3385b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3386b21d0597SMatthew G Knepley }
3387b21d0597SMatthew G Knepley 
3388b21d0597SMatthew G Knepley #undef __FUNCT__
3389af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetNumFields"
3390af122d2aSMatthew G Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
3391af122d2aSMatthew G Knepley {
3392af122d2aSMatthew G Knepley   PetscFunctionBegin;
3393af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3394af122d2aSMatthew G Knepley   PetscValidPointer(numFields, 2);
3395af122d2aSMatthew G Knepley   *numFields = dm->numFields;
3396af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3397af122d2aSMatthew G Knepley }
3398af122d2aSMatthew G Knepley 
3399af122d2aSMatthew G Knepley #undef __FUNCT__
3400af122d2aSMatthew G Knepley #define __FUNCT__ "DMSetNumFields"
3401af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
3402af122d2aSMatthew G Knepley {
3403af122d2aSMatthew G Knepley   PetscInt       f;
3404af122d2aSMatthew G Knepley   PetscErrorCode ierr;
3405af122d2aSMatthew G Knepley 
3406af122d2aSMatthew G Knepley   PetscFunctionBegin;
3407af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3408af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3409af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&dm->fields[f]);CHKERRQ(ierr);
3410af122d2aSMatthew G Knepley   }
3411af122d2aSMatthew G Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
3412af122d2aSMatthew G Knepley   dm->numFields = numFields;
3413af122d2aSMatthew G Knepley   ierr = PetscMalloc(dm->numFields * sizeof(PetscObject), &dm->fields);CHKERRQ(ierr);
3414af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3415af122d2aSMatthew G Knepley     ierr = PetscContainerCreate(((PetscObject) dm)->comm, (PetscContainer *) &dm->fields[f]);CHKERRQ(ierr);
3416af122d2aSMatthew G Knepley   }
3417af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3418af122d2aSMatthew G Knepley }
3419af122d2aSMatthew G Knepley 
3420af122d2aSMatthew G Knepley #undef __FUNCT__
3421af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetField"
3422af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field)
3423af122d2aSMatthew G Knepley {
3424af122d2aSMatthew G Knepley   PetscFunctionBegin;
3425af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3426af122d2aSMatthew G Knepley   PetscValidPointer(field, 2);
3427af122d2aSMatthew G Knepley   if (!dm->fields) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Fields have not been setup in this DM. Call DMSetNumFields()");
3428af122d2aSMatthew 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);
3429af122d2aSMatthew G Knepley   *field = dm->fields[f];
3430af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3431af122d2aSMatthew G Knepley }
34326636e97aSMatthew G Knepley 
34336636e97aSMatthew G Knepley #undef __FUNCT__
34346636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinates"
34356636e97aSMatthew G Knepley /*@
34366636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
34376636e97aSMatthew G Knepley 
34386636e97aSMatthew G Knepley   Collective on DM
34396636e97aSMatthew G Knepley 
34406636e97aSMatthew G Knepley   Input Parameters:
34416636e97aSMatthew G Knepley + dm - the DM
34426636e97aSMatthew G Knepley - c - coordinate vector
34436636e97aSMatthew G Knepley 
34446636e97aSMatthew G Knepley   Note:
34456636e97aSMatthew G Knepley   The coordinates do include those for ghost points, which are in the local vector
34466636e97aSMatthew G Knepley 
34476636e97aSMatthew G Knepley   Level: intermediate
34486636e97aSMatthew G Knepley 
34496636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
34506636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM()
34516636e97aSMatthew G Knepley @*/
34526636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
34536636e97aSMatthew G Knepley {
34546636e97aSMatthew G Knepley   PetscErrorCode ierr;
34556636e97aSMatthew G Knepley 
34566636e97aSMatthew G Knepley   PetscFunctionBegin;
34576636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
34586636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
34596636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
34606636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
34616636e97aSMatthew G Knepley   dm->coordinates = c;
34626636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
34636636e97aSMatthew G Knepley   PetscFunctionReturn(0);
34646636e97aSMatthew G Knepley }
34656636e97aSMatthew G Knepley 
34666636e97aSMatthew G Knepley #undef __FUNCT__
34676636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinatesLocal"
34686636e97aSMatthew G Knepley /*@
34696636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
34706636e97aSMatthew G Knepley 
34716636e97aSMatthew G Knepley   Collective on DM
34726636e97aSMatthew G Knepley 
34736636e97aSMatthew G Knepley    Input Parameters:
34746636e97aSMatthew G Knepley +  dm - the DM
34756636e97aSMatthew G Knepley -  c - coordinate vector
34766636e97aSMatthew G Knepley 
34776636e97aSMatthew G Knepley   Note:
34786636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
34796636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
34806636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
34816636e97aSMatthew G Knepley 
34826636e97aSMatthew G Knepley   Level: intermediate
34836636e97aSMatthew G Knepley 
34846636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
34856636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
34866636e97aSMatthew G Knepley @*/
34876636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
34886636e97aSMatthew G Knepley {
34896636e97aSMatthew G Knepley   PetscErrorCode ierr;
34906636e97aSMatthew G Knepley 
34916636e97aSMatthew G Knepley   PetscFunctionBegin;
34926636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
34936636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
34946636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
34956636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
34966636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
34976636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
34986636e97aSMatthew G Knepley   PetscFunctionReturn(0);
34996636e97aSMatthew G Knepley }
35006636e97aSMatthew G Knepley 
35016636e97aSMatthew G Knepley #undef __FUNCT__
35026636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinates"
35036636e97aSMatthew G Knepley /*@
35046636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
35056636e97aSMatthew G Knepley 
35066636e97aSMatthew G Knepley   Not Collective
35076636e97aSMatthew G Knepley 
35086636e97aSMatthew G Knepley   Input Parameter:
35096636e97aSMatthew G Knepley . dm - the DM
35106636e97aSMatthew G Knepley 
35116636e97aSMatthew G Knepley   Output Parameter:
35126636e97aSMatthew G Knepley . c - global coordinate vector
35136636e97aSMatthew G Knepley 
35146636e97aSMatthew G Knepley   Note:
35156636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
35166636e97aSMatthew G Knepley 
35176636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
35186636e97aSMatthew G Knepley 
35196636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
35206636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
35216636e97aSMatthew G Knepley 
35226636e97aSMatthew G Knepley   Level: intermediate
35236636e97aSMatthew G Knepley 
35246636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
35256636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
35266636e97aSMatthew G Knepley @*/
35276636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
35286636e97aSMatthew G Knepley {
35296636e97aSMatthew G Knepley   PetscErrorCode ierr;
35306636e97aSMatthew G Knepley 
35316636e97aSMatthew G Knepley   PetscFunctionBegin;
35326636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
35336636e97aSMatthew G Knepley   PetscValidPointer(c,2);
35341f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
35356636e97aSMatthew G Knepley     DM cdm;
35366636e97aSMatthew G Knepley 
35376636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
35386636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
35396636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
35406636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
35416636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
35426636e97aSMatthew G Knepley   }
35436636e97aSMatthew G Knepley   *c = dm->coordinates;
35446636e97aSMatthew G Knepley   PetscFunctionReturn(0);
35456636e97aSMatthew G Knepley }
35466636e97aSMatthew G Knepley 
35476636e97aSMatthew G Knepley #undef __FUNCT__
35486636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinatesLocal"
35496636e97aSMatthew G Knepley /*@
35506636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
35516636e97aSMatthew G Knepley 
35526636e97aSMatthew G Knepley   Collective on DM
35536636e97aSMatthew G Knepley 
35546636e97aSMatthew G Knepley   Input Parameter:
35556636e97aSMatthew G Knepley . dm - the DM
35566636e97aSMatthew G Knepley 
35576636e97aSMatthew G Knepley   Output Parameter:
35586636e97aSMatthew G Knepley . c - coordinate vector
35596636e97aSMatthew G Knepley 
35606636e97aSMatthew G Knepley   Note:
35616636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
35626636e97aSMatthew G Knepley 
35636636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
35646636e97aSMatthew G Knepley 
35656636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
35666636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
35676636e97aSMatthew G Knepley 
35686636e97aSMatthew G Knepley   Level: intermediate
35696636e97aSMatthew G Knepley 
35706636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
35716636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
35726636e97aSMatthew G Knepley @*/
35736636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
35746636e97aSMatthew G Knepley {
35756636e97aSMatthew G Knepley   PetscErrorCode ierr;
35766636e97aSMatthew G Knepley 
35776636e97aSMatthew G Knepley   PetscFunctionBegin;
35786636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
35796636e97aSMatthew G Knepley   PetscValidPointer(c,2);
35801f588964SMatthew G Knepley   if (!dm->coordinatesLocal && dm->coordinates) {
35816636e97aSMatthew G Knepley     DM cdm;
35826636e97aSMatthew G Knepley 
35836636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
35846636e97aSMatthew G Knepley     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
35856636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
35866636e97aSMatthew G Knepley     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
35876636e97aSMatthew G Knepley     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
35886636e97aSMatthew G Knepley   }
35896636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
35906636e97aSMatthew G Knepley   PetscFunctionReturn(0);
35916636e97aSMatthew G Knepley }
35926636e97aSMatthew G Knepley 
35936636e97aSMatthew G Knepley #undef __FUNCT__
35946636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinateDM"
35956636e97aSMatthew G Knepley /*@
35966636e97aSMatthew G Knepley   DMGetCoordinateDM - Gets the DM that scatters between global and local coordinates
35976636e97aSMatthew G Knepley 
35986636e97aSMatthew G Knepley   Collective on DM
35996636e97aSMatthew G Knepley 
36006636e97aSMatthew G Knepley   Input Parameter:
36016636e97aSMatthew G Knepley . dm - the DM
36026636e97aSMatthew G Knepley 
36036636e97aSMatthew G Knepley   Output Parameter:
36046636e97aSMatthew G Knepley . cdm - coordinate DM
36056636e97aSMatthew G Knepley 
36066636e97aSMatthew G Knepley   Level: intermediate
36076636e97aSMatthew G Knepley 
36086636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
36096636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
36106636e97aSMatthew G Knepley @*/
36116636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
36126636e97aSMatthew G Knepley {
36136636e97aSMatthew G Knepley   PetscErrorCode ierr;
36146636e97aSMatthew G Knepley 
36156636e97aSMatthew G Knepley   PetscFunctionBegin;
36166636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
36176636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
36186636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
36196636e97aSMatthew G Knepley     if (!dm->ops->createcoordinatedm) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Unable to create coordinates for this DM");
36206636e97aSMatthew G Knepley     ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr);
36216636e97aSMatthew G Knepley   }
36226636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
36236636e97aSMatthew G Knepley   PetscFunctionReturn(0);
36246636e97aSMatthew G Knepley }
3625