xref: /petsc/src/dm/interface/dm.c (revision 731c8d9e1f9f91f39c4b0b5997034d833e57f8f6)
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 
45a89ea682SMatthew G Knepley   v->workSize     = 0;
46a89ea682SMatthew G Knepley   v->workArray    = PETSC_NULL;
471411c6eeSJed Brown   v->ltogmap      = PETSC_NULL;
481411c6eeSJed Brown   v->ltogmapb     = PETSC_NULL;
491411c6eeSJed Brown   v->bs           = 1;
50171400e9SBarry Smith   v->coloringtype = IS_COLORING_GLOBAL;
51970e74d5SMatthew G Knepley   v->lf           = PETSC_NULL;
52970e74d5SMatthew G Knepley   v->lj           = PETSC_NULL;
5388ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
5488ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
5588ed4aceSMatthew G Knepley   v->defaultSection       = PETSC_NULL;
5688ed4aceSMatthew G Knepley   v->defaultGlobalSection = PETSC_NULL;
571411c6eeSJed Brown 
581411c6eeSJed Brown   *dm = v;
59a4121054SBarry Smith   PetscFunctionReturn(0);
60a4121054SBarry Smith }
61a4121054SBarry Smith 
62a4121054SBarry Smith 
63a4121054SBarry Smith #undef __FUNCT__
649a42bb27SBarry Smith #define __FUNCT__ "DMSetVecType"
659a42bb27SBarry Smith /*@C
66564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
679a42bb27SBarry Smith 
68aa219208SBarry Smith    Logically Collective on DMDA
699a42bb27SBarry Smith 
709a42bb27SBarry Smith    Input Parameter:
719a42bb27SBarry Smith +  da - initial distributed array
728154be41SBarry Smith .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
739a42bb27SBarry Smith 
749a42bb27SBarry Smith    Options Database:
75dd85299cSBarry Smith .   -dm_vec_type ctype
769a42bb27SBarry Smith 
779a42bb27SBarry Smith    Level: intermediate
789a42bb27SBarry Smith 
79aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
809a42bb27SBarry Smith @*/
817087cfbeSBarry Smith PetscErrorCode  DMSetVecType(DM da,const VecType ctype)
829a42bb27SBarry Smith {
839a42bb27SBarry Smith   PetscErrorCode ierr;
849a42bb27SBarry Smith 
859a42bb27SBarry Smith   PetscFunctionBegin;
869a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
879a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
889a42bb27SBarry Smith   ierr = PetscStrallocpy(ctype,&da->vectype);CHKERRQ(ierr);
899a42bb27SBarry Smith   PetscFunctionReturn(0);
909a42bb27SBarry Smith }
919a42bb27SBarry Smith 
929a42bb27SBarry Smith #undef __FUNCT__
93521d9a4cSLisandro Dalcin #define __FUNCT__ "DMSetMatType"
94521d9a4cSLisandro Dalcin /*@C
95521d9a4cSLisandro Dalcin        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
96521d9a4cSLisandro Dalcin 
97521d9a4cSLisandro Dalcin    Logically Collective on DM
98521d9a4cSLisandro Dalcin 
99521d9a4cSLisandro Dalcin    Input Parameter:
100521d9a4cSLisandro Dalcin +  dm - the DM context
101521d9a4cSLisandro Dalcin .  ctype - the matrix type
102521d9a4cSLisandro Dalcin 
103521d9a4cSLisandro Dalcin    Options Database:
104521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
105521d9a4cSLisandro Dalcin 
106521d9a4cSLisandro Dalcin    Level: intermediate
107521d9a4cSLisandro Dalcin 
108521d9a4cSLisandro Dalcin .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType
109521d9a4cSLisandro Dalcin @*/
110521d9a4cSLisandro Dalcin PetscErrorCode  DMSetMatType(DM dm,const MatType ctype)
111521d9a4cSLisandro Dalcin {
112521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
113521d9a4cSLisandro Dalcin   PetscFunctionBegin;
114521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
115521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
116521d9a4cSLisandro Dalcin   ierr = PetscStrallocpy(ctype,&dm->mattype);CHKERRQ(ierr);
117521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
118521d9a4cSLisandro Dalcin }
119521d9a4cSLisandro Dalcin 
120521d9a4cSLisandro Dalcin #undef __FUNCT__
1219a42bb27SBarry Smith #define __FUNCT__ "DMSetOptionsPrefix"
1229a42bb27SBarry Smith /*@C
1239a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
124aa219208SBarry Smith    DMDA options in the database.
1259a42bb27SBarry Smith 
126aa219208SBarry Smith    Logically Collective on DMDA
1279a42bb27SBarry Smith 
1289a42bb27SBarry Smith    Input Parameter:
129aa219208SBarry Smith +  da - the DMDA context
1309a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
1319a42bb27SBarry Smith 
1329a42bb27SBarry Smith    Notes:
1339a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
1349a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
1359a42bb27SBarry Smith 
1369a42bb27SBarry Smith    Level: advanced
1379a42bb27SBarry Smith 
138aa219208SBarry Smith .keywords: DMDA, set, options, prefix, database
1399a42bb27SBarry Smith 
1409a42bb27SBarry Smith .seealso: DMSetFromOptions()
1419a42bb27SBarry Smith @*/
1427087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
1439a42bb27SBarry Smith {
1449a42bb27SBarry Smith   PetscErrorCode ierr;
1459a42bb27SBarry Smith 
1469a42bb27SBarry Smith   PetscFunctionBegin;
1479a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1489a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
1499a42bb27SBarry Smith   PetscFunctionReturn(0);
1509a42bb27SBarry Smith }
1519a42bb27SBarry Smith 
1529a42bb27SBarry Smith #undef __FUNCT__
15347c6ae99SBarry Smith #define __FUNCT__ "DMDestroy"
15447c6ae99SBarry Smith /*@
155aa219208SBarry Smith     DMDestroy - Destroys a vector packer or DMDA.
15647c6ae99SBarry Smith 
15747c6ae99SBarry Smith     Collective on DM
15847c6ae99SBarry Smith 
15947c6ae99SBarry Smith     Input Parameter:
16047c6ae99SBarry Smith .   dm - the DM object to destroy
16147c6ae99SBarry Smith 
16247c6ae99SBarry Smith     Level: developer
16347c6ae99SBarry Smith 
164e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
16547c6ae99SBarry Smith 
16647c6ae99SBarry Smith @*/
167fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
16847c6ae99SBarry Smith {
169732e2eb9SMatthew G Knepley   PetscInt       i, cnt = 0;
170dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
17147c6ae99SBarry Smith   PetscErrorCode ierr;
17247c6ae99SBarry Smith 
17347c6ae99SBarry Smith   PetscFunctionBegin;
1746bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
1756bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
17687e657c6SBarry Smith 
17787e657c6SBarry Smith   /* count all the circular references of DM and its contained Vecs */
178732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
1796bf464f9SBarry Smith     if ((*dm)->localin[i])  {cnt++;}
1806bf464f9SBarry Smith     if ((*dm)->globalin[i]) {cnt++;}
181732e2eb9SMatthew G Knepley   }
182dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++;
18371cd77b2SBarry Smith   if ((*dm)->x) {
18471cd77b2SBarry Smith     PetscObject obj;
18571cd77b2SBarry Smith     ierr = PetscObjectQuery((PetscObject)(*dm)->x,"DM",&obj);CHKERRQ(ierr);
18671cd77b2SBarry Smith     if (obj == (PetscObject)*dm) cnt++;
18771cd77b2SBarry Smith   }
188732e2eb9SMatthew G Knepley 
1896bf464f9SBarry Smith   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
190732e2eb9SMatthew G Knepley   /*
191732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
192732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
193732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
194732e2eb9SMatthew G Knepley   */
1956bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
1966bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
197732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
1986bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
1996bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
200732e2eb9SMatthew G Knepley   }
201dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nnext) { /* Destroy the named vectors */
202dfe15315SJed Brown     nnext = nlink->next;
203dfe15315SJed 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);
204dfe15315SJed Brown     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
205dfe15315SJed Brown     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
206dfe15315SJed Brown     ierr = PetscFree(nlink);CHKERRQ(ierr);
207dfe15315SJed Brown   }
208dfe15315SJed Brown   (*dm)->namedglobal = PETSC_NULL;
2091a266240SBarry Smith 
210b17ce1afSJed Brown   /* Destroy the list of hooks */
211c833c3b5SJed Brown   {
212c833c3b5SJed Brown     DMCoarsenHookLink link,next;
213b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
214b17ce1afSJed Brown       next = link->next;
215b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
216b17ce1afSJed Brown     }
217b17ce1afSJed Brown     (*dm)->coarsenhook = PETSC_NULL;
218c833c3b5SJed Brown   }
219c833c3b5SJed Brown   {
220c833c3b5SJed Brown     DMRefineHookLink link,next;
221c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
222c833c3b5SJed Brown       next = link->next;
223c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
224c833c3b5SJed Brown     }
225c833c3b5SJed Brown     (*dm)->refinehook = PETSC_NULL;
226c833c3b5SJed Brown   }
227b17ce1afSJed Brown 
2281a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
2291a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
2301a266240SBarry Smith   }
23187e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
23271cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
2334dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
2346bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
2356bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr);
2366bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
237073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
238a89ea682SMatthew G Knepley   ierr = PetscFree((*dm)->workArray);CHKERRQ(ierr);
23988ed4aceSMatthew G Knepley 
24088ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
24188ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
24288ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
24388ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
244732e2eb9SMatthew G Knepley   /* if memory was published with AMS then destroy it */
2456bf464f9SBarry Smith   ierr = PetscObjectDepublish(*dm);CHKERRQ(ierr);
246732e2eb9SMatthew G Knepley 
247*731c8d9eSDmitry Karpeev   ierr = DMDestroy(&(*dm)->ambientdm);    CHKERRQ(ierr);
248*731c8d9eSDmitry Karpeev   ierr = ISDestroy(&(*dm)->embedding); CHKERRQ(ierr);
249*731c8d9eSDmitry Karpeev 
2506bf464f9SBarry Smith   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
2516bf464f9SBarry Smith   ierr = PetscFree((*dm)->data);CHKERRQ(ierr);
252732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
25347c6ae99SBarry Smith   PetscFunctionReturn(0);
25447c6ae99SBarry Smith }
25547c6ae99SBarry Smith 
25647c6ae99SBarry Smith #undef __FUNCT__
257d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp"
258d7bf68aeSBarry Smith /*@
259d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
260d7bf68aeSBarry Smith 
261d7bf68aeSBarry Smith     Collective on DM
262d7bf68aeSBarry Smith 
263d7bf68aeSBarry Smith     Input Parameter:
264d7bf68aeSBarry Smith .   dm - the DM object to setup
265d7bf68aeSBarry Smith 
266d7bf68aeSBarry Smith     Level: developer
267d7bf68aeSBarry Smith 
268e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
269d7bf68aeSBarry Smith 
270d7bf68aeSBarry Smith @*/
2717087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
272d7bf68aeSBarry Smith {
273d7bf68aeSBarry Smith   PetscErrorCode ierr;
274d7bf68aeSBarry Smith 
275d7bf68aeSBarry Smith   PetscFunctionBegin;
276171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2778387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
278d7bf68aeSBarry Smith   if (dm->ops->setup) {
279d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
280d7bf68aeSBarry Smith   }
2818387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
282d7bf68aeSBarry Smith   PetscFunctionReturn(0);
283d7bf68aeSBarry Smith }
284d7bf68aeSBarry Smith 
285d7bf68aeSBarry Smith #undef __FUNCT__
286d7bf68aeSBarry Smith #define __FUNCT__ "DMSetFromOptions"
287d7bf68aeSBarry Smith /*@
288d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
289d7bf68aeSBarry Smith 
290d7bf68aeSBarry Smith     Collective on DM
291d7bf68aeSBarry Smith 
292d7bf68aeSBarry Smith     Input Parameter:
293d7bf68aeSBarry Smith .   dm - the DM object to set options for
294d7bf68aeSBarry Smith 
295732e2eb9SMatthew G Knepley     Options Database:
296dd85299cSBarry Smith +   -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
297dd85299cSBarry Smith .   -dm_vec_type <type>  type of vector to create inside DM
298171400e9SBarry Smith .   -dm_mat_type <type>  type of matrix to create inside DM
299171400e9SBarry Smith -   -dm_coloring_type <global or ghosted>
300732e2eb9SMatthew G Knepley 
301d7bf68aeSBarry Smith     Level: developer
302d7bf68aeSBarry Smith 
303e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
304d7bf68aeSBarry Smith 
305d7bf68aeSBarry Smith @*/
3067087cfbeSBarry Smith PetscErrorCode  DMSetFromOptions(DM dm)
307d7bf68aeSBarry Smith {
30867ad5babSMatthew G Knepley   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg;
309d7bf68aeSBarry Smith   PetscErrorCode ierr;
310f9ba7244SBarry Smith   char           typeName[256] = MATAIJ;
311d7bf68aeSBarry Smith 
312d7bf68aeSBarry Smith   PetscFunctionBegin;
313171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3143194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
31582fcb398SMatthew G Knepley     ierr = PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);CHKERRQ(ierr);
316c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_detail", "Exhaustive mesh description", "DMView", flg2, &flg2, PETSC_NULL);CHKERRQ(ierr);
317c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_vtk", "Output mesh in VTK format", "DMView", flg3, &flg3, PETSC_NULL);CHKERRQ(ierr);
31867ad5babSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_latex", "Output mesh in LaTeX TikZ format", "DMView", flg4, &flg4, PETSC_NULL);CHKERRQ(ierr);
319073dac72SJed 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);
320f9ba7244SBarry Smith     ierr = PetscOptionsList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
321f9ba7244SBarry Smith     if (flg) {
322f9ba7244SBarry Smith       ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
323f9ba7244SBarry Smith     }
324521d9a4cSLisandro 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);
325073dac72SJed Brown     if (flg) {
326521d9a4cSLisandro Dalcin       ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
327073dac72SJed Brown     }
3281b89239cSHong 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);
329f9ba7244SBarry Smith     if (dm->ops->setfromoptions) {
330f9ba7244SBarry Smith       ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr);
331f9ba7244SBarry Smith     }
332f9ba7244SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
333f9ba7244SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
33482fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
33582fcb398SMatthew G Knepley   if (flg1) {
33682fcb398SMatthew G Knepley     ierr = DMView(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
33782fcb398SMatthew G Knepley   }
338c4721b0eSMatthew G Knepley   if (flg2) {
339c4721b0eSMatthew G Knepley     PetscViewer viewer;
340c4721b0eSMatthew G Knepley 
341c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
342c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
343c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
344c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
345c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
346c4721b0eSMatthew G Knepley   }
347c4721b0eSMatthew G Knepley   if (flg3) {
348c4721b0eSMatthew G Knepley     PetscViewer viewer;
349c4721b0eSMatthew G Knepley 
350c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
351c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
352c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);
353c4721b0eSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.vtk");CHKERRQ(ierr);
354c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
355c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
356c4721b0eSMatthew G Knepley   }
35767ad5babSMatthew G Knepley   if (flg4) {
35867ad5babSMatthew G Knepley     PetscViewer viewer;
35967ad5babSMatthew G Knepley 
36067ad5babSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
36167ad5babSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
36267ad5babSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_LATEX);CHKERRQ(ierr);
36367ad5babSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.tex");CHKERRQ(ierr);
36467ad5babSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
36567ad5babSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
36667ad5babSMatthew G Knepley   }
367d7bf68aeSBarry Smith   PetscFunctionReturn(0);
368d7bf68aeSBarry Smith }
369d7bf68aeSBarry Smith 
370d7bf68aeSBarry Smith #undef __FUNCT__
37147c6ae99SBarry Smith #define __FUNCT__ "DMView"
372fc9bc008SSatish Balay /*@C
373aa219208SBarry Smith     DMView - Views a vector packer or DMDA.
37447c6ae99SBarry Smith 
37547c6ae99SBarry Smith     Collective on DM
37647c6ae99SBarry Smith 
37747c6ae99SBarry Smith     Input Parameter:
37847c6ae99SBarry Smith +   dm - the DM object to view
37947c6ae99SBarry Smith -   v - the viewer
38047c6ae99SBarry Smith 
38147c6ae99SBarry Smith     Level: developer
38247c6ae99SBarry Smith 
383e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
38447c6ae99SBarry Smith 
38547c6ae99SBarry Smith @*/
3867087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
38747c6ae99SBarry Smith {
38847c6ae99SBarry Smith   PetscErrorCode ierr;
38947c6ae99SBarry Smith 
39047c6ae99SBarry Smith   PetscFunctionBegin;
391171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3923014e516SBarry Smith  if (!v) {
3933014e516SBarry Smith     ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr);
3943014e516SBarry Smith   }
3950c010503SBarry Smith   if (dm->ops->view) {
3960c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
39747c6ae99SBarry Smith   }
39847c6ae99SBarry Smith   PetscFunctionReturn(0);
39947c6ae99SBarry Smith }
40047c6ae99SBarry Smith 
40147c6ae99SBarry Smith #undef __FUNCT__
40247c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
40347c6ae99SBarry Smith /*@
404aa219208SBarry Smith     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
40547c6ae99SBarry Smith 
40647c6ae99SBarry Smith     Collective on DM
40747c6ae99SBarry Smith 
40847c6ae99SBarry Smith     Input Parameter:
40947c6ae99SBarry Smith .   dm - the DM object
41047c6ae99SBarry Smith 
41147c6ae99SBarry Smith     Output Parameter:
41247c6ae99SBarry Smith .   vec - the global vector
41347c6ae99SBarry Smith 
414073dac72SJed Brown     Level: beginner
41547c6ae99SBarry Smith 
416e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
41747c6ae99SBarry Smith 
41847c6ae99SBarry Smith @*/
4197087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
42047c6ae99SBarry Smith {
42147c6ae99SBarry Smith   PetscErrorCode ierr;
42247c6ae99SBarry Smith 
42347c6ae99SBarry Smith   PetscFunctionBegin;
424171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
42588ed4aceSMatthew G Knepley   if (dm->defaultSection) {
42688ed4aceSMatthew G Knepley     PetscSection gSection;
42788ed4aceSMatthew G Knepley     PetscInt     localSize;
42888ed4aceSMatthew G Knepley 
42988ed4aceSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
43088ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr);
43188ed4aceSMatthew G Knepley     ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr);
43288ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
43388ed4aceSMatthew G Knepley     /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */
43488ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
43588ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
43688ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */
43788ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */
43888ed4aceSMatthew G Knepley     /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */
43988ed4aceSMatthew G Knepley   } else {
44047c6ae99SBarry Smith     ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
44188ed4aceSMatthew G Knepley   }
44247c6ae99SBarry Smith   PetscFunctionReturn(0);
44347c6ae99SBarry Smith }
44447c6ae99SBarry Smith 
44547c6ae99SBarry Smith #undef __FUNCT__
44647c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
44747c6ae99SBarry Smith /*@
448aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
44947c6ae99SBarry Smith 
45047c6ae99SBarry Smith     Not Collective
45147c6ae99SBarry Smith 
45247c6ae99SBarry Smith     Input Parameter:
45347c6ae99SBarry Smith .   dm - the DM object
45447c6ae99SBarry Smith 
45547c6ae99SBarry Smith     Output Parameter:
45647c6ae99SBarry Smith .   vec - the local vector
45747c6ae99SBarry Smith 
458073dac72SJed Brown     Level: beginner
45947c6ae99SBarry Smith 
460e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
46147c6ae99SBarry Smith 
46247c6ae99SBarry Smith @*/
4637087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
46447c6ae99SBarry Smith {
46547c6ae99SBarry Smith   PetscErrorCode ierr;
46647c6ae99SBarry Smith 
46747c6ae99SBarry Smith   PetscFunctionBegin;
468171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
46988ed4aceSMatthew G Knepley   if (dm->defaultSection) {
47088ed4aceSMatthew G Knepley     PetscInt localSize;
47188ed4aceSMatthew G Knepley 
47288ed4aceSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr);
47388ed4aceSMatthew G Knepley     ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr);
47488ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr);
47588ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
47688ed4aceSMatthew G Knepley     ierr = PetscObjectCompose((PetscObject) *vec, "DM", (PetscObject) dm);CHKERRQ(ierr);
47788ed4aceSMatthew G Knepley   } else {
47847c6ae99SBarry Smith     ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
47988ed4aceSMatthew G Knepley   }
48047c6ae99SBarry Smith   PetscFunctionReturn(0);
48147c6ae99SBarry Smith }
48247c6ae99SBarry Smith 
48347c6ae99SBarry Smith #undef __FUNCT__
4841411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
4851411c6eeSJed Brown /*@
4861411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
4871411c6eeSJed Brown 
4881411c6eeSJed Brown    Collective on DM
4891411c6eeSJed Brown 
4901411c6eeSJed Brown    Input Parameter:
4911411c6eeSJed Brown .  dm - the DM that provides the mapping
4921411c6eeSJed Brown 
4931411c6eeSJed Brown    Output Parameter:
4941411c6eeSJed Brown .  ltog - the mapping
4951411c6eeSJed Brown 
4961411c6eeSJed Brown    Level: intermediate
4971411c6eeSJed Brown 
4981411c6eeSJed Brown    Notes:
4991411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
5001411c6eeSJed Brown    MatSetLocalToGlobalMapping().
5011411c6eeSJed Brown 
5021411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
5031411c6eeSJed Brown @*/
5047087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
5051411c6eeSJed Brown {
5061411c6eeSJed Brown   PetscErrorCode ierr;
5071411c6eeSJed Brown 
5081411c6eeSJed Brown   PetscFunctionBegin;
5091411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5101411c6eeSJed Brown   PetscValidPointer(ltog,2);
5111411c6eeSJed Brown   if (!dm->ltogmap) {
51237d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
51337d0c07bSMatthew G Knepley 
51437d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
51537d0c07bSMatthew G Knepley     if (section) {
51637d0c07bSMatthew G Knepley       PetscInt      *ltog;
51737d0c07bSMatthew G Knepley       PetscInt       pStart, pEnd, size, p, l;
51837d0c07bSMatthew G Knepley 
51937d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
52037d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
52137d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
52237d0c07bSMatthew G Knepley       ierr = PetscMalloc(size * sizeof(PetscInt), &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
52337d0c07bSMatthew G Knepley       for(p = pStart, l = 0; p < pEnd; ++p) {
52437d0c07bSMatthew G Knepley         PetscInt dof, off, c;
52537d0c07bSMatthew G Knepley 
52637d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
52737d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
52837d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
52937d0c07bSMatthew G Knepley         for(c = 0; c < dof; ++c, ++l) {
53037d0c07bSMatthew G Knepley           ltog[l] = off+c;
53137d0c07bSMatthew G Knepley         }
53237d0c07bSMatthew G Knepley       }
53337d0c07bSMatthew G Knepley       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
53437d0c07bSMatthew G Knepley       ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr);
53537d0c07bSMatthew G Knepley     } else {
5361411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
5371411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
5381411c6eeSJed Brown     }
53937d0c07bSMatthew G Knepley   }
5401411c6eeSJed Brown   *ltog = dm->ltogmap;
5411411c6eeSJed Brown   PetscFunctionReturn(0);
5421411c6eeSJed Brown }
5431411c6eeSJed Brown 
5441411c6eeSJed Brown #undef __FUNCT__
5451411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
5461411c6eeSJed Brown /*@
5471411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
5481411c6eeSJed Brown 
5491411c6eeSJed Brown    Collective on DM
5501411c6eeSJed Brown 
5511411c6eeSJed Brown    Input Parameter:
5521411c6eeSJed Brown .  da - the distributed array that provides the mapping
5531411c6eeSJed Brown 
5541411c6eeSJed Brown    Output Parameter:
5551411c6eeSJed Brown .  ltog - the block mapping
5561411c6eeSJed Brown 
5571411c6eeSJed Brown    Level: intermediate
5581411c6eeSJed Brown 
5591411c6eeSJed Brown    Notes:
5601411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
5611411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
5621411c6eeSJed Brown 
5631411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
5641411c6eeSJed Brown @*/
5657087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
5661411c6eeSJed Brown {
5671411c6eeSJed Brown   PetscErrorCode ierr;
5681411c6eeSJed Brown 
5691411c6eeSJed Brown   PetscFunctionBegin;
5701411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5711411c6eeSJed Brown   PetscValidPointer(ltog,2);
5721411c6eeSJed Brown   if (!dm->ltogmapb) {
5731411c6eeSJed Brown     PetscInt bs;
5741411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
5751411c6eeSJed Brown     if (bs > 1) {
5761411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
5771411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
5781411c6eeSJed Brown     } else {
5791411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
5801411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
5811411c6eeSJed Brown     }
5821411c6eeSJed Brown   }
5831411c6eeSJed Brown   *ltog = dm->ltogmapb;
5841411c6eeSJed Brown   PetscFunctionReturn(0);
5851411c6eeSJed Brown }
5861411c6eeSJed Brown 
5871411c6eeSJed Brown #undef __FUNCT__
5881411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
5891411c6eeSJed Brown /*@
5901411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
5911411c6eeSJed Brown 
5921411c6eeSJed Brown    Not Collective
5931411c6eeSJed Brown 
5941411c6eeSJed Brown    Input Parameter:
5951411c6eeSJed Brown .  dm - the DM with block structure
5961411c6eeSJed Brown 
5971411c6eeSJed Brown    Output Parameter:
5981411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
5991411c6eeSJed Brown 
6001411c6eeSJed Brown    Level: intermediate
6011411c6eeSJed Brown 
6021411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
6031411c6eeSJed Brown @*/
6047087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
6051411c6eeSJed Brown {
6061411c6eeSJed Brown   PetscFunctionBegin;
6071411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6081411c6eeSJed Brown   PetscValidPointer(bs,2);
6091411c6eeSJed 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");
6101411c6eeSJed Brown   *bs = dm->bs;
6111411c6eeSJed Brown   PetscFunctionReturn(0);
6121411c6eeSJed Brown }
6131411c6eeSJed Brown 
6141411c6eeSJed Brown #undef __FUNCT__
615e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
61647c6ae99SBarry Smith /*@
617e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
61847c6ae99SBarry Smith 
61947c6ae99SBarry Smith     Collective on DM
62047c6ae99SBarry Smith 
62147c6ae99SBarry Smith     Input Parameter:
62247c6ae99SBarry Smith +   dm1 - the DM object
62347c6ae99SBarry Smith -   dm2 - the second, finer DM object
62447c6ae99SBarry Smith 
62547c6ae99SBarry Smith     Output Parameter:
62647c6ae99SBarry Smith +  mat - the interpolation
62747c6ae99SBarry Smith -  vec - the scaling (optional)
62847c6ae99SBarry Smith 
62947c6ae99SBarry Smith     Level: developer
63047c6ae99SBarry Smith 
63185afcc9aSBarry 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
63285afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
633d52bd9f3SBarry Smith 
634d52bd9f3SBarry Smith         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMDAGetCoordinateDA()) to interpolate the mesh coordinate vectors
635d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
63685afcc9aSBarry Smith 
63785afcc9aSBarry Smith 
638e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
63947c6ae99SBarry Smith 
64047c6ae99SBarry Smith @*/
641e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
64247c6ae99SBarry Smith {
64347c6ae99SBarry Smith   PetscErrorCode ierr;
64447c6ae99SBarry Smith 
64547c6ae99SBarry Smith   PetscFunctionBegin;
646171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
647171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
64825296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
64947c6ae99SBarry Smith   PetscFunctionReturn(0);
65047c6ae99SBarry Smith }
65147c6ae99SBarry Smith 
65247c6ae99SBarry Smith #undef __FUNCT__
653e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
65447c6ae99SBarry Smith /*@
655e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
65647c6ae99SBarry Smith 
65747c6ae99SBarry Smith     Collective on DM
65847c6ae99SBarry Smith 
65947c6ae99SBarry Smith     Input Parameter:
66047c6ae99SBarry Smith +   dm1 - the DM object
66147c6ae99SBarry Smith -   dm2 - the second, finer DM object
66247c6ae99SBarry Smith 
66347c6ae99SBarry Smith     Output Parameter:
66447c6ae99SBarry Smith .   ctx - the injection
66547c6ae99SBarry Smith 
66647c6ae99SBarry Smith     Level: developer
66747c6ae99SBarry Smith 
66885afcc9aSBarry 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
66985afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
67085afcc9aSBarry Smith 
671e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
67247c6ae99SBarry Smith 
67347c6ae99SBarry Smith @*/
674e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
67547c6ae99SBarry Smith {
67647c6ae99SBarry Smith   PetscErrorCode ierr;
67747c6ae99SBarry Smith 
67847c6ae99SBarry Smith   PetscFunctionBegin;
679171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
680171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
68147c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
68247c6ae99SBarry Smith   PetscFunctionReturn(0);
68347c6ae99SBarry Smith }
68447c6ae99SBarry Smith 
68547c6ae99SBarry Smith #undef __FUNCT__
686e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
687d1e2c406SBarry Smith /*@C
688e727c939SJed Brown     DMCreateColoring - Gets coloring for a DMDA or DMComposite
68947c6ae99SBarry Smith 
69047c6ae99SBarry Smith     Collective on DM
69147c6ae99SBarry Smith 
69247c6ae99SBarry Smith     Input Parameter:
69347c6ae99SBarry Smith +   dm - the DM object
69447c6ae99SBarry Smith .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
69547c6ae99SBarry Smith -   matype - either MATAIJ or MATBAIJ
69647c6ae99SBarry Smith 
69747c6ae99SBarry Smith     Output Parameter:
69847c6ae99SBarry Smith .   coloring - the coloring
69947c6ae99SBarry Smith 
70047c6ae99SBarry Smith     Level: developer
70147c6ae99SBarry Smith 
702e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
70347c6ae99SBarry Smith 
704aab9d709SJed Brown @*/
705e727c939SJed Brown PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring)
70647c6ae99SBarry Smith {
70747c6ae99SBarry Smith   PetscErrorCode ierr;
70847c6ae99SBarry Smith 
70947c6ae99SBarry Smith   PetscFunctionBegin;
710171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
71147c6ae99SBarry Smith   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
71247c6ae99SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
71347c6ae99SBarry Smith   PetscFunctionReturn(0);
71447c6ae99SBarry Smith }
71547c6ae99SBarry Smith 
71647c6ae99SBarry Smith #undef __FUNCT__
717950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
71847c6ae99SBarry Smith /*@C
719950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
72047c6ae99SBarry Smith 
72147c6ae99SBarry Smith     Collective on DM
72247c6ae99SBarry Smith 
72347c6ae99SBarry Smith     Input Parameter:
72447c6ae99SBarry Smith +   dm - the DM object
72547c6ae99SBarry Smith -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
72694013140SBarry Smith             any type which inherits from one of these (such as MATAIJ)
72747c6ae99SBarry Smith 
72847c6ae99SBarry Smith     Output Parameter:
72947c6ae99SBarry Smith .   mat - the empty Jacobian
73047c6ae99SBarry Smith 
731073dac72SJed Brown     Level: beginner
73247c6ae99SBarry Smith 
73394013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
73494013140SBarry Smith        do not need to do it yourself.
73594013140SBarry Smith 
73694013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
737aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
73894013140SBarry Smith 
73994013140SBarry 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
74094013140SBarry Smith        internally by PETSc.
74194013140SBarry Smith 
74294013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
743aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
74494013140SBarry Smith 
745e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
74647c6ae99SBarry Smith 
747aab9d709SJed Brown @*/
748950540a4SJed Brown PetscErrorCode  DMCreateMatrix(DM dm,const MatType mtype,Mat *mat)
74947c6ae99SBarry Smith {
75047c6ae99SBarry Smith   PetscErrorCode ierr;
75147c6ae99SBarry Smith 
75247c6ae99SBarry Smith   PetscFunctionBegin;
753171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
754235683edSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
755235683edSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
756235683edSBarry Smith #endif
757c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
758c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
759073dac72SJed Brown   if (dm->mattype) {
76025296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
761073dac72SJed Brown   } else {
76225296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
763c7b7c8a4SJed Brown   }
76447c6ae99SBarry Smith   PetscFunctionReturn(0);
76547c6ae99SBarry Smith }
76647c6ae99SBarry Smith 
76747c6ae99SBarry Smith #undef __FUNCT__
768732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
769732e2eb9SMatthew G Knepley /*@
770950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
771732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
772732e2eb9SMatthew G Knepley 
773732e2eb9SMatthew G Knepley   Logically Collective on DMDA
774732e2eb9SMatthew G Knepley 
775732e2eb9SMatthew G Knepley   Input Parameter:
776732e2eb9SMatthew G Knepley + dm - the DM
777732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
778732e2eb9SMatthew G Knepley 
779732e2eb9SMatthew G Knepley   Level: developer
780950540a4SJed Brown .seealso DMCreateMatrix()
781732e2eb9SMatthew G Knepley @*/
782732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
783732e2eb9SMatthew G Knepley {
784732e2eb9SMatthew G Knepley   PetscFunctionBegin;
785732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
786732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
787732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
788732e2eb9SMatthew G Knepley }
789732e2eb9SMatthew G Knepley 
790732e2eb9SMatthew G Knepley #undef __FUNCT__
791a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
792a89ea682SMatthew G Knepley /*@C
793a89ea682SMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size
794a89ea682SMatthew G Knepley 
795a89ea682SMatthew G Knepley   Not Collective
796a89ea682SMatthew G Knepley 
797a89ea682SMatthew G Knepley   Input Parameters:
798a89ea682SMatthew G Knepley + dm - the DM object
799a89ea682SMatthew G Knepley - size - The minium size
800a89ea682SMatthew G Knepley 
801a89ea682SMatthew G Knepley   Output Parameter:
802a89ea682SMatthew G Knepley . array - the work array
803a89ea682SMatthew G Knepley 
804a89ea682SMatthew G Knepley   Level: developer
805a89ea682SMatthew G Knepley 
806a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
807a89ea682SMatthew G Knepley @*/
808a89ea682SMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt size,PetscScalar **array)
809a89ea682SMatthew G Knepley {
810a89ea682SMatthew G Knepley   PetscErrorCode ierr;
811a89ea682SMatthew G Knepley 
812a89ea682SMatthew G Knepley   PetscFunctionBegin;
813a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
814a89ea682SMatthew G Knepley   PetscValidPointer(array,3);
815a89ea682SMatthew G Knepley   if (size > dm->workSize) {
816a89ea682SMatthew G Knepley     dm->workSize = size;
817a89ea682SMatthew G Knepley     ierr = PetscFree(dm->workArray);CHKERRQ(ierr);
818a89ea682SMatthew G Knepley     ierr = PetscMalloc(dm->workSize * sizeof(PetscScalar), &dm->workArray);CHKERRQ(ierr);
819a89ea682SMatthew G Knepley   }
820a89ea682SMatthew G Knepley   *array = dm->workArray;
821a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
822a89ea682SMatthew G Knepley }
823a89ea682SMatthew G Knepley 
824e7c4fc90SDmitry Karpeev 
825e7c4fc90SDmitry Karpeev #undef __FUNCT__
8264d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
8274f3b5142SJed Brown /*@C
8284d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
8294d343eeaSMatthew G Knepley 
8304d343eeaSMatthew G Knepley   Not collective
8314d343eeaSMatthew G Knepley 
8324d343eeaSMatthew G Knepley   Input Parameter:
8334d343eeaSMatthew G Knepley . dm - the DM object
8344d343eeaSMatthew G Knepley 
8354d343eeaSMatthew G Knepley   Output Parameters:
83621c9b008SJed Brown + numFields  - The number of fields (or PETSC_NULL if not requested)
83737d0c07bSMatthew G Knepley . fieldNames - The name for each field (or PETSC_NULL if not requested)
83821c9b008SJed Brown - fields     - The global indices for each field (or PETSC_NULL if not requested)
8394d343eeaSMatthew G Knepley 
8404d343eeaSMatthew G Knepley   Level: intermediate
8414d343eeaSMatthew G Knepley 
84221c9b008SJed Brown   Notes:
84321c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
84421c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
84521c9b008SJed Brown   PetscFree().
84621c9b008SJed Brown 
8474d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
8484d343eeaSMatthew G Knepley @*/
84937d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
8504d343eeaSMatthew G Knepley {
85137d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
8524d343eeaSMatthew G Knepley   PetscErrorCode ierr;
8534d343eeaSMatthew G Knepley 
8544d343eeaSMatthew G Knepley   PetscFunctionBegin;
8554d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
85669ca1f37SDmitry Karpeev   if (numFields) {
85769ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
85869ca1f37SDmitry Karpeev     *numFields = 0;
85969ca1f37SDmitry Karpeev   }
86037d0c07bSMatthew G Knepley   if (fieldNames) {
86137d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
86237d0c07bSMatthew G Knepley     *fieldNames = PETSC_NULL;
86369ca1f37SDmitry Karpeev   }
86469ca1f37SDmitry Karpeev   if (fields) {
86569ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
86669ca1f37SDmitry Karpeev     *fields = PETSC_NULL;
86769ca1f37SDmitry Karpeev   }
86837d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
86937d0c07bSMatthew G Knepley   if (section) {
87037d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
87137d0c07bSMatthew G Knepley     PetscInt  nF, f, pStart, pEnd, p;
87237d0c07bSMatthew G Knepley 
87337d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
87437d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
87537d0c07bSMatthew G Knepley     ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr);
87637d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
87737d0c07bSMatthew G Knepley     for(f = 0; f < nF; ++f) {
87837d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
87937d0c07bSMatthew G Knepley     }
88037d0c07bSMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
88137d0c07bSMatthew G Knepley       PetscInt gdof;
88237d0c07bSMatthew G Knepley 
88337d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
88437d0c07bSMatthew G Knepley       if (gdof > 0) {
88537d0c07bSMatthew G Knepley         for(f = 0; f < nF; ++f) {
88637d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
88737d0c07bSMatthew G Knepley 
88837d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
88937d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
89037d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
89137d0c07bSMatthew G Knepley         }
89237d0c07bSMatthew G Knepley       }
89337d0c07bSMatthew G Knepley     }
89437d0c07bSMatthew G Knepley     for(f = 0; f < nF; ++f) {
89537d0c07bSMatthew G Knepley       ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr);
89637d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
89737d0c07bSMatthew G Knepley     }
89837d0c07bSMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
89937d0c07bSMatthew G Knepley       PetscInt gdof, goff;
90037d0c07bSMatthew G Knepley 
90137d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
90237d0c07bSMatthew G Knepley       if (gdof > 0) {
90337d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
90437d0c07bSMatthew G Knepley         for(f = 0; f < nF; ++f) {
90537d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
90637d0c07bSMatthew G Knepley 
90737d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
90837d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
90937d0c07bSMatthew G Knepley           for(fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
91037d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
91137d0c07bSMatthew G Knepley           }
91237d0c07bSMatthew G Knepley         }
91337d0c07bSMatthew G Knepley       }
91437d0c07bSMatthew G Knepley     }
91537d0c07bSMatthew G Knepley     if (numFields) {*numFields = nF;}
91637d0c07bSMatthew G Knepley     if (fieldNames) {
91737d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr);
91837d0c07bSMatthew G Knepley       for(f = 0; f < nF; ++f) {
91937d0c07bSMatthew G Knepley         const char *fieldName;
92037d0c07bSMatthew G Knepley 
92137d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
92237d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr);
92337d0c07bSMatthew G Knepley       }
92437d0c07bSMatthew G Knepley     }
92537d0c07bSMatthew G Knepley     if (fields) {
92637d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr);
92737d0c07bSMatthew G Knepley       for(f = 0; f < nF; ++f) {
92837d0c07bSMatthew G Knepley         ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
92937d0c07bSMatthew G Knepley       }
93037d0c07bSMatthew G Knepley     }
93137d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
93237d0c07bSMatthew G Knepley   } else {
93337d0c07bSMatthew G Knepley     if(dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);}
93469ca1f37SDmitry Karpeev   }
9354d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
9364d343eeaSMatthew G Knepley }
9374d343eeaSMatthew G Knepley 
9385fe1f584SPeter Brune 
939a89ea682SMatthew G Knepley #undef __FUNCT__
94016621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecompositionDM"
941e7c4fc90SDmitry Karpeev /*@C
94216621825SDmitry Karpeev   DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields.
94316621825SDmitry Karpeev 
94416621825SDmitry Karpeev   Not Collective
94516621825SDmitry Karpeev 
94616621825SDmitry Karpeev   Input Parameters:
94716621825SDmitry Karpeev + dm   - the DM object
94816621825SDmitry Karpeev - name - the name of the field decomposition
94916621825SDmitry Karpeev 
95016621825SDmitry Karpeev   Output Parameter:
95116621825SDmitry Karpeev . ddm  - the field decomposition DM (PETSC_NULL, if no such decomposition is known)
95216621825SDmitry Karpeev 
95316621825SDmitry Karpeev   Level: advanced
95416621825SDmitry Karpeev 
95516621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
95616621825SDmitry Karpeev @*/
95716621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm)
95816621825SDmitry Karpeev {
95916621825SDmitry Karpeev   PetscErrorCode ierr;
96016621825SDmitry Karpeev 
96116621825SDmitry Karpeev   PetscFunctionBegin;
96216621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
96316621825SDmitry Karpeev   PetscValidCharPointer(name,2);
96416621825SDmitry Karpeev   PetscValidPointer(ddm,3);
96516621825SDmitry Karpeev   *ddm = PETSC_NULL;
966*731c8d9eSDmitry Karpeev   if(dm->ops->createfielddecompositiondm) {
96716621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
96816621825SDmitry Karpeev   }
96916621825SDmitry Karpeev   PetscFunctionReturn(0);
97016621825SDmitry Karpeev }
97116621825SDmitry Karpeev 
97216621825SDmitry Karpeev 
97316621825SDmitry Karpeev #undef __FUNCT__
97416621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
97516621825SDmitry Karpeev /*@C
97616621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
97716621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
97816621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
979e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
980e7c4fc90SDmitry Karpeev 
981e7c4fc90SDmitry Karpeev   Not collective
982e7c4fc90SDmitry Karpeev 
983e7c4fc90SDmitry Karpeev   Input Parameter:
984e7c4fc90SDmitry Karpeev . dm - the DM object
985e7c4fc90SDmitry Karpeev 
986e7c4fc90SDmitry Karpeev   Output Parameters:
98716621825SDmitry Karpeev + len       - The number of subproblems in the field decomposition (or PETSC_NULL if not requested)
98816621825SDmitry Karpeev . namelist  - The name for each field (or PETSC_NULL if not requested)
98916621825SDmitry Karpeev . islist    - The global indices for each field (or PETSC_NULL if not requested)
99016621825SDmitry Karpeev - dmlist    - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
991e7c4fc90SDmitry Karpeev 
992e7c4fc90SDmitry Karpeev   Level: intermediate
993e7c4fc90SDmitry Karpeev 
994e7c4fc90SDmitry Karpeev   Notes:
995e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
996e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
997e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
998e7c4fc90SDmitry Karpeev 
999e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1000e7c4fc90SDmitry Karpeev @*/
100116621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1002e7c4fc90SDmitry Karpeev {
1003e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1004e7c4fc90SDmitry Karpeev 
1005e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1006e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1007*731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);      *len      = 0;}
1008*731c8d9eSDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;}
1009*731c8d9eSDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);   *islist   = 0;}
1010*731c8d9eSDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);   *dmlist   = 0;}
101116621825SDmitry Karpeev   if(!dm->ops->createfielddecomposition) {
101269ca1f37SDmitry Karpeev     ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1013e7c4fc90SDmitry Karpeev     /* By default there are no DMs associated with subproblems. */
1014e7c4fc90SDmitry Karpeev     if(dmlist) *dmlist = PETSC_NULL;
1015e7c4fc90SDmitry Karpeev   }
1016e7c4fc90SDmitry Karpeev   else {
101716621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
101816621825SDmitry Karpeev   }
101916621825SDmitry Karpeev   PetscFunctionReturn(0);
102016621825SDmitry Karpeev }
102116621825SDmitry Karpeev 
102216621825SDmitry Karpeev #undef __FUNCT__
102316621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecompositionDM"
102416621825SDmitry Karpeev /*@C
102516621825SDmitry Karpeev   DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains.
102616621825SDmitry Karpeev 
102716621825SDmitry Karpeev   Not Collective
102816621825SDmitry Karpeev 
102916621825SDmitry Karpeev   Input Parameters:
103016621825SDmitry Karpeev + dm   - the DM object
103116621825SDmitry Karpeev - name - the name of the subdomain decomposition
103216621825SDmitry Karpeev 
103316621825SDmitry Karpeev   Output Parameter:
103416621825SDmitry Karpeev . ddm  - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known)
103516621825SDmitry Karpeev 
103616621825SDmitry Karpeev   Level: advanced
103716621825SDmitry Karpeev 
103816621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
103916621825SDmitry Karpeev @*/
104016621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm)
104116621825SDmitry Karpeev {
104216621825SDmitry Karpeev   PetscErrorCode ierr;
104316621825SDmitry Karpeev 
104416621825SDmitry Karpeev   PetscFunctionBegin;
104516621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
104616621825SDmitry Karpeev   PetscValidCharPointer(name,2);
104716621825SDmitry Karpeev   PetscValidPointer(ddm,3);
104816621825SDmitry Karpeev   *ddm = PETSC_NULL;
1049*731c8d9eSDmitry Karpeev   if(dm->ops->createdomaindecompositiondm) {
105016621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
105116621825SDmitry Karpeev   }
105216621825SDmitry Karpeev   PetscFunctionReturn(0);
105316621825SDmitry Karpeev }
105416621825SDmitry Karpeev 
105516621825SDmitry Karpeev 
105616621825SDmitry Karpeev #undef __FUNCT__
105716621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
105816621825SDmitry Karpeev /*@C
105916621825SDmitry Karpeev   DMCreateDomainDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
106016621825SDmitry Karpeev                           corresponding to restrictions to a family of subdomains : each IS contains the global indices
106116621825SDmitry Karpeev                           of the dofs of the corresponding subdomains. The optional list of DMs define the DM for each
106216621825SDmitry Karpeev                           subproblem.
106316621825SDmitry Karpeev 
106416621825SDmitry Karpeev   Not collective
106516621825SDmitry Karpeev 
106616621825SDmitry Karpeev   Input Parameter:
106716621825SDmitry Karpeev . dm - the DM object
106816621825SDmitry Karpeev 
106916621825SDmitry Karpeev   Output Parameters:
107016621825SDmitry Karpeev + len       - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested)
107116621825SDmitry Karpeev . namelist  - The name for each subdomain (or PETSC_NULL if not requested)
107216621825SDmitry Karpeev . islist    - The global indices for each subdomain (or PETSC_NULL if not requested)
107316621825SDmitry Karpeev - dmlist    - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
107416621825SDmitry Karpeev 
107516621825SDmitry Karpeev   Level: intermediate
107616621825SDmitry Karpeev 
107716621825SDmitry Karpeev   Notes:
107816621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
107916621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
108016621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
108116621825SDmitry Karpeev 
108216621825SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), CreateFieldDecomposition()
108316621825SDmitry Karpeev @*/
108416621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
108516621825SDmitry Karpeev {
108616621825SDmitry Karpeev   PetscErrorCode ierr;
108716621825SDmitry Karpeev 
108816621825SDmitry Karpeev   PetscFunctionBegin;
108916621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1090*731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);       *len      = PETSC_NULL;}
109116621825SDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3);  *namelist = PETSC_NULL;}
109216621825SDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);    *islist   = PETSC_NULL;}
109316621825SDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);    *dmlist   = PETSC_NULL;}
109416621825SDmitry Karpeev   if(dm->ops->createdomaindecomposition) {
109516621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
1096e7c4fc90SDmitry Karpeev   }
1097e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1098e7c4fc90SDmitry Karpeev }
1099e7c4fc90SDmitry Karpeev 
1100*731c8d9eSDmitry Karpeev #undef __FUNCT__
1101*731c8d9eSDmitry Karpeev #define __FUNCT__ "DMSetEmbedding"
1102*731c8d9eSDmitry Karpeev /*@C
1103*731c8d9eSDmitry Karpeev   DMSetEmbedding - Set the embedding of DM's indices (hence, vectors and matrices) into another DM's index space.
1104*731c8d9eSDmitry Karpeev 
1105*731c8d9eSDmitry Karpeev   Not collective
1106*731c8d9eSDmitry Karpeev 
1107*731c8d9eSDmitry Karpeev   Input Parameters:
1108*731c8d9eSDmitry Karpeev + dm         - the DM object
1109*731c8d9eSDmitry Karpeev . embedding  - IS mapping dm's local indices into ambientdm's global indices (or PETSC_NULL to remove the embedding)
1110*731c8d9eSDmitry Karpeev - ambientdm  - the DM into which to embed (or PETSC_NULL to remove the embedding)
1111*731c8d9eSDmitry Karpeev 
1112*731c8d9eSDmitry Karpeev   Level: advanced
1113*731c8d9eSDmitry Karpeev 
1114*731c8d9eSDmitry Karpeev   Notes:
1115*731c8d9eSDmitry Karpeev   Decomposition DMs created with DMCreateDecomposition() are automatically embedded into the decomposing DM.
1116*731c8d9eSDmitry Karpeev   This allows (for evaluation of embedded DMs' residuals, Jacobians and bounds by injecting the current solution
1117*731c8d9eSDmitry Karpeev   into the ambient DM's solution, evaluating the ambient DM's residual (or Jacobian, or bounds) and then
1118*731c8d9eSDmitry Karpeev   extracting the subvector (submatrix or bounds subvectors).
1119*731c8d9eSDmitry Karpeev 
1120*731c8d9eSDmitry Karpeev   Both embedding and ambientdm must either be valid or PETSC_NULL together.
1121*731c8d9eSDmitry Karpeev 
1122*731c8d9eSDmitry Karpeev .seealso DMCreateDecomposition(), DMCreateFieldIS()
1123*731c8d9eSDmitry Karpeev @*/
1124*731c8d9eSDmitry Karpeev PetscErrorCode DMSetEmbedding(DM dm, IS embedding, DM ambientdm)
1125*731c8d9eSDmitry Karpeev {
1126*731c8d9eSDmitry Karpeev   PetscErrorCode ierr;
1127*731c8d9eSDmitry Karpeev   PetscFunctionBegin;
1128*731c8d9eSDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1129*731c8d9eSDmitry Karpeev   if((!embedding && ambientdm) ||(embedding &&!ambientdm))
1130*731c8d9eSDmitry Karpeev     SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Both embedding IS and DM must be PETSC_NULL or valid together");
1131*731c8d9eSDmitry Karpeev   if(embedding) {
1132*731c8d9eSDmitry Karpeev     PetscValidHeaderSpecific(embedding,IS_CLASSID,2);
1133*731c8d9eSDmitry Karpeev     PetscValidHeaderSpecific(ambientdm,DM_CLASSID,3);
1134*731c8d9eSDmitry Karpeev     ierr = PetscObjectReference((PetscObject)ambientdm); CHKERRQ(ierr);
1135*731c8d9eSDmitry Karpeev     ierr = PetscObjectReference((PetscObject)embedding); CHKERRQ(ierr);
1136*731c8d9eSDmitry Karpeev   }
1137*731c8d9eSDmitry Karpeev   ierr = DMDestroy(&dm->ambientdm);                    CHKERRQ(ierr);
1138*731c8d9eSDmitry Karpeev   dm->ambientdm = ambientdm;
1139*731c8d9eSDmitry Karpeev   ierr = ISDestroy(&dm->embedding);                    CHKERRQ(ierr);
1140*731c8d9eSDmitry Karpeev   dm->embedding = embedding;
1141*731c8d9eSDmitry Karpeev   PetscFunctionReturn(0);
1142*731c8d9eSDmitry Karpeev }
1143*731c8d9eSDmitry Karpeev 
1144*731c8d9eSDmitry Karpeev #undef __FUNCT__
1145*731c8d9eSDmitry Karpeev #define __FUNCT__ "DMGetEmbedding"
1146*731c8d9eSDmitry Karpeev /*@C
1147*731c8d9eSDmitry Karpeev   DMGetEmbedding - extract the embedding of this DM into another DM.
1148*731c8d9eSDmitry Karpeev 
1149*731c8d9eSDmitry Karpeev   Not collective
1150*731c8d9eSDmitry Karpeev 
1151*731c8d9eSDmitry Karpeev   Input Parameter:
1152*731c8d9eSDmitry Karpeev . dm         - the DM object
1153*731c8d9eSDmitry Karpeev 
1154*731c8d9eSDmitry Karpeev   Output Parameters:
1155*731c8d9eSDmitry Karpeev + embedding  - IS mapping dm's local indices into ambientdm's global indices
1156*731c8d9eSDmitry Karpeev - ambientdm  - the DM into which this DM is embedded
1157*731c8d9eSDmitry Karpeev 
1158*731c8d9eSDmitry Karpeev   Level: advanced
1159*731c8d9eSDmitry Karpeev 
1160*731c8d9eSDmitry Karpeev   Notes:
1161*731c8d9eSDmitry Karpeev   The embedding IS and the ambient dm are read-only and must be restored to this DM using DMRestoreEmbedding().
1162*731c8d9eSDmitry Karpeev   The embedding must have been set using DMSetEmbedding() or automatically created by a routine such as  DMCreateDecomposition().
1163*731c8d9eSDmitry Karpeev 
1164*731c8d9eSDmitry Karpeev .seealso DMSetEmbedding(), DMRestoreEmbedding(), DMCreateDecomposition()
1165*731c8d9eSDmitry Karpeev @*/
1166*731c8d9eSDmitry Karpeev PetscErrorCode DMGetEmbedding(DM dm, IS* embedding, DM* ambientdm)
1167*731c8d9eSDmitry Karpeev {
1168*731c8d9eSDmitry Karpeev   PetscErrorCode ierr;
1169*731c8d9eSDmitry Karpeev   PetscFunctionBegin;
1170*731c8d9eSDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1171*731c8d9eSDmitry Karpeev   if(embedding) {PetscValidPointer(embedding,2); *embedding = dm->embedding;}
1172*731c8d9eSDmitry Karpeev   if(ambientdm) {PetscValidPointer(ambientdm,3); *ambientdm = dm->ambientdm;};
1173*731c8d9eSDmitry Karpeev   PetscFunctionReturn(0);
1174*731c8d9eSDmitry Karpeev }
1175*731c8d9eSDmitry Karpeev 
1176*731c8d9eSDmitry Karpeev #undef __FUNCT__
1177*731c8d9eSDmitry Karpeev #define __FUNCT__ "DMRestoreEmbedding"
1178*731c8d9eSDmitry Karpeev /*@C
1179*731c8d9eSDmitry Karpeev   DMRestoreEmbedding - restore the embedding obtained with DMGetEmbedding()
1180*731c8d9eSDmitry Karpeev 
1181*731c8d9eSDmitry Karpeev   Not collective
1182*731c8d9eSDmitry Karpeev 
1183*731c8d9eSDmitry Karpeev   Input Parameters:
1184*731c8d9eSDmitry Karpeev + dm         - the DM object
1185*731c8d9eSDmitry Karpeev . embedding  - IS mapping dm's local indices into ambientdm's global indices (must have been obtained with DMGetEmbedding())
1186*731c8d9eSDmitry Karpeev - ambientdm  - the DM into which to embed (must have been obtained with DMGetEmbedding())
1187*731c8d9eSDmitry Karpeev 
1188*731c8d9eSDmitry Karpeev   Level: advanced
1189*731c8d9eSDmitry Karpeev 
1190*731c8d9eSDmitry Karpeev   Notes:
1191*731c8d9eSDmitry Karpeev   The embedding must have been obtained with DMGetEmbedding().
1192*731c8d9eSDmitry Karpeev 
1193*731c8d9eSDmitry Karpeev .seealso DMSetEmbedding(), DMGetEmbedding()
1194*731c8d9eSDmitry Karpeev @*/
1195*731c8d9eSDmitry Karpeev PetscErrorCode DMRestoreEmbedding(DM dm, IS* embedding, DM* ambientdm)
1196*731c8d9eSDmitry Karpeev {
1197*731c8d9eSDmitry Karpeev   PetscErrorCode ierr;
1198*731c8d9eSDmitry Karpeev   PetscFunctionBegin;
1199*731c8d9eSDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1200*731c8d9eSDmitry Karpeev   if(embedding) {
1201*731c8d9eSDmitry Karpeev     PetscValidPointer(embedding,2);
1202*731c8d9eSDmitry Karpeev     if(*embedding != dm->embedding)
1203*731c8d9eSDmitry Karpeev       SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Embedding IS not obtained with DMGetEmbedding()");
1204*731c8d9eSDmitry Karpeev   }
1205*731c8d9eSDmitry Karpeev   if(ambientdm) {
1206*731c8d9eSDmitry Karpeev     PetscValidPointer(ambientdm,3);
1207*731c8d9eSDmitry Karpeev     if(*ambientdm != dm->ambientdm)
1208*731c8d9eSDmitry Karpeev       SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "Ambient DM not obtained with DMGetEmbedding()");
1209*731c8d9eSDmitry Karpeev   }
1210*731c8d9eSDmitry Karpeev   PetscFunctionReturn(0);
1211*731c8d9eSDmitry Karpeev }
1212*731c8d9eSDmitry Karpeev 
1213e7c4fc90SDmitry Karpeev 
1214e7c4fc90SDmitry Karpeev #undef __FUNCT__
121547c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
121647c6ae99SBarry Smith /*@
121747c6ae99SBarry Smith   DMRefine - Refines a DM object
121847c6ae99SBarry Smith 
121947c6ae99SBarry Smith   Collective on DM
122047c6ae99SBarry Smith 
122147c6ae99SBarry Smith   Input Parameter:
122247c6ae99SBarry Smith + dm   - the DM object
122391d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
122447c6ae99SBarry Smith 
122547c6ae99SBarry Smith   Output Parameter:
1226ae0a1c52SMatthew G Knepley . dmf - the refined DM, or PETSC_NULL
1227ae0a1c52SMatthew G Knepley 
1228ae0a1c52SMatthew G Knepley   Note: If no refinement was done, the return value is PETSC_NULL
122947c6ae99SBarry Smith 
123047c6ae99SBarry Smith   Level: developer
123147c6ae99SBarry Smith 
1232e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
123347c6ae99SBarry Smith @*/
12347087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
123547c6ae99SBarry Smith {
123647c6ae99SBarry Smith   PetscErrorCode ierr;
1237c833c3b5SJed Brown   DMRefineHookLink link;
123847c6ae99SBarry Smith 
123947c6ae99SBarry Smith   PetscFunctionBegin;
1240732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
124147c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
12424057135bSMatthew G Knepley   if (*dmf) {
124343842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
1244644e2e5bSBarry Smith     (*dmf)->ops->initialguess = dm->ops->initialguess;
1245644e2e5bSBarry Smith     (*dmf)->ops->function     = dm->ops->function;
1246644e2e5bSBarry Smith     (*dmf)->ops->functionj    = dm->ops->functionj;
1247644e2e5bSBarry Smith     if (dm->ops->jacobian != DMComputeJacobianDefault) {
1248644e2e5bSBarry Smith       (*dmf)->ops->jacobian     = dm->ops->jacobian;
1249644e2e5bSBarry Smith     }
12508cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
1251644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
12520598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1253656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
1254c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
1255c833c3b5SJed Brown       if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);}
1256c833c3b5SJed Brown     }
1257c833c3b5SJed Brown   }
1258c833c3b5SJed Brown   PetscFunctionReturn(0);
1259c833c3b5SJed Brown }
1260c833c3b5SJed Brown 
1261c833c3b5SJed Brown #undef __FUNCT__
1262c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1263c833c3b5SJed Brown /*@
1264c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1265c833c3b5SJed Brown 
1266c833c3b5SJed Brown    Logically Collective
1267c833c3b5SJed Brown 
1268c833c3b5SJed Brown    Input Arguments:
1269c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1270c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1271c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
1272c833c3b5SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1273c833c3b5SJed Brown 
1274c833c3b5SJed Brown    Calling sequence of refinehook:
1275c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1276c833c3b5SJed Brown 
1277c833c3b5SJed Brown +  coarse - coarse level DM
1278c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1279c833c3b5SJed Brown -  ctx - optional user-defined function context
1280c833c3b5SJed Brown 
1281c833c3b5SJed Brown    Calling sequence for interphook:
1282c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1283c833c3b5SJed Brown 
1284c833c3b5SJed Brown +  coarse - coarse level DM
1285c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1286c833c3b5SJed Brown .  fine - fine level DM to update
1287c833c3b5SJed Brown -  ctx - optional user-defined function context
1288c833c3b5SJed Brown 
1289c833c3b5SJed Brown    Level: advanced
1290c833c3b5SJed Brown 
1291c833c3b5SJed Brown    Notes:
1292c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1293c833c3b5SJed Brown 
1294c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1295c833c3b5SJed Brown 
1296c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1297c833c3b5SJed Brown @*/
1298c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1299c833c3b5SJed Brown {
1300c833c3b5SJed Brown   PetscErrorCode ierr;
1301c833c3b5SJed Brown   DMRefineHookLink link,*p;
1302c833c3b5SJed Brown 
1303c833c3b5SJed Brown   PetscFunctionBegin;
1304c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1305c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1306c833c3b5SJed Brown   ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1307c833c3b5SJed Brown   link->refinehook = refinehook;
1308c833c3b5SJed Brown   link->interphook = interphook;
1309c833c3b5SJed Brown   link->ctx = ctx;
1310c833c3b5SJed Brown   link->next = PETSC_NULL;
1311c833c3b5SJed Brown   *p = link;
1312c833c3b5SJed Brown   PetscFunctionReturn(0);
1313c833c3b5SJed Brown }
1314c833c3b5SJed Brown 
1315c833c3b5SJed Brown #undef __FUNCT__
1316c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1317c833c3b5SJed Brown /*@
1318c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1319c833c3b5SJed Brown 
1320c833c3b5SJed Brown    Collective if any hooks are
1321c833c3b5SJed Brown 
1322c833c3b5SJed Brown    Input Arguments:
1323c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1324c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1325c833c3b5SJed Brown -  fine - finer DM to update
1326c833c3b5SJed Brown 
1327c833c3b5SJed Brown    Level: developer
1328c833c3b5SJed Brown 
1329c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1330c833c3b5SJed Brown @*/
1331c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1332c833c3b5SJed Brown {
1333c833c3b5SJed Brown   PetscErrorCode ierr;
1334c833c3b5SJed Brown   DMRefineHookLink link;
1335c833c3b5SJed Brown 
1336c833c3b5SJed Brown   PetscFunctionBegin;
1337c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
1338c833c3b5SJed Brown     if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);}
13394057135bSMatthew G Knepley   }
134047c6ae99SBarry Smith   PetscFunctionReturn(0);
134147c6ae99SBarry Smith }
134247c6ae99SBarry Smith 
134347c6ae99SBarry Smith #undef __FUNCT__
1344eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1345eb3f98d2SBarry Smith /*@
1346eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1347eb3f98d2SBarry Smith 
1348eb3f98d2SBarry Smith     Not Collective
1349eb3f98d2SBarry Smith 
1350eb3f98d2SBarry Smith     Input Parameter:
1351eb3f98d2SBarry Smith .   dm - the DM object
1352eb3f98d2SBarry Smith 
1353eb3f98d2SBarry Smith     Output Parameter:
1354eb3f98d2SBarry Smith .   level - number of refinements
1355eb3f98d2SBarry Smith 
1356eb3f98d2SBarry Smith     Level: developer
1357eb3f98d2SBarry Smith 
13586a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1359eb3f98d2SBarry Smith 
1360eb3f98d2SBarry Smith @*/
1361eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1362eb3f98d2SBarry Smith {
1363eb3f98d2SBarry Smith   PetscFunctionBegin;
1364eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1365eb3f98d2SBarry Smith   *level = dm->levelup;
1366eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1367eb3f98d2SBarry Smith }
1368eb3f98d2SBarry Smith 
1369eb3f98d2SBarry Smith #undef __FUNCT__
137047c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
137147c6ae99SBarry Smith /*@
137247c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
137347c6ae99SBarry Smith 
137447c6ae99SBarry Smith     Neighbor-wise Collective on DM
137547c6ae99SBarry Smith 
137647c6ae99SBarry Smith     Input Parameters:
137747c6ae99SBarry Smith +   dm - the DM object
137847c6ae99SBarry Smith .   g - the global vector
137947c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
138047c6ae99SBarry Smith -   l - the local vector
138147c6ae99SBarry Smith 
138247c6ae99SBarry Smith 
138347c6ae99SBarry Smith     Level: beginner
138447c6ae99SBarry Smith 
1385e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
138647c6ae99SBarry Smith 
138747c6ae99SBarry Smith @*/
13887087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
138947c6ae99SBarry Smith {
13907128ae9fSMatthew G Knepley   PetscSF        sf;
139147c6ae99SBarry Smith   PetscErrorCode ierr;
139247c6ae99SBarry Smith 
139347c6ae99SBarry Smith   PetscFunctionBegin;
1394171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13957128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
13967128ae9fSMatthew G Knepley   if (sf) {
13977128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
13987128ae9fSMatthew G Knepley 
13997128ae9fSMatthew G Knepley     if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14007128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14017128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14027128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14037128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14047128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14057128ae9fSMatthew G Knepley   } else {
1406843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14077128ae9fSMatthew G Knepley   }
140847c6ae99SBarry Smith   PetscFunctionReturn(0);
140947c6ae99SBarry Smith }
141047c6ae99SBarry Smith 
141147c6ae99SBarry Smith #undef __FUNCT__
141247c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
141347c6ae99SBarry Smith /*@
141447c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
141547c6ae99SBarry Smith 
141647c6ae99SBarry Smith     Neighbor-wise Collective on DM
141747c6ae99SBarry Smith 
141847c6ae99SBarry Smith     Input Parameters:
141947c6ae99SBarry Smith +   dm - the DM object
142047c6ae99SBarry Smith .   g - the global vector
142147c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
142247c6ae99SBarry Smith -   l - the local vector
142347c6ae99SBarry Smith 
142447c6ae99SBarry Smith 
142547c6ae99SBarry Smith     Level: beginner
142647c6ae99SBarry Smith 
1427e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
142847c6ae99SBarry Smith 
142947c6ae99SBarry Smith @*/
14307087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
143147c6ae99SBarry Smith {
14327128ae9fSMatthew G Knepley   PetscSF        sf;
143347c6ae99SBarry Smith   PetscErrorCode ierr;
143461a3c1faSSatish Balay   PetscScalar    *lArray, *gArray;
143547c6ae99SBarry Smith 
143647c6ae99SBarry Smith   PetscFunctionBegin;
1437171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14387128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14397128ae9fSMatthew G Knepley   if (sf) {
14407128ae9fSMatthew G Knepley   if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
14417128ae9fSMatthew G Knepley 
14427128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
14437128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
14447128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
14457128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
14467128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
14477128ae9fSMatthew G Knepley   } else {
1448843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
14497128ae9fSMatthew G Knepley   }
145047c6ae99SBarry Smith   PetscFunctionReturn(0);
145147c6ae99SBarry Smith }
145247c6ae99SBarry Smith 
145347c6ae99SBarry Smith #undef __FUNCT__
14549a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
145547c6ae99SBarry Smith /*@
14569a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
14579a42bb27SBarry Smith 
14589a42bb27SBarry Smith     Neighbor-wise Collective on DM
14599a42bb27SBarry Smith 
14609a42bb27SBarry Smith     Input Parameters:
14619a42bb27SBarry Smith +   dm - the DM object
1462f6813fd5SJed Brown .   l - the local vector
14639a42bb27SBarry 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
14649a42bb27SBarry Smith            base point.
1465f6813fd5SJed Brown - - the global vector
14669a42bb27SBarry Smith 
14679a42bb27SBarry 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
14689a42bb27SBarry 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
14699a42bb27SBarry Smith            global array to the final global array with VecAXPY().
14709a42bb27SBarry Smith 
14719a42bb27SBarry Smith     Level: beginner
14729a42bb27SBarry Smith 
1473e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
14749a42bb27SBarry Smith 
14759a42bb27SBarry Smith @*/
14767087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
14779a42bb27SBarry Smith {
14787128ae9fSMatthew G Knepley   PetscSF        sf;
14799a42bb27SBarry Smith   PetscErrorCode ierr;
14809a42bb27SBarry Smith 
14819a42bb27SBarry Smith   PetscFunctionBegin;
1482171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
14837128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
14847128ae9fSMatthew G Knepley   if (sf) {
14857128ae9fSMatthew G Knepley     MPI_Op       op;
14867128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
14877128ae9fSMatthew G Knepley 
14887128ae9fSMatthew G Knepley     switch(mode) {
14897128ae9fSMatthew G Knepley     case INSERT_VALUES:
14907128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
14917128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
14927128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
14937128ae9fSMatthew G Knepley #else
14947128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
14957128ae9fSMatthew G Knepley #endif
14967128ae9fSMatthew G Knepley     case ADD_VALUES:
14977128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
14987128ae9fSMatthew G Knepley       op = MPI_SUM; break;
14997128ae9fSMatthew G Knepley   default:
15007128ae9fSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15017128ae9fSMatthew G Knepley     }
15027128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15037128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15047128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
15057128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15067128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15077128ae9fSMatthew G Knepley   } else {
1508843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
15097128ae9fSMatthew G Knepley   }
15109a42bb27SBarry Smith   PetscFunctionReturn(0);
15119a42bb27SBarry Smith }
15129a42bb27SBarry Smith 
15139a42bb27SBarry Smith #undef __FUNCT__
15149a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
15159a42bb27SBarry Smith /*@
15169a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
151747c6ae99SBarry Smith 
151847c6ae99SBarry Smith     Neighbor-wise Collective on DM
151947c6ae99SBarry Smith 
152047c6ae99SBarry Smith     Input Parameters:
152147c6ae99SBarry Smith +   dm - the DM object
1522f6813fd5SJed Brown .   l - the local vector
152347c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1524f6813fd5SJed Brown -   g - the global vector
152547c6ae99SBarry Smith 
152647c6ae99SBarry Smith 
152747c6ae99SBarry Smith     Level: beginner
152847c6ae99SBarry Smith 
1529e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
153047c6ae99SBarry Smith 
153147c6ae99SBarry Smith @*/
15327087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
153347c6ae99SBarry Smith {
15347128ae9fSMatthew G Knepley   PetscSF        sf;
153547c6ae99SBarry Smith   PetscErrorCode ierr;
153647c6ae99SBarry Smith 
153747c6ae99SBarry Smith   PetscFunctionBegin;
1538171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15397128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
15407128ae9fSMatthew G Knepley   if (sf) {
15417128ae9fSMatthew G Knepley     MPI_Op       op;
15427128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
15437128ae9fSMatthew G Knepley 
15447128ae9fSMatthew G Knepley     switch(mode) {
15457128ae9fSMatthew G Knepley     case INSERT_VALUES:
15467128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
15477128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
15487128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
15497128ae9fSMatthew G Knepley #else
15507128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
15517128ae9fSMatthew G Knepley #endif
15527128ae9fSMatthew G Knepley     case ADD_VALUES:
15537128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
15547128ae9fSMatthew G Knepley       op = MPI_SUM; break;
15557128ae9fSMatthew G Knepley     default:
15567128ae9fSMatthew G Knepley       SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15577128ae9fSMatthew G Knepley     }
15587128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15597128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15607128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
15617128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15627128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15637128ae9fSMatthew G Knepley   } else {
1564843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
15657128ae9fSMatthew G Knepley   }
156647c6ae99SBarry Smith   PetscFunctionReturn(0);
156747c6ae99SBarry Smith }
156847c6ae99SBarry Smith 
156947c6ae99SBarry Smith #undef __FUNCT__
157047c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobianDefault"
157147c6ae99SBarry Smith /*@
157247c6ae99SBarry Smith     DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided
157347c6ae99SBarry Smith 
157447c6ae99SBarry Smith     Collective on DM
157547c6ae99SBarry Smith 
157647c6ae99SBarry Smith     Input Parameter:
157747c6ae99SBarry Smith +   dm - the DM object
157847c6ae99SBarry Smith .   x - location to compute Jacobian at; may be ignored for linear problems
157947c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
158047c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
158147c6ae99SBarry Smith 
158247c6ae99SBarry Smith     Level: developer
158347c6ae99SBarry Smith 
1584e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
158547c6ae99SBarry Smith          DMSetFunction()
158647c6ae99SBarry Smith 
158747c6ae99SBarry Smith @*/
15887087cfbeSBarry Smith PetscErrorCode  DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
158947c6ae99SBarry Smith {
159047c6ae99SBarry Smith   PetscErrorCode ierr;
1591171400e9SBarry Smith 
159247c6ae99SBarry Smith   PetscFunctionBegin;
1593171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
159447c6ae99SBarry Smith   *stflag = SAME_NONZERO_PATTERN;
159547c6ae99SBarry Smith   ierr  = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr);
159647c6ae99SBarry Smith   if (A != B) {
159747c6ae99SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
159847c6ae99SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
159947c6ae99SBarry Smith   }
160047c6ae99SBarry Smith   PetscFunctionReturn(0);
160147c6ae99SBarry Smith }
160247c6ae99SBarry Smith 
160347c6ae99SBarry Smith #undef __FUNCT__
160447c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
160547c6ae99SBarry Smith /*@
160647c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
160747c6ae99SBarry Smith 
160847c6ae99SBarry Smith     Collective on DM
160947c6ae99SBarry Smith 
161047c6ae99SBarry Smith     Input Parameter:
161147c6ae99SBarry Smith +   dm - the DM object
161291d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
161347c6ae99SBarry Smith 
161447c6ae99SBarry Smith     Output Parameter:
161547c6ae99SBarry Smith .   dmc - the coarsened DM
161647c6ae99SBarry Smith 
161747c6ae99SBarry Smith     Level: developer
161847c6ae99SBarry Smith 
1619e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
162047c6ae99SBarry Smith 
162147c6ae99SBarry Smith @*/
16227087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
162347c6ae99SBarry Smith {
162447c6ae99SBarry Smith   PetscErrorCode ierr;
1625b17ce1afSJed Brown   DMCoarsenHookLink link;
162647c6ae99SBarry Smith 
162747c6ae99SBarry Smith   PetscFunctionBegin;
1628171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
162947c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
163043842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
163147c6ae99SBarry Smith   (*dmc)->ops->initialguess = dm->ops->initialguess;
163247c6ae99SBarry Smith   (*dmc)->ops->function     = dm->ops->function;
163347c6ae99SBarry Smith   (*dmc)->ops->functionj    = dm->ops->functionj;
163447c6ae99SBarry Smith   if (dm->ops->jacobian != DMComputeJacobianDefault) {
163547c6ae99SBarry Smith     (*dmc)->ops->jacobian     = dm->ops->jacobian;
163647c6ae99SBarry Smith   }
16378cd211a4SJed Brown   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1638644e2e5bSBarry Smith   (*dmc)->ctx       = dm->ctx;
16390598a293SJed Brown   (*dmc)->levelup   = dm->levelup;
1640656b349aSBarry Smith   (*dmc)->leveldown = dm->leveldown + 1;
1641b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1642b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1643b17ce1afSJed Brown   }
1644b17ce1afSJed Brown   PetscFunctionReturn(0);
1645b17ce1afSJed Brown }
1646b17ce1afSJed Brown 
1647b17ce1afSJed Brown #undef __FUNCT__
1648b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1649b17ce1afSJed Brown /*@
1650b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1651b17ce1afSJed Brown 
1652b17ce1afSJed Brown    Logically Collective
1653b17ce1afSJed Brown 
1654b17ce1afSJed Brown    Input Arguments:
1655b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1656b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1657b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
1658b17ce1afSJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1659b17ce1afSJed Brown 
1660b17ce1afSJed Brown    Calling sequence of coarsenhook:
1661b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1662b17ce1afSJed Brown 
1663b17ce1afSJed Brown +  fine - fine level DM
1664b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1665b17ce1afSJed Brown -  ctx - optional user-defined function context
1666b17ce1afSJed Brown 
1667b17ce1afSJed Brown    Calling sequence for restricthook:
1668c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
1669b17ce1afSJed Brown 
1670b17ce1afSJed Brown +  fine - fine level DM
1671b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
1672c833c3b5SJed Brown .  rscale - scaling vector for restriction
1673c833c3b5SJed Brown .  inject - matrix restricting by injection
1674b17ce1afSJed Brown .  coarse - coarse level DM to update
1675b17ce1afSJed Brown -  ctx - optional user-defined function context
1676b17ce1afSJed Brown 
1677b17ce1afSJed Brown    Level: advanced
1678b17ce1afSJed Brown 
1679b17ce1afSJed Brown    Notes:
1680b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
1681b17ce1afSJed Brown 
1682b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1683b17ce1afSJed Brown 
1684b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1685b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
1686b17ce1afSJed Brown 
1687c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1688b17ce1afSJed Brown @*/
1689b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1690b17ce1afSJed Brown {
1691b17ce1afSJed Brown   PetscErrorCode ierr;
1692b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
1693b17ce1afSJed Brown 
1694b17ce1afSJed Brown   PetscFunctionBegin;
1695b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
16966bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1697b17ce1afSJed Brown   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1698b17ce1afSJed Brown   link->coarsenhook = coarsenhook;
1699b17ce1afSJed Brown   link->restricthook = restricthook;
1700b17ce1afSJed Brown   link->ctx = ctx;
17016cab3a1bSJed Brown   link->next = PETSC_NULL;
1702b17ce1afSJed Brown   *p = link;
1703b17ce1afSJed Brown   PetscFunctionReturn(0);
1704b17ce1afSJed Brown }
1705b17ce1afSJed Brown 
1706b17ce1afSJed Brown #undef __FUNCT__
1707b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
1708b17ce1afSJed Brown /*@
1709b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1710b17ce1afSJed Brown 
1711b17ce1afSJed Brown    Collective if any hooks are
1712b17ce1afSJed Brown 
1713b17ce1afSJed Brown    Input Arguments:
1714b17ce1afSJed Brown +  fine - finer DM to use as a base
1715b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
1716b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
1717b17ce1afSJed Brown -  coarse - coarer DM to update
1718b17ce1afSJed Brown 
1719b17ce1afSJed Brown    Level: developer
1720b17ce1afSJed Brown 
1721b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
1722b17ce1afSJed Brown @*/
1723b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1724b17ce1afSJed Brown {
1725b17ce1afSJed Brown   PetscErrorCode ierr;
1726b17ce1afSJed Brown   DMCoarsenHookLink link;
1727b17ce1afSJed Brown 
1728b17ce1afSJed Brown   PetscFunctionBegin;
1729b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
1730b17ce1afSJed Brown     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1731b17ce1afSJed Brown   }
173247c6ae99SBarry Smith   PetscFunctionReturn(0);
173347c6ae99SBarry Smith }
173447c6ae99SBarry Smith 
173547c6ae99SBarry Smith #undef __FUNCT__
17365fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
17375fe1f584SPeter Brune /*@
17386a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
17395fe1f584SPeter Brune 
17405fe1f584SPeter Brune     Not Collective
17415fe1f584SPeter Brune 
17425fe1f584SPeter Brune     Input Parameter:
17435fe1f584SPeter Brune .   dm - the DM object
17445fe1f584SPeter Brune 
17455fe1f584SPeter Brune     Output Parameter:
17466a7d9d85SPeter Brune .   level - number of coarsenings
17475fe1f584SPeter Brune 
17485fe1f584SPeter Brune     Level: developer
17495fe1f584SPeter Brune 
17506a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
17515fe1f584SPeter Brune 
17525fe1f584SPeter Brune @*/
17535fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
17545fe1f584SPeter Brune {
17555fe1f584SPeter Brune   PetscFunctionBegin;
17565fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17575fe1f584SPeter Brune   *level = dm->leveldown;
17585fe1f584SPeter Brune   PetscFunctionReturn(0);
17595fe1f584SPeter Brune }
17605fe1f584SPeter Brune 
17615fe1f584SPeter Brune 
17625fe1f584SPeter Brune 
17635fe1f584SPeter Brune #undef __FUNCT__
176447c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
176547c6ae99SBarry Smith /*@C
176647c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
176747c6ae99SBarry Smith 
176847c6ae99SBarry Smith     Collective on DM
176947c6ae99SBarry Smith 
177047c6ae99SBarry Smith     Input Parameter:
177147c6ae99SBarry Smith +   dm - the DM object
177247c6ae99SBarry Smith -   nlevels - the number of levels of refinement
177347c6ae99SBarry Smith 
177447c6ae99SBarry Smith     Output Parameter:
177547c6ae99SBarry Smith .   dmf - the refined DM hierarchy
177647c6ae99SBarry Smith 
177747c6ae99SBarry Smith     Level: developer
177847c6ae99SBarry Smith 
1779e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
178047c6ae99SBarry Smith 
178147c6ae99SBarry Smith @*/
17827087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
178347c6ae99SBarry Smith {
178447c6ae99SBarry Smith   PetscErrorCode ierr;
178547c6ae99SBarry Smith 
178647c6ae99SBarry Smith   PetscFunctionBegin;
1787171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
178847c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
178947c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
179047c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
179147c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
179247c6ae99SBarry Smith   } else if (dm->ops->refine) {
179347c6ae99SBarry Smith     PetscInt i;
179447c6ae99SBarry Smith 
179547c6ae99SBarry Smith     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
179647c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
179747c6ae99SBarry Smith       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
179847c6ae99SBarry Smith     }
179947c6ae99SBarry Smith   } else {
180047c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
180147c6ae99SBarry Smith   }
180247c6ae99SBarry Smith   PetscFunctionReturn(0);
180347c6ae99SBarry Smith }
180447c6ae99SBarry Smith 
180547c6ae99SBarry Smith #undef __FUNCT__
180647c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
180747c6ae99SBarry Smith /*@C
180847c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
180947c6ae99SBarry Smith 
181047c6ae99SBarry Smith     Collective on DM
181147c6ae99SBarry Smith 
181247c6ae99SBarry Smith     Input Parameter:
181347c6ae99SBarry Smith +   dm - the DM object
181447c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
181547c6ae99SBarry Smith 
181647c6ae99SBarry Smith     Output Parameter:
181747c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
181847c6ae99SBarry Smith 
181947c6ae99SBarry Smith     Level: developer
182047c6ae99SBarry Smith 
1821e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
182247c6ae99SBarry Smith 
182347c6ae99SBarry Smith @*/
18247087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
182547c6ae99SBarry Smith {
182647c6ae99SBarry Smith   PetscErrorCode ierr;
182747c6ae99SBarry Smith 
182847c6ae99SBarry Smith   PetscFunctionBegin;
1829171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
183047c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
183147c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
183247c6ae99SBarry Smith   PetscValidPointer(dmc,3);
183347c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
183447c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
183547c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
183647c6ae99SBarry Smith     PetscInt i;
183747c6ae99SBarry Smith 
183847c6ae99SBarry Smith     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
183947c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
184047c6ae99SBarry Smith       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
184147c6ae99SBarry Smith     }
184247c6ae99SBarry Smith   } else {
184347c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
184447c6ae99SBarry Smith   }
184547c6ae99SBarry Smith   PetscFunctionReturn(0);
184647c6ae99SBarry Smith }
184747c6ae99SBarry Smith 
184847c6ae99SBarry Smith #undef __FUNCT__
1849e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
185047c6ae99SBarry Smith /*@
1851e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
185247c6ae99SBarry Smith    grids associated with two DMs.
185347c6ae99SBarry Smith 
185447c6ae99SBarry Smith    Collective on DM
185547c6ae99SBarry Smith 
185647c6ae99SBarry Smith    Input Parameters:
185747c6ae99SBarry Smith +  dmc - the coarse grid DM
185847c6ae99SBarry Smith -  dmf - the fine grid DM
185947c6ae99SBarry Smith 
186047c6ae99SBarry Smith    Output Parameters:
186147c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
186247c6ae99SBarry Smith 
186347c6ae99SBarry Smith    Level: intermediate
186447c6ae99SBarry Smith 
186547c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
186647c6ae99SBarry Smith 
1867e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
186847c6ae99SBarry Smith @*/
1869e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
187047c6ae99SBarry Smith {
187147c6ae99SBarry Smith   PetscErrorCode ierr;
187247c6ae99SBarry Smith 
187347c6ae99SBarry Smith   PetscFunctionBegin;
1874171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
1875171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
187647c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
187747c6ae99SBarry Smith   PetscFunctionReturn(0);
187847c6ae99SBarry Smith }
187947c6ae99SBarry Smith 
188047c6ae99SBarry Smith #undef __FUNCT__
18811a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
18821a266240SBarry Smith /*@C
18831a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
18841a266240SBarry Smith 
18851a266240SBarry Smith     Not Collective
18861a266240SBarry Smith 
18871a266240SBarry Smith     Input Parameters:
18881a266240SBarry Smith +   dm - the DM object
18891a266240SBarry Smith -   destroy - the destroy function
18901a266240SBarry Smith 
18911a266240SBarry Smith     Level: intermediate
18921a266240SBarry Smith 
1893e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
18941a266240SBarry Smith 
1895f07f9ceaSJed Brown @*/
18961a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
18971a266240SBarry Smith {
18981a266240SBarry Smith   PetscFunctionBegin;
1899171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
19001a266240SBarry Smith   dm->ctxdestroy = destroy;
19011a266240SBarry Smith   PetscFunctionReturn(0);
19021a266240SBarry Smith }
19031a266240SBarry Smith 
19041a266240SBarry Smith #undef __FUNCT__
19051b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
1906b07ff414SBarry Smith /*@
19071b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
190847c6ae99SBarry Smith 
190947c6ae99SBarry Smith     Not Collective
191047c6ae99SBarry Smith 
191147c6ae99SBarry Smith     Input Parameters:
191247c6ae99SBarry Smith +   dm - the DM object
191347c6ae99SBarry Smith -   ctx - the user context
191447c6ae99SBarry Smith 
191547c6ae99SBarry Smith     Level: intermediate
191647c6ae99SBarry Smith 
1917e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
191847c6ae99SBarry Smith 
191947c6ae99SBarry Smith @*/
19201b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
192147c6ae99SBarry Smith {
192247c6ae99SBarry Smith   PetscFunctionBegin;
1923171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
192447c6ae99SBarry Smith   dm->ctx = ctx;
192547c6ae99SBarry Smith   PetscFunctionReturn(0);
192647c6ae99SBarry Smith }
192747c6ae99SBarry Smith 
192847c6ae99SBarry Smith #undef __FUNCT__
19291b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
193047c6ae99SBarry Smith /*@
19311b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
193247c6ae99SBarry Smith 
193347c6ae99SBarry Smith     Not Collective
193447c6ae99SBarry Smith 
193547c6ae99SBarry Smith     Input Parameter:
193647c6ae99SBarry Smith .   dm - the DM object
193747c6ae99SBarry Smith 
193847c6ae99SBarry Smith     Output Parameter:
193947c6ae99SBarry Smith .   ctx - the user context
194047c6ae99SBarry Smith 
194147c6ae99SBarry Smith     Level: intermediate
194247c6ae99SBarry Smith 
1943e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
194447c6ae99SBarry Smith 
194547c6ae99SBarry Smith @*/
19461b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
194747c6ae99SBarry Smith {
194847c6ae99SBarry Smith   PetscFunctionBegin;
1949171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
19501b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
195147c6ae99SBarry Smith   PetscFunctionReturn(0);
195247c6ae99SBarry Smith }
195347c6ae99SBarry Smith 
195447c6ae99SBarry Smith #undef __FUNCT__
195547c6ae99SBarry Smith #define __FUNCT__ "DMSetInitialGuess"
19567e833e3aSBarry Smith /*@C
195747c6ae99SBarry Smith     DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers
195847c6ae99SBarry Smith 
195947c6ae99SBarry Smith     Logically Collective on DM
196047c6ae99SBarry Smith 
196147c6ae99SBarry Smith     Input Parameter:
196247c6ae99SBarry Smith +   dm - the DM object to destroy
196347c6ae99SBarry Smith -   f - the function to compute the initial guess
196447c6ae99SBarry Smith 
196547c6ae99SBarry Smith     Level: intermediate
196647c6ae99SBarry Smith 
1967e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
196847c6ae99SBarry Smith 
1969f07f9ceaSJed Brown @*/
19707087cfbeSBarry Smith PetscErrorCode  DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec))
197147c6ae99SBarry Smith {
197247c6ae99SBarry Smith   PetscFunctionBegin;
1973171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
197447c6ae99SBarry Smith   dm->ops->initialguess = f;
197547c6ae99SBarry Smith   PetscFunctionReturn(0);
197647c6ae99SBarry Smith }
197747c6ae99SBarry Smith 
197847c6ae99SBarry Smith #undef __FUNCT__
197947c6ae99SBarry Smith #define __FUNCT__ "DMSetFunction"
19807e833e3aSBarry Smith /*@C
198147c6ae99SBarry Smith     DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES
198247c6ae99SBarry Smith 
198347c6ae99SBarry Smith     Logically Collective on DM
198447c6ae99SBarry Smith 
198547c6ae99SBarry Smith     Input Parameter:
198647c6ae99SBarry Smith +   dm - the DM object
198747c6ae99SBarry Smith -   f - the function to compute (use PETSC_NULL to cancel a previous function that was set)
198847c6ae99SBarry Smith 
198947c6ae99SBarry Smith     Level: intermediate
199047c6ae99SBarry Smith 
199147c6ae99SBarry Smith     Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian
199247c6ae99SBarry Smith            computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian.
199347c6ae99SBarry Smith 
1994e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
199547c6ae99SBarry Smith          DMSetJacobian()
199647c6ae99SBarry Smith 
1997f07f9ceaSJed Brown @*/
19987087cfbeSBarry Smith PetscErrorCode  DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
199947c6ae99SBarry Smith {
200047c6ae99SBarry Smith   PetscFunctionBegin;
2001171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
200247c6ae99SBarry Smith   dm->ops->function = f;
200347c6ae99SBarry Smith   if (f) {
200447c6ae99SBarry Smith     dm->ops->functionj = f;
200547c6ae99SBarry Smith   }
200647c6ae99SBarry Smith   PetscFunctionReturn(0);
200747c6ae99SBarry Smith }
200847c6ae99SBarry Smith 
200947c6ae99SBarry Smith #undef __FUNCT__
201047c6ae99SBarry Smith #define __FUNCT__ "DMSetJacobian"
20117e833e3aSBarry Smith /*@C
201247c6ae99SBarry Smith     DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES
201347c6ae99SBarry Smith 
201447c6ae99SBarry Smith     Logically Collective on DM
201547c6ae99SBarry Smith 
201647c6ae99SBarry Smith     Input Parameter:
201747c6ae99SBarry Smith +   dm - the DM object to destroy
201847c6ae99SBarry Smith -   f - the function to compute the matrix entries
201947c6ae99SBarry Smith 
202047c6ae99SBarry Smith     Level: intermediate
202147c6ae99SBarry Smith 
2022e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
202347c6ae99SBarry Smith          DMSetFunction()
202447c6ae99SBarry Smith 
2025f07f9ceaSJed Brown @*/
20267087cfbeSBarry Smith PetscErrorCode  DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*))
202747c6ae99SBarry Smith {
202847c6ae99SBarry Smith   PetscFunctionBegin;
2029171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
203047c6ae99SBarry Smith   dm->ops->jacobian = f;
203147c6ae99SBarry Smith   PetscFunctionReturn(0);
203247c6ae99SBarry Smith }
203347c6ae99SBarry Smith 
203447c6ae99SBarry Smith #undef __FUNCT__
203508da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
203608da532bSDmitry Karpeev /*@C
203708da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
203808da532bSDmitry Karpeev 
203908da532bSDmitry Karpeev     Logically Collective on DM
204008da532bSDmitry Karpeev 
204108da532bSDmitry Karpeev     Input Parameter:
204208da532bSDmitry Karpeev +   dm - the DM object
204308da532bSDmitry Karpeev -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
204408da532bSDmitry Karpeev 
204508da532bSDmitry Karpeev     Level: intermediate
204608da532bSDmitry Karpeev 
2047e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
204808da532bSDmitry Karpeev          DMSetJacobian()
204908da532bSDmitry Karpeev 
205008da532bSDmitry Karpeev @*/
205108da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
205208da532bSDmitry Karpeev {
205308da532bSDmitry Karpeev   PetscFunctionBegin;
205408da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
205508da532bSDmitry Karpeev   PetscFunctionReturn(0);
205608da532bSDmitry Karpeev }
205708da532bSDmitry Karpeev 
205808da532bSDmitry Karpeev #undef __FUNCT__
205908da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
206008da532bSDmitry Karpeev /*@
206108da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
206208da532bSDmitry Karpeev 
206308da532bSDmitry Karpeev     Not Collective
206408da532bSDmitry Karpeev 
206508da532bSDmitry Karpeev     Input Parameter:
206608da532bSDmitry Karpeev .   dm - the DM object to destroy
206708da532bSDmitry Karpeev 
206808da532bSDmitry Karpeev     Output Parameter:
206908da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
207008da532bSDmitry Karpeev 
207108da532bSDmitry Karpeev     Level: developer
207208da532bSDmitry Karpeev 
2073e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
207408da532bSDmitry Karpeev 
207508da532bSDmitry Karpeev @*/
207608da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
207708da532bSDmitry Karpeev {
207808da532bSDmitry Karpeev   PetscFunctionBegin;
207908da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
208008da532bSDmitry Karpeev   PetscFunctionReturn(0);
208108da532bSDmitry Karpeev }
208208da532bSDmitry Karpeev 
208308da532bSDmitry Karpeev #undef __FUNCT__
208408da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
208508da532bSDmitry Karpeev /*@C
208608da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
208708da532bSDmitry Karpeev 
208808da532bSDmitry Karpeev     Logically Collective on DM
208908da532bSDmitry Karpeev 
209008da532bSDmitry Karpeev     Input Parameters:
209108da532bSDmitry Karpeev +   dm - the DM object to destroy
209208da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
209308da532bSDmitry Karpeev 
209408da532bSDmitry Karpeev     Output parameters:
209508da532bSDmitry Karpeev +   xl - lower bound
209608da532bSDmitry Karpeev -   xu - upper bound
209708da532bSDmitry Karpeev 
209808da532bSDmitry Karpeev     Level: intermediate
209908da532bSDmitry Karpeev 
2100e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
210108da532bSDmitry Karpeev          DMSetFunction(), DMSetVariableBounds()
210208da532bSDmitry Karpeev 
210308da532bSDmitry Karpeev @*/
210408da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
210508da532bSDmitry Karpeev {
210608da532bSDmitry Karpeev   PetscErrorCode ierr;
210708da532bSDmitry Karpeev   PetscFunctionBegin;
210808da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
210908da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
211008da532bSDmitry Karpeev   if(dm->ops->computevariablebounds) {
211108da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
211208da532bSDmitry Karpeev   }
211308da532bSDmitry Karpeev   else {
211408da532bSDmitry Karpeev     ierr = VecSet(xl,SNES_VI_NINF); CHKERRQ(ierr);
211508da532bSDmitry Karpeev     ierr = VecSet(xu,SNES_VI_INF);  CHKERRQ(ierr);
211608da532bSDmitry Karpeev   }
211708da532bSDmitry Karpeev   PetscFunctionReturn(0);
211808da532bSDmitry Karpeev }
211908da532bSDmitry Karpeev 
212008da532bSDmitry Karpeev #undef __FUNCT__
212147c6ae99SBarry Smith #define __FUNCT__ "DMComputeInitialGuess"
212247c6ae99SBarry Smith /*@
212347c6ae99SBarry Smith     DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers
212447c6ae99SBarry Smith 
212547c6ae99SBarry Smith     Collective on DM
212647c6ae99SBarry Smith 
212747c6ae99SBarry Smith     Input Parameter:
212847c6ae99SBarry Smith +   dm - the DM object to destroy
212947c6ae99SBarry Smith -   x - the vector to hold the initial guess values
213047c6ae99SBarry Smith 
213147c6ae99SBarry Smith     Level: developer
213247c6ae99SBarry Smith 
2133e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat()
213447c6ae99SBarry Smith 
213547c6ae99SBarry Smith @*/
21367087cfbeSBarry Smith PetscErrorCode  DMComputeInitialGuess(DM dm,Vec x)
213747c6ae99SBarry Smith {
213847c6ae99SBarry Smith   PetscErrorCode ierr;
213947c6ae99SBarry Smith   PetscFunctionBegin;
2140171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
214147c6ae99SBarry Smith   if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()");
214247c6ae99SBarry Smith   ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr);
214347c6ae99SBarry Smith   PetscFunctionReturn(0);
214447c6ae99SBarry Smith }
214547c6ae99SBarry Smith 
214647c6ae99SBarry Smith #undef __FUNCT__
214747c6ae99SBarry Smith #define __FUNCT__ "DMHasInitialGuess"
214847c6ae99SBarry Smith /*@
214947c6ae99SBarry Smith     DMHasInitialGuess - does the DM object have an initial guess function
215047c6ae99SBarry Smith 
215147c6ae99SBarry Smith     Not Collective
215247c6ae99SBarry Smith 
215347c6ae99SBarry Smith     Input Parameter:
215447c6ae99SBarry Smith .   dm - the DM object to destroy
215547c6ae99SBarry Smith 
215647c6ae99SBarry Smith     Output Parameter:
215747c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
215847c6ae99SBarry Smith 
215947c6ae99SBarry Smith     Level: developer
216047c6ae99SBarry Smith 
2161e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
216247c6ae99SBarry Smith 
216347c6ae99SBarry Smith @*/
21647087cfbeSBarry Smith PetscErrorCode  DMHasInitialGuess(DM dm,PetscBool  *flg)
216547c6ae99SBarry Smith {
216647c6ae99SBarry Smith   PetscFunctionBegin;
2167171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
216847c6ae99SBarry Smith   *flg =  (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE;
216947c6ae99SBarry Smith   PetscFunctionReturn(0);
217047c6ae99SBarry Smith }
217147c6ae99SBarry Smith 
217247c6ae99SBarry Smith #undef __FUNCT__
217347c6ae99SBarry Smith #define __FUNCT__ "DMHasFunction"
217447c6ae99SBarry Smith /*@
217547c6ae99SBarry Smith     DMHasFunction - does the DM object have a function
217647c6ae99SBarry Smith 
217747c6ae99SBarry Smith     Not Collective
217847c6ae99SBarry Smith 
217947c6ae99SBarry Smith     Input Parameter:
218047c6ae99SBarry Smith .   dm - the DM object to destroy
218147c6ae99SBarry Smith 
218247c6ae99SBarry Smith     Output Parameter:
218347c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
218447c6ae99SBarry Smith 
218547c6ae99SBarry Smith     Level: developer
218647c6ae99SBarry Smith 
2187e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
218847c6ae99SBarry Smith 
218947c6ae99SBarry Smith @*/
21907087cfbeSBarry Smith PetscErrorCode  DMHasFunction(DM dm,PetscBool  *flg)
219147c6ae99SBarry Smith {
219247c6ae99SBarry Smith   PetscFunctionBegin;
2193171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
219447c6ae99SBarry Smith   *flg =  (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE;
219547c6ae99SBarry Smith   PetscFunctionReturn(0);
219647c6ae99SBarry Smith }
219747c6ae99SBarry Smith 
219847c6ae99SBarry Smith #undef __FUNCT__
219947c6ae99SBarry Smith #define __FUNCT__ "DMHasJacobian"
220047c6ae99SBarry Smith /*@
220147c6ae99SBarry Smith     DMHasJacobian - does the DM object have a matrix function
220247c6ae99SBarry Smith 
220347c6ae99SBarry Smith     Not Collective
220447c6ae99SBarry Smith 
220547c6ae99SBarry Smith     Input Parameter:
220647c6ae99SBarry Smith .   dm - the DM object to destroy
220747c6ae99SBarry Smith 
220847c6ae99SBarry Smith     Output Parameter:
220947c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
221047c6ae99SBarry Smith 
221147c6ae99SBarry Smith     Level: developer
221247c6ae99SBarry Smith 
2213e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
221447c6ae99SBarry Smith 
221547c6ae99SBarry Smith @*/
22167087cfbeSBarry Smith PetscErrorCode  DMHasJacobian(DM dm,PetscBool  *flg)
221747c6ae99SBarry Smith {
221847c6ae99SBarry Smith   PetscFunctionBegin;
2219171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
222047c6ae99SBarry Smith   *flg =  (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE;
222147c6ae99SBarry Smith   PetscFunctionReturn(0);
222247c6ae99SBarry Smith }
222347c6ae99SBarry Smith 
222447c6ae99SBarry Smith #undef  __FUNCT__
222508da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2226748fac09SDmitry Karpeev /*@C
222708da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
222808da532bSDmitry Karpeev 
222908da532bSDmitry Karpeev     Collective on DM
223008da532bSDmitry Karpeev 
223108da532bSDmitry Karpeev     Input Parameter:
223208da532bSDmitry Karpeev +   dm - the DM object
2233e88d7f4bSDmitry Karpeev -   x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems.
223408da532bSDmitry Karpeev 
223508da532bSDmitry Karpeev     Level: developer
223608da532bSDmitry Karpeev 
2237e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
223808da532bSDmitry Karpeev          DMSetFunction(), DMSetJacobian(), DMSetVariableBounds()
223908da532bSDmitry Karpeev 
224008da532bSDmitry Karpeev @*/
224108da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
224208da532bSDmitry Karpeev {
224308da532bSDmitry Karpeev   PetscErrorCode ierr;
224408da532bSDmitry Karpeev   PetscFunctionBegin;
224508da532bSDmitry Karpeev   if (x) {
224608da532bSDmitry Karpeev     if (!dm->x) {
224708da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
224808da532bSDmitry Karpeev     }
224908da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
225008da532bSDmitry Karpeev   }
225108da532bSDmitry Karpeev   else if(dm->x) {
225208da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
225308da532bSDmitry Karpeev   }
225408da532bSDmitry Karpeev   PetscFunctionReturn(0);
225508da532bSDmitry Karpeev }
225608da532bSDmitry Karpeev 
225708da532bSDmitry Karpeev 
225808da532bSDmitry Karpeev #undef __FUNCT__
225947c6ae99SBarry Smith #define __FUNCT__ "DMComputeFunction"
226047c6ae99SBarry Smith /*@
226147c6ae99SBarry Smith     DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES
226247c6ae99SBarry Smith 
226347c6ae99SBarry Smith     Collective on DM
226447c6ae99SBarry Smith 
226547c6ae99SBarry Smith     Input Parameter:
226647c6ae99SBarry Smith +   dm - the DM object to destroy
226747c6ae99SBarry Smith .   x - the location where the function is evaluationed, may be ignored for linear problems
226847c6ae99SBarry Smith -   b - the vector to hold the right hand side entries
226947c6ae99SBarry Smith 
227047c6ae99SBarry Smith     Level: developer
227147c6ae99SBarry Smith 
2272e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
227347c6ae99SBarry Smith          DMSetJacobian()
227447c6ae99SBarry Smith 
227547c6ae99SBarry Smith @*/
22767087cfbeSBarry Smith PetscErrorCode  DMComputeFunction(DM dm,Vec x,Vec b)
227747c6ae99SBarry Smith {
227847c6ae99SBarry Smith   PetscErrorCode ierr;
227947c6ae99SBarry Smith   PetscFunctionBegin;
2280171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
228147c6ae99SBarry Smith   if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()");
2282644e2e5bSBarry Smith   PetscStackPush("DM user function");
228347c6ae99SBarry Smith   ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr);
2284644e2e5bSBarry Smith   PetscStackPop;
228547c6ae99SBarry Smith   PetscFunctionReturn(0);
228647c6ae99SBarry Smith }
228747c6ae99SBarry Smith 
228847c6ae99SBarry Smith 
228908da532bSDmitry Karpeev 
229047c6ae99SBarry Smith #undef __FUNCT__
229147c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobian"
229247c6ae99SBarry Smith /*@
229347c6ae99SBarry Smith     DMComputeJacobian - compute the matrix entries for the solver
229447c6ae99SBarry Smith 
229547c6ae99SBarry Smith     Collective on DM
229647c6ae99SBarry Smith 
229747c6ae99SBarry Smith     Input Parameter:
229847c6ae99SBarry Smith +   dm - the DM object
2299cab2e9ccSBarry Smith .   x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM
230047c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
230147c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
230247c6ae99SBarry Smith 
230347c6ae99SBarry Smith     Level: developer
230447c6ae99SBarry Smith 
2305e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
230647c6ae99SBarry Smith          DMSetFunction()
230747c6ae99SBarry Smith 
230847c6ae99SBarry Smith @*/
23097087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
231047c6ae99SBarry Smith {
231147c6ae99SBarry Smith   PetscErrorCode ierr;
231247c6ae99SBarry Smith 
231347c6ae99SBarry Smith   PetscFunctionBegin;
2314171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
231547c6ae99SBarry Smith   if (!dm->ops->jacobian) {
231647c6ae99SBarry Smith     ISColoring     coloring;
231747c6ae99SBarry Smith     MatFDColoring  fd;
23182c9966d7SBarry Smith     const MatType  mtype;
231947c6ae99SBarry Smith 
23202c9966d7SBarry Smith     ierr = PetscObjectGetType((PetscObject)B,&mtype);CHKERRQ(ierr);
23212c9966d7SBarry Smith     ierr = DMCreateColoring(dm,dm->coloringtype,mtype,&coloring);CHKERRQ(ierr);
232247c6ae99SBarry Smith     ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr);
2323fcfd50ebSBarry Smith     ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
232447c6ae99SBarry Smith     ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr);
23250bdded8aSJed Brown     ierr = PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);CHKERRQ(ierr);
23260bdded8aSJed Brown     ierr = MatFDColoringSetFromOptions(fd);CHKERRQ(ierr);
232771cd77b2SBarry Smith 
232847c6ae99SBarry Smith     dm->fd = fd;
232947c6ae99SBarry Smith     dm->ops->jacobian = DMComputeJacobianDefault;
23302533e041SBarry Smith 
233171cd77b2SBarry Smith     /* don't know why this is needed */
233271cd77b2SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
233347c6ae99SBarry Smith   }
233447c6ae99SBarry Smith   if (!x) x = dm->x;
233547c6ae99SBarry Smith   ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr);
2336cab2e9ccSBarry Smith 
233771cd77b2SBarry 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 */
2338649052a6SBarry Smith   if (x) {
2339cab2e9ccSBarry Smith     if (!dm->x) {
234071cd77b2SBarry Smith       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
2341cab2e9ccSBarry Smith     }
2342cab2e9ccSBarry Smith     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
2343649052a6SBarry Smith   }
2344a8248277SBarry Smith   if (A != B) {
2345a8248277SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2346a8248277SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2347a8248277SBarry Smith   }
234847c6ae99SBarry Smith   PetscFunctionReturn(0);
234947c6ae99SBarry Smith }
2350264ace61SBarry Smith 
2351cab2e9ccSBarry Smith 
2352264ace61SBarry Smith PetscFList DMList                       = PETSC_NULL;
2353264ace61SBarry Smith PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
2354264ace61SBarry Smith 
2355264ace61SBarry Smith #undef __FUNCT__
2356264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2357264ace61SBarry Smith /*@C
2358264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2359264ace61SBarry Smith 
2360264ace61SBarry Smith   Collective on DM
2361264ace61SBarry Smith 
2362264ace61SBarry Smith   Input Parameters:
2363264ace61SBarry Smith + dm     - The DM object
2364264ace61SBarry Smith - method - The name of the DM type
2365264ace61SBarry Smith 
2366264ace61SBarry Smith   Options Database Key:
2367264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2368264ace61SBarry Smith 
2369264ace61SBarry Smith   Notes:
2370e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2371264ace61SBarry Smith 
2372264ace61SBarry Smith   Level: intermediate
2373264ace61SBarry Smith 
2374264ace61SBarry Smith .keywords: DM, set, type
2375264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2376264ace61SBarry Smith @*/
23777087cfbeSBarry Smith PetscErrorCode  DMSetType(DM dm, const DMType method)
2378264ace61SBarry Smith {
2379264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2380264ace61SBarry Smith   PetscBool      match;
2381264ace61SBarry Smith   PetscErrorCode ierr;
2382264ace61SBarry Smith 
2383264ace61SBarry Smith   PetscFunctionBegin;
2384264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2385251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2386264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2387264ace61SBarry Smith 
2388264ace61SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
23894b91b6eaSBarry Smith   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2390264ace61SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2391264ace61SBarry Smith 
2392264ace61SBarry Smith   if (dm->ops->destroy) {
2393264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
2394b5c23020SJed Brown     dm->ops->destroy = PETSC_NULL;
2395264ace61SBarry Smith   }
2396264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2397264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2398264ace61SBarry Smith   PetscFunctionReturn(0);
2399264ace61SBarry Smith }
2400264ace61SBarry Smith 
2401264ace61SBarry Smith #undef __FUNCT__
2402264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2403264ace61SBarry Smith /*@C
2404264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2405264ace61SBarry Smith 
2406264ace61SBarry Smith   Not Collective
2407264ace61SBarry Smith 
2408264ace61SBarry Smith   Input Parameter:
2409264ace61SBarry Smith . dm  - The DM
2410264ace61SBarry Smith 
2411264ace61SBarry Smith   Output Parameter:
2412264ace61SBarry Smith . type - The DM type name
2413264ace61SBarry Smith 
2414264ace61SBarry Smith   Level: intermediate
2415264ace61SBarry Smith 
2416264ace61SBarry Smith .keywords: DM, get, type, name
2417264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2418264ace61SBarry Smith @*/
24197087cfbeSBarry Smith PetscErrorCode  DMGetType(DM dm, const DMType *type)
2420264ace61SBarry Smith {
2421264ace61SBarry Smith   PetscErrorCode ierr;
2422264ace61SBarry Smith 
2423264ace61SBarry Smith   PetscFunctionBegin;
2424264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2425264ace61SBarry Smith   PetscValidCharPointer(type,2);
2426264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2427264ace61SBarry Smith     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2428264ace61SBarry Smith   }
2429264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2430264ace61SBarry Smith   PetscFunctionReturn(0);
2431264ace61SBarry Smith }
2432264ace61SBarry Smith 
243367a56275SMatthew G Knepley #undef __FUNCT__
243467a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
243567a56275SMatthew G Knepley /*@C
243667a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
243767a56275SMatthew G Knepley 
243867a56275SMatthew G Knepley   Collective on DM
243967a56275SMatthew G Knepley 
244067a56275SMatthew G Knepley   Input Parameters:
244167a56275SMatthew G Knepley + dm - the DM
244267a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
244367a56275SMatthew G Knepley 
244467a56275SMatthew G Knepley   Output Parameter:
244567a56275SMatthew G Knepley . M - pointer to new DM
244667a56275SMatthew G Knepley 
244767a56275SMatthew G Knepley   Notes:
244867a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
244967a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
245067a56275SMatthew G Knepley   of the input DM.
245167a56275SMatthew G Knepley 
245267a56275SMatthew G Knepley   Level: intermediate
245367a56275SMatthew G Knepley 
245467a56275SMatthew G Knepley .seealso: DMCreate()
245567a56275SMatthew G Knepley @*/
245667a56275SMatthew G Knepley PetscErrorCode DMConvert(DM dm, const DMType newtype, DM *M)
245767a56275SMatthew G Knepley {
245867a56275SMatthew G Knepley   DM             B;
245967a56275SMatthew G Knepley   char           convname[256];
246067a56275SMatthew G Knepley   PetscBool      sametype, issame;
246167a56275SMatthew G Knepley   PetscErrorCode ierr;
246267a56275SMatthew G Knepley 
246367a56275SMatthew G Knepley   PetscFunctionBegin;
246467a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
246567a56275SMatthew G Knepley   PetscValidType(dm,1);
246667a56275SMatthew G Knepley   PetscValidPointer(M,3);
2467251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
246867a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
246967a56275SMatthew G Knepley   {
247067a56275SMatthew G Knepley     PetscErrorCode (*conv)(DM, const DMType, DM *) = PETSC_NULL;
247167a56275SMatthew G Knepley 
247267a56275SMatthew G Knepley     /*
247367a56275SMatthew G Knepley        Order of precedence:
247467a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
247567a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
247667a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
247767a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
247867a56275SMatthew G Knepley        5) Use a really basic converter.
247967a56275SMatthew G Knepley     */
248067a56275SMatthew G Knepley 
248167a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
248267a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
248367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
248467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
248567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
248667a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
248767a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
248867a56275SMatthew G Knepley     if (conv) goto foundconv;
248967a56275SMatthew G Knepley 
249067a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
249167a56275SMatthew G Knepley     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
249267a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
249367a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
249467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
249567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
249667a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
249767a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
249867a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
249967a56275SMatthew G Knepley     if (conv) {
2500fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
250167a56275SMatthew G Knepley       goto foundconv;
250267a56275SMatthew G Knepley     }
250367a56275SMatthew G Knepley 
250467a56275SMatthew G Knepley #if 0
250567a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
250667a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2507fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
250867a56275SMatthew G Knepley     if (conv) goto foundconv;
250967a56275SMatthew G Knepley 
251067a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
251167a56275SMatthew G Knepley     if (dm->ops->convert) {
251267a56275SMatthew G Knepley       conv = dm->ops->convert;
251367a56275SMatthew G Knepley     }
251467a56275SMatthew G Knepley     if (conv) goto foundconv;
251567a56275SMatthew G Knepley #endif
251667a56275SMatthew G Knepley 
251767a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
251867a56275SMatthew G Knepley     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
251967a56275SMatthew G Knepley 
252067a56275SMatthew G Knepley     foundconv:
252167a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
252267a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
252367a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
252467a56275SMatthew G Knepley   }
252567a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
252667a56275SMatthew G Knepley   PetscFunctionReturn(0);
252767a56275SMatthew G Knepley }
2528264ace61SBarry Smith 
2529264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2530264ace61SBarry Smith 
2531264ace61SBarry Smith #undef __FUNCT__
2532264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2533264ace61SBarry Smith /*@C
2534264ace61SBarry Smith   DMRegister - See DMRegisterDynamic()
2535264ace61SBarry Smith 
2536264ace61SBarry Smith   Level: advanced
2537264ace61SBarry Smith @*/
25387087cfbeSBarry Smith PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
2539264ace61SBarry Smith {
2540264ace61SBarry Smith   char fullname[PETSC_MAX_PATH_LEN];
2541264ace61SBarry Smith   PetscErrorCode ierr;
2542264ace61SBarry Smith 
2543264ace61SBarry Smith   PetscFunctionBegin;
2544264ace61SBarry Smith   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
2545264ace61SBarry Smith   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
2546264ace61SBarry Smith   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
2547264ace61SBarry Smith   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
2548264ace61SBarry Smith   PetscFunctionReturn(0);
2549264ace61SBarry Smith }
2550264ace61SBarry Smith 
2551264ace61SBarry Smith 
2552264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2553264ace61SBarry Smith #undef __FUNCT__
2554264ace61SBarry Smith #define __FUNCT__ "DMRegisterDestroy"
2555264ace61SBarry Smith /*@C
2556264ace61SBarry Smith    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
2557264ace61SBarry Smith 
2558264ace61SBarry Smith    Not Collective
2559264ace61SBarry Smith 
2560264ace61SBarry Smith    Level: advanced
2561264ace61SBarry Smith 
2562264ace61SBarry Smith .keywords: DM, register, destroy
2563264ace61SBarry Smith .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
2564264ace61SBarry Smith @*/
25657087cfbeSBarry Smith PetscErrorCode  DMRegisterDestroy(void)
2566264ace61SBarry Smith {
2567264ace61SBarry Smith   PetscErrorCode ierr;
2568264ace61SBarry Smith 
2569264ace61SBarry Smith   PetscFunctionBegin;
2570264ace61SBarry Smith   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
2571264ace61SBarry Smith   DMRegisterAllCalled = PETSC_FALSE;
2572264ace61SBarry Smith   PetscFunctionReturn(0);
2573264ace61SBarry Smith }
257423f975d1SBarry Smith 
257523f975d1SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2576c6db04a5SJed Brown #include <mex.h>
257723f975d1SBarry Smith 
25783014e516SBarry Smith typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext;
257923f975d1SBarry Smith 
258023f975d1SBarry Smith #undef __FUNCT__
258123f975d1SBarry Smith #define __FUNCT__ "DMComputeFunction_Matlab"
258223f975d1SBarry Smith /*
258323f975d1SBarry Smith    DMComputeFunction_Matlab - Calls the function that has been set with
258423f975d1SBarry Smith                          DMSetFunctionMatlab().
258523f975d1SBarry Smith 
258623f975d1SBarry Smith    For linear problems x is null
258723f975d1SBarry Smith 
258823f975d1SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
258923f975d1SBarry Smith */
25907087cfbeSBarry Smith PetscErrorCode  DMComputeFunction_Matlab(DM dm,Vec x,Vec y)
259123f975d1SBarry Smith {
259223f975d1SBarry Smith   PetscErrorCode    ierr;
259323f975d1SBarry Smith   DMMatlabContext   *sctx;
259423f975d1SBarry Smith   int               nlhs = 1,nrhs = 4;
259523f975d1SBarry Smith   mxArray	    *plhs[1],*prhs[4];
259623f975d1SBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
259723f975d1SBarry Smith 
259823f975d1SBarry Smith   PetscFunctionBegin;
259923f975d1SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
260023f975d1SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
260123f975d1SBarry Smith   PetscCheckSameComm(dm,1,y,3);
260223f975d1SBarry Smith 
260323f975d1SBarry Smith   /* call Matlab function in ctx with arguments x and y */
26041b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
260523f975d1SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
260623f975d1SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
26073014e516SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr);
260823f975d1SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
260923f975d1SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
261023f975d1SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
261123f975d1SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
2612b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr);
261323f975d1SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
261423f975d1SBarry Smith   mxDestroyArray(prhs[0]);
261523f975d1SBarry Smith   mxDestroyArray(prhs[1]);
261623f975d1SBarry Smith   mxDestroyArray(prhs[2]);
261723f975d1SBarry Smith   mxDestroyArray(prhs[3]);
261823f975d1SBarry Smith   mxDestroyArray(plhs[0]);
261923f975d1SBarry Smith   PetscFunctionReturn(0);
262023f975d1SBarry Smith }
262123f975d1SBarry Smith 
262223f975d1SBarry Smith 
262323f975d1SBarry Smith #undef __FUNCT__
262423f975d1SBarry Smith #define __FUNCT__ "DMSetFunctionMatlab"
262523f975d1SBarry Smith /*
262623f975d1SBarry Smith    DMSetFunctionMatlab - Sets the function evaluation routine
262723f975d1SBarry Smith 
262823f975d1SBarry Smith */
26297087cfbeSBarry Smith PetscErrorCode  DMSetFunctionMatlab(DM dm,const char *func)
263023f975d1SBarry Smith {
263123f975d1SBarry Smith   PetscErrorCode    ierr;
263223f975d1SBarry Smith   DMMatlabContext   *sctx;
263323f975d1SBarry Smith 
263423f975d1SBarry Smith   PetscFunctionBegin;
2635171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
263623f975d1SBarry Smith   /* currently sctx is memory bleed */
26371b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
26383014e516SBarry Smith   if (!sctx) {
263923f975d1SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
26403014e516SBarry Smith   }
264123f975d1SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
26421b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
264323f975d1SBarry Smith   ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr);
264423f975d1SBarry Smith   PetscFunctionReturn(0);
264523f975d1SBarry Smith }
26463014e516SBarry Smith 
26473014e516SBarry Smith #undef __FUNCT__
26483014e516SBarry Smith #define __FUNCT__ "DMComputeJacobian_Matlab"
26493014e516SBarry Smith /*
26503014e516SBarry Smith    DMComputeJacobian_Matlab - Calls the function that has been set with
26513014e516SBarry Smith                          DMSetJacobianMatlab().
26523014e516SBarry Smith 
26533014e516SBarry Smith    For linear problems x is null
26543014e516SBarry Smith 
26553014e516SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
26563014e516SBarry Smith */
26577087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str)
26583014e516SBarry Smith {
26593014e516SBarry Smith   PetscErrorCode    ierr;
26603014e516SBarry Smith   DMMatlabContext   *sctx;
26613014e516SBarry Smith   int               nlhs = 2,nrhs = 5;
26623014e516SBarry Smith   mxArray	    *plhs[2],*prhs[5];
26633014e516SBarry Smith   long long int     lx = 0,lA = 0,lB = 0,ls = 0;
26643014e516SBarry Smith 
26653014e516SBarry Smith   PetscFunctionBegin;
26663014e516SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
26673014e516SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
26683014e516SBarry Smith 
2669e3c5b3baSBarry Smith   /* call MATLAB function in ctx with arguments x, A, and B */
26701b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
26713014e516SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
26723014e516SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
26733014e516SBarry Smith   ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr);
26743014e516SBarry Smith   ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr);
26753014e516SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
26763014e516SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
26773014e516SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
26783014e516SBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
26793014e516SBarry Smith   prhs[4] =  mxCreateString(sctx->jacname);
2680b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr);
2681c980e822SBarry Smith   *str    =  (MatStructure) mxGetScalar(plhs[0]);
2682c088a8dcSBarry Smith   ierr    =  (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr);
26833014e516SBarry Smith   mxDestroyArray(prhs[0]);
26843014e516SBarry Smith   mxDestroyArray(prhs[1]);
26853014e516SBarry Smith   mxDestroyArray(prhs[2]);
26863014e516SBarry Smith   mxDestroyArray(prhs[3]);
26873014e516SBarry Smith   mxDestroyArray(prhs[4]);
26883014e516SBarry Smith   mxDestroyArray(plhs[0]);
26893014e516SBarry Smith   mxDestroyArray(plhs[1]);
26903014e516SBarry Smith   PetscFunctionReturn(0);
26913014e516SBarry Smith }
26923014e516SBarry Smith 
26933014e516SBarry Smith 
26943014e516SBarry Smith #undef __FUNCT__
26953014e516SBarry Smith #define __FUNCT__ "DMSetJacobianMatlab"
26963014e516SBarry Smith /*
26973014e516SBarry Smith    DMSetJacobianMatlab - Sets the Jacobian function evaluation routine
26983014e516SBarry Smith 
26993014e516SBarry Smith */
27007087cfbeSBarry Smith PetscErrorCode  DMSetJacobianMatlab(DM dm,const char *func)
27013014e516SBarry Smith {
27023014e516SBarry Smith   PetscErrorCode    ierr;
27033014e516SBarry Smith   DMMatlabContext   *sctx;
27043014e516SBarry Smith 
27053014e516SBarry Smith   PetscFunctionBegin;
2706171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
27073014e516SBarry Smith   /* currently sctx is memory bleed */
27081b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
27093014e516SBarry Smith   if (!sctx) {
27103014e516SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
27113014e516SBarry Smith   }
27123014e516SBarry Smith   ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr);
27131b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
27143014e516SBarry Smith   ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr);
27153014e516SBarry Smith   PetscFunctionReturn(0);
27163014e516SBarry Smith }
271723f975d1SBarry Smith #endif
2718b859378eSBarry Smith 
2719b859378eSBarry Smith #undef __FUNCT__
2720b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2721b859378eSBarry Smith /*@C
2722b859378eSBarry Smith   DMLoad - Loads a DM that has been stored in binary or HDF5 format
2723b859378eSBarry Smith   with DMView().
2724b859378eSBarry Smith 
2725b859378eSBarry Smith   Collective on PetscViewer
2726b859378eSBarry Smith 
2727b859378eSBarry Smith   Input Parameters:
2728b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2729b859378eSBarry Smith            some related function before a call to DMLoad().
2730b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2731b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2732b859378eSBarry Smith 
2733b859378eSBarry Smith    Level: intermediate
2734b859378eSBarry Smith 
2735b859378eSBarry Smith   Notes:
2736b859378eSBarry Smith   Defaults to the DM DA.
2737b859378eSBarry Smith 
2738b859378eSBarry Smith   Notes for advanced users:
2739b859378eSBarry Smith   Most users should not need to know the details of the binary storage
2740b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
2741b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
2742b859378eSBarry Smith   format is
2743b859378eSBarry Smith .vb
2744b859378eSBarry Smith      has not yet been determined
2745b859378eSBarry Smith .ve
2746b859378eSBarry Smith 
2747b859378eSBarry Smith    In addition, PETSc automatically does the byte swapping for
2748b859378eSBarry Smith machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
2749b859378eSBarry Smith linux, Windows and the paragon; thus if you write your own binary
2750b859378eSBarry Smith read/write routines you have to swap the bytes; see PetscBinaryRead()
2751b859378eSBarry Smith and PetscBinaryWrite() to see how this may be done.
2752b859378eSBarry Smith 
2753b859378eSBarry Smith   Concepts: vector^loading from file
2754b859378eSBarry Smith 
2755b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2756b859378eSBarry Smith @*/
2757b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2758b859378eSBarry Smith {
2759b859378eSBarry Smith   PetscErrorCode ierr;
2760b859378eSBarry Smith 
2761b859378eSBarry Smith   PetscFunctionBegin;
2762b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2763b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
2764b859378eSBarry Smith 
2765b859378eSBarry Smith   if (!((PetscObject)newdm)->type_name) {
2766b859378eSBarry Smith     ierr = DMSetType(newdm, DMDA);CHKERRQ(ierr);
2767b859378eSBarry Smith   }
2768b859378eSBarry Smith   ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
2769b859378eSBarry Smith   PetscFunctionReturn(0);
2770b859378eSBarry Smith }
2771b859378eSBarry Smith 
27727da65231SMatthew G Knepley /******************************** FEM Support **********************************/
27737da65231SMatthew G Knepley 
27747da65231SMatthew G Knepley #undef __FUNCT__
27757da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
27767da65231SMatthew G Knepley PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
27771d47ebbbSSatish Balay   PetscInt       f;
27781b30c384SMatthew G Knepley   PetscErrorCode ierr;
27791b30c384SMatthew G Knepley 
27807da65231SMatthew G Knepley   PetscFunctionBegin;
278174778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
27821d47ebbbSSatish Balay   for(f = 0; f < len; ++f) {
278374778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
27847da65231SMatthew G Knepley   }
27857da65231SMatthew G Knepley   PetscFunctionReturn(0);
27867da65231SMatthew G Knepley }
27877da65231SMatthew G Knepley 
27887da65231SMatthew G Knepley #undef __FUNCT__
27897da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
27907da65231SMatthew G Knepley PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
27911b30c384SMatthew G Knepley   PetscInt       f, g;
27927da65231SMatthew G Knepley   PetscErrorCode ierr;
27937da65231SMatthew G Knepley 
27947da65231SMatthew G Knepley   PetscFunctionBegin;
279574778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
27961d47ebbbSSatish Balay   for(f = 0; f < rows; ++f) {
279774778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
27981d47ebbbSSatish Balay     for(g = 0; g < cols; ++g) {
279974778d6cSJed Brown       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
28007da65231SMatthew G Knepley     }
280174778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
28027da65231SMatthew G Knepley   }
28037da65231SMatthew G Knepley   PetscFunctionReturn(0);
28047da65231SMatthew G Knepley }
2805e7c4fc90SDmitry Karpeev 
2806970e74d5SMatthew G Knepley #undef __FUNCT__
2807970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalFunction"
2808970e74d5SMatthew G Knepley /*@C
2809970e74d5SMatthew G Knepley   DMGetLocalFunction - Get the local residual function from this DM
2810970e74d5SMatthew G Knepley 
2811970e74d5SMatthew G Knepley   Not collective
2812970e74d5SMatthew G Knepley 
2813970e74d5SMatthew G Knepley   Input Parameter:
2814970e74d5SMatthew G Knepley . dm - The DM
2815970e74d5SMatthew G Knepley 
2816970e74d5SMatthew G Knepley   Output Parameter:
2817970e74d5SMatthew G Knepley . lf - The local residual function
2818970e74d5SMatthew G Knepley 
2819970e74d5SMatthew G Knepley    Calling sequence of lf:
2820970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
2821970e74d5SMatthew G Knepley 
2822970e74d5SMatthew G Knepley +  snes - the SNES context
2823970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2824970e74d5SMatthew G Knepley .  f - local vector to put residual in
2825970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2826970e74d5SMatthew G Knepley 
2827970e74d5SMatthew G Knepley   Level: intermediate
2828970e74d5SMatthew G Knepley 
2829970e74d5SMatthew G Knepley .seealso DMSetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
2830970e74d5SMatthew G Knepley @*/
2831970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalFunction(DM dm, PetscErrorCode (**lf)(DM, Vec, Vec, void *))
2832970e74d5SMatthew G Knepley {
2833970e74d5SMatthew G Knepley   PetscFunctionBegin;
2834970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2835970e74d5SMatthew G Knepley   if (lf) *lf = dm->lf;
2836970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2837970e74d5SMatthew G Knepley }
2838970e74d5SMatthew G Knepley 
2839970e74d5SMatthew G Knepley #undef __FUNCT__
2840970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalFunction"
2841970e74d5SMatthew G Knepley /*@C
2842970e74d5SMatthew G Knepley   DMSetLocalFunction - Set the local residual function from this DM
2843970e74d5SMatthew G Knepley 
2844970e74d5SMatthew G Knepley   Not collective
2845970e74d5SMatthew G Knepley 
2846970e74d5SMatthew G Knepley   Input Parameters:
2847970e74d5SMatthew G Knepley + dm - The DM
2848970e74d5SMatthew G Knepley - lf - The local residual function
2849970e74d5SMatthew G Knepley 
2850970e74d5SMatthew G Knepley    Calling sequence of lf:
2851970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
2852970e74d5SMatthew G Knepley 
2853970e74d5SMatthew G Knepley +  snes - the SNES context
2854970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2855970e74d5SMatthew G Knepley .  f - local vector to put residual in
2856970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2857970e74d5SMatthew G Knepley 
2858970e74d5SMatthew G Knepley   Level: intermediate
2859970e74d5SMatthew G Knepley 
2860970e74d5SMatthew G Knepley .seealso DMGetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
2861970e74d5SMatthew G Knepley @*/
2862970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalFunction(DM dm, PetscErrorCode (*lf)(DM, Vec, Vec, void *))
2863970e74d5SMatthew G Knepley {
2864970e74d5SMatthew G Knepley   PetscFunctionBegin;
2865970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2866970e74d5SMatthew G Knepley   dm->lf = lf;
2867970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2868970e74d5SMatthew G Knepley }
2869970e74d5SMatthew G Knepley 
2870970e74d5SMatthew G Knepley #undef __FUNCT__
2871970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalJacobian"
2872970e74d5SMatthew G Knepley /*@C
2873970e74d5SMatthew G Knepley   DMGetLocalJacobian - Get the local Jacobian function from this DM
2874970e74d5SMatthew G Knepley 
2875970e74d5SMatthew G Knepley   Not collective
2876970e74d5SMatthew G Knepley 
2877970e74d5SMatthew G Knepley   Input Parameter:
2878970e74d5SMatthew G Knepley . dm - The DM
2879970e74d5SMatthew G Knepley 
2880970e74d5SMatthew G Knepley   Output Parameter:
2881970e74d5SMatthew G Knepley . lj - The local Jacobian function
2882970e74d5SMatthew G Knepley 
2883970e74d5SMatthew G Knepley    Calling sequence of lj:
2884970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
2885970e74d5SMatthew G Knepley 
2886970e74d5SMatthew G Knepley +  snes - the SNES context
2887970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2888970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
2889970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
2890970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2891970e74d5SMatthew G Knepley 
2892970e74d5SMatthew G Knepley   Level: intermediate
2893970e74d5SMatthew G Knepley 
2894970e74d5SMatthew G Knepley .seealso DMSetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
2895970e74d5SMatthew G Knepley @*/
2896970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalJacobian(DM dm, PetscErrorCode (**lj)(DM, Vec, Mat, Mat, void *))
2897970e74d5SMatthew G Knepley {
2898970e74d5SMatthew G Knepley   PetscFunctionBegin;
2899970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2900970e74d5SMatthew G Knepley   if (lj) *lj = dm->lj;
2901970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2902970e74d5SMatthew G Knepley }
2903970e74d5SMatthew G Knepley 
2904970e74d5SMatthew G Knepley #undef __FUNCT__
2905970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalJacobian"
2906970e74d5SMatthew G Knepley /*@C
2907970e74d5SMatthew G Knepley   DMSetLocalJacobian - Set the local Jacobian function from this DM
2908970e74d5SMatthew G Knepley 
2909970e74d5SMatthew G Knepley   Not collective
2910970e74d5SMatthew G Knepley 
2911970e74d5SMatthew G Knepley   Input Parameters:
2912970e74d5SMatthew G Knepley + dm - The DM
2913970e74d5SMatthew G Knepley - lj - The local Jacobian function
2914970e74d5SMatthew G Knepley 
2915970e74d5SMatthew G Knepley    Calling sequence of lj:
2916970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
2917970e74d5SMatthew G Knepley 
2918970e74d5SMatthew G Knepley +  snes - the SNES context
2919970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
2920970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
2921970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
2922970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
2923970e74d5SMatthew G Knepley 
2924970e74d5SMatthew G Knepley   Level: intermediate
2925970e74d5SMatthew G Knepley 
2926970e74d5SMatthew G Knepley .seealso DMGetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
2927970e74d5SMatthew G Knepley @*/
2928970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalJacobian(DM dm, PetscErrorCode (*lj)(DM, Vec, Mat,  Mat, void *))
2929970e74d5SMatthew G Knepley {
2930970e74d5SMatthew G Knepley   PetscFunctionBegin;
2931970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2932970e74d5SMatthew G Knepley   dm->lj = lj;
2933970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
2934970e74d5SMatthew G Knepley }
293588ed4aceSMatthew G Knepley 
293688ed4aceSMatthew G Knepley #undef __FUNCT__
293788ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
293888ed4aceSMatthew G Knepley /*@
293988ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
294088ed4aceSMatthew G Knepley 
294188ed4aceSMatthew G Knepley   Input Parameter:
294288ed4aceSMatthew G Knepley . dm - The DM
294388ed4aceSMatthew G Knepley 
294488ed4aceSMatthew G Knepley   Output Parameter:
294588ed4aceSMatthew G Knepley . section - The PetscSection
294688ed4aceSMatthew G Knepley 
294788ed4aceSMatthew G Knepley   Level: intermediate
294888ed4aceSMatthew G Knepley 
294988ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
295088ed4aceSMatthew G Knepley 
295188ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
295288ed4aceSMatthew G Knepley @*/
295388ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) {
295488ed4aceSMatthew G Knepley   PetscFunctionBegin;
295588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
295688ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
295788ed4aceSMatthew G Knepley   *section = dm->defaultSection;
295888ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
295988ed4aceSMatthew G Knepley }
296088ed4aceSMatthew G Knepley 
296188ed4aceSMatthew G Knepley #undef __FUNCT__
296288ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
296388ed4aceSMatthew G Knepley /*@
296488ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
296588ed4aceSMatthew G Knepley 
296688ed4aceSMatthew G Knepley   Input Parameters:
296788ed4aceSMatthew G Knepley + dm - The DM
296888ed4aceSMatthew G Knepley - section - The PetscSection
296988ed4aceSMatthew G Knepley 
297088ed4aceSMatthew G Knepley   Level: intermediate
297188ed4aceSMatthew G Knepley 
297288ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
297388ed4aceSMatthew G Knepley 
297488ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
297588ed4aceSMatthew G Knepley @*/
297688ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) {
297788ed4aceSMatthew G Knepley   PetscErrorCode ierr;
297888ed4aceSMatthew G Knepley 
297988ed4aceSMatthew G Knepley   PetscFunctionBegin;
298088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
298188ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
298288ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
298388ed4aceSMatthew G Knepley   dm->defaultSection = section;
298488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
298588ed4aceSMatthew G Knepley }
298688ed4aceSMatthew G Knepley 
298788ed4aceSMatthew G Knepley #undef __FUNCT__
298888ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
298988ed4aceSMatthew G Knepley /*@
299088ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
299188ed4aceSMatthew G Knepley 
299288ed4aceSMatthew G Knepley   Input Parameter:
299388ed4aceSMatthew G Knepley . dm - The DM
299488ed4aceSMatthew G Knepley 
299588ed4aceSMatthew G Knepley   Output Parameter:
299688ed4aceSMatthew G Knepley . section - The PetscSection
299788ed4aceSMatthew G Knepley 
299888ed4aceSMatthew G Knepley   Level: intermediate
299988ed4aceSMatthew G Knepley 
300088ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
300188ed4aceSMatthew G Knepley 
300288ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
300388ed4aceSMatthew G Knepley @*/
300488ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) {
300588ed4aceSMatthew G Knepley   PetscErrorCode ierr;
300688ed4aceSMatthew G Knepley 
300788ed4aceSMatthew G Knepley   PetscFunctionBegin;
300888ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
300988ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
301088ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
301188ed4aceSMatthew G Knepley     ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, &dm->defaultGlobalSection);CHKERRQ(ierr);
301288ed4aceSMatthew G Knepley   }
301388ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
301488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
301588ed4aceSMatthew G Knepley }
301688ed4aceSMatthew G Knepley 
301788ed4aceSMatthew G Knepley #undef __FUNCT__
301888ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
301988ed4aceSMatthew G Knepley /*@
302088ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
302188ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
302288ed4aceSMatthew G Knepley 
302388ed4aceSMatthew G Knepley   Input Parameter:
302488ed4aceSMatthew G Knepley . dm - The DM
302588ed4aceSMatthew G Knepley 
302688ed4aceSMatthew G Knepley   Output Parameter:
302788ed4aceSMatthew G Knepley . sf - The PetscSF
302888ed4aceSMatthew G Knepley 
302988ed4aceSMatthew G Knepley   Level: intermediate
303088ed4aceSMatthew G Knepley 
303188ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
303288ed4aceSMatthew G Knepley 
303388ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
303488ed4aceSMatthew G Knepley @*/
303588ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) {
303688ed4aceSMatthew G Knepley   PetscInt       nroots;
303788ed4aceSMatthew G Knepley   PetscErrorCode ierr;
303888ed4aceSMatthew G Knepley 
303988ed4aceSMatthew G Knepley   PetscFunctionBegin;
304088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
304188ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
304288ed4aceSMatthew G Knepley   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
304388ed4aceSMatthew G Knepley   if (nroots < 0) {
304488ed4aceSMatthew G Knepley     PetscSection section, gSection;
304588ed4aceSMatthew G Knepley 
304688ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
304731ea6d37SMatthew G Knepley     if (section) {
304888ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
304988ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
305031ea6d37SMatthew G Knepley     } else {
305131ea6d37SMatthew G Knepley       *sf = PETSC_NULL;
305231ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
305331ea6d37SMatthew G Knepley     }
305488ed4aceSMatthew G Knepley   }
305588ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
305688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
305788ed4aceSMatthew G Knepley }
305888ed4aceSMatthew G Knepley 
305988ed4aceSMatthew G Knepley #undef __FUNCT__
306088ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
306188ed4aceSMatthew G Knepley /*@
306288ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
306388ed4aceSMatthew G Knepley 
306488ed4aceSMatthew G Knepley   Input Parameters:
306588ed4aceSMatthew G Knepley + dm - The DM
306688ed4aceSMatthew G Knepley - sf - The PetscSF
306788ed4aceSMatthew G Knepley 
306888ed4aceSMatthew G Knepley   Level: intermediate
306988ed4aceSMatthew G Knepley 
307088ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
307188ed4aceSMatthew G Knepley 
307288ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
307388ed4aceSMatthew G Knepley @*/
307488ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) {
307588ed4aceSMatthew G Knepley   PetscErrorCode ierr;
307688ed4aceSMatthew G Knepley 
307788ed4aceSMatthew G Knepley   PetscFunctionBegin;
307888ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
307988ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
308088ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
308188ed4aceSMatthew G Knepley   dm->defaultSF = sf;
308288ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
308388ed4aceSMatthew G Knepley }
308488ed4aceSMatthew G Knepley 
308588ed4aceSMatthew G Knepley #undef __FUNCT__
308688ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
308788ed4aceSMatthew G Knepley /*@C
308888ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
308988ed4aceSMatthew G Knepley   describing the data layout.
309088ed4aceSMatthew G Knepley 
309188ed4aceSMatthew G Knepley   Input Parameters:
309288ed4aceSMatthew G Knepley + dm - The DM
309388ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
309488ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
309588ed4aceSMatthew G Knepley 
309688ed4aceSMatthew G Knepley   Level: intermediate
309788ed4aceSMatthew G Knepley 
309888ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
309988ed4aceSMatthew G Knepley @*/
310088ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
310188ed4aceSMatthew G Knepley {
310288ed4aceSMatthew G Knepley   MPI_Comm        comm = ((PetscObject) dm)->comm;
310388ed4aceSMatthew G Knepley   PetscLayout     layout;
310488ed4aceSMatthew G Knepley   const PetscInt *ranges;
310588ed4aceSMatthew G Knepley   PetscInt       *local;
310688ed4aceSMatthew G Knepley   PetscSFNode    *remote;
310788ed4aceSMatthew G Knepley   PetscInt        pStart, pEnd, p, nroots, nleaves, l;
310888ed4aceSMatthew G Knepley   PetscMPIInt     size, rank;
310988ed4aceSMatthew G Knepley   PetscErrorCode  ierr;
311088ed4aceSMatthew G Knepley 
311188ed4aceSMatthew G Knepley   PetscFunctionBegin;
311288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
311388ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
311488ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
311588ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
311688ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
311788ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
311888ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
311988ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
312088ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
312188ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
312288ed4aceSMatthew G Knepley   for(p = pStart, nleaves = 0; p < pEnd; ++p) {
312388ed4aceSMatthew G Knepley     PetscInt dof, cdof;
312488ed4aceSMatthew G Knepley 
312588ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &dof);CHKERRQ(ierr);
312688ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &cdof);CHKERRQ(ierr);
312788ed4aceSMatthew G Knepley     nleaves += dof < 0 ? -(dof+1)-cdof : dof-cdof;
312888ed4aceSMatthew G Knepley   }
312988ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr);
313088ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr);
313188ed4aceSMatthew G Knepley   for(p = pStart, l = 0; p < pEnd; ++p) {
313288ed4aceSMatthew G Knepley     PetscInt *cind;
313388ed4aceSMatthew G Knepley     PetscInt  dof, gdof, cdof, dim, off, goff, d, c;
313488ed4aceSMatthew G Knepley 
313588ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
313688ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
313788ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
313888ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
313988ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
314088ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
314188ed4aceSMatthew G Knepley     dim  = dof-cdof;
314288ed4aceSMatthew G Knepley     for(d = 0, c = 0; d < dof; ++d) {
314388ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
314488ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
314588ed4aceSMatthew G Knepley     }
314688ed4aceSMatthew G Knepley     if (gdof < 0) {
314788ed4aceSMatthew G Knepley       for(d = 0; d < dim; ++d, ++l) {
314888ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
314988ed4aceSMatthew G Knepley 
315088ed4aceSMatthew G Knepley         for(r = 0; r < size; ++r) {
315188ed4aceSMatthew G Knepley           if ((offset >= ranges[r]) && (offset < ranges[r+1])) break;
315288ed4aceSMatthew G Knepley         }
315388ed4aceSMatthew G Knepley         remote[l].rank  = r;
315488ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
315588ed4aceSMatthew G Knepley       }
315688ed4aceSMatthew G Knepley     } else {
315788ed4aceSMatthew G Knepley       for(d = 0; d < dim; ++d, ++l) {
315888ed4aceSMatthew G Knepley         remote[l].rank  = rank;
315988ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
316088ed4aceSMatthew G Knepley       }
316188ed4aceSMatthew G Knepley     }
316288ed4aceSMatthew G Knepley   }
316388ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
316488ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
316588ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
316688ed4aceSMatthew G Knepley }
3167