xref: /petsc/src/dm/interface/dm.c (revision aa1993de6e046ca787fc06fba2a1b90268ee3353)
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   }
611411c6eeSJed Brown 
621411c6eeSJed Brown   *dm = v;
63a4121054SBarry Smith   PetscFunctionReturn(0);
64a4121054SBarry Smith }
65a4121054SBarry Smith 
66a4121054SBarry Smith 
67a4121054SBarry Smith #undef __FUNCT__
689a42bb27SBarry Smith #define __FUNCT__ "DMSetVecType"
699a42bb27SBarry Smith /*@C
70564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
719a42bb27SBarry Smith 
72aa219208SBarry Smith    Logically Collective on DMDA
739a42bb27SBarry Smith 
749a42bb27SBarry Smith    Input Parameter:
759a42bb27SBarry Smith +  da - initial distributed array
768154be41SBarry Smith .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
779a42bb27SBarry Smith 
789a42bb27SBarry Smith    Options Database:
79dd85299cSBarry Smith .   -dm_vec_type ctype
809a42bb27SBarry Smith 
819a42bb27SBarry Smith    Level: intermediate
829a42bb27SBarry Smith 
83aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
849a42bb27SBarry Smith @*/
857087cfbeSBarry Smith PetscErrorCode  DMSetVecType(DM da,const VecType ctype)
869a42bb27SBarry Smith {
879a42bb27SBarry Smith   PetscErrorCode ierr;
889a42bb27SBarry Smith 
899a42bb27SBarry Smith   PetscFunctionBegin;
909a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
919a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
929a42bb27SBarry Smith   ierr = PetscStrallocpy(ctype,&da->vectype);CHKERRQ(ierr);
939a42bb27SBarry Smith   PetscFunctionReturn(0);
949a42bb27SBarry Smith }
959a42bb27SBarry Smith 
969a42bb27SBarry Smith #undef __FUNCT__
97521d9a4cSLisandro Dalcin #define __FUNCT__ "DMSetMatType"
98521d9a4cSLisandro Dalcin /*@C
99521d9a4cSLisandro Dalcin        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
100521d9a4cSLisandro Dalcin 
101521d9a4cSLisandro Dalcin    Logically Collective on DM
102521d9a4cSLisandro Dalcin 
103521d9a4cSLisandro Dalcin    Input Parameter:
104521d9a4cSLisandro Dalcin +  dm - the DM context
105521d9a4cSLisandro Dalcin .  ctype - the matrix type
106521d9a4cSLisandro Dalcin 
107521d9a4cSLisandro Dalcin    Options Database:
108521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
109521d9a4cSLisandro Dalcin 
110521d9a4cSLisandro Dalcin    Level: intermediate
111521d9a4cSLisandro Dalcin 
112521d9a4cSLisandro Dalcin .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType
113521d9a4cSLisandro Dalcin @*/
114521d9a4cSLisandro Dalcin PetscErrorCode  DMSetMatType(DM dm,const MatType ctype)
115521d9a4cSLisandro Dalcin {
116521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
117521d9a4cSLisandro Dalcin   PetscFunctionBegin;
118521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
119521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
120521d9a4cSLisandro Dalcin   ierr = PetscStrallocpy(ctype,&dm->mattype);CHKERRQ(ierr);
121521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
122521d9a4cSLisandro Dalcin }
123521d9a4cSLisandro Dalcin 
124521d9a4cSLisandro Dalcin #undef __FUNCT__
1259a42bb27SBarry Smith #define __FUNCT__ "DMSetOptionsPrefix"
1269a42bb27SBarry Smith /*@C
1279a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
128aa219208SBarry Smith    DMDA options in the database.
1299a42bb27SBarry Smith 
130aa219208SBarry Smith    Logically Collective on DMDA
1319a42bb27SBarry Smith 
1329a42bb27SBarry Smith    Input Parameter:
133aa219208SBarry Smith +  da - the DMDA context
1349a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
1359a42bb27SBarry Smith 
1369a42bb27SBarry Smith    Notes:
1379a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
1389a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
1399a42bb27SBarry Smith 
1409a42bb27SBarry Smith    Level: advanced
1419a42bb27SBarry Smith 
142aa219208SBarry Smith .keywords: DMDA, set, options, prefix, database
1439a42bb27SBarry Smith 
1449a42bb27SBarry Smith .seealso: DMSetFromOptions()
1459a42bb27SBarry Smith @*/
1467087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
1479a42bb27SBarry Smith {
1489a42bb27SBarry Smith   PetscErrorCode ierr;
1499a42bb27SBarry Smith 
1509a42bb27SBarry Smith   PetscFunctionBegin;
1519a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1529a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
1539a42bb27SBarry Smith   PetscFunctionReturn(0);
1549a42bb27SBarry Smith }
1559a42bb27SBarry Smith 
1569a42bb27SBarry Smith #undef __FUNCT__
15747c6ae99SBarry Smith #define __FUNCT__ "DMDestroy"
15847c6ae99SBarry Smith /*@
159aa219208SBarry Smith     DMDestroy - Destroys a vector packer or DMDA.
16047c6ae99SBarry Smith 
16147c6ae99SBarry Smith     Collective on DM
16247c6ae99SBarry Smith 
16347c6ae99SBarry Smith     Input Parameter:
16447c6ae99SBarry Smith .   dm - the DM object to destroy
16547c6ae99SBarry Smith 
16647c6ae99SBarry Smith     Level: developer
16747c6ae99SBarry Smith 
168e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
16947c6ae99SBarry Smith 
17047c6ae99SBarry Smith @*/
171fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
17247c6ae99SBarry Smith {
173732e2eb9SMatthew G Knepley   PetscInt       i, cnt = 0;
174dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
17547c6ae99SBarry Smith   PetscErrorCode ierr;
17647c6ae99SBarry Smith 
17747c6ae99SBarry Smith   PetscFunctionBegin;
1786bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
1796bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
18087e657c6SBarry Smith 
18187e657c6SBarry Smith   /* count all the circular references of DM and its contained Vecs */
182732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
1836bf464f9SBarry Smith     if ((*dm)->localin[i])  {cnt++;}
1846bf464f9SBarry Smith     if ((*dm)->globalin[i]) {cnt++;}
185732e2eb9SMatthew G Knepley   }
186dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++;
18771cd77b2SBarry Smith   if ((*dm)->x) {
18871cd77b2SBarry Smith     PetscObject obj;
18971cd77b2SBarry Smith     ierr = PetscObjectQuery((PetscObject)(*dm)->x,"DM",&obj);CHKERRQ(ierr);
19071cd77b2SBarry Smith     if (obj == (PetscObject)*dm) cnt++;
19171cd77b2SBarry Smith   }
192732e2eb9SMatthew G Knepley 
1936bf464f9SBarry Smith   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
194732e2eb9SMatthew G Knepley   /*
195732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
196732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
197732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
198732e2eb9SMatthew G Knepley   */
1996bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
2006bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
201732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
2026bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
2036bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
204732e2eb9SMatthew G Knepley   }
205dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nnext) { /* Destroy the named vectors */
206dfe15315SJed Brown     nnext = nlink->next;
207dfe15315SJed 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);
208dfe15315SJed Brown     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
209dfe15315SJed Brown     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
210dfe15315SJed Brown     ierr = PetscFree(nlink);CHKERRQ(ierr);
211dfe15315SJed Brown   }
212dfe15315SJed Brown   (*dm)->namedglobal = PETSC_NULL;
2131a266240SBarry Smith 
214b17ce1afSJed Brown   /* Destroy the list of hooks */
215c833c3b5SJed Brown   {
216c833c3b5SJed Brown     DMCoarsenHookLink link,next;
217b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
218b17ce1afSJed Brown       next = link->next;
219b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
220b17ce1afSJed Brown     }
221b17ce1afSJed Brown     (*dm)->coarsenhook = PETSC_NULL;
222c833c3b5SJed Brown   }
223c833c3b5SJed Brown   {
224c833c3b5SJed Brown     DMRefineHookLink link,next;
225c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
226c833c3b5SJed Brown       next = link->next;
227c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
228c833c3b5SJed Brown     }
229c833c3b5SJed Brown     (*dm)->refinehook = PETSC_NULL;
230c833c3b5SJed Brown   }
231*aa1993deSMatthew G Knepley   /* Destroy the work arrays */
232*aa1993deSMatthew G Knepley   {
233*aa1993deSMatthew G Knepley     DMWorkLink link,next;
234*aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
235*aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
236*aa1993deSMatthew G Knepley       next = link->next;
237*aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
238*aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
239*aa1993deSMatthew G Knepley     }
240*aa1993deSMatthew G Knepley     (*dm)->workin = PETSC_NULL;
241*aa1993deSMatthew G Knepley   }
242b17ce1afSJed Brown 
2431a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
2441a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
2451a266240SBarry Smith   }
24687e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
24771cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
2484dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
2496bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
2506bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr);
2516bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
252073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
25388ed4aceSMatthew G Knepley 
25488ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
25588ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
25688ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
25788ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
258732e2eb9SMatthew G Knepley   /* if memory was published with AMS then destroy it */
2596bf464f9SBarry Smith   ierr = PetscObjectDepublish(*dm);CHKERRQ(ierr);
260732e2eb9SMatthew G Knepley 
2616bf464f9SBarry Smith   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
262435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
263732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
26447c6ae99SBarry Smith   PetscFunctionReturn(0);
26547c6ae99SBarry Smith }
26647c6ae99SBarry Smith 
26747c6ae99SBarry Smith #undef __FUNCT__
268d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp"
269d7bf68aeSBarry Smith /*@
270d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
271d7bf68aeSBarry Smith 
272d7bf68aeSBarry Smith     Collective on DM
273d7bf68aeSBarry Smith 
274d7bf68aeSBarry Smith     Input Parameter:
275d7bf68aeSBarry Smith .   dm - the DM object to setup
276d7bf68aeSBarry Smith 
277d7bf68aeSBarry Smith     Level: developer
278d7bf68aeSBarry Smith 
279e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
280d7bf68aeSBarry Smith 
281d7bf68aeSBarry Smith @*/
2827087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
283d7bf68aeSBarry Smith {
284d7bf68aeSBarry Smith   PetscErrorCode ierr;
285d7bf68aeSBarry Smith 
286d7bf68aeSBarry Smith   PetscFunctionBegin;
287171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2888387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
289d7bf68aeSBarry Smith   if (dm->ops->setup) {
290d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
291d7bf68aeSBarry Smith   }
2928387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
293d7bf68aeSBarry Smith   PetscFunctionReturn(0);
294d7bf68aeSBarry Smith }
295d7bf68aeSBarry Smith 
296d7bf68aeSBarry Smith #undef __FUNCT__
297d7bf68aeSBarry Smith #define __FUNCT__ "DMSetFromOptions"
298d7bf68aeSBarry Smith /*@
299d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
300d7bf68aeSBarry Smith 
301d7bf68aeSBarry Smith     Collective on DM
302d7bf68aeSBarry Smith 
303d7bf68aeSBarry Smith     Input Parameter:
304d7bf68aeSBarry Smith .   dm - the DM object to set options for
305d7bf68aeSBarry Smith 
306732e2eb9SMatthew G Knepley     Options Database:
307dd85299cSBarry Smith +   -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
308dd85299cSBarry Smith .   -dm_vec_type <type>  type of vector to create inside DM
309171400e9SBarry Smith .   -dm_mat_type <type>  type of matrix to create inside DM
310171400e9SBarry Smith -   -dm_coloring_type <global or ghosted>
311732e2eb9SMatthew G Knepley 
312d7bf68aeSBarry Smith     Level: developer
313d7bf68aeSBarry Smith 
314e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
315d7bf68aeSBarry Smith 
316d7bf68aeSBarry Smith @*/
3177087cfbeSBarry Smith PetscErrorCode  DMSetFromOptions(DM dm)
318d7bf68aeSBarry Smith {
31967ad5babSMatthew G Knepley   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg;
320d7bf68aeSBarry Smith   PetscErrorCode ierr;
321f9ba7244SBarry Smith   char           typeName[256] = MATAIJ;
322d7bf68aeSBarry Smith 
323d7bf68aeSBarry Smith   PetscFunctionBegin;
324171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3253194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
32682fcb398SMatthew G Knepley     ierr = PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);CHKERRQ(ierr);
327c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_detail", "Exhaustive mesh description", "DMView", flg2, &flg2, PETSC_NULL);CHKERRQ(ierr);
328c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_vtk", "Output mesh in VTK format", "DMView", flg3, &flg3, PETSC_NULL);CHKERRQ(ierr);
32967ad5babSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_latex", "Output mesh in LaTeX TikZ format", "DMView", flg4, &flg4, PETSC_NULL);CHKERRQ(ierr);
330073dac72SJed 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);
331f9ba7244SBarry Smith     ierr = PetscOptionsList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
332f9ba7244SBarry Smith     if (flg) {
333f9ba7244SBarry Smith       ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
334f9ba7244SBarry Smith     }
335521d9a4cSLisandro Dalcin     ierr = PetscOptionsList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype?dm->mattype:typeName,typeName,sizeof typeName,&flg);CHKERRQ(ierr);
336073dac72SJed Brown     if (flg) {
337521d9a4cSLisandro Dalcin       ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
338073dac72SJed Brown     }
3391b89239cSHong 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);
340f9ba7244SBarry Smith     if (dm->ops->setfromoptions) {
341f9ba7244SBarry Smith       ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr);
342f9ba7244SBarry Smith     }
343f9ba7244SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
344f9ba7244SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
34582fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
34682fcb398SMatthew G Knepley   if (flg1) {
34782fcb398SMatthew G Knepley     ierr = DMView(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
34882fcb398SMatthew G Knepley   }
349c4721b0eSMatthew G Knepley   if (flg2) {
350c4721b0eSMatthew G Knepley     PetscViewer viewer;
351c4721b0eSMatthew G Knepley 
352c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
353c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
354c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
355c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
356c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
357c4721b0eSMatthew G Knepley   }
358c4721b0eSMatthew G Knepley   if (flg3) {
359c4721b0eSMatthew G Knepley     PetscViewer viewer;
360c4721b0eSMatthew G Knepley 
361c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
362c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
363c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);
364c4721b0eSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.vtk");CHKERRQ(ierr);
365c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
366c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
367c4721b0eSMatthew G Knepley   }
36867ad5babSMatthew G Knepley   if (flg4) {
36967ad5babSMatthew G Knepley     PetscViewer viewer;
37067ad5babSMatthew G Knepley 
37167ad5babSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
37267ad5babSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
37367ad5babSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_LATEX);CHKERRQ(ierr);
37467ad5babSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.tex");CHKERRQ(ierr);
37567ad5babSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
37667ad5babSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
37767ad5babSMatthew G Knepley   }
378d7bf68aeSBarry Smith   PetscFunctionReturn(0);
379d7bf68aeSBarry Smith }
380d7bf68aeSBarry Smith 
381d7bf68aeSBarry Smith #undef __FUNCT__
38247c6ae99SBarry Smith #define __FUNCT__ "DMView"
383fc9bc008SSatish Balay /*@C
384aa219208SBarry Smith     DMView - Views a vector packer or DMDA.
38547c6ae99SBarry Smith 
38647c6ae99SBarry Smith     Collective on DM
38747c6ae99SBarry Smith 
38847c6ae99SBarry Smith     Input Parameter:
38947c6ae99SBarry Smith +   dm - the DM object to view
39047c6ae99SBarry Smith -   v - the viewer
39147c6ae99SBarry Smith 
39247c6ae99SBarry Smith     Level: developer
39347c6ae99SBarry Smith 
394e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
39547c6ae99SBarry Smith 
39647c6ae99SBarry Smith @*/
3977087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
39847c6ae99SBarry Smith {
39947c6ae99SBarry Smith   PetscErrorCode ierr;
40047c6ae99SBarry Smith 
40147c6ae99SBarry Smith   PetscFunctionBegin;
402171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4033014e516SBarry Smith  if (!v) {
4043014e516SBarry Smith     ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr);
4053014e516SBarry Smith   }
4060c010503SBarry Smith   if (dm->ops->view) {
4070c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
40847c6ae99SBarry Smith   }
40947c6ae99SBarry Smith   PetscFunctionReturn(0);
41047c6ae99SBarry Smith }
41147c6ae99SBarry Smith 
41247c6ae99SBarry Smith #undef __FUNCT__
41347c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
41447c6ae99SBarry Smith /*@
415aa219208SBarry Smith     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
41647c6ae99SBarry Smith 
41747c6ae99SBarry Smith     Collective on DM
41847c6ae99SBarry Smith 
41947c6ae99SBarry Smith     Input Parameter:
42047c6ae99SBarry Smith .   dm - the DM object
42147c6ae99SBarry Smith 
42247c6ae99SBarry Smith     Output Parameter:
42347c6ae99SBarry Smith .   vec - the global vector
42447c6ae99SBarry Smith 
425073dac72SJed Brown     Level: beginner
42647c6ae99SBarry Smith 
427e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
42847c6ae99SBarry Smith 
42947c6ae99SBarry Smith @*/
4307087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
43147c6ae99SBarry Smith {
43247c6ae99SBarry Smith   PetscErrorCode ierr;
43347c6ae99SBarry Smith 
43447c6ae99SBarry Smith   PetscFunctionBegin;
435171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
43688ed4aceSMatthew G Knepley   if (dm->defaultSection) {
43788ed4aceSMatthew G Knepley     PetscSection gSection;
43888ed4aceSMatthew G Knepley     PetscInt     localSize;
43988ed4aceSMatthew G Knepley 
44088ed4aceSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
44188ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr);
44288ed4aceSMatthew G Knepley     ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr);
44388ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
44488ed4aceSMatthew G Knepley     /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */
44588ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
44688ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
44788ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */
44888ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */
44988ed4aceSMatthew G Knepley     /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */
45088ed4aceSMatthew G Knepley   } else {
45147c6ae99SBarry Smith     ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
45288ed4aceSMatthew G Knepley   }
45347c6ae99SBarry Smith   PetscFunctionReturn(0);
45447c6ae99SBarry Smith }
45547c6ae99SBarry Smith 
45647c6ae99SBarry Smith #undef __FUNCT__
45747c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
45847c6ae99SBarry Smith /*@
459aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
46047c6ae99SBarry Smith 
46147c6ae99SBarry Smith     Not Collective
46247c6ae99SBarry Smith 
46347c6ae99SBarry Smith     Input Parameter:
46447c6ae99SBarry Smith .   dm - the DM object
46547c6ae99SBarry Smith 
46647c6ae99SBarry Smith     Output Parameter:
46747c6ae99SBarry Smith .   vec - the local vector
46847c6ae99SBarry Smith 
469073dac72SJed Brown     Level: beginner
47047c6ae99SBarry Smith 
471e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
47247c6ae99SBarry Smith 
47347c6ae99SBarry Smith @*/
4747087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
47547c6ae99SBarry Smith {
47647c6ae99SBarry Smith   PetscErrorCode ierr;
47747c6ae99SBarry Smith 
47847c6ae99SBarry Smith   PetscFunctionBegin;
479171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
48088ed4aceSMatthew G Knepley   if (dm->defaultSection) {
48188ed4aceSMatthew G Knepley     PetscInt localSize;
48288ed4aceSMatthew G Knepley 
48388ed4aceSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr);
48488ed4aceSMatthew G Knepley     ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr);
48588ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr);
48688ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
48788ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
48888ed4aceSMatthew G Knepley   } else {
48947c6ae99SBarry Smith     ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
49088ed4aceSMatthew G Knepley   }
49147c6ae99SBarry Smith   PetscFunctionReturn(0);
49247c6ae99SBarry Smith }
49347c6ae99SBarry Smith 
49447c6ae99SBarry Smith #undef __FUNCT__
4951411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
4961411c6eeSJed Brown /*@
4971411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
4981411c6eeSJed Brown 
4991411c6eeSJed Brown    Collective on DM
5001411c6eeSJed Brown 
5011411c6eeSJed Brown    Input Parameter:
5021411c6eeSJed Brown .  dm - the DM that provides the mapping
5031411c6eeSJed Brown 
5041411c6eeSJed Brown    Output Parameter:
5051411c6eeSJed Brown .  ltog - the mapping
5061411c6eeSJed Brown 
5071411c6eeSJed Brown    Level: intermediate
5081411c6eeSJed Brown 
5091411c6eeSJed Brown    Notes:
5101411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
5111411c6eeSJed Brown    MatSetLocalToGlobalMapping().
5121411c6eeSJed Brown 
5131411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
5141411c6eeSJed Brown @*/
5157087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
5161411c6eeSJed Brown {
5171411c6eeSJed Brown   PetscErrorCode ierr;
5181411c6eeSJed Brown 
5191411c6eeSJed Brown   PetscFunctionBegin;
5201411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5211411c6eeSJed Brown   PetscValidPointer(ltog,2);
5221411c6eeSJed Brown   if (!dm->ltogmap) {
52337d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
52437d0c07bSMatthew G Knepley 
52537d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
52637d0c07bSMatthew G Knepley     if (section) {
52737d0c07bSMatthew G Knepley       PetscInt      *ltog;
52837d0c07bSMatthew G Knepley       PetscInt       pStart, pEnd, size, p, l;
52937d0c07bSMatthew G Knepley 
53037d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
53137d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
53237d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
53337d0c07bSMatthew G Knepley       ierr = PetscMalloc(size * sizeof(PetscInt), &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
53437d0c07bSMatthew G Knepley       for(p = pStart, l = 0; p < pEnd; ++p) {
53537d0c07bSMatthew G Knepley         PetscInt dof, off, c;
53637d0c07bSMatthew G Knepley 
53737d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
53837d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
53937d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
54037d0c07bSMatthew G Knepley         for(c = 0; c < dof; ++c, ++l) {
54137d0c07bSMatthew G Knepley           ltog[l] = off+c;
54237d0c07bSMatthew G Knepley         }
54337d0c07bSMatthew G Knepley       }
54437d0c07bSMatthew G Knepley       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
54537d0c07bSMatthew G Knepley       ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr);
54637d0c07bSMatthew G Knepley     } else {
5471411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
5481411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
5491411c6eeSJed Brown     }
55037d0c07bSMatthew G Knepley   }
5511411c6eeSJed Brown   *ltog = dm->ltogmap;
5521411c6eeSJed Brown   PetscFunctionReturn(0);
5531411c6eeSJed Brown }
5541411c6eeSJed Brown 
5551411c6eeSJed Brown #undef __FUNCT__
5561411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
5571411c6eeSJed Brown /*@
5581411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
5591411c6eeSJed Brown 
5601411c6eeSJed Brown    Collective on DM
5611411c6eeSJed Brown 
5621411c6eeSJed Brown    Input Parameter:
5631411c6eeSJed Brown .  da - the distributed array that provides the mapping
5641411c6eeSJed Brown 
5651411c6eeSJed Brown    Output Parameter:
5661411c6eeSJed Brown .  ltog - the block mapping
5671411c6eeSJed Brown 
5681411c6eeSJed Brown    Level: intermediate
5691411c6eeSJed Brown 
5701411c6eeSJed Brown    Notes:
5711411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
5721411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
5731411c6eeSJed Brown 
5741411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
5751411c6eeSJed Brown @*/
5767087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
5771411c6eeSJed Brown {
5781411c6eeSJed Brown   PetscErrorCode ierr;
5791411c6eeSJed Brown 
5801411c6eeSJed Brown   PetscFunctionBegin;
5811411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5821411c6eeSJed Brown   PetscValidPointer(ltog,2);
5831411c6eeSJed Brown   if (!dm->ltogmapb) {
5841411c6eeSJed Brown     PetscInt bs;
5851411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
5861411c6eeSJed Brown     if (bs > 1) {
5871411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
5881411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
5891411c6eeSJed Brown     } else {
5901411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
5911411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
5921411c6eeSJed Brown     }
5931411c6eeSJed Brown   }
5941411c6eeSJed Brown   *ltog = dm->ltogmapb;
5951411c6eeSJed Brown   PetscFunctionReturn(0);
5961411c6eeSJed Brown }
5971411c6eeSJed Brown 
5981411c6eeSJed Brown #undef __FUNCT__
5991411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
6001411c6eeSJed Brown /*@
6011411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
6021411c6eeSJed Brown 
6031411c6eeSJed Brown    Not Collective
6041411c6eeSJed Brown 
6051411c6eeSJed Brown    Input Parameter:
6061411c6eeSJed Brown .  dm - the DM with block structure
6071411c6eeSJed Brown 
6081411c6eeSJed Brown    Output Parameter:
6091411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
6101411c6eeSJed Brown 
6111411c6eeSJed Brown    Level: intermediate
6121411c6eeSJed Brown 
6131411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
6141411c6eeSJed Brown @*/
6157087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
6161411c6eeSJed Brown {
6171411c6eeSJed Brown   PetscFunctionBegin;
6181411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6191411c6eeSJed Brown   PetscValidPointer(bs,2);
6201411c6eeSJed 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");
6211411c6eeSJed Brown   *bs = dm->bs;
6221411c6eeSJed Brown   PetscFunctionReturn(0);
6231411c6eeSJed Brown }
6241411c6eeSJed Brown 
6251411c6eeSJed Brown #undef __FUNCT__
626e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
62747c6ae99SBarry Smith /*@
628e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
62947c6ae99SBarry Smith 
63047c6ae99SBarry Smith     Collective on DM
63147c6ae99SBarry Smith 
63247c6ae99SBarry Smith     Input Parameter:
63347c6ae99SBarry Smith +   dm1 - the DM object
63447c6ae99SBarry Smith -   dm2 - the second, finer DM object
63547c6ae99SBarry Smith 
63647c6ae99SBarry Smith     Output Parameter:
63747c6ae99SBarry Smith +  mat - the interpolation
63847c6ae99SBarry Smith -  vec - the scaling (optional)
63947c6ae99SBarry Smith 
64047c6ae99SBarry Smith     Level: developer
64147c6ae99SBarry Smith 
64285afcc9aSBarry 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
64385afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
644d52bd9f3SBarry Smith 
645d52bd9f3SBarry Smith         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMDAGetCoordinateDA()) to interpolate the mesh coordinate vectors
646d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
64785afcc9aSBarry Smith 
64885afcc9aSBarry Smith 
649e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
65047c6ae99SBarry Smith 
65147c6ae99SBarry Smith @*/
652e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
65347c6ae99SBarry Smith {
65447c6ae99SBarry Smith   PetscErrorCode ierr;
65547c6ae99SBarry Smith 
65647c6ae99SBarry Smith   PetscFunctionBegin;
657171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
658171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
65925296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
66047c6ae99SBarry Smith   PetscFunctionReturn(0);
66147c6ae99SBarry Smith }
66247c6ae99SBarry Smith 
66347c6ae99SBarry Smith #undef __FUNCT__
664e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
66547c6ae99SBarry Smith /*@
666e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
66747c6ae99SBarry Smith 
66847c6ae99SBarry Smith     Collective on DM
66947c6ae99SBarry Smith 
67047c6ae99SBarry Smith     Input Parameter:
67147c6ae99SBarry Smith +   dm1 - the DM object
67247c6ae99SBarry Smith -   dm2 - the second, finer DM object
67347c6ae99SBarry Smith 
67447c6ae99SBarry Smith     Output Parameter:
67547c6ae99SBarry Smith .   ctx - the injection
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 injection.
68185afcc9aSBarry Smith 
682e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
68347c6ae99SBarry Smith 
68447c6ae99SBarry Smith @*/
685e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
68647c6ae99SBarry Smith {
68747c6ae99SBarry Smith   PetscErrorCode ierr;
68847c6ae99SBarry Smith 
68947c6ae99SBarry Smith   PetscFunctionBegin;
690171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
691171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
69247c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
69347c6ae99SBarry Smith   PetscFunctionReturn(0);
69447c6ae99SBarry Smith }
69547c6ae99SBarry Smith 
69647c6ae99SBarry Smith #undef __FUNCT__
697e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
698d1e2c406SBarry Smith /*@C
699e727c939SJed Brown     DMCreateColoring - Gets coloring for a DMDA or DMComposite
70047c6ae99SBarry Smith 
70147c6ae99SBarry Smith     Collective on DM
70247c6ae99SBarry Smith 
70347c6ae99SBarry Smith     Input Parameter:
70447c6ae99SBarry Smith +   dm - the DM object
70547c6ae99SBarry Smith .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
70647c6ae99SBarry Smith -   matype - either MATAIJ or MATBAIJ
70747c6ae99SBarry Smith 
70847c6ae99SBarry Smith     Output Parameter:
70947c6ae99SBarry Smith .   coloring - the coloring
71047c6ae99SBarry Smith 
71147c6ae99SBarry Smith     Level: developer
71247c6ae99SBarry Smith 
713e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
71447c6ae99SBarry Smith 
715aab9d709SJed Brown @*/
716e727c939SJed Brown PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring)
71747c6ae99SBarry Smith {
71847c6ae99SBarry Smith   PetscErrorCode ierr;
71947c6ae99SBarry Smith 
72047c6ae99SBarry Smith   PetscFunctionBegin;
721171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
72247c6ae99SBarry Smith   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
72347c6ae99SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
72447c6ae99SBarry Smith   PetscFunctionReturn(0);
72547c6ae99SBarry Smith }
72647c6ae99SBarry Smith 
72747c6ae99SBarry Smith #undef __FUNCT__
728950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
72947c6ae99SBarry Smith /*@C
730950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
73147c6ae99SBarry Smith 
73247c6ae99SBarry Smith     Collective on DM
73347c6ae99SBarry Smith 
73447c6ae99SBarry Smith     Input Parameter:
73547c6ae99SBarry Smith +   dm - the DM object
73647c6ae99SBarry Smith -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
73794013140SBarry Smith             any type which inherits from one of these (such as MATAIJ)
73847c6ae99SBarry Smith 
73947c6ae99SBarry Smith     Output Parameter:
74047c6ae99SBarry Smith .   mat - the empty Jacobian
74147c6ae99SBarry Smith 
742073dac72SJed Brown     Level: beginner
74347c6ae99SBarry Smith 
74494013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
74594013140SBarry Smith        do not need to do it yourself.
74694013140SBarry Smith 
74794013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
748aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
74994013140SBarry Smith 
75094013140SBarry 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
75194013140SBarry Smith        internally by PETSc.
75294013140SBarry Smith 
75394013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
754aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
75594013140SBarry Smith 
756e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
75747c6ae99SBarry Smith 
758aab9d709SJed Brown @*/
759950540a4SJed Brown PetscErrorCode  DMCreateMatrix(DM dm,const MatType mtype,Mat *mat)
76047c6ae99SBarry Smith {
76147c6ae99SBarry Smith   PetscErrorCode ierr;
76247c6ae99SBarry Smith 
76347c6ae99SBarry Smith   PetscFunctionBegin;
764171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
765235683edSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
766235683edSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
767235683edSBarry Smith #endif
768c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
769c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
770073dac72SJed Brown   if (dm->mattype) {
77125296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
772073dac72SJed Brown   } else {
77325296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
774c7b7c8a4SJed Brown   }
77547c6ae99SBarry Smith   PetscFunctionReturn(0);
77647c6ae99SBarry Smith }
77747c6ae99SBarry Smith 
77847c6ae99SBarry Smith #undef __FUNCT__
779732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
780732e2eb9SMatthew G Knepley /*@
781950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
782732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
783732e2eb9SMatthew G Knepley 
784732e2eb9SMatthew G Knepley   Logically Collective on DMDA
785732e2eb9SMatthew G Knepley 
786732e2eb9SMatthew G Knepley   Input Parameter:
787732e2eb9SMatthew G Knepley + dm - the DM
788732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
789732e2eb9SMatthew G Knepley 
790732e2eb9SMatthew G Knepley   Level: developer
791950540a4SJed Brown .seealso DMCreateMatrix()
792732e2eb9SMatthew G Knepley @*/
793732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
794732e2eb9SMatthew G Knepley {
795732e2eb9SMatthew G Knepley   PetscFunctionBegin;
796732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
797732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
798732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
799732e2eb9SMatthew G Knepley }
800732e2eb9SMatthew G Knepley 
801732e2eb9SMatthew G Knepley #undef __FUNCT__
802a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
803a89ea682SMatthew G Knepley /*@C
804*aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
805a89ea682SMatthew G Knepley 
806a89ea682SMatthew G Knepley   Not Collective
807a89ea682SMatthew G Knepley 
808a89ea682SMatthew G Knepley   Input Parameters:
809a89ea682SMatthew G Knepley + dm - the DM object
810*aa1993deSMatthew G Knepley . count - The minium size
811*aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
812a89ea682SMatthew G Knepley 
813a89ea682SMatthew G Knepley   Output Parameter:
814a89ea682SMatthew G Knepley . array - the work array
815a89ea682SMatthew G Knepley 
816a89ea682SMatthew G Knepley   Level: developer
817a89ea682SMatthew G Knepley 
818a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
819a89ea682SMatthew G Knepley @*/
820*aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
821a89ea682SMatthew G Knepley {
822a89ea682SMatthew G Knepley   PetscErrorCode ierr;
823*aa1993deSMatthew G Knepley   DMWorkLink link;
824*aa1993deSMatthew G Knepley   size_t size;
825a89ea682SMatthew G Knepley 
826a89ea682SMatthew G Knepley   PetscFunctionBegin;
827a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
828*aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
829*aa1993deSMatthew G Knepley   if (dm->workin) {
830*aa1993deSMatthew G Knepley     link = dm->workin;
831*aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
832*aa1993deSMatthew G Knepley   } else {
833*aa1993deSMatthew G Knepley     ierr = PetscNewLog(dm,struct _DMWorkLink,&link);CHKERRQ(ierr);
834a89ea682SMatthew G Knepley   }
835*aa1993deSMatthew G Knepley   ierr = PetscDataTypeGetSize(dtype,&size);CHKERRQ(ierr);
836*aa1993deSMatthew G Knepley   if (size*count > link->bytes) {
837*aa1993deSMatthew G Knepley     ierr = PetscFree(link->mem);CHKERRQ(ierr);
838*aa1993deSMatthew G Knepley     ierr = PetscMalloc(size*count,&link->mem);CHKERRQ(ierr);
839*aa1993deSMatthew G Knepley     link->bytes = size*count;
840*aa1993deSMatthew G Knepley   }
841*aa1993deSMatthew G Knepley   link->next = dm->workout;
842*aa1993deSMatthew G Knepley   dm->workout = link;
843*aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
844a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
845a89ea682SMatthew G Knepley }
846a89ea682SMatthew G Knepley 
847*aa1993deSMatthew G Knepley #undef __FUNCT__
848*aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
849*aa1993deSMatthew G Knepley /*@C
850*aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
851*aa1993deSMatthew G Knepley 
852*aa1993deSMatthew G Knepley   Not Collective
853*aa1993deSMatthew G Knepley 
854*aa1993deSMatthew G Knepley   Input Parameters:
855*aa1993deSMatthew G Knepley + dm - the DM object
856*aa1993deSMatthew G Knepley . count - The minium size
857*aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
858*aa1993deSMatthew G Knepley 
859*aa1993deSMatthew G Knepley   Output Parameter:
860*aa1993deSMatthew G Knepley . array - the work array
861*aa1993deSMatthew G Knepley 
862*aa1993deSMatthew G Knepley   Level: developer
863*aa1993deSMatthew G Knepley 
864*aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
865*aa1993deSMatthew G Knepley @*/
866*aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
867*aa1993deSMatthew G Knepley {
868*aa1993deSMatthew G Knepley   DMWorkLink *p,link;
869*aa1993deSMatthew G Knepley 
870*aa1993deSMatthew G Knepley   PetscFunctionBegin;
871*aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
872*aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
873*aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
874*aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
875*aa1993deSMatthew G Knepley       *p = link->next;
876*aa1993deSMatthew G Knepley       link->next = dm->workin;
877*aa1993deSMatthew G Knepley       dm->workin = link;
878*aa1993deSMatthew G Knepley       *(void**)mem = PETSC_NULL;
879*aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
880*aa1993deSMatthew G Knepley     }
881*aa1993deSMatthew G Knepley   }
882*aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
883*aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
884*aa1993deSMatthew G Knepley }
885e7c4fc90SDmitry Karpeev 
886e7c4fc90SDmitry Karpeev #undef __FUNCT__
887435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
888435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
889435a35e8SMatthew G Knepley {
890435a35e8SMatthew G Knepley   PetscFunctionBegin;
891435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
892435a35e8SMatthew G Knepley   if (field >= 10) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
893435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
894435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
895435a35e8SMatthew G Knepley }
896435a35e8SMatthew G Knepley 
897435a35e8SMatthew G Knepley #undef __FUNCT__
8984d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
8994f3b5142SJed Brown /*@C
9004d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
9014d343eeaSMatthew G Knepley 
9024d343eeaSMatthew G Knepley   Not collective
9034d343eeaSMatthew G Knepley 
9044d343eeaSMatthew G Knepley   Input Parameter:
9054d343eeaSMatthew G Knepley . dm - the DM object
9064d343eeaSMatthew G Knepley 
9074d343eeaSMatthew G Knepley   Output Parameters:
90821c9b008SJed Brown + numFields  - The number of fields (or PETSC_NULL if not requested)
90937d0c07bSMatthew G Knepley . fieldNames - The name for each field (or PETSC_NULL if not requested)
91021c9b008SJed Brown - fields     - The global indices for each field (or PETSC_NULL if not requested)
9114d343eeaSMatthew G Knepley 
9124d343eeaSMatthew G Knepley   Level: intermediate
9134d343eeaSMatthew G Knepley 
91421c9b008SJed Brown   Notes:
91521c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
91621c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
91721c9b008SJed Brown   PetscFree().
91821c9b008SJed Brown 
9194d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
9204d343eeaSMatthew G Knepley @*/
92137d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
9224d343eeaSMatthew G Knepley {
92337d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
9244d343eeaSMatthew G Knepley   PetscErrorCode ierr;
9254d343eeaSMatthew G Knepley 
9264d343eeaSMatthew G Knepley   PetscFunctionBegin;
9274d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
92869ca1f37SDmitry Karpeev   if (numFields) {
92969ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
93069ca1f37SDmitry Karpeev     *numFields = 0;
93169ca1f37SDmitry Karpeev   }
93237d0c07bSMatthew G Knepley   if (fieldNames) {
93337d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
93437d0c07bSMatthew G Knepley     *fieldNames = PETSC_NULL;
93569ca1f37SDmitry Karpeev   }
93669ca1f37SDmitry Karpeev   if (fields) {
93769ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
93869ca1f37SDmitry Karpeev     *fields = PETSC_NULL;
93969ca1f37SDmitry Karpeev   }
94037d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
94137d0c07bSMatthew G Knepley   if (section) {
94237d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
94337d0c07bSMatthew G Knepley     PetscInt  nF, f, pStart, pEnd, p;
94437d0c07bSMatthew G Knepley 
94537d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
94637d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
94737d0c07bSMatthew G Knepley     ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr);
94837d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
94937d0c07bSMatthew G Knepley     for(f = 0; f < nF; ++f) {
95037d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
95137d0c07bSMatthew G Knepley     }
95237d0c07bSMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
95337d0c07bSMatthew G Knepley       PetscInt gdof;
95437d0c07bSMatthew G Knepley 
95537d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
95637d0c07bSMatthew G Knepley       if (gdof > 0) {
95737d0c07bSMatthew G Knepley         for(f = 0; f < nF; ++f) {
95837d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
95937d0c07bSMatthew G Knepley 
96037d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
96137d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
96237d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
96337d0c07bSMatthew G Knepley         }
96437d0c07bSMatthew G Knepley       }
96537d0c07bSMatthew G Knepley     }
96637d0c07bSMatthew G Knepley     for(f = 0; f < nF; ++f) {
96737d0c07bSMatthew G Knepley       ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr);
96837d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
96937d0c07bSMatthew G Knepley     }
97037d0c07bSMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
97137d0c07bSMatthew G Knepley       PetscInt gdof, goff;
97237d0c07bSMatthew G Knepley 
97337d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
97437d0c07bSMatthew G Knepley       if (gdof > 0) {
97537d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
97637d0c07bSMatthew G Knepley         for(f = 0; f < nF; ++f) {
97737d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
97837d0c07bSMatthew G Knepley 
97937d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
98037d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
98137d0c07bSMatthew G Knepley           for(fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
98237d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
98337d0c07bSMatthew G Knepley           }
98437d0c07bSMatthew G Knepley         }
98537d0c07bSMatthew G Knepley       }
98637d0c07bSMatthew G Knepley     }
98737d0c07bSMatthew G Knepley     if (numFields) {*numFields = nF;}
98837d0c07bSMatthew G Knepley     if (fieldNames) {
98937d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr);
99037d0c07bSMatthew G Knepley       for(f = 0; f < nF; ++f) {
99137d0c07bSMatthew G Knepley         const char *fieldName;
99237d0c07bSMatthew G Knepley 
99337d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
99437d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr);
99537d0c07bSMatthew G Knepley       }
99637d0c07bSMatthew G Knepley     }
99737d0c07bSMatthew G Knepley     if (fields) {
99837d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr);
99937d0c07bSMatthew G Knepley       for(f = 0; f < nF; ++f) {
100037d0c07bSMatthew G Knepley         ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
100137d0c07bSMatthew G Knepley       }
100237d0c07bSMatthew G Knepley     }
100337d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
100437d0c07bSMatthew G Knepley   } else {
100537d0c07bSMatthew G Knepley     if(dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);}
100669ca1f37SDmitry Karpeev   }
10074d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
10084d343eeaSMatthew G Knepley }
10094d343eeaSMatthew G Knepley 
1010a89ea682SMatthew G Knepley #undef __FUNCT__
101116621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecompositionDM"
1012e7c4fc90SDmitry Karpeev /*@C
101316621825SDmitry Karpeev   DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields.
101416621825SDmitry Karpeev 
101516621825SDmitry Karpeev   Not Collective
101616621825SDmitry Karpeev 
101716621825SDmitry Karpeev   Input Parameters:
101816621825SDmitry Karpeev + dm   - the DM object
101916621825SDmitry Karpeev - name - the name of the field decomposition
102016621825SDmitry Karpeev 
102116621825SDmitry Karpeev   Output Parameter:
102216621825SDmitry Karpeev . ddm  - the field decomposition DM (PETSC_NULL, if no such decomposition is known)
102316621825SDmitry Karpeev 
102416621825SDmitry Karpeev   Level: advanced
102516621825SDmitry Karpeev 
102616621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
102716621825SDmitry Karpeev @*/
102816621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm)
102916621825SDmitry Karpeev {
103016621825SDmitry Karpeev   PetscErrorCode ierr;
103116621825SDmitry Karpeev 
103216621825SDmitry Karpeev   PetscFunctionBegin;
103316621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
103416621825SDmitry Karpeev   PetscValidCharPointer(name,2);
103516621825SDmitry Karpeev   PetscValidPointer(ddm,3);
103616621825SDmitry Karpeev   *ddm = PETSC_NULL;
1037731c8d9eSDmitry Karpeev   if(dm->ops->createfielddecompositiondm) {
103816621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
103916621825SDmitry Karpeev   }
104016621825SDmitry Karpeev   PetscFunctionReturn(0);
104116621825SDmitry Karpeev }
104216621825SDmitry Karpeev 
104316621825SDmitry Karpeev #undef __FUNCT__
104416621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
104516621825SDmitry Karpeev /*@C
104616621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
104716621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
104816621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1049e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1050e7c4fc90SDmitry Karpeev 
1051e7c4fc90SDmitry Karpeev   Not collective
1052e7c4fc90SDmitry Karpeev 
1053e7c4fc90SDmitry Karpeev   Input Parameter:
1054e7c4fc90SDmitry Karpeev . dm - the DM object
1055e7c4fc90SDmitry Karpeev 
1056e7c4fc90SDmitry Karpeev   Output Parameters:
105716621825SDmitry Karpeev + len       - The number of subproblems in the field decomposition (or PETSC_NULL if not requested)
105816621825SDmitry Karpeev . namelist  - The name for each field (or PETSC_NULL if not requested)
105916621825SDmitry Karpeev . islist    - The global indices for each field (or PETSC_NULL if not requested)
106016621825SDmitry Karpeev - dmlist    - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
1061e7c4fc90SDmitry Karpeev 
1062e7c4fc90SDmitry Karpeev   Level: intermediate
1063e7c4fc90SDmitry Karpeev 
1064e7c4fc90SDmitry Karpeev   Notes:
1065e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1066e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1067e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1068e7c4fc90SDmitry Karpeev 
1069e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1070e7c4fc90SDmitry Karpeev @*/
107116621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1072e7c4fc90SDmitry Karpeev {
1073e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1074e7c4fc90SDmitry Karpeev 
1075e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1076e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1077731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);      *len      = 0;}
1078731c8d9eSDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;}
1079731c8d9eSDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);   *islist   = 0;}
1080731c8d9eSDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);   *dmlist   = 0;}
108116621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1082435a35e8SMatthew G Knepley     PetscSection section;
1083435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1084435a35e8SMatthew G Knepley 
1085435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1086435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1087435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1088435a35e8SMatthew G Knepley       *len = numFields;
1089435a35e8SMatthew G Knepley       ierr = PetscMalloc3(numFields,char*,namelist,numFields,IS,islist,numFields,DM,dmlist);CHKERRQ(ierr);
1090435a35e8SMatthew G Knepley       for(f = 0; f < numFields; ++f) {
1091435a35e8SMatthew G Knepley         const char *fieldName;
1092435a35e8SMatthew G Knepley 
1093435a35e8SMatthew G Knepley         ierr = DMCreateSubDM(dm, 1, &f, &(*islist)[f], &(*dmlist)[f]);CHKERRQ(ierr);
1094435a35e8SMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1095435a35e8SMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*namelist)[f]);CHKERRQ(ierr);
1096435a35e8SMatthew G Knepley       }
1097435a35e8SMatthew G Knepley     } else {
109869ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1099e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
1100e7c4fc90SDmitry Karpeev       if(dmlist) *dmlist = PETSC_NULL;
1101e7c4fc90SDmitry Karpeev     }
1102435a35e8SMatthew G Knepley   }
1103e7c4fc90SDmitry Karpeev   else {
110416621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
110516621825SDmitry Karpeev   }
110616621825SDmitry Karpeev   PetscFunctionReturn(0);
110716621825SDmitry Karpeev }
110816621825SDmitry Karpeev 
110916621825SDmitry Karpeev #undef __FUNCT__
1110435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1111435a35e8SMatthew G Knepley /*@C
1112435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1113435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1114435a35e8SMatthew G Knepley 
1115435a35e8SMatthew G Knepley   Not collective
1116435a35e8SMatthew G Knepley 
1117435a35e8SMatthew G Knepley   Input Parameters:
1118435a35e8SMatthew G Knepley + dm - the DM object
1119435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
1120435a35e8SMatthew G Knepley - len       - The number of subproblems in the decomposition (or PETSC_NULL if not requested)
1121435a35e8SMatthew G Knepley 
1122435a35e8SMatthew G Knepley   Output Parameters:
1123435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1124435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1125435a35e8SMatthew G Knepley 
1126435a35e8SMatthew G Knepley   Level: intermediate
1127435a35e8SMatthew G Knepley 
1128435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1129435a35e8SMatthew G Knepley @*/
1130435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1131435a35e8SMatthew G Knepley {
1132435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1133435a35e8SMatthew G Knepley 
1134435a35e8SMatthew G Knepley   PetscFunctionBegin;
1135435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1136435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
1137435a35e8SMatthew G Knepley   if (is) {PetscValidPointer(is,4);}
1138435a35e8SMatthew G Knepley   if (subdm) {PetscValidPointer(subdm,5);}
1139435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1140435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm); CHKERRQ(ierr);
1141435a35e8SMatthew G Knepley   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1142435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1143435a35e8SMatthew G Knepley }
1144435a35e8SMatthew G Knepley 
1145435a35e8SMatthew G Knepley #undef __FUNCT__
114616621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecompositionDM"
114716621825SDmitry Karpeev /*@C
114816621825SDmitry Karpeev   DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains.
114916621825SDmitry Karpeev 
115016621825SDmitry Karpeev   Not Collective
115116621825SDmitry Karpeev 
115216621825SDmitry Karpeev   Input Parameters:
115316621825SDmitry Karpeev + dm   - the DM object
115416621825SDmitry Karpeev - name - the name of the subdomain decomposition
115516621825SDmitry Karpeev 
115616621825SDmitry Karpeev   Output Parameter:
115716621825SDmitry Karpeev . ddm  - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known)
115816621825SDmitry Karpeev 
115916621825SDmitry Karpeev   Level: advanced
116016621825SDmitry Karpeev 
116116621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
116216621825SDmitry Karpeev @*/
116316621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm)
116416621825SDmitry Karpeev {
116516621825SDmitry Karpeev   PetscErrorCode ierr;
116616621825SDmitry Karpeev 
116716621825SDmitry Karpeev   PetscFunctionBegin;
116816621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
116916621825SDmitry Karpeev   PetscValidCharPointer(name,2);
117016621825SDmitry Karpeev   PetscValidPointer(ddm,3);
117116621825SDmitry Karpeev   *ddm = PETSC_NULL;
1172731c8d9eSDmitry Karpeev   if(dm->ops->createdomaindecompositiondm) {
117316621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
117416621825SDmitry Karpeev   }
117516621825SDmitry Karpeev   PetscFunctionReturn(0);
117616621825SDmitry Karpeev }
117716621825SDmitry Karpeev 
117816621825SDmitry Karpeev #undef __FUNCT__
117916621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
118016621825SDmitry Karpeev /*@C
11818d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
11828d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
11838d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
11848d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
11858d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
118616621825SDmitry Karpeev 
118716621825SDmitry Karpeev   Not collective
118816621825SDmitry Karpeev 
118916621825SDmitry Karpeev   Input Parameter:
119016621825SDmitry Karpeev . dm - the DM object
119116621825SDmitry Karpeev 
119216621825SDmitry Karpeev   Output Parameters:
119316621825SDmitry Karpeev + len         - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested)
119416621825SDmitry Karpeev . namelist    - The name for each subdomain (or PETSC_NULL if not requested)
11958d4ac253SDmitry Karpeev . innerislist - The global indices for each inner subdomain (or PETSC_NULL, if not requested)
11968d4ac253SDmitry Karpeev . outerislist - The global indices for each outer subdomain (or PETSC_NULL, if not requested)
119716621825SDmitry Karpeev - dmlist      - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
119816621825SDmitry Karpeev 
119916621825SDmitry Karpeev   Level: intermediate
120016621825SDmitry Karpeev 
120116621825SDmitry Karpeev   Notes:
120216621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
120316621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
120416621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
120516621825SDmitry Karpeev 
12068d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
120716621825SDmitry Karpeev @*/
12088d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
120916621825SDmitry Karpeev {
121016621825SDmitry Karpeev   PetscErrorCode ierr;
121116621825SDmitry Karpeev 
121216621825SDmitry Karpeev   PetscFunctionBegin;
121316621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1214731c8d9eSDmitry Karpeev   if (len)           {PetscValidPointer(len,2);            *len         = PETSC_NULL;}
121516621825SDmitry Karpeev   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = PETSC_NULL;}
12168d4ac253SDmitry Karpeev   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = PETSC_NULL;}
12178d4ac253SDmitry Karpeev   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = PETSC_NULL;}
12188d4ac253SDmitry Karpeev   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = PETSC_NULL;}
121916621825SDmitry Karpeev   if(dm->ops->createdomaindecomposition) {
12208d4ac253SDmitry Karpeev     ierr = (*dm->ops->createdomaindecomposition)(dm,len,namelist,innerislist,outerislist,dmlist); CHKERRQ(ierr);
1221e7c4fc90SDmitry Karpeev   }
1222e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1223e7c4fc90SDmitry Karpeev }
1224e7c4fc90SDmitry Karpeev 
1225731c8d9eSDmitry Karpeev #undef __FUNCT__
122647c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
122747c6ae99SBarry Smith /*@
122847c6ae99SBarry Smith   DMRefine - Refines a DM object
122947c6ae99SBarry Smith 
123047c6ae99SBarry Smith   Collective on DM
123147c6ae99SBarry Smith 
123247c6ae99SBarry Smith   Input Parameter:
123347c6ae99SBarry Smith + dm   - the DM object
123491d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
123547c6ae99SBarry Smith 
123647c6ae99SBarry Smith   Output Parameter:
1237ae0a1c52SMatthew G Knepley . dmf - the refined DM, or PETSC_NULL
1238ae0a1c52SMatthew G Knepley 
1239ae0a1c52SMatthew G Knepley   Note: If no refinement was done, the return value is PETSC_NULL
124047c6ae99SBarry Smith 
124147c6ae99SBarry Smith   Level: developer
124247c6ae99SBarry Smith 
1243e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
124447c6ae99SBarry Smith @*/
12457087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
124647c6ae99SBarry Smith {
124747c6ae99SBarry Smith   PetscErrorCode ierr;
1248c833c3b5SJed Brown   DMRefineHookLink link;
124947c6ae99SBarry Smith 
125047c6ae99SBarry Smith   PetscFunctionBegin;
1251732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
125247c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
12534057135bSMatthew G Knepley   if (*dmf) {
125443842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
1255644e2e5bSBarry Smith     (*dmf)->ops->initialguess = dm->ops->initialguess;
1256644e2e5bSBarry Smith     (*dmf)->ops->function     = dm->ops->function;
1257644e2e5bSBarry Smith     (*dmf)->ops->functionj    = dm->ops->functionj;
1258644e2e5bSBarry Smith     if (dm->ops->jacobian != DMComputeJacobianDefault) {
1259644e2e5bSBarry Smith       (*dmf)->ops->jacobian     = dm->ops->jacobian;
1260644e2e5bSBarry Smith     }
12618cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
1262644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
12630598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1264656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
1265e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1266c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
1267c833c3b5SJed Brown       if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);}
1268c833c3b5SJed Brown     }
1269c833c3b5SJed Brown   }
1270c833c3b5SJed Brown   PetscFunctionReturn(0);
1271c833c3b5SJed Brown }
1272c833c3b5SJed Brown 
1273c833c3b5SJed Brown #undef __FUNCT__
1274c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1275c833c3b5SJed Brown /*@
1276c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1277c833c3b5SJed Brown 
1278c833c3b5SJed Brown    Logically Collective
1279c833c3b5SJed Brown 
1280c833c3b5SJed Brown    Input Arguments:
1281c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1282c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1283c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
1284c833c3b5SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1285c833c3b5SJed Brown 
1286c833c3b5SJed Brown    Calling sequence of refinehook:
1287c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1288c833c3b5SJed Brown 
1289c833c3b5SJed Brown +  coarse - coarse level DM
1290c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1291c833c3b5SJed Brown -  ctx - optional user-defined function context
1292c833c3b5SJed Brown 
1293c833c3b5SJed Brown    Calling sequence for interphook:
1294c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1295c833c3b5SJed Brown 
1296c833c3b5SJed Brown +  coarse - coarse level DM
1297c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1298c833c3b5SJed Brown .  fine - fine level DM to update
1299c833c3b5SJed Brown -  ctx - optional user-defined function context
1300c833c3b5SJed Brown 
1301c833c3b5SJed Brown    Level: advanced
1302c833c3b5SJed Brown 
1303c833c3b5SJed Brown    Notes:
1304c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1305c833c3b5SJed Brown 
1306c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1307c833c3b5SJed Brown 
1308c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1309c833c3b5SJed Brown @*/
1310c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1311c833c3b5SJed Brown {
1312c833c3b5SJed Brown   PetscErrorCode ierr;
1313c833c3b5SJed Brown   DMRefineHookLink link,*p;
1314c833c3b5SJed Brown 
1315c833c3b5SJed Brown   PetscFunctionBegin;
1316c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1317c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1318c833c3b5SJed Brown   ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1319c833c3b5SJed Brown   link->refinehook = refinehook;
1320c833c3b5SJed Brown   link->interphook = interphook;
1321c833c3b5SJed Brown   link->ctx = ctx;
1322c833c3b5SJed Brown   link->next = PETSC_NULL;
1323c833c3b5SJed Brown   *p = link;
1324c833c3b5SJed Brown   PetscFunctionReturn(0);
1325c833c3b5SJed Brown }
1326c833c3b5SJed Brown 
1327c833c3b5SJed Brown #undef __FUNCT__
1328c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1329c833c3b5SJed Brown /*@
1330c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1331c833c3b5SJed Brown 
1332c833c3b5SJed Brown    Collective if any hooks are
1333c833c3b5SJed Brown 
1334c833c3b5SJed Brown    Input Arguments:
1335c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1336c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1337c833c3b5SJed Brown -  fine - finer DM to update
1338c833c3b5SJed Brown 
1339c833c3b5SJed Brown    Level: developer
1340c833c3b5SJed Brown 
1341c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1342c833c3b5SJed Brown @*/
1343c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1344c833c3b5SJed Brown {
1345c833c3b5SJed Brown   PetscErrorCode ierr;
1346c833c3b5SJed Brown   DMRefineHookLink link;
1347c833c3b5SJed Brown 
1348c833c3b5SJed Brown   PetscFunctionBegin;
1349c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
1350c833c3b5SJed Brown     if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);}
13514057135bSMatthew G Knepley   }
135247c6ae99SBarry Smith   PetscFunctionReturn(0);
135347c6ae99SBarry Smith }
135447c6ae99SBarry Smith 
135547c6ae99SBarry Smith #undef __FUNCT__
1356eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1357eb3f98d2SBarry Smith /*@
1358eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1359eb3f98d2SBarry Smith 
1360eb3f98d2SBarry Smith     Not Collective
1361eb3f98d2SBarry Smith 
1362eb3f98d2SBarry Smith     Input Parameter:
1363eb3f98d2SBarry Smith .   dm - the DM object
1364eb3f98d2SBarry Smith 
1365eb3f98d2SBarry Smith     Output Parameter:
1366eb3f98d2SBarry Smith .   level - number of refinements
1367eb3f98d2SBarry Smith 
1368eb3f98d2SBarry Smith     Level: developer
1369eb3f98d2SBarry Smith 
13706a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1371eb3f98d2SBarry Smith 
1372eb3f98d2SBarry Smith @*/
1373eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1374eb3f98d2SBarry Smith {
1375eb3f98d2SBarry Smith   PetscFunctionBegin;
1376eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1377eb3f98d2SBarry Smith   *level = dm->levelup;
1378eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1379eb3f98d2SBarry Smith }
1380eb3f98d2SBarry Smith 
1381eb3f98d2SBarry Smith #undef __FUNCT__
138247c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
138347c6ae99SBarry Smith /*@
138447c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
138547c6ae99SBarry Smith 
138647c6ae99SBarry Smith     Neighbor-wise Collective on DM
138747c6ae99SBarry Smith 
138847c6ae99SBarry Smith     Input Parameters:
138947c6ae99SBarry Smith +   dm - the DM object
139047c6ae99SBarry Smith .   g - the global vector
139147c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
139247c6ae99SBarry Smith -   l - the local vector
139347c6ae99SBarry Smith 
139447c6ae99SBarry Smith 
139547c6ae99SBarry Smith     Level: beginner
139647c6ae99SBarry Smith 
1397e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
139847c6ae99SBarry Smith 
139947c6ae99SBarry Smith @*/
14007087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
140147c6ae99SBarry Smith {
14027128ae9fSMatthew G Knepley   PetscSF        sf;
140347c6ae99SBarry Smith   PetscErrorCode ierr;
140447c6ae99SBarry Smith 
140547c6ae99SBarry Smith   PetscFunctionBegin;
1406171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14077128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14087128ae9fSMatthew G Knepley   if (sf) {
14097128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
14107128ae9fSMatthew G Knepley 
14117128ae9fSMatthew G Knepley     if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14127128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14137128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14147128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14157128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14167128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14177128ae9fSMatthew G Knepley   } else {
1418843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14197128ae9fSMatthew G Knepley   }
142047c6ae99SBarry Smith   PetscFunctionReturn(0);
142147c6ae99SBarry Smith }
142247c6ae99SBarry Smith 
142347c6ae99SBarry Smith #undef __FUNCT__
142447c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
142547c6ae99SBarry Smith /*@
142647c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
142747c6ae99SBarry Smith 
142847c6ae99SBarry Smith     Neighbor-wise Collective on DM
142947c6ae99SBarry Smith 
143047c6ae99SBarry Smith     Input Parameters:
143147c6ae99SBarry Smith +   dm - the DM object
143247c6ae99SBarry Smith .   g - the global vector
143347c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
143447c6ae99SBarry Smith -   l - the local vector
143547c6ae99SBarry Smith 
143647c6ae99SBarry Smith 
143747c6ae99SBarry Smith     Level: beginner
143847c6ae99SBarry Smith 
1439e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
144047c6ae99SBarry Smith 
144147c6ae99SBarry Smith @*/
14427087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
144347c6ae99SBarry Smith {
14447128ae9fSMatthew G Knepley   PetscSF        sf;
144547c6ae99SBarry Smith   PetscErrorCode ierr;
144661a3c1faSSatish Balay   PetscScalar    *lArray, *gArray;
144747c6ae99SBarry Smith 
144847c6ae99SBarry Smith   PetscFunctionBegin;
1449171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14507128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14517128ae9fSMatthew G Knepley   if (sf) {
14527128ae9fSMatthew G Knepley   if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14537128ae9fSMatthew G Knepley 
14547128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14557128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14567128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14577128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14587128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14597128ae9fSMatthew G Knepley   } else {
1460843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14617128ae9fSMatthew G Knepley   }
146247c6ae99SBarry Smith   PetscFunctionReturn(0);
146347c6ae99SBarry Smith }
146447c6ae99SBarry Smith 
146547c6ae99SBarry Smith #undef __FUNCT__
14669a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
146747c6ae99SBarry Smith /*@
14689a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
14699a42bb27SBarry Smith 
14709a42bb27SBarry Smith     Neighbor-wise Collective on DM
14719a42bb27SBarry Smith 
14729a42bb27SBarry Smith     Input Parameters:
14739a42bb27SBarry Smith +   dm - the DM object
1474f6813fd5SJed Brown .   l - the local vector
14759a42bb27SBarry 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
14769a42bb27SBarry Smith            base point.
1477f6813fd5SJed Brown - - the global vector
14789a42bb27SBarry Smith 
14799a42bb27SBarry 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
14809a42bb27SBarry 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
14819a42bb27SBarry Smith            global array to the final global array with VecAXPY().
14829a42bb27SBarry Smith 
14839a42bb27SBarry Smith     Level: beginner
14849a42bb27SBarry Smith 
1485e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
14869a42bb27SBarry Smith 
14879a42bb27SBarry Smith @*/
14887087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
14899a42bb27SBarry Smith {
14907128ae9fSMatthew G Knepley   PetscSF        sf;
14919a42bb27SBarry Smith   PetscErrorCode ierr;
14929a42bb27SBarry Smith 
14939a42bb27SBarry Smith   PetscFunctionBegin;
1494171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14957128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14967128ae9fSMatthew G Knepley   if (sf) {
14977128ae9fSMatthew G Knepley     MPI_Op       op;
14987128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
14997128ae9fSMatthew G Knepley 
15007128ae9fSMatthew G Knepley     switch(mode) {
15017128ae9fSMatthew G Knepley     case INSERT_VALUES:
15027128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
15037128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
15047128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
15057128ae9fSMatthew G Knepley #else
15067128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
15077128ae9fSMatthew G Knepley #endif
15087128ae9fSMatthew G Knepley     case ADD_VALUES:
15097128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
15107128ae9fSMatthew G Knepley       op = MPI_SUM; break;
15117128ae9fSMatthew G Knepley   default:
15127128ae9fSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15137128ae9fSMatthew G Knepley     }
15147128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15157128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15167128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
15177128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15187128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15197128ae9fSMatthew G Knepley   } else {
1520843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
15217128ae9fSMatthew G Knepley   }
15229a42bb27SBarry Smith   PetscFunctionReturn(0);
15239a42bb27SBarry Smith }
15249a42bb27SBarry Smith 
15259a42bb27SBarry Smith #undef __FUNCT__
15269a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
15279a42bb27SBarry Smith /*@
15289a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
152947c6ae99SBarry Smith 
153047c6ae99SBarry Smith     Neighbor-wise Collective on DM
153147c6ae99SBarry Smith 
153247c6ae99SBarry Smith     Input Parameters:
153347c6ae99SBarry Smith +   dm - the DM object
1534f6813fd5SJed Brown .   l - the local vector
153547c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1536f6813fd5SJed Brown -   g - the global vector
153747c6ae99SBarry Smith 
153847c6ae99SBarry Smith 
153947c6ae99SBarry Smith     Level: beginner
154047c6ae99SBarry Smith 
1541e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
154247c6ae99SBarry Smith 
154347c6ae99SBarry Smith @*/
15447087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
154547c6ae99SBarry Smith {
15467128ae9fSMatthew G Knepley   PetscSF        sf;
154747c6ae99SBarry Smith   PetscErrorCode ierr;
154847c6ae99SBarry Smith 
154947c6ae99SBarry Smith   PetscFunctionBegin;
1550171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15517128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
15527128ae9fSMatthew G Knepley   if (sf) {
15537128ae9fSMatthew G Knepley     MPI_Op       op;
15547128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
15557128ae9fSMatthew G Knepley 
15567128ae9fSMatthew G Knepley     switch(mode) {
15577128ae9fSMatthew G Knepley     case INSERT_VALUES:
15587128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
15597128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
15607128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
15617128ae9fSMatthew G Knepley #else
15627128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
15637128ae9fSMatthew G Knepley #endif
15647128ae9fSMatthew G Knepley     case ADD_VALUES:
15657128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
15667128ae9fSMatthew G Knepley       op = MPI_SUM; break;
15677128ae9fSMatthew G Knepley     default:
15687128ae9fSMatthew G Knepley       SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15697128ae9fSMatthew G Knepley     }
15707128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15717128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15727128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
15737128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15747128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15757128ae9fSMatthew G Knepley   } else {
1576843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
15777128ae9fSMatthew G Knepley   }
157847c6ae99SBarry Smith   PetscFunctionReturn(0);
157947c6ae99SBarry Smith }
158047c6ae99SBarry Smith 
158147c6ae99SBarry Smith #undef __FUNCT__
158247c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobianDefault"
158347c6ae99SBarry Smith /*@
158447c6ae99SBarry Smith     DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided
158547c6ae99SBarry Smith 
158647c6ae99SBarry Smith     Collective on DM
158747c6ae99SBarry Smith 
158847c6ae99SBarry Smith     Input Parameter:
158947c6ae99SBarry Smith +   dm - the DM object
159047c6ae99SBarry Smith .   x - location to compute Jacobian at; may be ignored for linear problems
159147c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
159247c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
159347c6ae99SBarry Smith 
159447c6ae99SBarry Smith     Level: developer
159547c6ae99SBarry Smith 
1596e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
159747c6ae99SBarry Smith          DMSetFunction()
159847c6ae99SBarry Smith 
159947c6ae99SBarry Smith @*/
16007087cfbeSBarry Smith PetscErrorCode  DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
160147c6ae99SBarry Smith {
160247c6ae99SBarry Smith   PetscErrorCode ierr;
1603171400e9SBarry Smith 
160447c6ae99SBarry Smith   PetscFunctionBegin;
1605171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
160647c6ae99SBarry Smith   *stflag = SAME_NONZERO_PATTERN;
160747c6ae99SBarry Smith   ierr  = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr);
160847c6ae99SBarry Smith   if (A != B) {
160947c6ae99SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
161047c6ae99SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
161147c6ae99SBarry Smith   }
161247c6ae99SBarry Smith   PetscFunctionReturn(0);
161347c6ae99SBarry Smith }
161447c6ae99SBarry Smith 
161547c6ae99SBarry Smith #undef __FUNCT__
161647c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
161747c6ae99SBarry Smith /*@
161847c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
161947c6ae99SBarry Smith 
162047c6ae99SBarry Smith     Collective on DM
162147c6ae99SBarry Smith 
162247c6ae99SBarry Smith     Input Parameter:
162347c6ae99SBarry Smith +   dm - the DM object
162491d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
162547c6ae99SBarry Smith 
162647c6ae99SBarry Smith     Output Parameter:
162747c6ae99SBarry Smith .   dmc - the coarsened DM
162847c6ae99SBarry Smith 
162947c6ae99SBarry Smith     Level: developer
163047c6ae99SBarry Smith 
1631e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
163247c6ae99SBarry Smith 
163347c6ae99SBarry Smith @*/
16347087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
163547c6ae99SBarry Smith {
163647c6ae99SBarry Smith   PetscErrorCode ierr;
1637b17ce1afSJed Brown   DMCoarsenHookLink link;
163847c6ae99SBarry Smith 
163947c6ae99SBarry Smith   PetscFunctionBegin;
1640171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
164147c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
164243842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
164347c6ae99SBarry Smith   (*dmc)->ops->initialguess = dm->ops->initialguess;
164447c6ae99SBarry Smith   (*dmc)->ops->function     = dm->ops->function;
164547c6ae99SBarry Smith   (*dmc)->ops->functionj    = dm->ops->functionj;
164647c6ae99SBarry Smith   if (dm->ops->jacobian != DMComputeJacobianDefault) {
164747c6ae99SBarry Smith     (*dmc)->ops->jacobian     = dm->ops->jacobian;
164847c6ae99SBarry Smith   }
16498cd211a4SJed Brown   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1650644e2e5bSBarry Smith   (*dmc)->ctx       = dm->ctx;
16510598a293SJed Brown   (*dmc)->levelup   = dm->levelup;
1652656b349aSBarry Smith   (*dmc)->leveldown = dm->leveldown + 1;
1653e4b4b23bSJed Brown   ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
1654b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1655b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1656b17ce1afSJed Brown   }
1657b17ce1afSJed Brown   PetscFunctionReturn(0);
1658b17ce1afSJed Brown }
1659b17ce1afSJed Brown 
1660b17ce1afSJed Brown #undef __FUNCT__
1661b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1662b17ce1afSJed Brown /*@
1663b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1664b17ce1afSJed Brown 
1665b17ce1afSJed Brown    Logically Collective
1666b17ce1afSJed Brown 
1667b17ce1afSJed Brown    Input Arguments:
1668b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1669b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1670b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
1671b17ce1afSJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1672b17ce1afSJed Brown 
1673b17ce1afSJed Brown    Calling sequence of coarsenhook:
1674b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1675b17ce1afSJed Brown 
1676b17ce1afSJed Brown +  fine - fine level DM
1677b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1678b17ce1afSJed Brown -  ctx - optional user-defined function context
1679b17ce1afSJed Brown 
1680b17ce1afSJed Brown    Calling sequence for restricthook:
1681c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
1682b17ce1afSJed Brown 
1683b17ce1afSJed Brown +  fine - fine level DM
1684b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
1685c833c3b5SJed Brown .  rscale - scaling vector for restriction
1686c833c3b5SJed Brown .  inject - matrix restricting by injection
1687b17ce1afSJed Brown .  coarse - coarse level DM to update
1688b17ce1afSJed Brown -  ctx - optional user-defined function context
1689b17ce1afSJed Brown 
1690b17ce1afSJed Brown    Level: advanced
1691b17ce1afSJed Brown 
1692b17ce1afSJed Brown    Notes:
1693b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
1694b17ce1afSJed Brown 
1695b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1696b17ce1afSJed Brown 
1697b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1698b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
1699b17ce1afSJed Brown 
1700c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1701b17ce1afSJed Brown @*/
1702b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1703b17ce1afSJed Brown {
1704b17ce1afSJed Brown   PetscErrorCode ierr;
1705b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
1706b17ce1afSJed Brown 
1707b17ce1afSJed Brown   PetscFunctionBegin;
1708b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
17096bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1710b17ce1afSJed Brown   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1711b17ce1afSJed Brown   link->coarsenhook = coarsenhook;
1712b17ce1afSJed Brown   link->restricthook = restricthook;
1713b17ce1afSJed Brown   link->ctx = ctx;
17146cab3a1bSJed Brown   link->next = PETSC_NULL;
1715b17ce1afSJed Brown   *p = link;
1716b17ce1afSJed Brown   PetscFunctionReturn(0);
1717b17ce1afSJed Brown }
1718b17ce1afSJed Brown 
1719b17ce1afSJed Brown #undef __FUNCT__
1720b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
1721b17ce1afSJed Brown /*@
1722b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1723b17ce1afSJed Brown 
1724b17ce1afSJed Brown    Collective if any hooks are
1725b17ce1afSJed Brown 
1726b17ce1afSJed Brown    Input Arguments:
1727b17ce1afSJed Brown +  fine - finer DM to use as a base
1728b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
1729b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
1730b17ce1afSJed Brown -  coarse - coarer DM to update
1731b17ce1afSJed Brown 
1732b17ce1afSJed Brown    Level: developer
1733b17ce1afSJed Brown 
1734b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
1735b17ce1afSJed Brown @*/
1736b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1737b17ce1afSJed Brown {
1738b17ce1afSJed Brown   PetscErrorCode ierr;
1739b17ce1afSJed Brown   DMCoarsenHookLink link;
1740b17ce1afSJed Brown 
1741b17ce1afSJed Brown   PetscFunctionBegin;
1742b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
1743b17ce1afSJed Brown     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1744b17ce1afSJed Brown   }
174547c6ae99SBarry Smith   PetscFunctionReturn(0);
174647c6ae99SBarry Smith }
174747c6ae99SBarry Smith 
174847c6ae99SBarry Smith #undef __FUNCT__
17495fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
17505fe1f584SPeter Brune /*@
17516a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
17525fe1f584SPeter Brune 
17535fe1f584SPeter Brune     Not Collective
17545fe1f584SPeter Brune 
17555fe1f584SPeter Brune     Input Parameter:
17565fe1f584SPeter Brune .   dm - the DM object
17575fe1f584SPeter Brune 
17585fe1f584SPeter Brune     Output Parameter:
17596a7d9d85SPeter Brune .   level - number of coarsenings
17605fe1f584SPeter Brune 
17615fe1f584SPeter Brune     Level: developer
17625fe1f584SPeter Brune 
17636a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
17645fe1f584SPeter Brune 
17655fe1f584SPeter Brune @*/
17665fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
17675fe1f584SPeter Brune {
17685fe1f584SPeter Brune   PetscFunctionBegin;
17695fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17705fe1f584SPeter Brune   *level = dm->leveldown;
17715fe1f584SPeter Brune   PetscFunctionReturn(0);
17725fe1f584SPeter Brune }
17735fe1f584SPeter Brune 
17745fe1f584SPeter Brune 
17755fe1f584SPeter Brune 
17765fe1f584SPeter Brune #undef __FUNCT__
177747c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
177847c6ae99SBarry Smith /*@C
177947c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
178047c6ae99SBarry Smith 
178147c6ae99SBarry Smith     Collective on DM
178247c6ae99SBarry Smith 
178347c6ae99SBarry Smith     Input Parameter:
178447c6ae99SBarry Smith +   dm - the DM object
178547c6ae99SBarry Smith -   nlevels - the number of levels of refinement
178647c6ae99SBarry Smith 
178747c6ae99SBarry Smith     Output Parameter:
178847c6ae99SBarry Smith .   dmf - the refined DM hierarchy
178947c6ae99SBarry Smith 
179047c6ae99SBarry Smith     Level: developer
179147c6ae99SBarry Smith 
1792e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
179347c6ae99SBarry Smith 
179447c6ae99SBarry Smith @*/
17957087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
179647c6ae99SBarry Smith {
179747c6ae99SBarry Smith   PetscErrorCode ierr;
179847c6ae99SBarry Smith 
179947c6ae99SBarry Smith   PetscFunctionBegin;
1800171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
180147c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
180247c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
180347c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
180447c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
180547c6ae99SBarry Smith   } else if (dm->ops->refine) {
180647c6ae99SBarry Smith     PetscInt i;
180747c6ae99SBarry Smith 
180847c6ae99SBarry Smith     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
180947c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
181047c6ae99SBarry Smith       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
181147c6ae99SBarry Smith     }
181247c6ae99SBarry Smith   } else {
181347c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
181447c6ae99SBarry Smith   }
181547c6ae99SBarry Smith   PetscFunctionReturn(0);
181647c6ae99SBarry Smith }
181747c6ae99SBarry Smith 
181847c6ae99SBarry Smith #undef __FUNCT__
181947c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
182047c6ae99SBarry Smith /*@C
182147c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
182247c6ae99SBarry Smith 
182347c6ae99SBarry Smith     Collective on DM
182447c6ae99SBarry Smith 
182547c6ae99SBarry Smith     Input Parameter:
182647c6ae99SBarry Smith +   dm - the DM object
182747c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
182847c6ae99SBarry Smith 
182947c6ae99SBarry Smith     Output Parameter:
183047c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
183147c6ae99SBarry Smith 
183247c6ae99SBarry Smith     Level: developer
183347c6ae99SBarry Smith 
1834e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
183547c6ae99SBarry Smith 
183647c6ae99SBarry Smith @*/
18377087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
183847c6ae99SBarry Smith {
183947c6ae99SBarry Smith   PetscErrorCode ierr;
184047c6ae99SBarry Smith 
184147c6ae99SBarry Smith   PetscFunctionBegin;
1842171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
184347c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
184447c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
184547c6ae99SBarry Smith   PetscValidPointer(dmc,3);
184647c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
184747c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
184847c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
184947c6ae99SBarry Smith     PetscInt i;
185047c6ae99SBarry Smith 
185147c6ae99SBarry Smith     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
185247c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
185347c6ae99SBarry Smith       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
185447c6ae99SBarry Smith     }
185547c6ae99SBarry Smith   } else {
185647c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
185747c6ae99SBarry Smith   }
185847c6ae99SBarry Smith   PetscFunctionReturn(0);
185947c6ae99SBarry Smith }
186047c6ae99SBarry Smith 
186147c6ae99SBarry Smith #undef __FUNCT__
1862e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
186347c6ae99SBarry Smith /*@
1864e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
186547c6ae99SBarry Smith    grids associated with two DMs.
186647c6ae99SBarry Smith 
186747c6ae99SBarry Smith    Collective on DM
186847c6ae99SBarry Smith 
186947c6ae99SBarry Smith    Input Parameters:
187047c6ae99SBarry Smith +  dmc - the coarse grid DM
187147c6ae99SBarry Smith -  dmf - the fine grid DM
187247c6ae99SBarry Smith 
187347c6ae99SBarry Smith    Output Parameters:
187447c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
187547c6ae99SBarry Smith 
187647c6ae99SBarry Smith    Level: intermediate
187747c6ae99SBarry Smith 
187847c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
187947c6ae99SBarry Smith 
1880e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
188147c6ae99SBarry Smith @*/
1882e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
188347c6ae99SBarry Smith {
188447c6ae99SBarry Smith   PetscErrorCode ierr;
188547c6ae99SBarry Smith 
188647c6ae99SBarry Smith   PetscFunctionBegin;
1887171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
1888171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
188947c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
189047c6ae99SBarry Smith   PetscFunctionReturn(0);
189147c6ae99SBarry Smith }
189247c6ae99SBarry Smith 
189347c6ae99SBarry Smith #undef __FUNCT__
18941a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
18951a266240SBarry Smith /*@C
18961a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
18971a266240SBarry Smith 
18981a266240SBarry Smith     Not Collective
18991a266240SBarry Smith 
19001a266240SBarry Smith     Input Parameters:
19011a266240SBarry Smith +   dm - the DM object
19021a266240SBarry Smith -   destroy - the destroy function
19031a266240SBarry Smith 
19041a266240SBarry Smith     Level: intermediate
19051a266240SBarry Smith 
1906e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
19071a266240SBarry Smith 
1908f07f9ceaSJed Brown @*/
19091a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
19101a266240SBarry Smith {
19111a266240SBarry Smith   PetscFunctionBegin;
1912171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
19131a266240SBarry Smith   dm->ctxdestroy = destroy;
19141a266240SBarry Smith   PetscFunctionReturn(0);
19151a266240SBarry Smith }
19161a266240SBarry Smith 
19171a266240SBarry Smith #undef __FUNCT__
19181b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
1919b07ff414SBarry Smith /*@
19201b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
192147c6ae99SBarry Smith 
192247c6ae99SBarry Smith     Not Collective
192347c6ae99SBarry Smith 
192447c6ae99SBarry Smith     Input Parameters:
192547c6ae99SBarry Smith +   dm - the DM object
192647c6ae99SBarry Smith -   ctx - the user context
192747c6ae99SBarry Smith 
192847c6ae99SBarry Smith     Level: intermediate
192947c6ae99SBarry Smith 
1930e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
193147c6ae99SBarry Smith 
193247c6ae99SBarry Smith @*/
19331b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
193447c6ae99SBarry Smith {
193547c6ae99SBarry Smith   PetscFunctionBegin;
1936171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
193747c6ae99SBarry Smith   dm->ctx = ctx;
193847c6ae99SBarry Smith   PetscFunctionReturn(0);
193947c6ae99SBarry Smith }
194047c6ae99SBarry Smith 
194147c6ae99SBarry Smith #undef __FUNCT__
19421b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
194347c6ae99SBarry Smith /*@
19441b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
194547c6ae99SBarry Smith 
194647c6ae99SBarry Smith     Not Collective
194747c6ae99SBarry Smith 
194847c6ae99SBarry Smith     Input Parameter:
194947c6ae99SBarry Smith .   dm - the DM object
195047c6ae99SBarry Smith 
195147c6ae99SBarry Smith     Output Parameter:
195247c6ae99SBarry Smith .   ctx - the user context
195347c6ae99SBarry Smith 
195447c6ae99SBarry Smith     Level: intermediate
195547c6ae99SBarry Smith 
1956e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
195747c6ae99SBarry Smith 
195847c6ae99SBarry Smith @*/
19591b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
196047c6ae99SBarry Smith {
196147c6ae99SBarry Smith   PetscFunctionBegin;
1962171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
19631b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
196447c6ae99SBarry Smith   PetscFunctionReturn(0);
196547c6ae99SBarry Smith }
196647c6ae99SBarry Smith 
196747c6ae99SBarry Smith #undef __FUNCT__
196847c6ae99SBarry Smith #define __FUNCT__ "DMSetInitialGuess"
19697e833e3aSBarry Smith /*@C
197047c6ae99SBarry Smith     DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers
197147c6ae99SBarry Smith 
197247c6ae99SBarry Smith     Logically Collective on DM
197347c6ae99SBarry Smith 
197447c6ae99SBarry Smith     Input Parameter:
197547c6ae99SBarry Smith +   dm - the DM object to destroy
197647c6ae99SBarry Smith -   f - the function to compute the initial guess
197747c6ae99SBarry Smith 
197847c6ae99SBarry Smith     Level: intermediate
197947c6ae99SBarry Smith 
1980e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
198147c6ae99SBarry Smith 
1982f07f9ceaSJed Brown @*/
19837087cfbeSBarry Smith PetscErrorCode  DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec))
198447c6ae99SBarry Smith {
198547c6ae99SBarry Smith   PetscFunctionBegin;
1986171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
198747c6ae99SBarry Smith   dm->ops->initialguess = f;
198847c6ae99SBarry Smith   PetscFunctionReturn(0);
198947c6ae99SBarry Smith }
199047c6ae99SBarry Smith 
199147c6ae99SBarry Smith #undef __FUNCT__
199247c6ae99SBarry Smith #define __FUNCT__ "DMSetFunction"
19937e833e3aSBarry Smith /*@C
199447c6ae99SBarry Smith     DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES
199547c6ae99SBarry Smith 
199647c6ae99SBarry Smith     Logically Collective on DM
199747c6ae99SBarry Smith 
199847c6ae99SBarry Smith     Input Parameter:
199947c6ae99SBarry Smith +   dm - the DM object
200047c6ae99SBarry Smith -   f - the function to compute (use PETSC_NULL to cancel a previous function that was set)
200147c6ae99SBarry Smith 
200247c6ae99SBarry Smith     Level: intermediate
200347c6ae99SBarry Smith 
200447c6ae99SBarry Smith     Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian
200547c6ae99SBarry Smith            computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian.
200647c6ae99SBarry Smith 
2007e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
200847c6ae99SBarry Smith          DMSetJacobian()
200947c6ae99SBarry Smith 
2010f07f9ceaSJed Brown @*/
20117087cfbeSBarry Smith PetscErrorCode  DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
201247c6ae99SBarry Smith {
201347c6ae99SBarry Smith   PetscFunctionBegin;
2014171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
201547c6ae99SBarry Smith   dm->ops->function = f;
201647c6ae99SBarry Smith   if (f) {
201747c6ae99SBarry Smith     dm->ops->functionj = f;
201847c6ae99SBarry Smith   }
201947c6ae99SBarry Smith   PetscFunctionReturn(0);
202047c6ae99SBarry Smith }
202147c6ae99SBarry Smith 
202247c6ae99SBarry Smith #undef __FUNCT__
202347c6ae99SBarry Smith #define __FUNCT__ "DMSetJacobian"
20247e833e3aSBarry Smith /*@C
202547c6ae99SBarry Smith     DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES
202647c6ae99SBarry Smith 
202747c6ae99SBarry Smith     Logically Collective on DM
202847c6ae99SBarry Smith 
202947c6ae99SBarry Smith     Input Parameter:
203047c6ae99SBarry Smith +   dm - the DM object to destroy
203147c6ae99SBarry Smith -   f - the function to compute the matrix entries
203247c6ae99SBarry Smith 
203347c6ae99SBarry Smith     Level: intermediate
203447c6ae99SBarry Smith 
2035e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
203647c6ae99SBarry Smith          DMSetFunction()
203747c6ae99SBarry Smith 
2038f07f9ceaSJed Brown @*/
20397087cfbeSBarry Smith PetscErrorCode  DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*))
204047c6ae99SBarry Smith {
204147c6ae99SBarry Smith   PetscFunctionBegin;
2042171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
204347c6ae99SBarry Smith   dm->ops->jacobian = f;
204447c6ae99SBarry Smith   PetscFunctionReturn(0);
204547c6ae99SBarry Smith }
204647c6ae99SBarry Smith 
204747c6ae99SBarry Smith #undef __FUNCT__
204808da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
204908da532bSDmitry Karpeev /*@C
205008da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
205108da532bSDmitry Karpeev 
205208da532bSDmitry Karpeev     Logically Collective on DM
205308da532bSDmitry Karpeev 
205408da532bSDmitry Karpeev     Input Parameter:
205508da532bSDmitry Karpeev +   dm - the DM object
205608da532bSDmitry Karpeev -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
205708da532bSDmitry Karpeev 
205808da532bSDmitry Karpeev     Level: intermediate
205908da532bSDmitry Karpeev 
2060e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
206108da532bSDmitry Karpeev          DMSetJacobian()
206208da532bSDmitry Karpeev 
206308da532bSDmitry Karpeev @*/
206408da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
206508da532bSDmitry Karpeev {
206608da532bSDmitry Karpeev   PetscFunctionBegin;
206708da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
206808da532bSDmitry Karpeev   PetscFunctionReturn(0);
206908da532bSDmitry Karpeev }
207008da532bSDmitry Karpeev 
207108da532bSDmitry Karpeev #undef __FUNCT__
207208da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
207308da532bSDmitry Karpeev /*@
207408da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
207508da532bSDmitry Karpeev 
207608da532bSDmitry Karpeev     Not Collective
207708da532bSDmitry Karpeev 
207808da532bSDmitry Karpeev     Input Parameter:
207908da532bSDmitry Karpeev .   dm - the DM object to destroy
208008da532bSDmitry Karpeev 
208108da532bSDmitry Karpeev     Output Parameter:
208208da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
208308da532bSDmitry Karpeev 
208408da532bSDmitry Karpeev     Level: developer
208508da532bSDmitry Karpeev 
2086e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
208708da532bSDmitry Karpeev 
208808da532bSDmitry Karpeev @*/
208908da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
209008da532bSDmitry Karpeev {
209108da532bSDmitry Karpeev   PetscFunctionBegin;
209208da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
209308da532bSDmitry Karpeev   PetscFunctionReturn(0);
209408da532bSDmitry Karpeev }
209508da532bSDmitry Karpeev 
209608da532bSDmitry Karpeev #undef __FUNCT__
209708da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
209808da532bSDmitry Karpeev /*@C
209908da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
210008da532bSDmitry Karpeev 
210108da532bSDmitry Karpeev     Logically Collective on DM
210208da532bSDmitry Karpeev 
210308da532bSDmitry Karpeev     Input Parameters:
210408da532bSDmitry Karpeev +   dm - the DM object to destroy
210508da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
210608da532bSDmitry Karpeev 
210708da532bSDmitry Karpeev     Output parameters:
210808da532bSDmitry Karpeev +   xl - lower bound
210908da532bSDmitry Karpeev -   xu - upper bound
211008da532bSDmitry Karpeev 
211108da532bSDmitry Karpeev     Level: intermediate
211208da532bSDmitry Karpeev 
2113e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
211408da532bSDmitry Karpeev          DMSetFunction(), DMSetVariableBounds()
211508da532bSDmitry Karpeev 
211608da532bSDmitry Karpeev @*/
211708da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
211808da532bSDmitry Karpeev {
211908da532bSDmitry Karpeev   PetscErrorCode ierr;
212008da532bSDmitry Karpeev   PetscFunctionBegin;
212108da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
212208da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
212308da532bSDmitry Karpeev   if(dm->ops->computevariablebounds) {
212408da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
212508da532bSDmitry Karpeev   }
2126a201590fSDmitry Karpeev   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
212708da532bSDmitry Karpeev   PetscFunctionReturn(0);
212808da532bSDmitry Karpeev }
212908da532bSDmitry Karpeev 
213008da532bSDmitry Karpeev #undef __FUNCT__
213147c6ae99SBarry Smith #define __FUNCT__ "DMComputeInitialGuess"
213247c6ae99SBarry Smith /*@
213347c6ae99SBarry Smith     DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers
213447c6ae99SBarry Smith 
213547c6ae99SBarry Smith     Collective on DM
213647c6ae99SBarry Smith 
213747c6ae99SBarry Smith     Input Parameter:
213847c6ae99SBarry Smith +   dm - the DM object to destroy
213947c6ae99SBarry Smith -   x - the vector to hold the initial guess values
214047c6ae99SBarry Smith 
214147c6ae99SBarry Smith     Level: developer
214247c6ae99SBarry Smith 
2143e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat()
214447c6ae99SBarry Smith 
214547c6ae99SBarry Smith @*/
21467087cfbeSBarry Smith PetscErrorCode  DMComputeInitialGuess(DM dm,Vec x)
214747c6ae99SBarry Smith {
214847c6ae99SBarry Smith   PetscErrorCode ierr;
214947c6ae99SBarry Smith   PetscFunctionBegin;
2150171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
215147c6ae99SBarry Smith   if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()");
215247c6ae99SBarry Smith   ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr);
215347c6ae99SBarry Smith   PetscFunctionReturn(0);
215447c6ae99SBarry Smith }
215547c6ae99SBarry Smith 
215647c6ae99SBarry Smith #undef __FUNCT__
215747c6ae99SBarry Smith #define __FUNCT__ "DMHasInitialGuess"
215847c6ae99SBarry Smith /*@
215947c6ae99SBarry Smith     DMHasInitialGuess - does the DM object have an initial guess function
216047c6ae99SBarry Smith 
216147c6ae99SBarry Smith     Not Collective
216247c6ae99SBarry Smith 
216347c6ae99SBarry Smith     Input Parameter:
216447c6ae99SBarry Smith .   dm - the DM object to destroy
216547c6ae99SBarry Smith 
216647c6ae99SBarry Smith     Output Parameter:
216747c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
216847c6ae99SBarry Smith 
216947c6ae99SBarry Smith     Level: developer
217047c6ae99SBarry Smith 
2171e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
217247c6ae99SBarry Smith 
217347c6ae99SBarry Smith @*/
21747087cfbeSBarry Smith PetscErrorCode  DMHasInitialGuess(DM dm,PetscBool  *flg)
217547c6ae99SBarry Smith {
217647c6ae99SBarry Smith   PetscFunctionBegin;
2177171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
217847c6ae99SBarry Smith   *flg =  (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE;
217947c6ae99SBarry Smith   PetscFunctionReturn(0);
218047c6ae99SBarry Smith }
218147c6ae99SBarry Smith 
218247c6ae99SBarry Smith #undef __FUNCT__
218347c6ae99SBarry Smith #define __FUNCT__ "DMHasFunction"
218447c6ae99SBarry Smith /*@
218547c6ae99SBarry Smith     DMHasFunction - does the DM object have a function
218647c6ae99SBarry Smith 
218747c6ae99SBarry Smith     Not Collective
218847c6ae99SBarry Smith 
218947c6ae99SBarry Smith     Input Parameter:
219047c6ae99SBarry Smith .   dm - the DM object to destroy
219147c6ae99SBarry Smith 
219247c6ae99SBarry Smith     Output Parameter:
219347c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
219447c6ae99SBarry Smith 
219547c6ae99SBarry Smith     Level: developer
219647c6ae99SBarry Smith 
2197e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
219847c6ae99SBarry Smith 
219947c6ae99SBarry Smith @*/
22007087cfbeSBarry Smith PetscErrorCode  DMHasFunction(DM dm,PetscBool  *flg)
220147c6ae99SBarry Smith {
220247c6ae99SBarry Smith   PetscFunctionBegin;
2203171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
220447c6ae99SBarry Smith   *flg =  (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE;
220547c6ae99SBarry Smith   PetscFunctionReturn(0);
220647c6ae99SBarry Smith }
220747c6ae99SBarry Smith 
220847c6ae99SBarry Smith #undef __FUNCT__
220947c6ae99SBarry Smith #define __FUNCT__ "DMHasJacobian"
221047c6ae99SBarry Smith /*@
221147c6ae99SBarry Smith     DMHasJacobian - does the DM object have a matrix function
221247c6ae99SBarry Smith 
221347c6ae99SBarry Smith     Not Collective
221447c6ae99SBarry Smith 
221547c6ae99SBarry Smith     Input Parameter:
221647c6ae99SBarry Smith .   dm - the DM object to destroy
221747c6ae99SBarry Smith 
221847c6ae99SBarry Smith     Output Parameter:
221947c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
222047c6ae99SBarry Smith 
222147c6ae99SBarry Smith     Level: developer
222247c6ae99SBarry Smith 
2223e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
222447c6ae99SBarry Smith 
222547c6ae99SBarry Smith @*/
22267087cfbeSBarry Smith PetscErrorCode  DMHasJacobian(DM dm,PetscBool  *flg)
222747c6ae99SBarry Smith {
222847c6ae99SBarry Smith   PetscFunctionBegin;
2229171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
223047c6ae99SBarry Smith   *flg =  (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE;
223147c6ae99SBarry Smith   PetscFunctionReturn(0);
223247c6ae99SBarry Smith }
223347c6ae99SBarry Smith 
223447c6ae99SBarry Smith #undef __FUNCT__
2235b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2236b0ae01b7SPeter Brune /*@
2237b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2238b0ae01b7SPeter Brune 
2239b0ae01b7SPeter Brune     Not Collective
2240b0ae01b7SPeter Brune 
2241b0ae01b7SPeter Brune     Input Parameter:
2242b0ae01b7SPeter Brune .   dm - the DM object
2243b0ae01b7SPeter Brune 
2244b0ae01b7SPeter Brune     Output Parameter:
2245b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2246b0ae01b7SPeter Brune 
2247b0ae01b7SPeter Brune     Level: developer
2248b0ae01b7SPeter Brune 
2249b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2250b0ae01b7SPeter Brune 
2251b0ae01b7SPeter Brune @*/
2252b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2253b0ae01b7SPeter Brune {
2254b0ae01b7SPeter Brune   PetscFunctionBegin;
2255b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2256b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2257b0ae01b7SPeter Brune }
2258b0ae01b7SPeter Brune 
2259b0ae01b7SPeter Brune #undef  __FUNCT__
226008da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2261748fac09SDmitry Karpeev /*@C
226208da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
226308da532bSDmitry Karpeev 
226408da532bSDmitry Karpeev     Collective on DM
226508da532bSDmitry Karpeev 
226608da532bSDmitry Karpeev     Input Parameter:
226708da532bSDmitry Karpeev +   dm - the DM object
2268e88d7f4bSDmitry Karpeev -   x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems.
226908da532bSDmitry Karpeev 
227008da532bSDmitry Karpeev     Level: developer
227108da532bSDmitry Karpeev 
2272e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
227308da532bSDmitry Karpeev          DMSetFunction(), DMSetJacobian(), DMSetVariableBounds()
227408da532bSDmitry Karpeev 
227508da532bSDmitry Karpeev @*/
227608da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
227708da532bSDmitry Karpeev {
227808da532bSDmitry Karpeev   PetscErrorCode ierr;
227908da532bSDmitry Karpeev   PetscFunctionBegin;
228008da532bSDmitry Karpeev   if (x) {
228108da532bSDmitry Karpeev     if (!dm->x) {
228208da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
228308da532bSDmitry Karpeev     }
228408da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
228508da532bSDmitry Karpeev   }
228608da532bSDmitry Karpeev   else if(dm->x) {
228708da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
228808da532bSDmitry Karpeev   }
228908da532bSDmitry Karpeev   PetscFunctionReturn(0);
229008da532bSDmitry Karpeev }
229108da532bSDmitry Karpeev 
229208da532bSDmitry Karpeev 
229308da532bSDmitry Karpeev #undef __FUNCT__
229447c6ae99SBarry Smith #define __FUNCT__ "DMComputeFunction"
229547c6ae99SBarry Smith /*@
229647c6ae99SBarry Smith     DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES
229747c6ae99SBarry Smith 
229847c6ae99SBarry Smith     Collective on DM
229947c6ae99SBarry Smith 
230047c6ae99SBarry Smith     Input Parameter:
230147c6ae99SBarry Smith +   dm - the DM object to destroy
230247c6ae99SBarry Smith .   x - the location where the function is evaluationed, may be ignored for linear problems
230347c6ae99SBarry Smith -   b - the vector to hold the right hand side entries
230447c6ae99SBarry Smith 
230547c6ae99SBarry Smith     Level: developer
230647c6ae99SBarry Smith 
2307e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
230847c6ae99SBarry Smith          DMSetJacobian()
230947c6ae99SBarry Smith 
231047c6ae99SBarry Smith @*/
23117087cfbeSBarry Smith PetscErrorCode  DMComputeFunction(DM dm,Vec x,Vec b)
231247c6ae99SBarry Smith {
231347c6ae99SBarry Smith   PetscErrorCode ierr;
231447c6ae99SBarry Smith   PetscFunctionBegin;
2315171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
231647c6ae99SBarry Smith   if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()");
2317644e2e5bSBarry Smith   PetscStackPush("DM user function");
231847c6ae99SBarry Smith   ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr);
2319644e2e5bSBarry Smith   PetscStackPop;
232047c6ae99SBarry Smith   PetscFunctionReturn(0);
232147c6ae99SBarry Smith }
232247c6ae99SBarry Smith 
232347c6ae99SBarry Smith 
232408da532bSDmitry Karpeev 
232547c6ae99SBarry Smith #undef __FUNCT__
232647c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobian"
232747c6ae99SBarry Smith /*@
232847c6ae99SBarry Smith     DMComputeJacobian - compute the matrix entries for the solver
232947c6ae99SBarry Smith 
233047c6ae99SBarry Smith     Collective on DM
233147c6ae99SBarry Smith 
233247c6ae99SBarry Smith     Input Parameter:
233347c6ae99SBarry Smith +   dm - the DM object
2334cab2e9ccSBarry Smith .   x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM
233547c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
233647c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
233747c6ae99SBarry Smith 
233847c6ae99SBarry Smith     Level: developer
233947c6ae99SBarry Smith 
2340e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
234147c6ae99SBarry Smith          DMSetFunction()
234247c6ae99SBarry Smith 
234347c6ae99SBarry Smith @*/
23447087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
234547c6ae99SBarry Smith {
234647c6ae99SBarry Smith   PetscErrorCode ierr;
234747c6ae99SBarry Smith 
234847c6ae99SBarry Smith   PetscFunctionBegin;
2349171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
235047c6ae99SBarry Smith   if (!dm->ops->jacobian) {
235147c6ae99SBarry Smith     ISColoring     coloring;
235247c6ae99SBarry Smith     MatFDColoring  fd;
23532c9966d7SBarry Smith     const MatType  mtype;
235447c6ae99SBarry Smith 
23552c9966d7SBarry Smith     ierr = PetscObjectGetType((PetscObject)B,&mtype);CHKERRQ(ierr);
23562c9966d7SBarry Smith     ierr = DMCreateColoring(dm,dm->coloringtype,mtype,&coloring);CHKERRQ(ierr);
235747c6ae99SBarry Smith     ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr);
2358fcfd50ebSBarry Smith     ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
235947c6ae99SBarry Smith     ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr);
23600bdded8aSJed Brown     ierr = PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);CHKERRQ(ierr);
23610bdded8aSJed Brown     ierr = MatFDColoringSetFromOptions(fd);CHKERRQ(ierr);
236271cd77b2SBarry Smith 
236347c6ae99SBarry Smith     dm->fd = fd;
236447c6ae99SBarry Smith     dm->ops->jacobian = DMComputeJacobianDefault;
23652533e041SBarry Smith 
236671cd77b2SBarry Smith     /* don't know why this is needed */
236771cd77b2SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
236847c6ae99SBarry Smith   }
236947c6ae99SBarry Smith   if (!x) x = dm->x;
237047c6ae99SBarry Smith   ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr);
2371cab2e9ccSBarry Smith 
237271cd77b2SBarry 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 */
2373649052a6SBarry Smith   if (x) {
2374cab2e9ccSBarry Smith     if (!dm->x) {
237571cd77b2SBarry Smith       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
2376cab2e9ccSBarry Smith     }
2377cab2e9ccSBarry Smith     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
2378649052a6SBarry Smith   }
2379a8248277SBarry Smith   if (A != B) {
2380a8248277SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2381a8248277SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2382a8248277SBarry Smith   }
238347c6ae99SBarry Smith   PetscFunctionReturn(0);
238447c6ae99SBarry Smith }
2385264ace61SBarry Smith 
2386cab2e9ccSBarry Smith 
2387264ace61SBarry Smith PetscFList DMList                       = PETSC_NULL;
2388264ace61SBarry Smith PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
2389264ace61SBarry Smith 
2390264ace61SBarry Smith #undef __FUNCT__
2391264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2392264ace61SBarry Smith /*@C
2393264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2394264ace61SBarry Smith 
2395264ace61SBarry Smith   Collective on DM
2396264ace61SBarry Smith 
2397264ace61SBarry Smith   Input Parameters:
2398264ace61SBarry Smith + dm     - The DM object
2399264ace61SBarry Smith - method - The name of the DM type
2400264ace61SBarry Smith 
2401264ace61SBarry Smith   Options Database Key:
2402264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2403264ace61SBarry Smith 
2404264ace61SBarry Smith   Notes:
2405e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2406264ace61SBarry Smith 
2407264ace61SBarry Smith   Level: intermediate
2408264ace61SBarry Smith 
2409264ace61SBarry Smith .keywords: DM, set, type
2410264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2411264ace61SBarry Smith @*/
24127087cfbeSBarry Smith PetscErrorCode  DMSetType(DM dm, const DMType method)
2413264ace61SBarry Smith {
2414264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2415264ace61SBarry Smith   PetscBool      match;
2416264ace61SBarry Smith   PetscErrorCode ierr;
2417264ace61SBarry Smith 
2418264ace61SBarry Smith   PetscFunctionBegin;
2419264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2420251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2421264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2422264ace61SBarry Smith 
2423264ace61SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
24244b91b6eaSBarry Smith   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2425264ace61SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2426264ace61SBarry Smith 
2427264ace61SBarry Smith   if (dm->ops->destroy) {
2428264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
2429b5c23020SJed Brown     dm->ops->destroy = PETSC_NULL;
2430264ace61SBarry Smith   }
2431264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2432264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2433264ace61SBarry Smith   PetscFunctionReturn(0);
2434264ace61SBarry Smith }
2435264ace61SBarry Smith 
2436264ace61SBarry Smith #undef __FUNCT__
2437264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2438264ace61SBarry Smith /*@C
2439264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2440264ace61SBarry Smith 
2441264ace61SBarry Smith   Not Collective
2442264ace61SBarry Smith 
2443264ace61SBarry Smith   Input Parameter:
2444264ace61SBarry Smith . dm  - The DM
2445264ace61SBarry Smith 
2446264ace61SBarry Smith   Output Parameter:
2447264ace61SBarry Smith . type - The DM type name
2448264ace61SBarry Smith 
2449264ace61SBarry Smith   Level: intermediate
2450264ace61SBarry Smith 
2451264ace61SBarry Smith .keywords: DM, get, type, name
2452264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2453264ace61SBarry Smith @*/
24547087cfbeSBarry Smith PetscErrorCode  DMGetType(DM dm, const DMType *type)
2455264ace61SBarry Smith {
2456264ace61SBarry Smith   PetscErrorCode ierr;
2457264ace61SBarry Smith 
2458264ace61SBarry Smith   PetscFunctionBegin;
2459264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2460264ace61SBarry Smith   PetscValidCharPointer(type,2);
2461264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2462264ace61SBarry Smith     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2463264ace61SBarry Smith   }
2464264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2465264ace61SBarry Smith   PetscFunctionReturn(0);
2466264ace61SBarry Smith }
2467264ace61SBarry Smith 
246867a56275SMatthew G Knepley #undef __FUNCT__
246967a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
247067a56275SMatthew G Knepley /*@C
247167a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
247267a56275SMatthew G Knepley 
247367a56275SMatthew G Knepley   Collective on DM
247467a56275SMatthew G Knepley 
247567a56275SMatthew G Knepley   Input Parameters:
247667a56275SMatthew G Knepley + dm - the DM
247767a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
247867a56275SMatthew G Knepley 
247967a56275SMatthew G Knepley   Output Parameter:
248067a56275SMatthew G Knepley . M - pointer to new DM
248167a56275SMatthew G Knepley 
248267a56275SMatthew G Knepley   Notes:
248367a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
248467a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
248567a56275SMatthew G Knepley   of the input DM.
248667a56275SMatthew G Knepley 
248767a56275SMatthew G Knepley   Level: intermediate
248867a56275SMatthew G Knepley 
248967a56275SMatthew G Knepley .seealso: DMCreate()
249067a56275SMatthew G Knepley @*/
249167a56275SMatthew G Knepley PetscErrorCode DMConvert(DM dm, const DMType newtype, DM *M)
249267a56275SMatthew G Knepley {
249367a56275SMatthew G Knepley   DM             B;
249467a56275SMatthew G Knepley   char           convname[256];
249567a56275SMatthew G Knepley   PetscBool      sametype, issame;
249667a56275SMatthew G Knepley   PetscErrorCode ierr;
249767a56275SMatthew G Knepley 
249867a56275SMatthew G Knepley   PetscFunctionBegin;
249967a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
250067a56275SMatthew G Knepley   PetscValidType(dm,1);
250167a56275SMatthew G Knepley   PetscValidPointer(M,3);
2502251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
250367a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
250467a56275SMatthew G Knepley   {
250567a56275SMatthew G Knepley     PetscErrorCode (*conv)(DM, const DMType, DM *) = PETSC_NULL;
250667a56275SMatthew G Knepley 
250767a56275SMatthew G Knepley     /*
250867a56275SMatthew G Knepley        Order of precedence:
250967a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
251067a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
251167a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
251267a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
251367a56275SMatthew G Knepley        5) Use a really basic converter.
251467a56275SMatthew G Knepley     */
251567a56275SMatthew G Knepley 
251667a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
251767a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
251867a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
251967a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
252067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
252167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
252267a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
252367a56275SMatthew G Knepley     if (conv) goto foundconv;
252467a56275SMatthew G Knepley 
252567a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
252667a56275SMatthew G Knepley     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
252767a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
252867a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
252967a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
253067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
253167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
253267a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
253367a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
253467a56275SMatthew G Knepley     if (conv) {
2535fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
253667a56275SMatthew G Knepley       goto foundconv;
253767a56275SMatthew G Knepley     }
253867a56275SMatthew G Knepley 
253967a56275SMatthew G Knepley #if 0
254067a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
254167a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2542fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
254367a56275SMatthew G Knepley     if (conv) goto foundconv;
254467a56275SMatthew G Knepley 
254567a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
254667a56275SMatthew G Knepley     if (dm->ops->convert) {
254767a56275SMatthew G Knepley       conv = dm->ops->convert;
254867a56275SMatthew G Knepley     }
254967a56275SMatthew G Knepley     if (conv) goto foundconv;
255067a56275SMatthew G Knepley #endif
255167a56275SMatthew G Knepley 
255267a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
255367a56275SMatthew G Knepley     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
255467a56275SMatthew G Knepley 
255567a56275SMatthew G Knepley     foundconv:
255667a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
255767a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
255867a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
255967a56275SMatthew G Knepley   }
256067a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
256167a56275SMatthew G Knepley   PetscFunctionReturn(0);
256267a56275SMatthew G Knepley }
2563264ace61SBarry Smith 
2564264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2565264ace61SBarry Smith 
2566264ace61SBarry Smith #undef __FUNCT__
2567264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2568264ace61SBarry Smith /*@C
2569264ace61SBarry Smith   DMRegister - See DMRegisterDynamic()
2570264ace61SBarry Smith 
2571264ace61SBarry Smith   Level: advanced
2572264ace61SBarry Smith @*/
25737087cfbeSBarry Smith PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
2574264ace61SBarry Smith {
2575264ace61SBarry Smith   char fullname[PETSC_MAX_PATH_LEN];
2576264ace61SBarry Smith   PetscErrorCode ierr;
2577264ace61SBarry Smith 
2578264ace61SBarry Smith   PetscFunctionBegin;
2579264ace61SBarry Smith   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
2580264ace61SBarry Smith   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
2581264ace61SBarry Smith   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
2582264ace61SBarry Smith   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
2583264ace61SBarry Smith   PetscFunctionReturn(0);
2584264ace61SBarry Smith }
2585264ace61SBarry Smith 
2586264ace61SBarry Smith 
2587264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2588264ace61SBarry Smith #undef __FUNCT__
2589264ace61SBarry Smith #define __FUNCT__ "DMRegisterDestroy"
2590264ace61SBarry Smith /*@C
2591264ace61SBarry Smith    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
2592264ace61SBarry Smith 
2593264ace61SBarry Smith    Not Collective
2594264ace61SBarry Smith 
2595264ace61SBarry Smith    Level: advanced
2596264ace61SBarry Smith 
2597264ace61SBarry Smith .keywords: DM, register, destroy
2598264ace61SBarry Smith .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
2599264ace61SBarry Smith @*/
26007087cfbeSBarry Smith PetscErrorCode  DMRegisterDestroy(void)
2601264ace61SBarry Smith {
2602264ace61SBarry Smith   PetscErrorCode ierr;
2603264ace61SBarry Smith 
2604264ace61SBarry Smith   PetscFunctionBegin;
2605264ace61SBarry Smith   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
2606264ace61SBarry Smith   DMRegisterAllCalled = PETSC_FALSE;
2607264ace61SBarry Smith   PetscFunctionReturn(0);
2608264ace61SBarry Smith }
260923f975d1SBarry Smith 
261023f975d1SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2611c6db04a5SJed Brown #include <mex.h>
261223f975d1SBarry Smith 
26133014e516SBarry Smith typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext;
261423f975d1SBarry Smith 
261523f975d1SBarry Smith #undef __FUNCT__
261623f975d1SBarry Smith #define __FUNCT__ "DMComputeFunction_Matlab"
261723f975d1SBarry Smith /*
261823f975d1SBarry Smith    DMComputeFunction_Matlab - Calls the function that has been set with
261923f975d1SBarry Smith                          DMSetFunctionMatlab().
262023f975d1SBarry Smith 
262123f975d1SBarry Smith    For linear problems x is null
262223f975d1SBarry Smith 
262323f975d1SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
262423f975d1SBarry Smith */
26257087cfbeSBarry Smith PetscErrorCode  DMComputeFunction_Matlab(DM dm,Vec x,Vec y)
262623f975d1SBarry Smith {
262723f975d1SBarry Smith   PetscErrorCode    ierr;
262823f975d1SBarry Smith   DMMatlabContext   *sctx;
262923f975d1SBarry Smith   int               nlhs = 1,nrhs = 4;
263023f975d1SBarry Smith   mxArray	    *plhs[1],*prhs[4];
263123f975d1SBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
263223f975d1SBarry Smith 
263323f975d1SBarry Smith   PetscFunctionBegin;
263423f975d1SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
263523f975d1SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
263623f975d1SBarry Smith   PetscCheckSameComm(dm,1,y,3);
263723f975d1SBarry Smith 
263823f975d1SBarry Smith   /* call Matlab function in ctx with arguments x and y */
26391b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
264023f975d1SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
264123f975d1SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
26423014e516SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr);
264323f975d1SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
264423f975d1SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
264523f975d1SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
264623f975d1SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
2647b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr);
264823f975d1SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
264923f975d1SBarry Smith   mxDestroyArray(prhs[0]);
265023f975d1SBarry Smith   mxDestroyArray(prhs[1]);
265123f975d1SBarry Smith   mxDestroyArray(prhs[2]);
265223f975d1SBarry Smith   mxDestroyArray(prhs[3]);
265323f975d1SBarry Smith   mxDestroyArray(plhs[0]);
265423f975d1SBarry Smith   PetscFunctionReturn(0);
265523f975d1SBarry Smith }
265623f975d1SBarry Smith 
265723f975d1SBarry Smith 
265823f975d1SBarry Smith #undef __FUNCT__
265923f975d1SBarry Smith #define __FUNCT__ "DMSetFunctionMatlab"
266023f975d1SBarry Smith /*
266123f975d1SBarry Smith    DMSetFunctionMatlab - Sets the function evaluation routine
266223f975d1SBarry Smith 
266323f975d1SBarry Smith */
26647087cfbeSBarry Smith PetscErrorCode  DMSetFunctionMatlab(DM dm,const char *func)
266523f975d1SBarry Smith {
266623f975d1SBarry Smith   PetscErrorCode    ierr;
266723f975d1SBarry Smith   DMMatlabContext   *sctx;
266823f975d1SBarry Smith 
266923f975d1SBarry Smith   PetscFunctionBegin;
2670171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
267123f975d1SBarry Smith   /* currently sctx is memory bleed */
26721b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
26733014e516SBarry Smith   if (!sctx) {
267423f975d1SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
26753014e516SBarry Smith   }
267623f975d1SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
26771b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
267823f975d1SBarry Smith   ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr);
267923f975d1SBarry Smith   PetscFunctionReturn(0);
268023f975d1SBarry Smith }
26813014e516SBarry Smith 
26823014e516SBarry Smith #undef __FUNCT__
26833014e516SBarry Smith #define __FUNCT__ "DMComputeJacobian_Matlab"
26843014e516SBarry Smith /*
26853014e516SBarry Smith    DMComputeJacobian_Matlab - Calls the function that has been set with
26863014e516SBarry Smith                          DMSetJacobianMatlab().
26873014e516SBarry Smith 
26883014e516SBarry Smith    For linear problems x is null
26893014e516SBarry Smith 
26903014e516SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
26913014e516SBarry Smith */
26927087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str)
26933014e516SBarry Smith {
26943014e516SBarry Smith   PetscErrorCode    ierr;
26953014e516SBarry Smith   DMMatlabContext   *sctx;
26963014e516SBarry Smith   int               nlhs = 2,nrhs = 5;
26973014e516SBarry Smith   mxArray	    *plhs[2],*prhs[5];
26983014e516SBarry Smith   long long int     lx = 0,lA = 0,lB = 0,ls = 0;
26993014e516SBarry Smith 
27003014e516SBarry Smith   PetscFunctionBegin;
27013014e516SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
27023014e516SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
27033014e516SBarry Smith 
2704e3c5b3baSBarry Smith   /* call MATLAB function in ctx with arguments x, A, and B */
27051b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
27063014e516SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
27073014e516SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
27083014e516SBarry Smith   ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr);
27093014e516SBarry Smith   ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr);
27103014e516SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
27113014e516SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
27123014e516SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
27133014e516SBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
27143014e516SBarry Smith   prhs[4] =  mxCreateString(sctx->jacname);
2715b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr);
2716c980e822SBarry Smith   *str    =  (MatStructure) mxGetScalar(plhs[0]);
2717c088a8dcSBarry Smith   ierr    =  (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr);
27183014e516SBarry Smith   mxDestroyArray(prhs[0]);
27193014e516SBarry Smith   mxDestroyArray(prhs[1]);
27203014e516SBarry Smith   mxDestroyArray(prhs[2]);
27213014e516SBarry Smith   mxDestroyArray(prhs[3]);
27223014e516SBarry Smith   mxDestroyArray(prhs[4]);
27233014e516SBarry Smith   mxDestroyArray(plhs[0]);
27243014e516SBarry Smith   mxDestroyArray(plhs[1]);
27253014e516SBarry Smith   PetscFunctionReturn(0);
27263014e516SBarry Smith }
27273014e516SBarry Smith 
27283014e516SBarry Smith 
27293014e516SBarry Smith #undef __FUNCT__
27303014e516SBarry Smith #define __FUNCT__ "DMSetJacobianMatlab"
27313014e516SBarry Smith /*
27323014e516SBarry Smith    DMSetJacobianMatlab - Sets the Jacobian function evaluation routine
27333014e516SBarry Smith 
27343014e516SBarry Smith */
27357087cfbeSBarry Smith PetscErrorCode  DMSetJacobianMatlab(DM dm,const char *func)
27363014e516SBarry Smith {
27373014e516SBarry Smith   PetscErrorCode    ierr;
27383014e516SBarry Smith   DMMatlabContext   *sctx;
27393014e516SBarry Smith 
27403014e516SBarry Smith   PetscFunctionBegin;
2741171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
27423014e516SBarry Smith   /* currently sctx is memory bleed */
27431b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
27443014e516SBarry Smith   if (!sctx) {
27453014e516SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
27463014e516SBarry Smith   }
27473014e516SBarry Smith   ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr);
27481b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
27493014e516SBarry Smith   ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr);
27503014e516SBarry Smith   PetscFunctionReturn(0);
27513014e516SBarry Smith }
275223f975d1SBarry Smith #endif
2753b859378eSBarry Smith 
2754b859378eSBarry Smith #undef __FUNCT__
2755b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2756b859378eSBarry Smith /*@C
2757b859378eSBarry Smith   DMLoad - Loads a DM that has been stored in binary or HDF5 format
2758b859378eSBarry Smith   with DMView().
2759b859378eSBarry Smith 
2760b859378eSBarry Smith   Collective on PetscViewer
2761b859378eSBarry Smith 
2762b859378eSBarry Smith   Input Parameters:
2763b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2764b859378eSBarry Smith            some related function before a call to DMLoad().
2765b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2766b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2767b859378eSBarry Smith 
2768b859378eSBarry Smith    Level: intermediate
2769b859378eSBarry Smith 
2770b859378eSBarry Smith   Notes:
2771b859378eSBarry Smith   Defaults to the DM DA.
2772b859378eSBarry Smith 
2773b859378eSBarry Smith   Notes for advanced users:
2774b859378eSBarry Smith   Most users should not need to know the details of the binary storage
2775b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
2776b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
2777b859378eSBarry Smith   format is
2778b859378eSBarry Smith .vb
2779b859378eSBarry Smith      has not yet been determined
2780b859378eSBarry Smith .ve
2781b859378eSBarry Smith 
2782b859378eSBarry Smith    In addition, PETSc automatically does the byte swapping for
2783b859378eSBarry Smith machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
2784b859378eSBarry Smith linux, Windows and the paragon; thus if you write your own binary
2785b859378eSBarry Smith read/write routines you have to swap the bytes; see PetscBinaryRead()
2786b859378eSBarry Smith and PetscBinaryWrite() to see how this may be done.
2787b859378eSBarry Smith 
2788b859378eSBarry Smith   Concepts: vector^loading from file
2789b859378eSBarry Smith 
2790b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2791b859378eSBarry Smith @*/
2792b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2793b859378eSBarry Smith {
2794b859378eSBarry Smith   PetscErrorCode ierr;
2795b859378eSBarry Smith 
2796b859378eSBarry Smith   PetscFunctionBegin;
2797b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2798b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
2799b859378eSBarry Smith 
2800b859378eSBarry Smith   if (!((PetscObject)newdm)->type_name) {
2801b859378eSBarry Smith     ierr = DMSetType(newdm, DMDA);CHKERRQ(ierr);
2802b859378eSBarry Smith   }
2803b859378eSBarry Smith   ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
2804b859378eSBarry Smith   PetscFunctionReturn(0);
2805b859378eSBarry Smith }
2806b859378eSBarry Smith 
28077da65231SMatthew G Knepley /******************************** FEM Support **********************************/
28087da65231SMatthew G Knepley 
28097da65231SMatthew G Knepley #undef __FUNCT__
28107da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
28117da65231SMatthew G Knepley PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
28121d47ebbbSSatish Balay   PetscInt       f;
28131b30c384SMatthew G Knepley   PetscErrorCode ierr;
28141b30c384SMatthew G Knepley 
28157da65231SMatthew G Knepley   PetscFunctionBegin;
281674778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
28171d47ebbbSSatish Balay   for(f = 0; f < len; ++f) {
281874778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
28197da65231SMatthew G Knepley   }
28207da65231SMatthew G Knepley   PetscFunctionReturn(0);
28217da65231SMatthew G Knepley }
28227da65231SMatthew G Knepley 
28237da65231SMatthew G Knepley #undef __FUNCT__
28247da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
28257da65231SMatthew G Knepley PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
28261b30c384SMatthew G Knepley   PetscInt       f, g;
28277da65231SMatthew G Knepley   PetscErrorCode ierr;
28287da65231SMatthew G Knepley 
28297da65231SMatthew G Knepley   PetscFunctionBegin;
283074778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
28311d47ebbbSSatish Balay   for(f = 0; f < rows; ++f) {
283274778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
28331d47ebbbSSatish Balay     for(g = 0; g < cols; ++g) {
283474778d6cSJed Brown       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
28357da65231SMatthew G Knepley     }
283674778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
28377da65231SMatthew G Knepley   }
28387da65231SMatthew G Knepley   PetscFunctionReturn(0);
28397da65231SMatthew G Knepley }
2840e7c4fc90SDmitry Karpeev 
2841970e74d5SMatthew G Knepley #undef __FUNCT__
2842970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalFunction"
2843970e74d5SMatthew G Knepley /*@C
2844970e74d5SMatthew G Knepley   DMGetLocalFunction - Get the local residual function from this DM
2845970e74d5SMatthew G Knepley 
2846970e74d5SMatthew G Knepley   Not collective
2847970e74d5SMatthew G Knepley 
2848970e74d5SMatthew G Knepley   Input Parameter:
2849970e74d5SMatthew G Knepley . dm - The DM
2850970e74d5SMatthew G Knepley 
2851970e74d5SMatthew G Knepley   Output Parameter:
2852970e74d5SMatthew G Knepley . lf - The local residual function
2853970e74d5SMatthew G Knepley 
2854970e74d5SMatthew G Knepley    Calling sequence of lf:
2855970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
2856970e74d5SMatthew G Knepley 
2857970e74d5SMatthew G Knepley +  snes - the SNES context
2858970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2859970e74d5SMatthew G Knepley .  f - local vector to put residual in
2860970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2861970e74d5SMatthew G Knepley 
2862970e74d5SMatthew G Knepley   Level: intermediate
2863970e74d5SMatthew G Knepley 
2864970e74d5SMatthew G Knepley .seealso DMSetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
2865970e74d5SMatthew G Knepley @*/
2866970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalFunction(DM dm, PetscErrorCode (**lf)(DM, Vec, Vec, void *))
2867970e74d5SMatthew G Knepley {
2868970e74d5SMatthew G Knepley   PetscFunctionBegin;
2869970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2870970e74d5SMatthew G Knepley   if (lf) *lf = dm->lf;
2871970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2872970e74d5SMatthew G Knepley }
2873970e74d5SMatthew G Knepley 
2874970e74d5SMatthew G Knepley #undef __FUNCT__
2875970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalFunction"
2876970e74d5SMatthew G Knepley /*@C
2877970e74d5SMatthew G Knepley   DMSetLocalFunction - Set the local residual function from this DM
2878970e74d5SMatthew G Knepley 
2879970e74d5SMatthew G Knepley   Not collective
2880970e74d5SMatthew G Knepley 
2881970e74d5SMatthew G Knepley   Input Parameters:
2882970e74d5SMatthew G Knepley + dm - The DM
2883970e74d5SMatthew G Knepley - lf - The local residual function
2884970e74d5SMatthew G Knepley 
2885970e74d5SMatthew G Knepley    Calling sequence of lf:
2886970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
2887970e74d5SMatthew G Knepley 
2888970e74d5SMatthew G Knepley +  snes - the SNES context
2889970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2890970e74d5SMatthew G Knepley .  f - local vector to put residual in
2891970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2892970e74d5SMatthew G Knepley 
2893970e74d5SMatthew G Knepley   Level: intermediate
2894970e74d5SMatthew G Knepley 
2895970e74d5SMatthew G Knepley .seealso DMGetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
2896970e74d5SMatthew G Knepley @*/
2897970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalFunction(DM dm, PetscErrorCode (*lf)(DM, Vec, Vec, void *))
2898970e74d5SMatthew G Knepley {
2899970e74d5SMatthew G Knepley   PetscFunctionBegin;
2900970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2901970e74d5SMatthew G Knepley   dm->lf = lf;
2902970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2903970e74d5SMatthew G Knepley }
2904970e74d5SMatthew G Knepley 
2905970e74d5SMatthew G Knepley #undef __FUNCT__
2906970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalJacobian"
2907970e74d5SMatthew G Knepley /*@C
2908970e74d5SMatthew G Knepley   DMGetLocalJacobian - Get the local Jacobian function from this DM
2909970e74d5SMatthew G Knepley 
2910970e74d5SMatthew G Knepley   Not collective
2911970e74d5SMatthew G Knepley 
2912970e74d5SMatthew G Knepley   Input Parameter:
2913970e74d5SMatthew G Knepley . dm - The DM
2914970e74d5SMatthew G Knepley 
2915970e74d5SMatthew G Knepley   Output Parameter:
2916970e74d5SMatthew G Knepley . lj - The local Jacobian function
2917970e74d5SMatthew G Knepley 
2918970e74d5SMatthew G Knepley    Calling sequence of lj:
2919970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
2920970e74d5SMatthew G Knepley 
2921970e74d5SMatthew G Knepley +  snes - the SNES context
2922970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2923970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
2924970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
2925970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2926970e74d5SMatthew G Knepley 
2927970e74d5SMatthew G Knepley   Level: intermediate
2928970e74d5SMatthew G Knepley 
2929970e74d5SMatthew G Knepley .seealso DMSetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
2930970e74d5SMatthew G Knepley @*/
2931970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalJacobian(DM dm, PetscErrorCode (**lj)(DM, Vec, Mat, Mat, void *))
2932970e74d5SMatthew G Knepley {
2933970e74d5SMatthew G Knepley   PetscFunctionBegin;
2934970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2935970e74d5SMatthew G Knepley   if (lj) *lj = dm->lj;
2936970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2937970e74d5SMatthew G Knepley }
2938970e74d5SMatthew G Knepley 
2939970e74d5SMatthew G Knepley #undef __FUNCT__
2940970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalJacobian"
2941970e74d5SMatthew G Knepley /*@C
2942970e74d5SMatthew G Knepley   DMSetLocalJacobian - Set the local Jacobian function from this DM
2943970e74d5SMatthew G Knepley 
2944970e74d5SMatthew G Knepley   Not collective
2945970e74d5SMatthew G Knepley 
2946970e74d5SMatthew G Knepley   Input Parameters:
2947970e74d5SMatthew G Knepley + dm - The DM
2948970e74d5SMatthew G Knepley - lj - The local Jacobian function
2949970e74d5SMatthew G Knepley 
2950970e74d5SMatthew G Knepley    Calling sequence of lj:
2951970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
2952970e74d5SMatthew G Knepley 
2953970e74d5SMatthew G Knepley +  snes - the SNES context
2954970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2955970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
2956970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
2957970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2958970e74d5SMatthew G Knepley 
2959970e74d5SMatthew G Knepley   Level: intermediate
2960970e74d5SMatthew G Knepley 
2961970e74d5SMatthew G Knepley .seealso DMGetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
2962970e74d5SMatthew G Knepley @*/
2963970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalJacobian(DM dm, PetscErrorCode (*lj)(DM, Vec, Mat,  Mat, void *))
2964970e74d5SMatthew G Knepley {
2965970e74d5SMatthew G Knepley   PetscFunctionBegin;
2966970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2967970e74d5SMatthew G Knepley   dm->lj = lj;
2968970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2969970e74d5SMatthew G Knepley }
297088ed4aceSMatthew G Knepley 
297188ed4aceSMatthew G Knepley #undef __FUNCT__
297288ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
297388ed4aceSMatthew G Knepley /*@
297488ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
297588ed4aceSMatthew G Knepley 
297688ed4aceSMatthew G Knepley   Input Parameter:
297788ed4aceSMatthew G Knepley . dm - The DM
297888ed4aceSMatthew G Knepley 
297988ed4aceSMatthew G Knepley   Output Parameter:
298088ed4aceSMatthew G Knepley . section - The PetscSection
298188ed4aceSMatthew G Knepley 
298288ed4aceSMatthew G Knepley   Level: intermediate
298388ed4aceSMatthew G Knepley 
298488ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
298588ed4aceSMatthew G Knepley 
298688ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
298788ed4aceSMatthew G Knepley @*/
298888ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) {
298988ed4aceSMatthew G Knepley   PetscFunctionBegin;
299088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
299188ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
299288ed4aceSMatthew G Knepley   *section = dm->defaultSection;
299388ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
299488ed4aceSMatthew G Knepley }
299588ed4aceSMatthew G Knepley 
299688ed4aceSMatthew G Knepley #undef __FUNCT__
299788ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
299888ed4aceSMatthew G Knepley /*@
299988ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
300088ed4aceSMatthew G Knepley 
300188ed4aceSMatthew G Knepley   Input Parameters:
300288ed4aceSMatthew G Knepley + dm - The DM
300388ed4aceSMatthew G Knepley - section - The PetscSection
300488ed4aceSMatthew G Knepley 
300588ed4aceSMatthew G Knepley   Level: intermediate
300688ed4aceSMatthew G Knepley 
300788ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
300888ed4aceSMatthew G Knepley 
300988ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
301088ed4aceSMatthew G Knepley @*/
301188ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) {
301288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
301388ed4aceSMatthew G Knepley 
301488ed4aceSMatthew G Knepley   PetscFunctionBegin;
301588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
301688ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
301788ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
301888ed4aceSMatthew G Knepley   dm->defaultSection = section;
301988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
302088ed4aceSMatthew G Knepley }
302188ed4aceSMatthew G Knepley 
302288ed4aceSMatthew G Knepley #undef __FUNCT__
302388ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
302488ed4aceSMatthew G Knepley /*@
302588ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
302688ed4aceSMatthew G Knepley 
302788ed4aceSMatthew G Knepley   Input Parameter:
302888ed4aceSMatthew G Knepley . dm - The DM
302988ed4aceSMatthew G Knepley 
303088ed4aceSMatthew G Knepley   Output Parameter:
303188ed4aceSMatthew G Knepley . section - The PetscSection
303288ed4aceSMatthew G Knepley 
303388ed4aceSMatthew G Knepley   Level: intermediate
303488ed4aceSMatthew G Knepley 
303588ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
303688ed4aceSMatthew G Knepley 
303788ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
303888ed4aceSMatthew G Knepley @*/
303988ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) {
304088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
304188ed4aceSMatthew G Knepley 
304288ed4aceSMatthew G Knepley   PetscFunctionBegin;
304388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
304488ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
304588ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
304688ed4aceSMatthew G Knepley     ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, &dm->defaultGlobalSection);CHKERRQ(ierr);
304788ed4aceSMatthew G Knepley   }
304888ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
304988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
305088ed4aceSMatthew G Knepley }
305188ed4aceSMatthew G Knepley 
305288ed4aceSMatthew G Knepley #undef __FUNCT__
305388ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
305488ed4aceSMatthew G Knepley /*@
305588ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
305688ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
305788ed4aceSMatthew G Knepley 
305888ed4aceSMatthew G Knepley   Input Parameter:
305988ed4aceSMatthew G Knepley . dm - The DM
306088ed4aceSMatthew G Knepley 
306188ed4aceSMatthew G Knepley   Output Parameter:
306288ed4aceSMatthew G Knepley . sf - The PetscSF
306388ed4aceSMatthew G Knepley 
306488ed4aceSMatthew G Knepley   Level: intermediate
306588ed4aceSMatthew G Knepley 
306688ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
306788ed4aceSMatthew G Knepley 
306888ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
306988ed4aceSMatthew G Knepley @*/
307088ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) {
307188ed4aceSMatthew G Knepley   PetscInt       nroots;
307288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
307388ed4aceSMatthew G Knepley 
307488ed4aceSMatthew G Knepley   PetscFunctionBegin;
307588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
307688ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
307788ed4aceSMatthew G Knepley   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
307888ed4aceSMatthew G Knepley   if (nroots < 0) {
307988ed4aceSMatthew G Knepley     PetscSection section, gSection;
308088ed4aceSMatthew G Knepley 
308188ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
308231ea6d37SMatthew G Knepley     if (section) {
308388ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
308488ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
308531ea6d37SMatthew G Knepley     } else {
308631ea6d37SMatthew G Knepley       *sf = PETSC_NULL;
308731ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
308831ea6d37SMatthew G Knepley     }
308988ed4aceSMatthew G Knepley   }
309088ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
309188ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
309288ed4aceSMatthew G Knepley }
309388ed4aceSMatthew G Knepley 
309488ed4aceSMatthew G Knepley #undef __FUNCT__
309588ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
309688ed4aceSMatthew G Knepley /*@
309788ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
309888ed4aceSMatthew G Knepley 
309988ed4aceSMatthew G Knepley   Input Parameters:
310088ed4aceSMatthew G Knepley + dm - The DM
310188ed4aceSMatthew G Knepley - sf - The PetscSF
310288ed4aceSMatthew G Knepley 
310388ed4aceSMatthew G Knepley   Level: intermediate
310488ed4aceSMatthew G Knepley 
310588ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
310688ed4aceSMatthew G Knepley 
310788ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
310888ed4aceSMatthew G Knepley @*/
310988ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) {
311088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
311188ed4aceSMatthew G Knepley 
311288ed4aceSMatthew G Knepley   PetscFunctionBegin;
311388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
311488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
311588ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
311688ed4aceSMatthew G Knepley   dm->defaultSF = sf;
311788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
311888ed4aceSMatthew G Knepley }
311988ed4aceSMatthew G Knepley 
312088ed4aceSMatthew G Knepley #undef __FUNCT__
312188ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
312288ed4aceSMatthew G Knepley /*@C
312388ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
312488ed4aceSMatthew G Knepley   describing the data layout.
312588ed4aceSMatthew G Knepley 
312688ed4aceSMatthew G Knepley   Input Parameters:
312788ed4aceSMatthew G Knepley + dm - The DM
312888ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
312988ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
313088ed4aceSMatthew G Knepley 
313188ed4aceSMatthew G Knepley   Level: intermediate
313288ed4aceSMatthew G Knepley 
313388ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
313488ed4aceSMatthew G Knepley @*/
313588ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
313688ed4aceSMatthew G Knepley {
313788ed4aceSMatthew G Knepley   MPI_Comm        comm = ((PetscObject) dm)->comm;
313888ed4aceSMatthew G Knepley   PetscLayout     layout;
313988ed4aceSMatthew G Knepley   const PetscInt *ranges;
314088ed4aceSMatthew G Knepley   PetscInt       *local;
314188ed4aceSMatthew G Knepley   PetscSFNode    *remote;
314288ed4aceSMatthew G Knepley   PetscInt        pStart, pEnd, p, nroots, nleaves, l;
314388ed4aceSMatthew G Knepley   PetscMPIInt     size, rank;
314488ed4aceSMatthew G Knepley   PetscErrorCode  ierr;
314588ed4aceSMatthew G Knepley 
314688ed4aceSMatthew G Knepley   PetscFunctionBegin;
314788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
314888ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
314988ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
315088ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
315188ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
315288ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
315388ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
315488ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
315588ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
315688ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
315788ed4aceSMatthew G Knepley   for(p = pStart, nleaves = 0; p < pEnd; ++p) {
315888ed4aceSMatthew G Knepley     PetscInt dof, cdof;
315988ed4aceSMatthew G Knepley 
316088ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &dof);CHKERRQ(ierr);
316188ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &cdof);CHKERRQ(ierr);
316288ed4aceSMatthew G Knepley     nleaves += dof < 0 ? -(dof+1)-cdof : dof-cdof;
316388ed4aceSMatthew G Knepley   }
316488ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr);
316588ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr);
316688ed4aceSMatthew G Knepley   for(p = pStart, l = 0; p < pEnd; ++p) {
316788ed4aceSMatthew G Knepley     PetscInt *cind;
316888ed4aceSMatthew G Knepley     PetscInt  dof, gdof, cdof, dim, off, goff, d, c;
316988ed4aceSMatthew G Knepley 
317088ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
317188ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
317288ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
317388ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
317488ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
317588ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
317688ed4aceSMatthew G Knepley     dim  = dof-cdof;
317788ed4aceSMatthew G Knepley     for(d = 0, c = 0; d < dof; ++d) {
317888ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
317988ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
318088ed4aceSMatthew G Knepley     }
318188ed4aceSMatthew G Knepley     if (gdof < 0) {
318288ed4aceSMatthew G Knepley       for(d = 0; d < dim; ++d, ++l) {
318388ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
318488ed4aceSMatthew G Knepley 
318588ed4aceSMatthew G Knepley         for(r = 0; r < size; ++r) {
318688ed4aceSMatthew G Knepley           if ((offset >= ranges[r]) && (offset < ranges[r+1])) break;
318788ed4aceSMatthew G Knepley         }
318888ed4aceSMatthew G Knepley         remote[l].rank  = r;
318988ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
319088ed4aceSMatthew G Knepley       }
319188ed4aceSMatthew G Knepley     } else {
319288ed4aceSMatthew G Knepley       for(d = 0; d < dim; ++d, ++l) {
319388ed4aceSMatthew G Knepley         remote[l].rank  = rank;
319488ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
319588ed4aceSMatthew G Knepley       }
319688ed4aceSMatthew G Knepley     }
319788ed4aceSMatthew G Knepley   }
319888ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
319988ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
320088ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
320188ed4aceSMatthew G Knepley }
3202