xref: /petsc/src/dm/interface/dm.c (revision 55849f575624b3890dfd9b38e2c3ba42c5d7d18f)
108da532bSDmitry Karpeev #include <petscsnes.h>
2b45d2f2cSJed Brown #include <petsc-private/dmimpl.h>     /*I      "petscdm.h"     I*/
347c6ae99SBarry Smith 
4732e2eb9SMatthew G Knepley PetscClassId  DM_CLASSID;
567a56275SMatthew G Knepley PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal;
667a56275SMatthew G Knepley 
747c6ae99SBarry Smith #undef __FUNCT__
8a4121054SBarry Smith #define __FUNCT__ "DMCreate"
9a4121054SBarry Smith /*@
10de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
11a4121054SBarry Smith 
12a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
13a4121054SBarry Smith    error when you try to use the vector.
14a4121054SBarry Smith 
15a4121054SBarry Smith   Collective on MPI_Comm
16a4121054SBarry Smith 
17a4121054SBarry Smith   Input Parameter:
18a4121054SBarry Smith . comm - The communicator for the DM object
19a4121054SBarry Smith 
20a4121054SBarry Smith   Output Parameter:
21a4121054SBarry Smith . dm - The DM object
22a4121054SBarry Smith 
23a4121054SBarry Smith   Level: beginner
24a4121054SBarry Smith 
25a4121054SBarry Smith .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE
26a4121054SBarry Smith @*/
277087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
28a4121054SBarry Smith {
29a4121054SBarry Smith   DM             v;
30a4121054SBarry Smith   PetscErrorCode ierr;
31a4121054SBarry Smith 
32a4121054SBarry Smith   PetscFunctionBegin;
331411c6eeSJed Brown   PetscValidPointer(dm,2);
341411c6eeSJed Brown   *dm = PETSC_NULL;
35a4121054SBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
36b84caa0eSBarry Smith   ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr);
37b84caa0eSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
38a4121054SBarry Smith   ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr);
39a4121054SBarry Smith #endif
40a4121054SBarry Smith 
413194b578SJed Brown   ierr = PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, -1, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
42a4121054SBarry Smith   ierr = PetscMemzero(v->ops, sizeof(struct _DMOps));CHKERRQ(ierr);
431411c6eeSJed Brown 
44e7c4fc90SDmitry Karpeev 
451411c6eeSJed Brown   v->ltogmap      = PETSC_NULL;
461411c6eeSJed Brown   v->ltogmapb     = PETSC_NULL;
471411c6eeSJed Brown   v->bs           = 1;
48171400e9SBarry Smith   v->coloringtype = IS_COLORING_GLOBAL;
49970e74d5SMatthew G Knepley   v->lf           = PETSC_NULL;
50970e74d5SMatthew G Knepley   v->lj           = PETSC_NULL;
5188ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
5288ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
5388ed4aceSMatthew G Knepley   v->defaultSection       = PETSC_NULL;
5488ed4aceSMatthew G Knepley   v->defaultGlobalSection = PETSC_NULL;
55435a35e8SMatthew G Knepley   {
56435a35e8SMatthew G Knepley     PetscInt i;
57435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
58435a35e8SMatthew G Knepley       v->nullspaceConstructors[i] = PETSC_NULL;
59435a35e8SMatthew G Knepley     }
60435a35e8SMatthew G Knepley   }
61af122d2aSMatthew G Knepley   v->numFields = 0;
62af122d2aSMatthew G Knepley   v->fields    = PETSC_NULL;
631411c6eeSJed Brown 
641411c6eeSJed Brown   *dm = v;
65a4121054SBarry Smith   PetscFunctionReturn(0);
66a4121054SBarry Smith }
67a4121054SBarry Smith 
68a4121054SBarry Smith #undef __FUNCT__
699a42bb27SBarry Smith #define __FUNCT__ "DMSetVecType"
709a42bb27SBarry Smith /*@C
71564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
729a42bb27SBarry Smith 
73aa219208SBarry Smith    Logically Collective on DMDA
749a42bb27SBarry Smith 
759a42bb27SBarry Smith    Input Parameter:
769a42bb27SBarry Smith +  da - initial distributed array
778154be41SBarry Smith .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
789a42bb27SBarry Smith 
799a42bb27SBarry Smith    Options Database:
80dd85299cSBarry Smith .   -dm_vec_type ctype
819a42bb27SBarry Smith 
829a42bb27SBarry Smith    Level: intermediate
839a42bb27SBarry Smith 
84aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
859a42bb27SBarry Smith @*/
8619fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
879a42bb27SBarry Smith {
889a42bb27SBarry Smith   PetscErrorCode ierr;
899a42bb27SBarry Smith 
909a42bb27SBarry Smith   PetscFunctionBegin;
919a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
929a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
9319fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
949a42bb27SBarry Smith   PetscFunctionReturn(0);
959a42bb27SBarry Smith }
969a42bb27SBarry Smith 
979a42bb27SBarry Smith #undef __FUNCT__
985f1ad066SMatthew G Knepley #define __FUNCT__ "VecGetDM"
995f1ad066SMatthew G Knepley /*@
10034f98d34SBarry Smith   VecGetDM - Gets the DM defining the data layout of the vector
1015f1ad066SMatthew G Knepley 
1025f1ad066SMatthew G Knepley   Not collective
1035f1ad066SMatthew G Knepley 
1045f1ad066SMatthew G Knepley   Input Parameter:
1055f1ad066SMatthew G Knepley . v - The Vec
1065f1ad066SMatthew G Knepley 
1075f1ad066SMatthew G Knepley   Output Parameter:
1085f1ad066SMatthew G Knepley . dm - The DM
1095f1ad066SMatthew G Knepley 
1105f1ad066SMatthew G Knepley   Level: intermediate
1115f1ad066SMatthew G Knepley 
1125f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
1135f1ad066SMatthew G Knepley @*/
1145f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm)
1155f1ad066SMatthew G Knepley {
1165f1ad066SMatthew G Knepley   PetscErrorCode ierr;
1175f1ad066SMatthew G Knepley 
1185f1ad066SMatthew G Knepley   PetscFunctionBegin;
1195f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1205f1ad066SMatthew G Knepley   PetscValidPointer(dm,2);
1215f1ad066SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject *) dm);CHKERRQ(ierr);
1225f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
1235f1ad066SMatthew G Knepley }
1245f1ad066SMatthew G Knepley 
1255f1ad066SMatthew G Knepley #undef __FUNCT__
1265f1ad066SMatthew G Knepley #define __FUNCT__ "VecSetDM"
1275f1ad066SMatthew G Knepley /*@
1285f1ad066SMatthew G Knepley   VecSetDM - Sets the DM defining the data layout of the vector
1295f1ad066SMatthew G Knepley 
1305f1ad066SMatthew G Knepley   Not collective
1315f1ad066SMatthew G Knepley 
1325f1ad066SMatthew G Knepley   Input Parameters:
1335f1ad066SMatthew G Knepley + v - The Vec
1345f1ad066SMatthew G Knepley - dm - The DM
1355f1ad066SMatthew G Knepley 
1365f1ad066SMatthew G Knepley   Level: intermediate
1375f1ad066SMatthew G Knepley 
1385f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
1395f1ad066SMatthew G Knepley @*/
1405f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm)
1415f1ad066SMatthew G Knepley {
1425f1ad066SMatthew G Knepley   PetscErrorCode ierr;
1435f1ad066SMatthew G Knepley 
1445f1ad066SMatthew G Knepley   PetscFunctionBegin;
1455f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1465f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
1475f1ad066SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
1485f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
1495f1ad066SMatthew G Knepley }
1505f1ad066SMatthew G Knepley 
1515f1ad066SMatthew G Knepley #undef __FUNCT__
152521d9a4cSLisandro Dalcin #define __FUNCT__ "DMSetMatType"
153521d9a4cSLisandro Dalcin /*@C
154521d9a4cSLisandro Dalcin        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
155521d9a4cSLisandro Dalcin 
156521d9a4cSLisandro Dalcin    Logically Collective on DM
157521d9a4cSLisandro Dalcin 
158521d9a4cSLisandro Dalcin    Input Parameter:
159521d9a4cSLisandro Dalcin +  dm - the DM context
160521d9a4cSLisandro Dalcin .  ctype - the matrix type
161521d9a4cSLisandro Dalcin 
162521d9a4cSLisandro Dalcin    Options Database:
163521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
164521d9a4cSLisandro Dalcin 
165521d9a4cSLisandro Dalcin    Level: intermediate
166521d9a4cSLisandro Dalcin 
167521d9a4cSLisandro Dalcin .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType
168521d9a4cSLisandro Dalcin @*/
16919fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
170521d9a4cSLisandro Dalcin {
171521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
172521d9a4cSLisandro Dalcin   PetscFunctionBegin;
173521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
174521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
17519fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
176521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
177521d9a4cSLisandro Dalcin }
178521d9a4cSLisandro Dalcin 
179521d9a4cSLisandro Dalcin #undef __FUNCT__
180c688c046SMatthew G Knepley #define __FUNCT__ "MatGetDM"
181c688c046SMatthew G Knepley /*@
18234f98d34SBarry Smith   MatGetDM - Gets the DM defining the data layout of the matrix
183c688c046SMatthew G Knepley 
184c688c046SMatthew G Knepley   Not collective
185c688c046SMatthew G Knepley 
186c688c046SMatthew G Knepley   Input Parameter:
187c688c046SMatthew G Knepley . A - The Mat
188c688c046SMatthew G Knepley 
189c688c046SMatthew G Knepley   Output Parameter:
190c688c046SMatthew G Knepley . dm - The DM
191c688c046SMatthew G Knepley 
192c688c046SMatthew G Knepley   Level: intermediate
193c688c046SMatthew G Knepley 
194c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType()
195c688c046SMatthew G Knepley @*/
196c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm)
197c688c046SMatthew G Knepley {
198c688c046SMatthew G Knepley   PetscErrorCode ierr;
199c688c046SMatthew G Knepley 
200c688c046SMatthew G Knepley   PetscFunctionBegin;
201c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
202c688c046SMatthew G Knepley   PetscValidPointer(dm,2);
203c688c046SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject *) dm);CHKERRQ(ierr);
204c688c046SMatthew G Knepley   PetscFunctionReturn(0);
205c688c046SMatthew G Knepley }
206c688c046SMatthew G Knepley 
207c688c046SMatthew G Knepley #undef __FUNCT__
208c688c046SMatthew G Knepley #define __FUNCT__ "MatSetDM"
209c688c046SMatthew G Knepley /*@
210c688c046SMatthew G Knepley   MatSetDM - Sets the DM defining the data layout of the matrix
211c688c046SMatthew G Knepley 
212c688c046SMatthew G Knepley   Not collective
213c688c046SMatthew G Knepley 
214c688c046SMatthew G Knepley   Input Parameters:
215c688c046SMatthew G Knepley + A - The Mat
216c688c046SMatthew G Knepley - dm - The DM
217c688c046SMatthew G Knepley 
218c688c046SMatthew G Knepley   Level: intermediate
219c688c046SMatthew G Knepley 
220c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType()
221c688c046SMatthew G Knepley @*/
222c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm)
223c688c046SMatthew G Knepley {
224c688c046SMatthew G Knepley   PetscErrorCode ierr;
225c688c046SMatthew G Knepley 
226c688c046SMatthew G Knepley   PetscFunctionBegin;
227c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
228c688c046SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
229c688c046SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
230c688c046SMatthew G Knepley   PetscFunctionReturn(0);
231c688c046SMatthew G Knepley }
232c688c046SMatthew G Knepley 
233c688c046SMatthew G Knepley #undef __FUNCT__
2349a42bb27SBarry Smith #define __FUNCT__ "DMSetOptionsPrefix"
2359a42bb27SBarry Smith /*@C
2369a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
237aa219208SBarry Smith    DMDA options in the database.
2389a42bb27SBarry Smith 
239aa219208SBarry Smith    Logically Collective on DMDA
2409a42bb27SBarry Smith 
2419a42bb27SBarry Smith    Input Parameter:
242aa219208SBarry Smith +  da - the DMDA context
2439a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
2449a42bb27SBarry Smith 
2459a42bb27SBarry Smith    Notes:
2469a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
2479a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
2489a42bb27SBarry Smith 
2499a42bb27SBarry Smith    Level: advanced
2509a42bb27SBarry Smith 
251aa219208SBarry Smith .keywords: DMDA, set, options, prefix, database
2529a42bb27SBarry Smith 
2539a42bb27SBarry Smith .seealso: DMSetFromOptions()
2549a42bb27SBarry Smith @*/
2557087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
2569a42bb27SBarry Smith {
2579a42bb27SBarry Smith   PetscErrorCode ierr;
2589a42bb27SBarry Smith 
2599a42bb27SBarry Smith   PetscFunctionBegin;
2609a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2619a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
2629a42bb27SBarry Smith   PetscFunctionReturn(0);
2639a42bb27SBarry Smith }
2649a42bb27SBarry Smith 
2659a42bb27SBarry Smith #undef __FUNCT__
26647c6ae99SBarry Smith #define __FUNCT__ "DMDestroy"
26747c6ae99SBarry Smith /*@
268aa219208SBarry Smith     DMDestroy - Destroys a vector packer or DMDA.
26947c6ae99SBarry Smith 
27047c6ae99SBarry Smith     Collective on DM
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith     Input Parameter:
27347c6ae99SBarry Smith .   dm - the DM object to destroy
27447c6ae99SBarry Smith 
27547c6ae99SBarry Smith     Level: developer
27647c6ae99SBarry Smith 
277e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
27847c6ae99SBarry Smith 
27947c6ae99SBarry Smith @*/
280fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
28147c6ae99SBarry Smith {
282af122d2aSMatthew G Knepley   PetscInt       i, cnt = 0, f;
283dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
28447c6ae99SBarry Smith   PetscErrorCode ierr;
28547c6ae99SBarry Smith 
28647c6ae99SBarry Smith   PetscFunctionBegin;
2876bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
2886bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
28987e657c6SBarry Smith 
29087e657c6SBarry Smith   /* count all the circular references of DM and its contained Vecs */
291732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
2926bf464f9SBarry Smith     if ((*dm)->localin[i])  {cnt++;}
2936bf464f9SBarry Smith     if ((*dm)->globalin[i]) {cnt++;}
294732e2eb9SMatthew G Knepley   }
295dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++;
29671cd77b2SBarry Smith   if ((*dm)->x) {
297c688c046SMatthew G Knepley     DM obj;
298c688c046SMatthew G Knepley     ierr = VecGetDM((*dm)->x, &obj);CHKERRQ(ierr);
299c688c046SMatthew G Knepley     if (obj == *dm) cnt++;
30071cd77b2SBarry Smith   }
301732e2eb9SMatthew G Knepley 
3026bf464f9SBarry Smith   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
303732e2eb9SMatthew G Knepley   /*
304732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
305732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
306732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
307732e2eb9SMatthew G Knepley   */
3086bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
3096bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
310732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
3116bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
3126bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
313732e2eb9SMatthew G Knepley   }
314dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nnext) { /* Destroy the named vectors */
315dfe15315SJed Brown     nnext = nlink->next;
316dfe15315SJed 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);
317dfe15315SJed Brown     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
318dfe15315SJed Brown     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
319dfe15315SJed Brown     ierr = PetscFree(nlink);CHKERRQ(ierr);
320dfe15315SJed Brown   }
321dfe15315SJed Brown   (*dm)->namedglobal = PETSC_NULL;
3221a266240SBarry Smith 
323b17ce1afSJed Brown   /* Destroy the list of hooks */
324c833c3b5SJed Brown   {
325c833c3b5SJed Brown     DMCoarsenHookLink link,next;
326b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
327b17ce1afSJed Brown       next = link->next;
328b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
329b17ce1afSJed Brown     }
330b17ce1afSJed Brown     (*dm)->coarsenhook = PETSC_NULL;
331c833c3b5SJed Brown   }
332c833c3b5SJed Brown   {
333c833c3b5SJed Brown     DMRefineHookLink link,next;
334c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
335c833c3b5SJed Brown       next = link->next;
336c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
337c833c3b5SJed Brown     }
338c833c3b5SJed Brown     (*dm)->refinehook = PETSC_NULL;
339c833c3b5SJed Brown   }
340aa1993deSMatthew G Knepley   /* Destroy the work arrays */
341aa1993deSMatthew G Knepley   {
342aa1993deSMatthew G Knepley     DMWorkLink link,next;
343aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
344aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
345aa1993deSMatthew G Knepley       next = link->next;
346aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
347aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
348aa1993deSMatthew G Knepley     }
349aa1993deSMatthew G Knepley     (*dm)->workin = PETSC_NULL;
350aa1993deSMatthew G Knepley   }
351b17ce1afSJed Brown 
3521a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
3531a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
3541a266240SBarry Smith   }
35587e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
35671cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
3574dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
3586bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
3596bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr);
3606bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
361073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
36288ed4aceSMatthew G Knepley 
36388ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
36488ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
3658b1ab98fSJed Brown   ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr);
36688ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
36788ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
368af122d2aSMatthew G Knepley 
3696636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
3706636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
3716636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
3726636e97aSMatthew G Knepley 
373af122d2aSMatthew G Knepley   for (f = 0; f < (*dm)->numFields; ++f) {
374af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&(*dm)->fields[f]);CHKERRQ(ierr);
375af122d2aSMatthew G Knepley   }
376af122d2aSMatthew G Knepley   ierr = PetscFree((*dm)->fields);CHKERRQ(ierr);
377732e2eb9SMatthew G Knepley   /* if memory was published with AMS then destroy it */
3786bf464f9SBarry Smith   ierr = PetscObjectDepublish(*dm);CHKERRQ(ierr);
379732e2eb9SMatthew G Knepley 
3806bf464f9SBarry Smith   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
381435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
382732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
38347c6ae99SBarry Smith   PetscFunctionReturn(0);
38447c6ae99SBarry Smith }
38547c6ae99SBarry Smith 
38647c6ae99SBarry Smith #undef __FUNCT__
387d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp"
388d7bf68aeSBarry Smith /*@
389d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
390d7bf68aeSBarry Smith 
391d7bf68aeSBarry Smith     Collective on DM
392d7bf68aeSBarry Smith 
393d7bf68aeSBarry Smith     Input Parameter:
394d7bf68aeSBarry Smith .   dm - the DM object to setup
395d7bf68aeSBarry Smith 
396d7bf68aeSBarry Smith     Level: developer
397d7bf68aeSBarry Smith 
398e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
399d7bf68aeSBarry Smith 
400d7bf68aeSBarry Smith @*/
4017087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
402d7bf68aeSBarry Smith {
403d7bf68aeSBarry Smith   PetscErrorCode ierr;
404d7bf68aeSBarry Smith 
405d7bf68aeSBarry Smith   PetscFunctionBegin;
406171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4078387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
408d7bf68aeSBarry Smith   if (dm->ops->setup) {
409d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
410d7bf68aeSBarry Smith   }
4118387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
412d7bf68aeSBarry Smith   PetscFunctionReturn(0);
413d7bf68aeSBarry Smith }
414d7bf68aeSBarry Smith 
415d7bf68aeSBarry Smith #undef __FUNCT__
416d7bf68aeSBarry Smith #define __FUNCT__ "DMSetFromOptions"
417d7bf68aeSBarry Smith /*@
418d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
419d7bf68aeSBarry Smith 
420d7bf68aeSBarry Smith     Collective on DM
421d7bf68aeSBarry Smith 
422d7bf68aeSBarry Smith     Input Parameter:
423d7bf68aeSBarry Smith .   dm - the DM object to set options for
424d7bf68aeSBarry Smith 
425732e2eb9SMatthew G Knepley     Options Database:
426dd85299cSBarry Smith +   -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
427dd85299cSBarry Smith .   -dm_vec_type <type>  type of vector to create inside DM
428171400e9SBarry Smith .   -dm_mat_type <type>  type of matrix to create inside DM
429171400e9SBarry Smith -   -dm_coloring_type <global or ghosted>
430732e2eb9SMatthew G Knepley 
431d7bf68aeSBarry Smith     Level: developer
432d7bf68aeSBarry Smith 
433e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
434d7bf68aeSBarry Smith 
435d7bf68aeSBarry Smith @*/
4367087cfbeSBarry Smith PetscErrorCode  DMSetFromOptions(DM dm)
437d7bf68aeSBarry Smith {
43867ad5babSMatthew G Knepley   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg;
439d7bf68aeSBarry Smith   PetscErrorCode ierr;
440f9ba7244SBarry Smith   char           typeName[256] = MATAIJ;
441d7bf68aeSBarry Smith 
442d7bf68aeSBarry Smith   PetscFunctionBegin;
443171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4443194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
44582fcb398SMatthew G Knepley     ierr = PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);CHKERRQ(ierr);
446c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_detail", "Exhaustive mesh description", "DMView", flg2, &flg2, PETSC_NULL);CHKERRQ(ierr);
447c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_vtk", "Output mesh in VTK format", "DMView", flg3, &flg3, PETSC_NULL);CHKERRQ(ierr);
44867ad5babSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_latex", "Output mesh in LaTeX TikZ format", "DMView", flg4, &flg4, PETSC_NULL);CHKERRQ(ierr);
449073dac72SJed 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);
450f9ba7244SBarry Smith     ierr = PetscOptionsList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
451f9ba7244SBarry Smith     if (flg) {
452f9ba7244SBarry Smith       ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
453f9ba7244SBarry Smith     }
4548caf3d72SBarry Smith     ierr = PetscOptionsList("-dm_mat_type","Matrix type used for created matrices","DMSetMatType",MatList,dm->mattype?dm->mattype:typeName,typeName,sizeof(typeName),&flg);CHKERRQ(ierr);
455073dac72SJed Brown     if (flg) {
456521d9a4cSLisandro Dalcin       ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
457073dac72SJed Brown     }
4581b89239cSHong 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);
459f9ba7244SBarry Smith     if (dm->ops->setfromoptions) {
460f9ba7244SBarry Smith       ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr);
461f9ba7244SBarry Smith     }
462f9ba7244SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
463f9ba7244SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
46482fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
46582fcb398SMatthew G Knepley   if (flg1) {
46682fcb398SMatthew G Knepley     ierr = DMView(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
46782fcb398SMatthew G Knepley   }
468c4721b0eSMatthew G Knepley   if (flg2) {
469c4721b0eSMatthew G Knepley     PetscViewer viewer;
470c4721b0eSMatthew G Knepley 
471c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
472c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
473c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
474c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
475c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
476c4721b0eSMatthew G Knepley   }
477c4721b0eSMatthew G Knepley   if (flg3) {
478c4721b0eSMatthew G Knepley     PetscViewer viewer;
479c4721b0eSMatthew G Knepley 
480c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
481c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
482c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);
483c4721b0eSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.vtk");CHKERRQ(ierr);
484c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
485c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
486c4721b0eSMatthew G Knepley   }
48767ad5babSMatthew G Knepley   if (flg4) {
48867ad5babSMatthew G Knepley     PetscViewer viewer;
48967ad5babSMatthew G Knepley 
49067ad5babSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
49167ad5babSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
49267ad5babSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_LATEX);CHKERRQ(ierr);
49367ad5babSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.tex");CHKERRQ(ierr);
49467ad5babSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
49567ad5babSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
49667ad5babSMatthew G Knepley   }
497d7bf68aeSBarry Smith   PetscFunctionReturn(0);
498d7bf68aeSBarry Smith }
499d7bf68aeSBarry Smith 
500d7bf68aeSBarry Smith #undef __FUNCT__
50147c6ae99SBarry Smith #define __FUNCT__ "DMView"
502fc9bc008SSatish Balay /*@C
503aa219208SBarry Smith     DMView - Views a vector packer or DMDA.
50447c6ae99SBarry Smith 
50547c6ae99SBarry Smith     Collective on DM
50647c6ae99SBarry Smith 
50747c6ae99SBarry Smith     Input Parameter:
50847c6ae99SBarry Smith +   dm - the DM object to view
50947c6ae99SBarry Smith -   v - the viewer
51047c6ae99SBarry Smith 
51147c6ae99SBarry Smith     Level: developer
51247c6ae99SBarry Smith 
513e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
51447c6ae99SBarry Smith 
51547c6ae99SBarry Smith @*/
5167087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
51747c6ae99SBarry Smith {
51847c6ae99SBarry Smith   PetscErrorCode ierr;
51932c0f0efSBarry Smith   PetscBool      isbinary;
52047c6ae99SBarry Smith 
52147c6ae99SBarry Smith   PetscFunctionBegin;
522171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5233014e516SBarry Smith   if (!v) {
5243014e516SBarry Smith     ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr);
5253014e516SBarry Smith   }
52632c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
52732c0f0efSBarry Smith   if (isbinary) {
528*55849f57SBarry Smith     PetscInt         classid = DM_FILE_CLASSID;
52932c0f0efSBarry Smith     MPI_Comm         comm;
53032c0f0efSBarry Smith     PetscMPIInt      rank;
53132c0f0efSBarry Smith     char             type[256];
53232c0f0efSBarry Smith 
53332c0f0efSBarry Smith     ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
53432c0f0efSBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
53532c0f0efSBarry Smith     if (!rank) {
53632c0f0efSBarry Smith       ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
53732c0f0efSBarry Smith       ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
53832c0f0efSBarry Smith       ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
53932c0f0efSBarry Smith     }
54032c0f0efSBarry Smith   }
5410c010503SBarry Smith   if (dm->ops->view) {
5420c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
54347c6ae99SBarry Smith   }
54447c6ae99SBarry Smith   PetscFunctionReturn(0);
54547c6ae99SBarry Smith }
54647c6ae99SBarry Smith 
547ba654b55SMatthew G Knepley PETSC_EXTERN PetscErrorCode VecView_Complex_Local(Vec, PetscViewer);
548ba654b55SMatthew G Knepley PETSC_EXTERN PetscErrorCode VecView_Complex(Vec, PetscViewer);
549ba654b55SMatthew G Knepley 
55047c6ae99SBarry Smith #undef __FUNCT__
55147c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
55247c6ae99SBarry Smith /*@
553aa219208SBarry Smith     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
55447c6ae99SBarry Smith 
55547c6ae99SBarry Smith     Collective on DM
55647c6ae99SBarry Smith 
55747c6ae99SBarry Smith     Input Parameter:
55847c6ae99SBarry Smith .   dm - the DM object
55947c6ae99SBarry Smith 
56047c6ae99SBarry Smith     Output Parameter:
56147c6ae99SBarry Smith .   vec - the global vector
56247c6ae99SBarry Smith 
563073dac72SJed Brown     Level: beginner
56447c6ae99SBarry Smith 
565e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
56647c6ae99SBarry Smith 
56747c6ae99SBarry Smith @*/
5687087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
56947c6ae99SBarry Smith {
57047c6ae99SBarry Smith   PetscErrorCode ierr;
57147c6ae99SBarry Smith 
57247c6ae99SBarry Smith   PetscFunctionBegin;
573171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
57488ed4aceSMatthew G Knepley   if (dm->defaultSection) {
57588ed4aceSMatthew G Knepley     PetscSection gSection;
5761f588964SMatthew G Knepley     PetscInt     localSize, blockSize = -1, pStart, pEnd, p;
57788ed4aceSMatthew G Knepley 
57888ed4aceSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
5791f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
5801f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
5811f588964SMatthew G Knepley       PetscInt dof, cdof;
5821f588964SMatthew G Knepley 
5831f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
5841f588964SMatthew G Knepley       ierr = PetscSectionGetConstraintDof(dm->defaultSection, p, &cdof);CHKERRQ(ierr);
5851f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof-cdof;
5861f588964SMatthew G Knepley       if ((dof > 0) && (dof-cdof != blockSize)) {
5871f588964SMatthew G Knepley         blockSize = 1;
5881f588964SMatthew G Knepley         break;
5891f588964SMatthew G Knepley       }
5901f588964SMatthew G Knepley     }
59188ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr);
5921f588964SMatthew G Knepley     if (localSize%blockSize) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONG, "Mismatch between blocksize %d and local storage size %d", blockSize, localSize);
59388ed4aceSMatthew G Knepley     ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr);
59488ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
5951f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
59688ed4aceSMatthew G Knepley     /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */
59788ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
598c688c046SMatthew G Knepley     ierr = VecSetDM(*vec, dm);CHKERRQ(ierr);
59988ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */
60088ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */
60188ed4aceSMatthew G Knepley     /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */
602ba654b55SMatthew G Knepley     ierr = VecSetOperation(*vec, VECOP_VIEW, (void(*)(void)) VecView_Complex);CHKERRQ(ierr);
60388ed4aceSMatthew G Knepley   } else {
60447c6ae99SBarry Smith     ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
60588ed4aceSMatthew G Knepley   }
60647c6ae99SBarry Smith   PetscFunctionReturn(0);
60747c6ae99SBarry Smith }
60847c6ae99SBarry Smith 
60947c6ae99SBarry Smith #undef __FUNCT__
61047c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
61147c6ae99SBarry Smith /*@
612aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
61347c6ae99SBarry Smith 
61447c6ae99SBarry Smith     Not Collective
61547c6ae99SBarry Smith 
61647c6ae99SBarry Smith     Input Parameter:
61747c6ae99SBarry Smith .   dm - the DM object
61847c6ae99SBarry Smith 
61947c6ae99SBarry Smith     Output Parameter:
62047c6ae99SBarry Smith .   vec - the local vector
62147c6ae99SBarry Smith 
622073dac72SJed Brown     Level: beginner
62347c6ae99SBarry Smith 
624e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
62547c6ae99SBarry Smith 
62647c6ae99SBarry Smith @*/
6277087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
62847c6ae99SBarry Smith {
62947c6ae99SBarry Smith   PetscErrorCode ierr;
63047c6ae99SBarry Smith 
63147c6ae99SBarry Smith   PetscFunctionBegin;
632171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
63388ed4aceSMatthew G Knepley   if (dm->defaultSection) {
6341f588964SMatthew G Knepley     PetscInt localSize, blockSize = -1, pStart, pEnd, p;
63588ed4aceSMatthew G Knepley 
6361f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
6371f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
6381f588964SMatthew G Knepley       PetscInt dof;
6391f588964SMatthew G Knepley 
6401f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
6411f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof;
6421f588964SMatthew G Knepley       if ((dof > 0) && (dof != blockSize)) {
6431f588964SMatthew G Knepley         blockSize = 1;
6441f588964SMatthew G Knepley         break;
6451f588964SMatthew G Knepley       }
6461f588964SMatthew G Knepley     }
64788ed4aceSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr);
64888ed4aceSMatthew G Knepley     ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr);
64988ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr);
6501f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
65188ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
652c688c046SMatthew G Knepley     ierr = VecSetDM(*vec, dm);CHKERRQ(ierr);
653ba654b55SMatthew G Knepley     ierr = VecSetOperation(*vec, VECOP_VIEW, (void(*)(void)) VecView_Complex_Local);CHKERRQ(ierr);
65488ed4aceSMatthew G Knepley   } else {
65547c6ae99SBarry Smith     ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
65688ed4aceSMatthew G Knepley   }
65747c6ae99SBarry Smith   PetscFunctionReturn(0);
65847c6ae99SBarry Smith }
65947c6ae99SBarry Smith 
66047c6ae99SBarry Smith #undef __FUNCT__
6611411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
6621411c6eeSJed Brown /*@
6631411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
6641411c6eeSJed Brown 
6651411c6eeSJed Brown    Collective on DM
6661411c6eeSJed Brown 
6671411c6eeSJed Brown    Input Parameter:
6681411c6eeSJed Brown .  dm - the DM that provides the mapping
6691411c6eeSJed Brown 
6701411c6eeSJed Brown    Output Parameter:
6711411c6eeSJed Brown .  ltog - the mapping
6721411c6eeSJed Brown 
6731411c6eeSJed Brown    Level: intermediate
6741411c6eeSJed Brown 
6751411c6eeSJed Brown    Notes:
6761411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
6771411c6eeSJed Brown    MatSetLocalToGlobalMapping().
6781411c6eeSJed Brown 
6791411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
6801411c6eeSJed Brown @*/
6817087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
6821411c6eeSJed Brown {
6831411c6eeSJed Brown   PetscErrorCode ierr;
6841411c6eeSJed Brown 
6851411c6eeSJed Brown   PetscFunctionBegin;
6861411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6871411c6eeSJed Brown   PetscValidPointer(ltog,2);
6881411c6eeSJed Brown   if (!dm->ltogmap) {
68937d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
69037d0c07bSMatthew G Knepley 
69137d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
69237d0c07bSMatthew G Knepley     if (section) {
69337d0c07bSMatthew G Knepley       PetscInt      *ltog;
69437d0c07bSMatthew G Knepley       PetscInt       pStart, pEnd, size, p, l;
69537d0c07bSMatthew G Knepley 
69637d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
69737d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
69837d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
69937d0c07bSMatthew G Knepley       ierr = PetscMalloc(size * sizeof(PetscInt), &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
70037d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
70137d0c07bSMatthew G Knepley         PetscInt dof, off, c;
70237d0c07bSMatthew G Knepley 
70337d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
70437d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
70537d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
70637d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
70737d0c07bSMatthew G Knepley           ltog[l] = off+c;
70837d0c07bSMatthew G Knepley         }
70937d0c07bSMatthew G Knepley       }
71037d0c07bSMatthew G Knepley       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
71137d0c07bSMatthew G Knepley       ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr);
71237d0c07bSMatthew G Knepley     } else {
7131411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
7141411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
7151411c6eeSJed Brown     }
71637d0c07bSMatthew G Knepley   }
7171411c6eeSJed Brown   *ltog = dm->ltogmap;
7181411c6eeSJed Brown   PetscFunctionReturn(0);
7191411c6eeSJed Brown }
7201411c6eeSJed Brown 
7211411c6eeSJed Brown #undef __FUNCT__
7221411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
7231411c6eeSJed Brown /*@
7241411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
7251411c6eeSJed Brown 
7261411c6eeSJed Brown    Collective on DM
7271411c6eeSJed Brown 
7281411c6eeSJed Brown    Input Parameter:
7291411c6eeSJed Brown .  da - the distributed array that provides the mapping
7301411c6eeSJed Brown 
7311411c6eeSJed Brown    Output Parameter:
7321411c6eeSJed Brown .  ltog - the block mapping
7331411c6eeSJed Brown 
7341411c6eeSJed Brown    Level: intermediate
7351411c6eeSJed Brown 
7361411c6eeSJed Brown    Notes:
7371411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
7381411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
7391411c6eeSJed Brown 
7401411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
7411411c6eeSJed Brown @*/
7427087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
7431411c6eeSJed Brown {
7441411c6eeSJed Brown   PetscErrorCode ierr;
7451411c6eeSJed Brown 
7461411c6eeSJed Brown   PetscFunctionBegin;
7471411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7481411c6eeSJed Brown   PetscValidPointer(ltog,2);
7491411c6eeSJed Brown   if (!dm->ltogmapb) {
7501411c6eeSJed Brown     PetscInt bs;
7511411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
7521411c6eeSJed Brown     if (bs > 1) {
7531411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
7541411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
7551411c6eeSJed Brown     } else {
7561411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
7571411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
7581411c6eeSJed Brown     }
7591411c6eeSJed Brown   }
7601411c6eeSJed Brown   *ltog = dm->ltogmapb;
7611411c6eeSJed Brown   PetscFunctionReturn(0);
7621411c6eeSJed Brown }
7631411c6eeSJed Brown 
7641411c6eeSJed Brown #undef __FUNCT__
7651411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
7661411c6eeSJed Brown /*@
7671411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
7681411c6eeSJed Brown 
7691411c6eeSJed Brown    Not Collective
7701411c6eeSJed Brown 
7711411c6eeSJed Brown    Input Parameter:
7721411c6eeSJed Brown .  dm - the DM with block structure
7731411c6eeSJed Brown 
7741411c6eeSJed Brown    Output Parameter:
7751411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
7761411c6eeSJed Brown 
7771411c6eeSJed Brown    Level: intermediate
7781411c6eeSJed Brown 
7791411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
7801411c6eeSJed Brown @*/
7817087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
7821411c6eeSJed Brown {
7831411c6eeSJed Brown   PetscFunctionBegin;
7841411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7851411c6eeSJed Brown   PetscValidPointer(bs,2);
7861411c6eeSJed 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");
7871411c6eeSJed Brown   *bs = dm->bs;
7881411c6eeSJed Brown   PetscFunctionReturn(0);
7891411c6eeSJed Brown }
7901411c6eeSJed Brown 
7911411c6eeSJed Brown #undef __FUNCT__
792e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
79347c6ae99SBarry Smith /*@
794e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
79547c6ae99SBarry Smith 
79647c6ae99SBarry Smith     Collective on DM
79747c6ae99SBarry Smith 
79847c6ae99SBarry Smith     Input Parameter:
79947c6ae99SBarry Smith +   dm1 - the DM object
80047c6ae99SBarry Smith -   dm2 - the second, finer DM object
80147c6ae99SBarry Smith 
80247c6ae99SBarry Smith     Output Parameter:
80347c6ae99SBarry Smith +  mat - the interpolation
80447c6ae99SBarry Smith -  vec - the scaling (optional)
80547c6ae99SBarry Smith 
80647c6ae99SBarry Smith     Level: developer
80747c6ae99SBarry Smith 
80885afcc9aSBarry 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
80985afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
810d52bd9f3SBarry Smith 
8111f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
812d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
81385afcc9aSBarry Smith 
81485afcc9aSBarry Smith 
815e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
81647c6ae99SBarry Smith 
81747c6ae99SBarry Smith @*/
818e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
81947c6ae99SBarry Smith {
82047c6ae99SBarry Smith   PetscErrorCode ierr;
82147c6ae99SBarry Smith 
82247c6ae99SBarry Smith   PetscFunctionBegin;
823171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
824171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
82525296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
82647c6ae99SBarry Smith   PetscFunctionReturn(0);
82747c6ae99SBarry Smith }
82847c6ae99SBarry Smith 
82947c6ae99SBarry Smith #undef __FUNCT__
830e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
83147c6ae99SBarry Smith /*@
832e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
83347c6ae99SBarry Smith 
83447c6ae99SBarry Smith     Collective on DM
83547c6ae99SBarry Smith 
83647c6ae99SBarry Smith     Input Parameter:
83747c6ae99SBarry Smith +   dm1 - the DM object
83847c6ae99SBarry Smith -   dm2 - the second, finer DM object
83947c6ae99SBarry Smith 
84047c6ae99SBarry Smith     Output Parameter:
84147c6ae99SBarry Smith .   ctx - the injection
84247c6ae99SBarry Smith 
84347c6ae99SBarry Smith     Level: developer
84447c6ae99SBarry Smith 
84585afcc9aSBarry 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
84685afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
84785afcc9aSBarry Smith 
848e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
84947c6ae99SBarry Smith 
85047c6ae99SBarry Smith @*/
851e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
85247c6ae99SBarry Smith {
85347c6ae99SBarry Smith   PetscErrorCode ierr;
85447c6ae99SBarry Smith 
85547c6ae99SBarry Smith   PetscFunctionBegin;
856171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
857171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
85847c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
85947c6ae99SBarry Smith   PetscFunctionReturn(0);
86047c6ae99SBarry Smith }
86147c6ae99SBarry Smith 
86247c6ae99SBarry Smith #undef __FUNCT__
863e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
864d1e2c406SBarry Smith /*@C
865e727c939SJed Brown     DMCreateColoring - Gets coloring for a DMDA or DMComposite
86647c6ae99SBarry Smith 
86747c6ae99SBarry Smith     Collective on DM
86847c6ae99SBarry Smith 
86947c6ae99SBarry Smith     Input Parameter:
87047c6ae99SBarry Smith +   dm - the DM object
87147c6ae99SBarry Smith .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
87247c6ae99SBarry Smith -   matype - either MATAIJ or MATBAIJ
87347c6ae99SBarry Smith 
87447c6ae99SBarry Smith     Output Parameter:
87547c6ae99SBarry Smith .   coloring - the coloring
87647c6ae99SBarry Smith 
87747c6ae99SBarry Smith     Level: developer
87847c6ae99SBarry Smith 
879e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
88047c6ae99SBarry Smith 
881aab9d709SJed Brown @*/
88219fd82e9SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
88347c6ae99SBarry Smith {
88447c6ae99SBarry Smith   PetscErrorCode ierr;
88547c6ae99SBarry Smith 
88647c6ae99SBarry Smith   PetscFunctionBegin;
887171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
88847c6ae99SBarry Smith   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
88947c6ae99SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
89047c6ae99SBarry Smith   PetscFunctionReturn(0);
89147c6ae99SBarry Smith }
89247c6ae99SBarry Smith 
89347c6ae99SBarry Smith #undef __FUNCT__
894950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
89547c6ae99SBarry Smith /*@C
896950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
89747c6ae99SBarry Smith 
89847c6ae99SBarry Smith     Collective on DM
89947c6ae99SBarry Smith 
90047c6ae99SBarry Smith     Input Parameter:
90147c6ae99SBarry Smith +   dm - the DM object
90247c6ae99SBarry Smith -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
90394013140SBarry Smith             any type which inherits from one of these (such as MATAIJ)
90447c6ae99SBarry Smith 
90547c6ae99SBarry Smith     Output Parameter:
90647c6ae99SBarry Smith .   mat - the empty Jacobian
90747c6ae99SBarry Smith 
908073dac72SJed Brown     Level: beginner
90947c6ae99SBarry Smith 
91094013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
91194013140SBarry Smith        do not need to do it yourself.
91294013140SBarry Smith 
91394013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
914aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
91594013140SBarry Smith 
91694013140SBarry 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
91794013140SBarry Smith        internally by PETSc.
91894013140SBarry Smith 
91994013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
920aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
92194013140SBarry Smith 
922e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
92347c6ae99SBarry Smith 
924aab9d709SJed Brown @*/
92519fd82e9SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,MatType mtype,Mat *mat)
92647c6ae99SBarry Smith {
92747c6ae99SBarry Smith   PetscErrorCode ierr;
92847c6ae99SBarry Smith 
92947c6ae99SBarry Smith   PetscFunctionBegin;
930171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
931235683edSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
932235683edSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
933235683edSBarry Smith #endif
934c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
935c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
936073dac72SJed Brown   if (dm->mattype) {
93725296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
938073dac72SJed Brown   } else {
93925296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
940c7b7c8a4SJed Brown   }
94147c6ae99SBarry Smith   PetscFunctionReturn(0);
94247c6ae99SBarry Smith }
94347c6ae99SBarry Smith 
94447c6ae99SBarry Smith #undef __FUNCT__
945732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
946732e2eb9SMatthew G Knepley /*@
947950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
948732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
949732e2eb9SMatthew G Knepley 
950732e2eb9SMatthew G Knepley   Logically Collective on DMDA
951732e2eb9SMatthew G Knepley 
952732e2eb9SMatthew G Knepley   Input Parameter:
953732e2eb9SMatthew G Knepley + dm - the DM
954732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
955732e2eb9SMatthew G Knepley 
956732e2eb9SMatthew G Knepley   Level: developer
957950540a4SJed Brown .seealso DMCreateMatrix()
958732e2eb9SMatthew G Knepley @*/
959732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
960732e2eb9SMatthew G Knepley {
961732e2eb9SMatthew G Knepley   PetscFunctionBegin;
962732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
963732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
964732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
965732e2eb9SMatthew G Knepley }
966732e2eb9SMatthew G Knepley 
967732e2eb9SMatthew G Knepley #undef __FUNCT__
968a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
969a89ea682SMatthew G Knepley /*@C
970aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
971a89ea682SMatthew G Knepley 
972a89ea682SMatthew G Knepley   Not Collective
973a89ea682SMatthew G Knepley 
974a89ea682SMatthew G Knepley   Input Parameters:
975a89ea682SMatthew G Knepley + dm - the DM object
976aa1993deSMatthew G Knepley . count - The minium size
977aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
978a89ea682SMatthew G Knepley 
979a89ea682SMatthew G Knepley   Output Parameter:
980a89ea682SMatthew G Knepley . array - the work array
981a89ea682SMatthew G Knepley 
982a89ea682SMatthew G Knepley   Level: developer
983a89ea682SMatthew G Knepley 
984a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
985a89ea682SMatthew G Knepley @*/
986aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
987a89ea682SMatthew G Knepley {
988a89ea682SMatthew G Knepley   PetscErrorCode ierr;
989aa1993deSMatthew G Knepley   DMWorkLink link;
990aa1993deSMatthew G Knepley   size_t size;
991a89ea682SMatthew G Knepley 
992a89ea682SMatthew G Knepley   PetscFunctionBegin;
993a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
994aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
995aa1993deSMatthew G Knepley   if (dm->workin) {
996aa1993deSMatthew G Knepley     link = dm->workin;
997aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
998aa1993deSMatthew G Knepley   } else {
999aa1993deSMatthew G Knepley     ierr = PetscNewLog(dm,struct _DMWorkLink,&link);CHKERRQ(ierr);
1000a89ea682SMatthew G Knepley   }
1001aa1993deSMatthew G Knepley   ierr = PetscDataTypeGetSize(dtype,&size);CHKERRQ(ierr);
1002aa1993deSMatthew G Knepley   if (size*count > link->bytes) {
1003aa1993deSMatthew G Knepley     ierr = PetscFree(link->mem);CHKERRQ(ierr);
1004aa1993deSMatthew G Knepley     ierr = PetscMalloc(size*count,&link->mem);CHKERRQ(ierr);
1005aa1993deSMatthew G Knepley     link->bytes = size*count;
1006aa1993deSMatthew G Knepley   }
1007aa1993deSMatthew G Knepley   link->next = dm->workout;
1008aa1993deSMatthew G Knepley   dm->workout = link;
1009aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
1010a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
1011a89ea682SMatthew G Knepley }
1012a89ea682SMatthew G Knepley 
1013aa1993deSMatthew G Knepley #undef __FUNCT__
1014aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
1015aa1993deSMatthew G Knepley /*@C
1016aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1017aa1993deSMatthew G Knepley 
1018aa1993deSMatthew G Knepley   Not Collective
1019aa1993deSMatthew G Knepley 
1020aa1993deSMatthew G Knepley   Input Parameters:
1021aa1993deSMatthew G Knepley + dm - the DM object
1022aa1993deSMatthew G Knepley . count - The minium size
1023aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
1024aa1993deSMatthew G Knepley 
1025aa1993deSMatthew G Knepley   Output Parameter:
1026aa1993deSMatthew G Knepley . array - the work array
1027aa1993deSMatthew G Knepley 
1028aa1993deSMatthew G Knepley   Level: developer
1029aa1993deSMatthew G Knepley 
1030aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
1031aa1993deSMatthew G Knepley @*/
1032aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1033aa1993deSMatthew G Knepley {
1034aa1993deSMatthew G Knepley   DMWorkLink *p,link;
1035aa1993deSMatthew G Knepley 
1036aa1993deSMatthew G Knepley   PetscFunctionBegin;
1037aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1038aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1039aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
1040aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
1041aa1993deSMatthew G Knepley       *p = link->next;
1042aa1993deSMatthew G Knepley       link->next = dm->workin;
1043aa1993deSMatthew G Knepley       dm->workin = link;
1044aa1993deSMatthew G Knepley       *(void**)mem = PETSC_NULL;
1045aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
1046aa1993deSMatthew G Knepley     }
1047aa1993deSMatthew G Knepley   }
1048aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
1049aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
1050aa1993deSMatthew G Knepley }
1051e7c4fc90SDmitry Karpeev 
1052e7c4fc90SDmitry Karpeev #undef __FUNCT__
1053435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
1054435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1055435a35e8SMatthew G Knepley {
1056435a35e8SMatthew G Knepley   PetscFunctionBegin;
1057435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1058435a35e8SMatthew G Knepley   if (field >= 10) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1059435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
1060435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1061435a35e8SMatthew G Knepley }
1062435a35e8SMatthew G Knepley 
1063435a35e8SMatthew G Knepley #undef __FUNCT__
10644d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
10654f3b5142SJed Brown /*@C
10664d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
10674d343eeaSMatthew G Knepley 
10684d343eeaSMatthew G Knepley   Not collective
10694d343eeaSMatthew G Knepley 
10704d343eeaSMatthew G Knepley   Input Parameter:
10714d343eeaSMatthew G Knepley . dm - the DM object
10724d343eeaSMatthew G Knepley 
10734d343eeaSMatthew G Knepley   Output Parameters:
107421c9b008SJed Brown + numFields  - The number of fields (or PETSC_NULL if not requested)
107537d0c07bSMatthew G Knepley . fieldNames - The name for each field (or PETSC_NULL if not requested)
107621c9b008SJed Brown - fields     - The global indices for each field (or PETSC_NULL if not requested)
10774d343eeaSMatthew G Knepley 
10784d343eeaSMatthew G Knepley   Level: intermediate
10794d343eeaSMatthew G Knepley 
108021c9b008SJed Brown   Notes:
108121c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
108221c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
108321c9b008SJed Brown   PetscFree().
108421c9b008SJed Brown 
10854d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
10864d343eeaSMatthew G Knepley @*/
108737d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
10884d343eeaSMatthew G Knepley {
108937d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
10904d343eeaSMatthew G Knepley   PetscErrorCode ierr;
10914d343eeaSMatthew G Knepley 
10924d343eeaSMatthew G Knepley   PetscFunctionBegin;
10934d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
109469ca1f37SDmitry Karpeev   if (numFields) {
109569ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
109669ca1f37SDmitry Karpeev     *numFields = 0;
109769ca1f37SDmitry Karpeev   }
109837d0c07bSMatthew G Knepley   if (fieldNames) {
109937d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
110037d0c07bSMatthew G Knepley     *fieldNames = PETSC_NULL;
110169ca1f37SDmitry Karpeev   }
110269ca1f37SDmitry Karpeev   if (fields) {
110369ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
110469ca1f37SDmitry Karpeev     *fields = PETSC_NULL;
110569ca1f37SDmitry Karpeev   }
110637d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
110737d0c07bSMatthew G Knepley   if (section) {
110837d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
110937d0c07bSMatthew G Knepley     PetscInt  nF, f, pStart, pEnd, p;
111037d0c07bSMatthew G Knepley 
111137d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
111237d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
111337d0c07bSMatthew G Knepley     ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr);
111437d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
111537d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
111637d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
111737d0c07bSMatthew G Knepley     }
111837d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
111937d0c07bSMatthew G Knepley       PetscInt gdof;
112037d0c07bSMatthew G Knepley 
112137d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
112237d0c07bSMatthew G Knepley       if (gdof > 0) {
112337d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
112437d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
112537d0c07bSMatthew G Knepley 
112637d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
112737d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
112837d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
112937d0c07bSMatthew G Knepley         }
113037d0c07bSMatthew G Knepley       }
113137d0c07bSMatthew G Knepley     }
113237d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
113337d0c07bSMatthew G Knepley       ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr);
113437d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
113537d0c07bSMatthew G Knepley     }
113637d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
113737d0c07bSMatthew G Knepley       PetscInt gdof, goff;
113837d0c07bSMatthew G Knepley 
113937d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
114037d0c07bSMatthew G Knepley       if (gdof > 0) {
114137d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
114237d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
114337d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
114437d0c07bSMatthew G Knepley 
114537d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
114637d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
114737d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
114837d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
114937d0c07bSMatthew G Knepley           }
115037d0c07bSMatthew G Knepley         }
115137d0c07bSMatthew G Knepley       }
115237d0c07bSMatthew G Knepley     }
115337d0c07bSMatthew G Knepley     if (numFields) {*numFields = nF;}
115437d0c07bSMatthew G Knepley     if (fieldNames) {
115537d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr);
115637d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
115737d0c07bSMatthew G Knepley         const char *fieldName;
115837d0c07bSMatthew G Knepley 
115937d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
116037d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr);
116137d0c07bSMatthew G Knepley       }
116237d0c07bSMatthew G Knepley     }
116337d0c07bSMatthew G Knepley     if (fields) {
116437d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr);
116537d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
116637d0c07bSMatthew G Knepley         ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
116737d0c07bSMatthew G Knepley       }
116837d0c07bSMatthew G Knepley     }
116937d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
117037d0c07bSMatthew G Knepley   } else {
117137d0c07bSMatthew G Knepley     if (dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);}
117269ca1f37SDmitry Karpeev   }
11734d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
11744d343eeaSMatthew G Knepley }
11754d343eeaSMatthew G Knepley 
1176a89ea682SMatthew G Knepley #undef __FUNCT__
117716621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecompositionDM"
1178e7c4fc90SDmitry Karpeev /*@C
117916621825SDmitry Karpeev   DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields.
118016621825SDmitry Karpeev 
118116621825SDmitry Karpeev   Not Collective
118216621825SDmitry Karpeev 
118316621825SDmitry Karpeev   Input Parameters:
118416621825SDmitry Karpeev + dm   - the DM object
118516621825SDmitry Karpeev - name - the name of the field decomposition
118616621825SDmitry Karpeev 
118716621825SDmitry Karpeev   Output Parameter:
118816621825SDmitry Karpeev . ddm  - the field decomposition DM (PETSC_NULL, if no such decomposition is known)
118916621825SDmitry Karpeev 
119016621825SDmitry Karpeev   Level: advanced
119116621825SDmitry Karpeev 
119216621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
119316621825SDmitry Karpeev @*/
119416621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm)
119516621825SDmitry Karpeev {
119616621825SDmitry Karpeev   PetscErrorCode ierr;
119716621825SDmitry Karpeev 
119816621825SDmitry Karpeev   PetscFunctionBegin;
119916621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
120016621825SDmitry Karpeev   PetscValidCharPointer(name,2);
120116621825SDmitry Karpeev   PetscValidPointer(ddm,3);
120216621825SDmitry Karpeev   *ddm = PETSC_NULL;
1203731c8d9eSDmitry Karpeev   if (dm->ops->createfielddecompositiondm) {
120416621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
120516621825SDmitry Karpeev   }
120616621825SDmitry Karpeev   PetscFunctionReturn(0);
120716621825SDmitry Karpeev }
120816621825SDmitry Karpeev 
120916621825SDmitry Karpeev #undef __FUNCT__
121016621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
121116621825SDmitry Karpeev /*@C
121216621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
121316621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
121416621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1215e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1216e7c4fc90SDmitry Karpeev 
1217e7c4fc90SDmitry Karpeev   Not collective
1218e7c4fc90SDmitry Karpeev 
1219e7c4fc90SDmitry Karpeev   Input Parameter:
1220e7c4fc90SDmitry Karpeev . dm - the DM object
1221e7c4fc90SDmitry Karpeev 
1222e7c4fc90SDmitry Karpeev   Output Parameters:
122316621825SDmitry Karpeev + len       - The number of subproblems in the field decomposition (or PETSC_NULL if not requested)
122416621825SDmitry Karpeev . namelist  - The name for each field (or PETSC_NULL if not requested)
122516621825SDmitry Karpeev . islist    - The global indices for each field (or PETSC_NULL if not requested)
122616621825SDmitry Karpeev - dmlist    - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
1227e7c4fc90SDmitry Karpeev 
1228e7c4fc90SDmitry Karpeev   Level: intermediate
1229e7c4fc90SDmitry Karpeev 
1230e7c4fc90SDmitry Karpeev   Notes:
1231e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1232e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1233e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1234e7c4fc90SDmitry Karpeev 
1235e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1236e7c4fc90SDmitry Karpeev @*/
123716621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1238e7c4fc90SDmitry Karpeev {
1239e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1240e7c4fc90SDmitry Karpeev 
1241e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1242e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1243731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);      *len      = 0;}
1244731c8d9eSDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;}
1245731c8d9eSDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);   *islist   = 0;}
1246731c8d9eSDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);   *dmlist   = 0;}
124716621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1248435a35e8SMatthew G Knepley     PetscSection section;
1249435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1250435a35e8SMatthew G Knepley 
1251435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1252435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1253435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1254435a35e8SMatthew G Knepley       *len = numFields;
1255435a35e8SMatthew G Knepley       ierr = PetscMalloc3(numFields,char*,namelist,numFields,IS,islist,numFields,DM,dmlist);CHKERRQ(ierr);
1256435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1257435a35e8SMatthew G Knepley         const char *fieldName;
1258435a35e8SMatthew G Knepley 
1259435a35e8SMatthew G Knepley         ierr = DMCreateSubDM(dm, 1, &f, &(*islist)[f], &(*dmlist)[f]);CHKERRQ(ierr);
1260435a35e8SMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1261435a35e8SMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*namelist)[f]);CHKERRQ(ierr);
1262435a35e8SMatthew G Knepley       }
1263435a35e8SMatthew G Knepley     } else {
126469ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1265e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
1266e7c4fc90SDmitry Karpeev       if (dmlist) *dmlist = PETSC_NULL;
1267e7c4fc90SDmitry Karpeev     }
1268435a35e8SMatthew G Knepley   }
1269e7c4fc90SDmitry Karpeev   else {
127016621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
127116621825SDmitry Karpeev   }
127216621825SDmitry Karpeev   PetscFunctionReturn(0);
127316621825SDmitry Karpeev }
127416621825SDmitry Karpeev 
127516621825SDmitry Karpeev #undef __FUNCT__
1276435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1277435a35e8SMatthew G Knepley /*@C
1278435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1279435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1280435a35e8SMatthew G Knepley 
1281435a35e8SMatthew G Knepley   Not collective
1282435a35e8SMatthew G Knepley 
1283435a35e8SMatthew G Knepley   Input Parameters:
1284435a35e8SMatthew G Knepley + dm - the DM object
1285435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
1286435a35e8SMatthew G Knepley - len       - The number of subproblems in the decomposition (or PETSC_NULL if not requested)
1287435a35e8SMatthew G Knepley 
1288435a35e8SMatthew G Knepley   Output Parameters:
1289435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1290435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1291435a35e8SMatthew G Knepley 
1292435a35e8SMatthew G Knepley   Level: intermediate
1293435a35e8SMatthew G Knepley 
1294435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1295435a35e8SMatthew G Knepley @*/
1296435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1297435a35e8SMatthew G Knepley {
1298435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1299435a35e8SMatthew G Knepley 
1300435a35e8SMatthew G Knepley   PetscFunctionBegin;
1301435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1302435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
1303435a35e8SMatthew G Knepley   if (is) {PetscValidPointer(is,4);}
1304435a35e8SMatthew G Knepley   if (subdm) {PetscValidPointer(subdm,5);}
1305435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1306435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm); CHKERRQ(ierr);
1307435a35e8SMatthew G Knepley   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1308435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1309435a35e8SMatthew G Knepley }
1310435a35e8SMatthew G Knepley 
1311435a35e8SMatthew G Knepley #undef __FUNCT__
131216621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecompositionDM"
131316621825SDmitry Karpeev /*@C
131416621825SDmitry Karpeev   DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains.
131516621825SDmitry Karpeev 
131616621825SDmitry Karpeev   Not Collective
131716621825SDmitry Karpeev 
131816621825SDmitry Karpeev   Input Parameters:
131916621825SDmitry Karpeev + dm   - the DM object
132016621825SDmitry Karpeev - name - the name of the subdomain decomposition
132116621825SDmitry Karpeev 
132216621825SDmitry Karpeev   Output Parameter:
132316621825SDmitry Karpeev . ddm  - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known)
132416621825SDmitry Karpeev 
132516621825SDmitry Karpeev   Level: advanced
132616621825SDmitry Karpeev 
132716621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
132816621825SDmitry Karpeev @*/
132916621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm)
133016621825SDmitry Karpeev {
133116621825SDmitry Karpeev   PetscErrorCode ierr;
133216621825SDmitry Karpeev 
133316621825SDmitry Karpeev   PetscFunctionBegin;
133416621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
133516621825SDmitry Karpeev   PetscValidCharPointer(name,2);
133616621825SDmitry Karpeev   PetscValidPointer(ddm,3);
133716621825SDmitry Karpeev   *ddm = PETSC_NULL;
1338731c8d9eSDmitry Karpeev   if (dm->ops->createdomaindecompositiondm) {
133916621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
134016621825SDmitry Karpeev   }
134116621825SDmitry Karpeev   PetscFunctionReturn(0);
134216621825SDmitry Karpeev }
134316621825SDmitry Karpeev 
134416621825SDmitry Karpeev #undef __FUNCT__
134516621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
134616621825SDmitry Karpeev /*@C
13478d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
13488d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
13498d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
13508d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
13518d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
135216621825SDmitry Karpeev 
135316621825SDmitry Karpeev   Not collective
135416621825SDmitry Karpeev 
135516621825SDmitry Karpeev   Input Parameter:
135616621825SDmitry Karpeev . dm - the DM object
135716621825SDmitry Karpeev 
135816621825SDmitry Karpeev   Output Parameters:
135916621825SDmitry Karpeev + len         - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested)
136016621825SDmitry Karpeev . namelist    - The name for each subdomain (or PETSC_NULL if not requested)
13618d4ac253SDmitry Karpeev . innerislist - The global indices for each inner subdomain (or PETSC_NULL, if not requested)
13628d4ac253SDmitry Karpeev . outerislist - The global indices for each outer subdomain (or PETSC_NULL, if not requested)
136316621825SDmitry Karpeev - dmlist      - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
136416621825SDmitry Karpeev 
136516621825SDmitry Karpeev   Level: intermediate
136616621825SDmitry Karpeev 
136716621825SDmitry Karpeev   Notes:
136816621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
136916621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
137016621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
137116621825SDmitry Karpeev 
13728d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
137316621825SDmitry Karpeev @*/
13748d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
137516621825SDmitry Karpeev {
137616621825SDmitry Karpeev   PetscErrorCode ierr;
137716621825SDmitry Karpeev 
137816621825SDmitry Karpeev   PetscFunctionBegin;
137916621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1380731c8d9eSDmitry Karpeev   if (len)           {PetscValidPointer(len,2);            *len         = PETSC_NULL;}
138116621825SDmitry Karpeev   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = PETSC_NULL;}
13828d4ac253SDmitry Karpeev   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = PETSC_NULL;}
13838d4ac253SDmitry Karpeev   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = PETSC_NULL;}
13848d4ac253SDmitry Karpeev   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = PETSC_NULL;}
138516621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
13868d4ac253SDmitry Karpeev     ierr = (*dm->ops->createdomaindecomposition)(dm,len,namelist,innerislist,outerislist,dmlist); CHKERRQ(ierr);
1387e7c4fc90SDmitry Karpeev   }
1388e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1389e7c4fc90SDmitry Karpeev }
1390e7c4fc90SDmitry Karpeev 
1391731c8d9eSDmitry Karpeev #undef __FUNCT__
139247c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
139347c6ae99SBarry Smith /*@
139447c6ae99SBarry Smith   DMRefine - Refines a DM object
139547c6ae99SBarry Smith 
139647c6ae99SBarry Smith   Collective on DM
139747c6ae99SBarry Smith 
139847c6ae99SBarry Smith   Input Parameter:
139947c6ae99SBarry Smith + dm   - the DM object
140091d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
140147c6ae99SBarry Smith 
140247c6ae99SBarry Smith   Output Parameter:
1403ae0a1c52SMatthew G Knepley . dmf - the refined DM, or PETSC_NULL
1404ae0a1c52SMatthew G Knepley 
1405ae0a1c52SMatthew G Knepley   Note: If no refinement was done, the return value is PETSC_NULL
140647c6ae99SBarry Smith 
140747c6ae99SBarry Smith   Level: developer
140847c6ae99SBarry Smith 
1409e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
141047c6ae99SBarry Smith @*/
14117087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
141247c6ae99SBarry Smith {
141347c6ae99SBarry Smith   PetscErrorCode ierr;
1414c833c3b5SJed Brown   DMRefineHookLink link;
141547c6ae99SBarry Smith 
141647c6ae99SBarry Smith   PetscFunctionBegin;
1417732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
141847c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
14194057135bSMatthew G Knepley   if (*dmf) {
142043842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
1421644e2e5bSBarry Smith     (*dmf)->ops->initialguess = dm->ops->initialguess;
1422644e2e5bSBarry Smith     (*dmf)->ops->function     = dm->ops->function;
1423644e2e5bSBarry Smith     (*dmf)->ops->functionj    = dm->ops->functionj;
1424644e2e5bSBarry Smith     if (dm->ops->jacobian != DMComputeJacobianDefault) {
1425644e2e5bSBarry Smith       (*dmf)->ops->jacobian     = dm->ops->jacobian;
1426644e2e5bSBarry Smith     }
14278cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
1428644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
14290598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1430656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
1431e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1432c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
1433c833c3b5SJed Brown       if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);}
1434c833c3b5SJed Brown     }
1435c833c3b5SJed Brown   }
1436c833c3b5SJed Brown   PetscFunctionReturn(0);
1437c833c3b5SJed Brown }
1438c833c3b5SJed Brown 
1439c833c3b5SJed Brown #undef __FUNCT__
1440c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1441c833c3b5SJed Brown /*@
1442c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1443c833c3b5SJed Brown 
1444c833c3b5SJed Brown    Logically Collective
1445c833c3b5SJed Brown 
1446c833c3b5SJed Brown    Input Arguments:
1447c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1448c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1449c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
1450c833c3b5SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1451c833c3b5SJed Brown 
1452c833c3b5SJed Brown    Calling sequence of refinehook:
1453c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1454c833c3b5SJed Brown 
1455c833c3b5SJed Brown +  coarse - coarse level DM
1456c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1457c833c3b5SJed Brown -  ctx - optional user-defined function context
1458c833c3b5SJed Brown 
1459c833c3b5SJed Brown    Calling sequence for interphook:
1460c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1461c833c3b5SJed Brown 
1462c833c3b5SJed Brown +  coarse - coarse level DM
1463c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1464c833c3b5SJed Brown .  fine - fine level DM to update
1465c833c3b5SJed Brown -  ctx - optional user-defined function context
1466c833c3b5SJed Brown 
1467c833c3b5SJed Brown    Level: advanced
1468c833c3b5SJed Brown 
1469c833c3b5SJed Brown    Notes:
1470c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1471c833c3b5SJed Brown 
1472c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1473c833c3b5SJed Brown 
1474c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1475c833c3b5SJed Brown @*/
1476c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1477c833c3b5SJed Brown {
1478c833c3b5SJed Brown   PetscErrorCode ierr;
1479c833c3b5SJed Brown   DMRefineHookLink link,*p;
1480c833c3b5SJed Brown 
1481c833c3b5SJed Brown   PetscFunctionBegin;
1482c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1483c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1484c833c3b5SJed Brown   ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1485c833c3b5SJed Brown   link->refinehook = refinehook;
1486c833c3b5SJed Brown   link->interphook = interphook;
1487c833c3b5SJed Brown   link->ctx = ctx;
1488c833c3b5SJed Brown   link->next = PETSC_NULL;
1489c833c3b5SJed Brown   *p = link;
1490c833c3b5SJed Brown   PetscFunctionReturn(0);
1491c833c3b5SJed Brown }
1492c833c3b5SJed Brown 
1493c833c3b5SJed Brown #undef __FUNCT__
1494c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1495c833c3b5SJed Brown /*@
1496c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1497c833c3b5SJed Brown 
1498c833c3b5SJed Brown    Collective if any hooks are
1499c833c3b5SJed Brown 
1500c833c3b5SJed Brown    Input Arguments:
1501c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1502c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1503c833c3b5SJed Brown -  fine - finer DM to update
1504c833c3b5SJed Brown 
1505c833c3b5SJed Brown    Level: developer
1506c833c3b5SJed Brown 
1507c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1508c833c3b5SJed Brown @*/
1509c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1510c833c3b5SJed Brown {
1511c833c3b5SJed Brown   PetscErrorCode ierr;
1512c833c3b5SJed Brown   DMRefineHookLink link;
1513c833c3b5SJed Brown 
1514c833c3b5SJed Brown   PetscFunctionBegin;
1515c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
1516c833c3b5SJed Brown     if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);}
15174057135bSMatthew G Knepley   }
151847c6ae99SBarry Smith   PetscFunctionReturn(0);
151947c6ae99SBarry Smith }
152047c6ae99SBarry Smith 
152147c6ae99SBarry Smith #undef __FUNCT__
1522eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1523eb3f98d2SBarry Smith /*@
1524eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1525eb3f98d2SBarry Smith 
1526eb3f98d2SBarry Smith     Not Collective
1527eb3f98d2SBarry Smith 
1528eb3f98d2SBarry Smith     Input Parameter:
1529eb3f98d2SBarry Smith .   dm - the DM object
1530eb3f98d2SBarry Smith 
1531eb3f98d2SBarry Smith     Output Parameter:
1532eb3f98d2SBarry Smith .   level - number of refinements
1533eb3f98d2SBarry Smith 
1534eb3f98d2SBarry Smith     Level: developer
1535eb3f98d2SBarry Smith 
15366a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1537eb3f98d2SBarry Smith 
1538eb3f98d2SBarry Smith @*/
1539eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1540eb3f98d2SBarry Smith {
1541eb3f98d2SBarry Smith   PetscFunctionBegin;
1542eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1543eb3f98d2SBarry Smith   *level = dm->levelup;
1544eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1545eb3f98d2SBarry Smith }
1546eb3f98d2SBarry Smith 
1547eb3f98d2SBarry Smith #undef __FUNCT__
154847c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
154947c6ae99SBarry Smith /*@
155047c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
155147c6ae99SBarry Smith 
155247c6ae99SBarry Smith     Neighbor-wise Collective on DM
155347c6ae99SBarry Smith 
155447c6ae99SBarry Smith     Input Parameters:
155547c6ae99SBarry Smith +   dm - the DM object
155647c6ae99SBarry Smith .   g - the global vector
155747c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
155847c6ae99SBarry Smith -   l - the local vector
155947c6ae99SBarry Smith 
156047c6ae99SBarry Smith 
156147c6ae99SBarry Smith     Level: beginner
156247c6ae99SBarry Smith 
1563e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
156447c6ae99SBarry Smith 
156547c6ae99SBarry Smith @*/
15667087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
156747c6ae99SBarry Smith {
15687128ae9fSMatthew G Knepley   PetscSF        sf;
156947c6ae99SBarry Smith   PetscErrorCode ierr;
157047c6ae99SBarry Smith 
157147c6ae99SBarry Smith   PetscFunctionBegin;
1572171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
15737128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
15747128ae9fSMatthew G Knepley   if (sf) {
15757128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
15767128ae9fSMatthew G Knepley 
15777128ae9fSMatthew G Knepley     if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
15787128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
15797128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
15807128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
15817128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
15827128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
15837128ae9fSMatthew G Knepley   } else {
1584843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
15857128ae9fSMatthew G Knepley   }
158647c6ae99SBarry Smith   PetscFunctionReturn(0);
158747c6ae99SBarry Smith }
158847c6ae99SBarry Smith 
158947c6ae99SBarry Smith #undef __FUNCT__
159047c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
159147c6ae99SBarry Smith /*@
159247c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
159347c6ae99SBarry Smith 
159447c6ae99SBarry Smith     Neighbor-wise Collective on DM
159547c6ae99SBarry Smith 
159647c6ae99SBarry Smith     Input Parameters:
159747c6ae99SBarry Smith +   dm - the DM object
159847c6ae99SBarry Smith .   g - the global vector
159947c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
160047c6ae99SBarry Smith -   l - the local vector
160147c6ae99SBarry Smith 
160247c6ae99SBarry Smith 
160347c6ae99SBarry Smith     Level: beginner
160447c6ae99SBarry Smith 
1605e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
160647c6ae99SBarry Smith 
160747c6ae99SBarry Smith @*/
16087087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
160947c6ae99SBarry Smith {
16107128ae9fSMatthew G Knepley   PetscSF        sf;
161147c6ae99SBarry Smith   PetscErrorCode ierr;
161261a3c1faSSatish Balay   PetscScalar    *lArray, *gArray;
161347c6ae99SBarry Smith 
161447c6ae99SBarry Smith   PetscFunctionBegin;
1615171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
16167128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
16177128ae9fSMatthew G Knepley   if (sf) {
16187128ae9fSMatthew G Knepley   if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
16197128ae9fSMatthew G Knepley 
16207128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
16217128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
16227128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
16237128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
16247128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
16257128ae9fSMatthew G Knepley   } else {
1626843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
16277128ae9fSMatthew G Knepley   }
162847c6ae99SBarry Smith   PetscFunctionReturn(0);
162947c6ae99SBarry Smith }
163047c6ae99SBarry Smith 
163147c6ae99SBarry Smith #undef __FUNCT__
16329a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
163347c6ae99SBarry Smith /*@
16349a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
16359a42bb27SBarry Smith 
16369a42bb27SBarry Smith     Neighbor-wise Collective on DM
16379a42bb27SBarry Smith 
16389a42bb27SBarry Smith     Input Parameters:
16399a42bb27SBarry Smith +   dm - the DM object
1640f6813fd5SJed Brown .   l - the local vector
16419a42bb27SBarry 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
16429a42bb27SBarry Smith            base point.
1643f6813fd5SJed Brown - - the global vector
16449a42bb27SBarry Smith 
16459a42bb27SBarry 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
16469a42bb27SBarry 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
16479a42bb27SBarry Smith            global array to the final global array with VecAXPY().
16489a42bb27SBarry Smith 
16499a42bb27SBarry Smith     Level: beginner
16509a42bb27SBarry Smith 
1651e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
16529a42bb27SBarry Smith 
16539a42bb27SBarry Smith @*/
16547087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
16559a42bb27SBarry Smith {
16567128ae9fSMatthew G Knepley   PetscSF        sf;
16579a42bb27SBarry Smith   PetscErrorCode ierr;
16589a42bb27SBarry Smith 
16599a42bb27SBarry Smith   PetscFunctionBegin;
1660171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
16617128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
16627128ae9fSMatthew G Knepley   if (sf) {
16637128ae9fSMatthew G Knepley     MPI_Op       op;
16647128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
16657128ae9fSMatthew G Knepley 
16667128ae9fSMatthew G Knepley     switch(mode) {
16677128ae9fSMatthew G Knepley     case INSERT_VALUES:
16687128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
16697128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
16707128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
16717128ae9fSMatthew G Knepley #else
16727128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
16737128ae9fSMatthew G Knepley #endif
16747128ae9fSMatthew G Knepley     case ADD_VALUES:
16757128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
16767128ae9fSMatthew G Knepley       op = MPI_SUM; break;
16777128ae9fSMatthew G Knepley   default:
16787128ae9fSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
16797128ae9fSMatthew G Knepley     }
16807128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
16817128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
16827128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
16837128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
16847128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
16857128ae9fSMatthew G Knepley   } else {
1686843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
16877128ae9fSMatthew G Knepley   }
16889a42bb27SBarry Smith   PetscFunctionReturn(0);
16899a42bb27SBarry Smith }
16909a42bb27SBarry Smith 
16919a42bb27SBarry Smith #undef __FUNCT__
16929a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
16939a42bb27SBarry Smith /*@
16949a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
169547c6ae99SBarry Smith 
169647c6ae99SBarry Smith     Neighbor-wise Collective on DM
169747c6ae99SBarry Smith 
169847c6ae99SBarry Smith     Input Parameters:
169947c6ae99SBarry Smith +   dm - the DM object
1700f6813fd5SJed Brown .   l - the local vector
170147c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1702f6813fd5SJed Brown -   g - the global vector
170347c6ae99SBarry Smith 
170447c6ae99SBarry Smith 
170547c6ae99SBarry Smith     Level: beginner
170647c6ae99SBarry Smith 
1707e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
170847c6ae99SBarry Smith 
170947c6ae99SBarry Smith @*/
17107087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
171147c6ae99SBarry Smith {
17127128ae9fSMatthew G Knepley   PetscSF        sf;
171347c6ae99SBarry Smith   PetscErrorCode ierr;
171447c6ae99SBarry Smith 
171547c6ae99SBarry Smith   PetscFunctionBegin;
1716171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17177128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17187128ae9fSMatthew G Knepley   if (sf) {
17197128ae9fSMatthew G Knepley     MPI_Op       op;
17207128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
17217128ae9fSMatthew G Knepley 
17227128ae9fSMatthew G Knepley     switch(mode) {
17237128ae9fSMatthew G Knepley     case INSERT_VALUES:
17247128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
17257128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
17267128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
17277128ae9fSMatthew G Knepley #else
17287128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
17297128ae9fSMatthew G Knepley #endif
17307128ae9fSMatthew G Knepley     case ADD_VALUES:
17317128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
17327128ae9fSMatthew G Knepley       op = MPI_SUM; break;
17337128ae9fSMatthew G Knepley     default:
17347128ae9fSMatthew G Knepley       SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17357128ae9fSMatthew G Knepley     }
17367128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
17377128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
17387128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
17397128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
17407128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
17417128ae9fSMatthew G Knepley   } else {
1742843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
17437128ae9fSMatthew G Knepley   }
174447c6ae99SBarry Smith   PetscFunctionReturn(0);
174547c6ae99SBarry Smith }
174647c6ae99SBarry Smith 
174747c6ae99SBarry Smith #undef __FUNCT__
174847c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobianDefault"
174947c6ae99SBarry Smith /*@
175047c6ae99SBarry Smith     DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided
175147c6ae99SBarry Smith 
175247c6ae99SBarry Smith     Collective on DM
175347c6ae99SBarry Smith 
175447c6ae99SBarry Smith     Input Parameter:
175547c6ae99SBarry Smith +   dm - the DM object
175647c6ae99SBarry Smith .   x - location to compute Jacobian at; may be ignored for linear problems
175747c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
175847c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
175947c6ae99SBarry Smith 
176047c6ae99SBarry Smith     Level: developer
176147c6ae99SBarry Smith 
1762e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
176347c6ae99SBarry Smith          DMSetFunction()
176447c6ae99SBarry Smith 
176547c6ae99SBarry Smith @*/
17667087cfbeSBarry Smith PetscErrorCode  DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
176747c6ae99SBarry Smith {
176847c6ae99SBarry Smith   PetscErrorCode ierr;
1769171400e9SBarry Smith 
177047c6ae99SBarry Smith   PetscFunctionBegin;
1771171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
177247c6ae99SBarry Smith   *stflag = SAME_NONZERO_PATTERN;
177347c6ae99SBarry Smith   ierr  = MatFDColoringApply(B,dm->fd,x,stflag,dm);CHKERRQ(ierr);
177447c6ae99SBarry Smith   if (A != B) {
177547c6ae99SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
177647c6ae99SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
177747c6ae99SBarry Smith   }
177847c6ae99SBarry Smith   PetscFunctionReturn(0);
177947c6ae99SBarry Smith }
178047c6ae99SBarry Smith 
178147c6ae99SBarry Smith #undef __FUNCT__
178247c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
178347c6ae99SBarry Smith /*@
178447c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
178547c6ae99SBarry Smith 
178647c6ae99SBarry Smith     Collective on DM
178747c6ae99SBarry Smith 
178847c6ae99SBarry Smith     Input Parameter:
178947c6ae99SBarry Smith +   dm - the DM object
179091d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
179147c6ae99SBarry Smith 
179247c6ae99SBarry Smith     Output Parameter:
179347c6ae99SBarry Smith .   dmc - the coarsened DM
179447c6ae99SBarry Smith 
179547c6ae99SBarry Smith     Level: developer
179647c6ae99SBarry Smith 
1797e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
179847c6ae99SBarry Smith 
179947c6ae99SBarry Smith @*/
18007087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
180147c6ae99SBarry Smith {
180247c6ae99SBarry Smith   PetscErrorCode ierr;
1803b17ce1afSJed Brown   DMCoarsenHookLink link;
180447c6ae99SBarry Smith 
180547c6ae99SBarry Smith   PetscFunctionBegin;
1806171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
180747c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
180843842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
180947c6ae99SBarry Smith   (*dmc)->ops->initialguess = dm->ops->initialguess;
181047c6ae99SBarry Smith   (*dmc)->ops->function     = dm->ops->function;
181147c6ae99SBarry Smith   (*dmc)->ops->functionj    = dm->ops->functionj;
181247c6ae99SBarry Smith   if (dm->ops->jacobian != DMComputeJacobianDefault) {
181347c6ae99SBarry Smith     (*dmc)->ops->jacobian     = dm->ops->jacobian;
181447c6ae99SBarry Smith   }
18158cd211a4SJed Brown   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1816644e2e5bSBarry Smith   (*dmc)->ctx       = dm->ctx;
18170598a293SJed Brown   (*dmc)->levelup   = dm->levelup;
1818656b349aSBarry Smith   (*dmc)->leveldown = dm->leveldown + 1;
1819e4b4b23bSJed Brown   ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
1820b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1821b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1822b17ce1afSJed Brown   }
1823b17ce1afSJed Brown   PetscFunctionReturn(0);
1824b17ce1afSJed Brown }
1825b17ce1afSJed Brown 
1826b17ce1afSJed Brown #undef __FUNCT__
1827b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1828b17ce1afSJed Brown /*@
1829b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1830b17ce1afSJed Brown 
1831b17ce1afSJed Brown    Logically Collective
1832b17ce1afSJed Brown 
1833b17ce1afSJed Brown    Input Arguments:
1834b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1835b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1836b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
1837b17ce1afSJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1838b17ce1afSJed Brown 
1839b17ce1afSJed Brown    Calling sequence of coarsenhook:
1840b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1841b17ce1afSJed Brown 
1842b17ce1afSJed Brown +  fine - fine level DM
1843b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1844b17ce1afSJed Brown -  ctx - optional user-defined function context
1845b17ce1afSJed Brown 
1846b17ce1afSJed Brown    Calling sequence for restricthook:
1847c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
1848b17ce1afSJed Brown 
1849b17ce1afSJed Brown +  fine - fine level DM
1850b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
1851c833c3b5SJed Brown .  rscale - scaling vector for restriction
1852c833c3b5SJed Brown .  inject - matrix restricting by injection
1853b17ce1afSJed Brown .  coarse - coarse level DM to update
1854b17ce1afSJed Brown -  ctx - optional user-defined function context
1855b17ce1afSJed Brown 
1856b17ce1afSJed Brown    Level: advanced
1857b17ce1afSJed Brown 
1858b17ce1afSJed Brown    Notes:
1859b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
1860b17ce1afSJed Brown 
1861b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1862b17ce1afSJed Brown 
1863b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1864b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
1865b17ce1afSJed Brown 
1866c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1867b17ce1afSJed Brown @*/
1868b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1869b17ce1afSJed Brown {
1870b17ce1afSJed Brown   PetscErrorCode ierr;
1871b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
1872b17ce1afSJed Brown 
1873b17ce1afSJed Brown   PetscFunctionBegin;
1874b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
18756bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1876b17ce1afSJed Brown   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1877b17ce1afSJed Brown   link->coarsenhook = coarsenhook;
1878b17ce1afSJed Brown   link->restricthook = restricthook;
1879b17ce1afSJed Brown   link->ctx = ctx;
18806cab3a1bSJed Brown   link->next = PETSC_NULL;
1881b17ce1afSJed Brown   *p = link;
1882b17ce1afSJed Brown   PetscFunctionReturn(0);
1883b17ce1afSJed Brown }
1884b17ce1afSJed Brown 
1885b17ce1afSJed Brown #undef __FUNCT__
1886b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
1887b17ce1afSJed Brown /*@
1888b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1889b17ce1afSJed Brown 
1890b17ce1afSJed Brown    Collective if any hooks are
1891b17ce1afSJed Brown 
1892b17ce1afSJed Brown    Input Arguments:
1893b17ce1afSJed Brown +  fine - finer DM to use as a base
1894b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
1895b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
1896b17ce1afSJed Brown -  coarse - coarer DM to update
1897b17ce1afSJed Brown 
1898b17ce1afSJed Brown    Level: developer
1899b17ce1afSJed Brown 
1900b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
1901b17ce1afSJed Brown @*/
1902b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1903b17ce1afSJed Brown {
1904b17ce1afSJed Brown   PetscErrorCode ierr;
1905b17ce1afSJed Brown   DMCoarsenHookLink link;
1906b17ce1afSJed Brown 
1907b17ce1afSJed Brown   PetscFunctionBegin;
1908b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
1909b17ce1afSJed Brown     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1910b17ce1afSJed Brown   }
191147c6ae99SBarry Smith   PetscFunctionReturn(0);
191247c6ae99SBarry Smith }
191347c6ae99SBarry Smith 
191447c6ae99SBarry Smith #undef __FUNCT__
19155dbd56e3SPeter Brune #define __FUNCT__ "DMBlockRestrictHookAdd"
19165dbd56e3SPeter Brune /*@
19175dbd56e3SPeter Brune    DMBlockRestrictHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
19185dbd56e3SPeter Brune 
19195dbd56e3SPeter Brune    Logically Collective
19205dbd56e3SPeter Brune 
19215dbd56e3SPeter Brune    Input Arguments:
19225dbd56e3SPeter Brune +  global - global DM
19235dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
19245dbd56e3SPeter Brune -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
19255dbd56e3SPeter Brune 
19265dbd56e3SPeter Brune    Calling sequence for restricthook:
19275dbd56e3SPeter Brune $    restricthook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
19285dbd56e3SPeter Brune 
19295dbd56e3SPeter Brune +  global - global DM
19305dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
19315dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
19325dbd56e3SPeter Brune .  block  - block DM (may just be a shell if the global DM is passed in correctly)
19335dbd56e3SPeter Brune -  ctx - optional user-defined function context
19345dbd56e3SPeter Brune 
19355dbd56e3SPeter Brune    Level: advanced
19365dbd56e3SPeter Brune 
19375dbd56e3SPeter Brune    Notes:
19385dbd56e3SPeter Brune    This function is only needed if auxiliary data needs to be set up on coarse grids.
19395dbd56e3SPeter Brune 
19405dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
19415dbd56e3SPeter Brune 
19425dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
19435dbd56e3SPeter Brune    extract the finest level information from its context (instead of from the SNES).
19445dbd56e3SPeter Brune 
19455dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
19465dbd56e3SPeter Brune @*/
19475dbd56e3SPeter Brune PetscErrorCode DMBlockRestrictHookAdd(DM global,PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
19485dbd56e3SPeter Brune {
19495dbd56e3SPeter Brune   PetscErrorCode ierr;
19505dbd56e3SPeter Brune   DMBlockRestrictHookLink link,*p;
19515dbd56e3SPeter Brune 
19525dbd56e3SPeter Brune   PetscFunctionBegin;
19535dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
19545dbd56e3SPeter Brune   for (p=&global->blockrestricthook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
19555dbd56e3SPeter Brune   ierr = PetscMalloc(sizeof(struct _DMBlockRestrictHookLink),&link);CHKERRQ(ierr);
19565dbd56e3SPeter Brune   link->restricthook = restricthook;
19575dbd56e3SPeter Brune   link->ctx = ctx;
19585dbd56e3SPeter Brune   link->next = PETSC_NULL;
19595dbd56e3SPeter Brune   *p = link;
19605dbd56e3SPeter Brune   PetscFunctionReturn(0);
19615dbd56e3SPeter Brune }
19625dbd56e3SPeter Brune 
19635dbd56e3SPeter Brune #undef __FUNCT__
19645dbd56e3SPeter Brune #define __FUNCT__ "DMBlockRestrict"
19655dbd56e3SPeter Brune /*@
19665dbd56e3SPeter Brune    DMBlockRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMBlockRestrictHookAdd()
19675dbd56e3SPeter Brune 
19685dbd56e3SPeter Brune    Collective if any hooks are
19695dbd56e3SPeter Brune 
19705dbd56e3SPeter Brune    Input Arguments:
19715dbd56e3SPeter Brune +  fine - finer DM to use as a base
19725dbd56e3SPeter Brune .  restrct - restriction matrix, apply using MatRestrict()
19735dbd56e3SPeter Brune .  inject - injection matrix, also use MatRestrict()
19745dbd56e3SPeter Brune -  coarse - coarer DM to update
19755dbd56e3SPeter Brune 
19765dbd56e3SPeter Brune    Level: developer
19775dbd56e3SPeter Brune 
19785dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
19795dbd56e3SPeter Brune @*/
19805dbd56e3SPeter Brune PetscErrorCode DMBlockRestrict(DM global,VecScatter in,VecScatter out,DM block)
19815dbd56e3SPeter Brune {
19825dbd56e3SPeter Brune   PetscErrorCode ierr;
19835dbd56e3SPeter Brune   DMBlockRestrictHookLink link;
19845dbd56e3SPeter Brune 
19855dbd56e3SPeter Brune   PetscFunctionBegin;
19865dbd56e3SPeter Brune   for (link=global->blockrestricthook; link; link=link->next) {
19875dbd56e3SPeter Brune     if (link->restricthook) {ierr = (*link->restricthook)(global,in,out,block,link->ctx);CHKERRQ(ierr);}
19885dbd56e3SPeter Brune   }
19895dbd56e3SPeter Brune   PetscFunctionReturn(0);
19905dbd56e3SPeter Brune }
19915dbd56e3SPeter Brune 
19925dbd56e3SPeter Brune #undef __FUNCT__
19935fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
19945fe1f584SPeter Brune /*@
19956a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
19965fe1f584SPeter Brune 
19975fe1f584SPeter Brune     Not Collective
19985fe1f584SPeter Brune 
19995fe1f584SPeter Brune     Input Parameter:
20005fe1f584SPeter Brune .   dm - the DM object
20015fe1f584SPeter Brune 
20025fe1f584SPeter Brune     Output Parameter:
20036a7d9d85SPeter Brune .   level - number of coarsenings
20045fe1f584SPeter Brune 
20055fe1f584SPeter Brune     Level: developer
20065fe1f584SPeter Brune 
20076a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
20085fe1f584SPeter Brune 
20095fe1f584SPeter Brune @*/
20105fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
20115fe1f584SPeter Brune {
20125fe1f584SPeter Brune   PetscFunctionBegin;
20135fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
20145fe1f584SPeter Brune   *level = dm->leveldown;
20155fe1f584SPeter Brune   PetscFunctionReturn(0);
20165fe1f584SPeter Brune }
20175fe1f584SPeter Brune 
20185fe1f584SPeter Brune 
20195fe1f584SPeter Brune 
20205fe1f584SPeter Brune #undef __FUNCT__
202147c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
202247c6ae99SBarry Smith /*@C
202347c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
202447c6ae99SBarry Smith 
202547c6ae99SBarry Smith     Collective on DM
202647c6ae99SBarry Smith 
202747c6ae99SBarry Smith     Input Parameter:
202847c6ae99SBarry Smith +   dm - the DM object
202947c6ae99SBarry Smith -   nlevels - the number of levels of refinement
203047c6ae99SBarry Smith 
203147c6ae99SBarry Smith     Output Parameter:
203247c6ae99SBarry Smith .   dmf - the refined DM hierarchy
203347c6ae99SBarry Smith 
203447c6ae99SBarry Smith     Level: developer
203547c6ae99SBarry Smith 
2036e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
203747c6ae99SBarry Smith 
203847c6ae99SBarry Smith @*/
20397087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
204047c6ae99SBarry Smith {
204147c6ae99SBarry Smith   PetscErrorCode ierr;
204247c6ae99SBarry Smith 
204347c6ae99SBarry Smith   PetscFunctionBegin;
2044171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
204547c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
204647c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
204747c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
204847c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
204947c6ae99SBarry Smith   } else if (dm->ops->refine) {
205047c6ae99SBarry Smith     PetscInt i;
205147c6ae99SBarry Smith 
205247c6ae99SBarry Smith     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
205347c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
205447c6ae99SBarry Smith       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
205547c6ae99SBarry Smith     }
205647c6ae99SBarry Smith   } else {
205747c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
205847c6ae99SBarry Smith   }
205947c6ae99SBarry Smith   PetscFunctionReturn(0);
206047c6ae99SBarry Smith }
206147c6ae99SBarry Smith 
206247c6ae99SBarry Smith #undef __FUNCT__
206347c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
206447c6ae99SBarry Smith /*@C
206547c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
206647c6ae99SBarry Smith 
206747c6ae99SBarry Smith     Collective on DM
206847c6ae99SBarry Smith 
206947c6ae99SBarry Smith     Input Parameter:
207047c6ae99SBarry Smith +   dm - the DM object
207147c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
207247c6ae99SBarry Smith 
207347c6ae99SBarry Smith     Output Parameter:
207447c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
207547c6ae99SBarry Smith 
207647c6ae99SBarry Smith     Level: developer
207747c6ae99SBarry Smith 
2078e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
207947c6ae99SBarry Smith 
208047c6ae99SBarry Smith @*/
20817087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
208247c6ae99SBarry Smith {
208347c6ae99SBarry Smith   PetscErrorCode ierr;
208447c6ae99SBarry Smith 
208547c6ae99SBarry Smith   PetscFunctionBegin;
2086171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
208747c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
208847c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
208947c6ae99SBarry Smith   PetscValidPointer(dmc,3);
209047c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
209147c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
209247c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
209347c6ae99SBarry Smith     PetscInt i;
209447c6ae99SBarry Smith 
209547c6ae99SBarry Smith     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
209647c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
209747c6ae99SBarry Smith       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
209847c6ae99SBarry Smith     }
209947c6ae99SBarry Smith   } else {
210047c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
210147c6ae99SBarry Smith   }
210247c6ae99SBarry Smith   PetscFunctionReturn(0);
210347c6ae99SBarry Smith }
210447c6ae99SBarry Smith 
210547c6ae99SBarry Smith #undef __FUNCT__
2106e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
210747c6ae99SBarry Smith /*@
2108e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
210947c6ae99SBarry Smith    grids associated with two DMs.
211047c6ae99SBarry Smith 
211147c6ae99SBarry Smith    Collective on DM
211247c6ae99SBarry Smith 
211347c6ae99SBarry Smith    Input Parameters:
211447c6ae99SBarry Smith +  dmc - the coarse grid DM
211547c6ae99SBarry Smith -  dmf - the fine grid DM
211647c6ae99SBarry Smith 
211747c6ae99SBarry Smith    Output Parameters:
211847c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
211947c6ae99SBarry Smith 
212047c6ae99SBarry Smith    Level: intermediate
212147c6ae99SBarry Smith 
212247c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
212347c6ae99SBarry Smith 
2124e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
212547c6ae99SBarry Smith @*/
2126e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
212747c6ae99SBarry Smith {
212847c6ae99SBarry Smith   PetscErrorCode ierr;
212947c6ae99SBarry Smith 
213047c6ae99SBarry Smith   PetscFunctionBegin;
2131171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
2132171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
213347c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
213447c6ae99SBarry Smith   PetscFunctionReturn(0);
213547c6ae99SBarry Smith }
213647c6ae99SBarry Smith 
213747c6ae99SBarry Smith #undef __FUNCT__
21381a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
21391a266240SBarry Smith /*@C
21401a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
21411a266240SBarry Smith 
21421a266240SBarry Smith     Not Collective
21431a266240SBarry Smith 
21441a266240SBarry Smith     Input Parameters:
21451a266240SBarry Smith +   dm - the DM object
21461a266240SBarry Smith -   destroy - the destroy function
21471a266240SBarry Smith 
21481a266240SBarry Smith     Level: intermediate
21491a266240SBarry Smith 
2150e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
21511a266240SBarry Smith 
2152f07f9ceaSJed Brown @*/
21531a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
21541a266240SBarry Smith {
21551a266240SBarry Smith   PetscFunctionBegin;
2156171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21571a266240SBarry Smith   dm->ctxdestroy = destroy;
21581a266240SBarry Smith   PetscFunctionReturn(0);
21591a266240SBarry Smith }
21601a266240SBarry Smith 
21611a266240SBarry Smith #undef __FUNCT__
21621b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
2163b07ff414SBarry Smith /*@
21641b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
216547c6ae99SBarry Smith 
216647c6ae99SBarry Smith     Not Collective
216747c6ae99SBarry Smith 
216847c6ae99SBarry Smith     Input Parameters:
216947c6ae99SBarry Smith +   dm - the DM object
217047c6ae99SBarry Smith -   ctx - the user context
217147c6ae99SBarry Smith 
217247c6ae99SBarry Smith     Level: intermediate
217347c6ae99SBarry Smith 
2174e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
217547c6ae99SBarry Smith 
217647c6ae99SBarry Smith @*/
21771b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
217847c6ae99SBarry Smith {
217947c6ae99SBarry Smith   PetscFunctionBegin;
2180171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
218147c6ae99SBarry Smith   dm->ctx = ctx;
218247c6ae99SBarry Smith   PetscFunctionReturn(0);
218347c6ae99SBarry Smith }
218447c6ae99SBarry Smith 
218547c6ae99SBarry Smith #undef __FUNCT__
21861b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
218747c6ae99SBarry Smith /*@
21881b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
218947c6ae99SBarry Smith 
219047c6ae99SBarry Smith     Not Collective
219147c6ae99SBarry Smith 
219247c6ae99SBarry Smith     Input Parameter:
219347c6ae99SBarry Smith .   dm - the DM object
219447c6ae99SBarry Smith 
219547c6ae99SBarry Smith     Output Parameter:
219647c6ae99SBarry Smith .   ctx - the user context
219747c6ae99SBarry Smith 
219847c6ae99SBarry Smith     Level: intermediate
219947c6ae99SBarry Smith 
2200e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
220147c6ae99SBarry Smith 
220247c6ae99SBarry Smith @*/
22031b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
220447c6ae99SBarry Smith {
220547c6ae99SBarry Smith   PetscFunctionBegin;
2206171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
22071b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
220847c6ae99SBarry Smith   PetscFunctionReturn(0);
220947c6ae99SBarry Smith }
221047c6ae99SBarry Smith 
221147c6ae99SBarry Smith #undef __FUNCT__
221247c6ae99SBarry Smith #define __FUNCT__ "DMSetInitialGuess"
22137e833e3aSBarry Smith /*@C
221447c6ae99SBarry Smith     DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers
221547c6ae99SBarry Smith 
221647c6ae99SBarry Smith     Logically Collective on DM
221747c6ae99SBarry Smith 
221847c6ae99SBarry Smith     Input Parameter:
221947c6ae99SBarry Smith +   dm - the DM object to destroy
222047c6ae99SBarry Smith -   f - the function to compute the initial guess
222147c6ae99SBarry Smith 
222247c6ae99SBarry Smith     Level: intermediate
222347c6ae99SBarry Smith 
2224e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
222547c6ae99SBarry Smith 
2226f07f9ceaSJed Brown @*/
22277087cfbeSBarry Smith PetscErrorCode  DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec))
222847c6ae99SBarry Smith {
222947c6ae99SBarry Smith   PetscFunctionBegin;
2230171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
223147c6ae99SBarry Smith   dm->ops->initialguess = f;
223247c6ae99SBarry Smith   PetscFunctionReturn(0);
223347c6ae99SBarry Smith }
223447c6ae99SBarry Smith 
223547c6ae99SBarry Smith #undef __FUNCT__
223647c6ae99SBarry Smith #define __FUNCT__ "DMSetFunction"
22377e833e3aSBarry Smith /*@C
223847c6ae99SBarry Smith     DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES
223947c6ae99SBarry Smith 
224047c6ae99SBarry Smith     Logically Collective on DM
224147c6ae99SBarry Smith 
224247c6ae99SBarry Smith     Input Parameter:
224347c6ae99SBarry Smith +   dm - the DM object
224447c6ae99SBarry Smith -   f - the function to compute (use PETSC_NULL to cancel a previous function that was set)
224547c6ae99SBarry Smith 
224647c6ae99SBarry Smith     Level: intermediate
224747c6ae99SBarry Smith 
224847c6ae99SBarry Smith     Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian
224947c6ae99SBarry Smith            computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian.
225047c6ae99SBarry Smith 
2251e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
225247c6ae99SBarry Smith          DMSetJacobian()
225347c6ae99SBarry Smith 
2254f07f9ceaSJed Brown @*/
22557087cfbeSBarry Smith PetscErrorCode  DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
225647c6ae99SBarry Smith {
225747c6ae99SBarry Smith   PetscFunctionBegin;
2258171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
225947c6ae99SBarry Smith   dm->ops->function = f;
226047c6ae99SBarry Smith   if (f) {
226147c6ae99SBarry Smith     dm->ops->functionj = f;
226247c6ae99SBarry Smith   }
226347c6ae99SBarry Smith   PetscFunctionReturn(0);
226447c6ae99SBarry Smith }
226547c6ae99SBarry Smith 
226647c6ae99SBarry Smith #undef __FUNCT__
226747c6ae99SBarry Smith #define __FUNCT__ "DMSetJacobian"
22687e833e3aSBarry Smith /*@C
226947c6ae99SBarry Smith     DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES
227047c6ae99SBarry Smith 
227147c6ae99SBarry Smith     Logically Collective on DM
227247c6ae99SBarry Smith 
227347c6ae99SBarry Smith     Input Parameter:
227447c6ae99SBarry Smith +   dm - the DM object to destroy
227547c6ae99SBarry Smith -   f - the function to compute the matrix entries
227647c6ae99SBarry Smith 
227747c6ae99SBarry Smith     Level: intermediate
227847c6ae99SBarry Smith 
2279e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
228047c6ae99SBarry Smith          DMSetFunction()
228147c6ae99SBarry Smith 
2282f07f9ceaSJed Brown @*/
22837087cfbeSBarry Smith PetscErrorCode  DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*))
228447c6ae99SBarry Smith {
228547c6ae99SBarry Smith   PetscFunctionBegin;
2286171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
228747c6ae99SBarry Smith   dm->ops->jacobian = f;
228847c6ae99SBarry Smith   PetscFunctionReturn(0);
228947c6ae99SBarry Smith }
229047c6ae99SBarry Smith 
229147c6ae99SBarry Smith #undef __FUNCT__
229208da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
229308da532bSDmitry Karpeev /*@C
229408da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
229508da532bSDmitry Karpeev 
229608da532bSDmitry Karpeev     Logically Collective on DM
229708da532bSDmitry Karpeev 
229808da532bSDmitry Karpeev     Input Parameter:
229908da532bSDmitry Karpeev +   dm - the DM object
230008da532bSDmitry Karpeev -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
230108da532bSDmitry Karpeev 
230208da532bSDmitry Karpeev     Level: intermediate
230308da532bSDmitry Karpeev 
2304e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
230508da532bSDmitry Karpeev          DMSetJacobian()
230608da532bSDmitry Karpeev 
230708da532bSDmitry Karpeev @*/
230808da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
230908da532bSDmitry Karpeev {
231008da532bSDmitry Karpeev   PetscFunctionBegin;
231108da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
231208da532bSDmitry Karpeev   PetscFunctionReturn(0);
231308da532bSDmitry Karpeev }
231408da532bSDmitry Karpeev 
231508da532bSDmitry Karpeev #undef __FUNCT__
231608da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
231708da532bSDmitry Karpeev /*@
231808da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
231908da532bSDmitry Karpeev 
232008da532bSDmitry Karpeev     Not Collective
232108da532bSDmitry Karpeev 
232208da532bSDmitry Karpeev     Input Parameter:
232308da532bSDmitry Karpeev .   dm - the DM object to destroy
232408da532bSDmitry Karpeev 
232508da532bSDmitry Karpeev     Output Parameter:
232608da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
232708da532bSDmitry Karpeev 
232808da532bSDmitry Karpeev     Level: developer
232908da532bSDmitry Karpeev 
2330e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
233108da532bSDmitry Karpeev 
233208da532bSDmitry Karpeev @*/
233308da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
233408da532bSDmitry Karpeev {
233508da532bSDmitry Karpeev   PetscFunctionBegin;
233608da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
233708da532bSDmitry Karpeev   PetscFunctionReturn(0);
233808da532bSDmitry Karpeev }
233908da532bSDmitry Karpeev 
234008da532bSDmitry Karpeev #undef __FUNCT__
234108da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
234208da532bSDmitry Karpeev /*@C
234308da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
234408da532bSDmitry Karpeev 
234508da532bSDmitry Karpeev     Logically Collective on DM
234608da532bSDmitry Karpeev 
234708da532bSDmitry Karpeev     Input Parameters:
234808da532bSDmitry Karpeev +   dm - the DM object to destroy
234908da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
235008da532bSDmitry Karpeev 
235108da532bSDmitry Karpeev     Output parameters:
235208da532bSDmitry Karpeev +   xl - lower bound
235308da532bSDmitry Karpeev -   xu - upper bound
235408da532bSDmitry Karpeev 
235508da532bSDmitry Karpeev     Level: intermediate
235608da532bSDmitry Karpeev 
2357e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
235808da532bSDmitry Karpeev          DMSetFunction(), DMSetVariableBounds()
235908da532bSDmitry Karpeev 
236008da532bSDmitry Karpeev @*/
236108da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
236208da532bSDmitry Karpeev {
236308da532bSDmitry Karpeev   PetscErrorCode ierr;
236408da532bSDmitry Karpeev   PetscFunctionBegin;
236508da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
236608da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
236708da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
236808da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
236908da532bSDmitry Karpeev   }
2370a201590fSDmitry Karpeev   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
237108da532bSDmitry Karpeev   PetscFunctionReturn(0);
237208da532bSDmitry Karpeev }
237308da532bSDmitry Karpeev 
237408da532bSDmitry Karpeev #undef __FUNCT__
237547c6ae99SBarry Smith #define __FUNCT__ "DMComputeInitialGuess"
237647c6ae99SBarry Smith /*@
237747c6ae99SBarry Smith     DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers
237847c6ae99SBarry Smith 
237947c6ae99SBarry Smith     Collective on DM
238047c6ae99SBarry Smith 
238147c6ae99SBarry Smith     Input Parameter:
238247c6ae99SBarry Smith +   dm - the DM object to destroy
238347c6ae99SBarry Smith -   x - the vector to hold the initial guess values
238447c6ae99SBarry Smith 
238547c6ae99SBarry Smith     Level: developer
238647c6ae99SBarry Smith 
2387e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat()
238847c6ae99SBarry Smith 
238947c6ae99SBarry Smith @*/
23907087cfbeSBarry Smith PetscErrorCode  DMComputeInitialGuess(DM dm,Vec x)
239147c6ae99SBarry Smith {
239247c6ae99SBarry Smith   PetscErrorCode ierr;
239347c6ae99SBarry Smith   PetscFunctionBegin;
2394171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
239547c6ae99SBarry Smith   if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()");
239647c6ae99SBarry Smith   ierr = (*dm->ops->initialguess)(dm,x);CHKERRQ(ierr);
239747c6ae99SBarry Smith   PetscFunctionReturn(0);
239847c6ae99SBarry Smith }
239947c6ae99SBarry Smith 
240047c6ae99SBarry Smith #undef __FUNCT__
240147c6ae99SBarry Smith #define __FUNCT__ "DMHasInitialGuess"
240247c6ae99SBarry Smith /*@
240347c6ae99SBarry Smith     DMHasInitialGuess - does the DM object have an initial guess function
240447c6ae99SBarry Smith 
240547c6ae99SBarry Smith     Not Collective
240647c6ae99SBarry Smith 
240747c6ae99SBarry Smith     Input Parameter:
240847c6ae99SBarry Smith .   dm - the DM object to destroy
240947c6ae99SBarry Smith 
241047c6ae99SBarry Smith     Output Parameter:
241147c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
241247c6ae99SBarry Smith 
241347c6ae99SBarry Smith     Level: developer
241447c6ae99SBarry Smith 
2415e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
241647c6ae99SBarry Smith 
241747c6ae99SBarry Smith @*/
24187087cfbeSBarry Smith PetscErrorCode  DMHasInitialGuess(DM dm,PetscBool  *flg)
241947c6ae99SBarry Smith {
242047c6ae99SBarry Smith   PetscFunctionBegin;
2421171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
242247c6ae99SBarry Smith   *flg =  (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE;
242347c6ae99SBarry Smith   PetscFunctionReturn(0);
242447c6ae99SBarry Smith }
242547c6ae99SBarry Smith 
242647c6ae99SBarry Smith #undef __FUNCT__
242747c6ae99SBarry Smith #define __FUNCT__ "DMHasFunction"
242847c6ae99SBarry Smith /*@
242947c6ae99SBarry Smith     DMHasFunction - does the DM object have a function
243047c6ae99SBarry Smith 
243147c6ae99SBarry Smith     Not Collective
243247c6ae99SBarry Smith 
243347c6ae99SBarry Smith     Input Parameter:
243447c6ae99SBarry Smith .   dm - the DM object to destroy
243547c6ae99SBarry Smith 
243647c6ae99SBarry Smith     Output Parameter:
243747c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
243847c6ae99SBarry Smith 
243947c6ae99SBarry Smith     Level: developer
244047c6ae99SBarry Smith 
2441e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
244247c6ae99SBarry Smith 
244347c6ae99SBarry Smith @*/
24447087cfbeSBarry Smith PetscErrorCode  DMHasFunction(DM dm,PetscBool  *flg)
244547c6ae99SBarry Smith {
244647c6ae99SBarry Smith   PetscFunctionBegin;
2447171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
244847c6ae99SBarry Smith   *flg =  (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE;
244947c6ae99SBarry Smith   PetscFunctionReturn(0);
245047c6ae99SBarry Smith }
245147c6ae99SBarry Smith 
245247c6ae99SBarry Smith #undef __FUNCT__
245347c6ae99SBarry Smith #define __FUNCT__ "DMHasJacobian"
245447c6ae99SBarry Smith /*@
245547c6ae99SBarry Smith     DMHasJacobian - does the DM object have a matrix function
245647c6ae99SBarry Smith 
245747c6ae99SBarry Smith     Not Collective
245847c6ae99SBarry Smith 
245947c6ae99SBarry Smith     Input Parameter:
246047c6ae99SBarry Smith .   dm - the DM object to destroy
246147c6ae99SBarry Smith 
246247c6ae99SBarry Smith     Output Parameter:
246347c6ae99SBarry Smith .   flg - PETSC_TRUE if function exists
246447c6ae99SBarry Smith 
246547c6ae99SBarry Smith     Level: developer
246647c6ae99SBarry Smith 
2467e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
246847c6ae99SBarry Smith 
246947c6ae99SBarry Smith @*/
24707087cfbeSBarry Smith PetscErrorCode  DMHasJacobian(DM dm,PetscBool  *flg)
247147c6ae99SBarry Smith {
247247c6ae99SBarry Smith   PetscFunctionBegin;
2473171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
247447c6ae99SBarry Smith   *flg =  (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE;
247547c6ae99SBarry Smith   PetscFunctionReturn(0);
247647c6ae99SBarry Smith }
247747c6ae99SBarry Smith 
247847c6ae99SBarry Smith #undef __FUNCT__
2479b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2480b0ae01b7SPeter Brune /*@
2481b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2482b0ae01b7SPeter Brune 
2483b0ae01b7SPeter Brune     Not Collective
2484b0ae01b7SPeter Brune 
2485b0ae01b7SPeter Brune     Input Parameter:
2486b0ae01b7SPeter Brune .   dm - the DM object
2487b0ae01b7SPeter Brune 
2488b0ae01b7SPeter Brune     Output Parameter:
2489b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2490b0ae01b7SPeter Brune 
2491b0ae01b7SPeter Brune     Level: developer
2492b0ae01b7SPeter Brune 
2493b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2494b0ae01b7SPeter Brune 
2495b0ae01b7SPeter Brune @*/
2496b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2497b0ae01b7SPeter Brune {
2498b0ae01b7SPeter Brune   PetscFunctionBegin;
2499b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2500b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2501b0ae01b7SPeter Brune }
2502b0ae01b7SPeter Brune 
2503b0ae01b7SPeter Brune #undef  __FUNCT__
250408da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2505748fac09SDmitry Karpeev /*@C
250608da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
250708da532bSDmitry Karpeev 
250808da532bSDmitry Karpeev     Collective on DM
250908da532bSDmitry Karpeev 
251008da532bSDmitry Karpeev     Input Parameter:
251108da532bSDmitry Karpeev +   dm - the DM object
2512e88d7f4bSDmitry Karpeev -   x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems.
251308da532bSDmitry Karpeev 
251408da532bSDmitry Karpeev     Level: developer
251508da532bSDmitry Karpeev 
2516e88d7f4bSDmitry Karpeev .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
251708da532bSDmitry Karpeev          DMSetFunction(), DMSetJacobian(), DMSetVariableBounds()
251808da532bSDmitry Karpeev 
251908da532bSDmitry Karpeev @*/
252008da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
252108da532bSDmitry Karpeev {
252208da532bSDmitry Karpeev   PetscErrorCode ierr;
252308da532bSDmitry Karpeev   PetscFunctionBegin;
252408da532bSDmitry Karpeev   if (x) {
252508da532bSDmitry Karpeev     if (!dm->x) {
252608da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
252708da532bSDmitry Karpeev     }
252808da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
252908da532bSDmitry Karpeev   }
253008da532bSDmitry Karpeev   else if (dm->x) {
253108da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
253208da532bSDmitry Karpeev   }
253308da532bSDmitry Karpeev   PetscFunctionReturn(0);
253408da532bSDmitry Karpeev }
253508da532bSDmitry Karpeev 
253608da532bSDmitry Karpeev 
253708da532bSDmitry Karpeev #undef __FUNCT__
253847c6ae99SBarry Smith #define __FUNCT__ "DMComputeFunction"
253947c6ae99SBarry Smith /*@
254047c6ae99SBarry Smith     DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES
254147c6ae99SBarry Smith 
254247c6ae99SBarry Smith     Collective on DM
254347c6ae99SBarry Smith 
254447c6ae99SBarry Smith     Input Parameter:
254547c6ae99SBarry Smith +   dm - the DM object to destroy
254647c6ae99SBarry Smith .   x - the location where the function is evaluationed, may be ignored for linear problems
254747c6ae99SBarry Smith -   b - the vector to hold the right hand side entries
254847c6ae99SBarry Smith 
254947c6ae99SBarry Smith     Level: developer
255047c6ae99SBarry Smith 
2551e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
255247c6ae99SBarry Smith          DMSetJacobian()
255347c6ae99SBarry Smith 
255447c6ae99SBarry Smith @*/
25557087cfbeSBarry Smith PetscErrorCode  DMComputeFunction(DM dm,Vec x,Vec b)
255647c6ae99SBarry Smith {
255747c6ae99SBarry Smith   PetscErrorCode ierr;
255847c6ae99SBarry Smith   PetscFunctionBegin;
2559171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
256047c6ae99SBarry Smith   if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()");
2561644e2e5bSBarry Smith   PetscStackPush("DM user function");
256247c6ae99SBarry Smith   ierr = (*dm->ops->function)(dm,x,b);CHKERRQ(ierr);
2563644e2e5bSBarry Smith   PetscStackPop;
256447c6ae99SBarry Smith   PetscFunctionReturn(0);
256547c6ae99SBarry Smith }
256647c6ae99SBarry Smith 
256747c6ae99SBarry Smith 
256808da532bSDmitry Karpeev 
256947c6ae99SBarry Smith #undef __FUNCT__
257047c6ae99SBarry Smith #define __FUNCT__ "DMComputeJacobian"
257147c6ae99SBarry Smith /*@
257247c6ae99SBarry Smith     DMComputeJacobian - compute the matrix entries for the solver
257347c6ae99SBarry Smith 
257447c6ae99SBarry Smith     Collective on DM
257547c6ae99SBarry Smith 
257647c6ae99SBarry Smith     Input Parameter:
257747c6ae99SBarry Smith +   dm - the DM object
2578cab2e9ccSBarry Smith .   x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM
257947c6ae99SBarry Smith .   A - matrix that defines the operator for the linear solve
258047c6ae99SBarry Smith -   B - the matrix used to construct the preconditioner
258147c6ae99SBarry Smith 
258247c6ae99SBarry Smith     Level: developer
258347c6ae99SBarry Smith 
2584e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
258547c6ae99SBarry Smith          DMSetFunction()
258647c6ae99SBarry Smith 
258747c6ae99SBarry Smith @*/
25887087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
258947c6ae99SBarry Smith {
259047c6ae99SBarry Smith   PetscErrorCode ierr;
259147c6ae99SBarry Smith 
259247c6ae99SBarry Smith   PetscFunctionBegin;
2593171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
259447c6ae99SBarry Smith   if (!dm->ops->jacobian) {
259547c6ae99SBarry Smith     ISColoring     coloring;
259647c6ae99SBarry Smith     MatFDColoring  fd;
259719fd82e9SBarry Smith     MatType        mtype;
259847c6ae99SBarry Smith 
25992c9966d7SBarry Smith     ierr = PetscObjectGetType((PetscObject)B,&mtype);CHKERRQ(ierr);
26002c9966d7SBarry Smith     ierr = DMCreateColoring(dm,dm->coloringtype,mtype,&coloring);CHKERRQ(ierr);
260147c6ae99SBarry Smith     ierr = MatFDColoringCreate(B,coloring,&fd);CHKERRQ(ierr);
2602fcfd50ebSBarry Smith     ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr);
260347c6ae99SBarry Smith     ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);CHKERRQ(ierr);
26040bdded8aSJed Brown     ierr = PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);CHKERRQ(ierr);
26050bdded8aSJed Brown     ierr = MatFDColoringSetFromOptions(fd);CHKERRQ(ierr);
260671cd77b2SBarry Smith 
260747c6ae99SBarry Smith     dm->fd = fd;
260847c6ae99SBarry Smith     dm->ops->jacobian = DMComputeJacobianDefault;
26092533e041SBarry Smith 
261071cd77b2SBarry Smith     /* don't know why this is needed */
261171cd77b2SBarry Smith     ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr);
261247c6ae99SBarry Smith   }
261347c6ae99SBarry Smith   if (!x) x = dm->x;
261447c6ae99SBarry Smith   ierr = (*dm->ops->jacobian)(dm,x,A,B,stflag);CHKERRQ(ierr);
2615cab2e9ccSBarry Smith 
261671cd77b2SBarry 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 */
2617649052a6SBarry Smith   if (x) {
2618cab2e9ccSBarry Smith     if (!dm->x) {
261971cd77b2SBarry Smith       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
2620cab2e9ccSBarry Smith     }
2621cab2e9ccSBarry Smith     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
2622649052a6SBarry Smith   }
2623a8248277SBarry Smith   if (A != B) {
2624a8248277SBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2625a8248277SBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2626a8248277SBarry Smith   }
262747c6ae99SBarry Smith   PetscFunctionReturn(0);
262847c6ae99SBarry Smith }
2629264ace61SBarry Smith 
2630cab2e9ccSBarry Smith 
2631264ace61SBarry Smith PetscFList DMList                       = PETSC_NULL;
2632264ace61SBarry Smith PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
2633264ace61SBarry Smith 
2634264ace61SBarry Smith #undef __FUNCT__
2635264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2636264ace61SBarry Smith /*@C
2637264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2638264ace61SBarry Smith 
2639264ace61SBarry Smith   Collective on DM
2640264ace61SBarry Smith 
2641264ace61SBarry Smith   Input Parameters:
2642264ace61SBarry Smith + dm     - The DM object
2643264ace61SBarry Smith - method - The name of the DM type
2644264ace61SBarry Smith 
2645264ace61SBarry Smith   Options Database Key:
2646264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2647264ace61SBarry Smith 
2648264ace61SBarry Smith   Notes:
2649e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2650264ace61SBarry Smith 
2651264ace61SBarry Smith   Level: intermediate
2652264ace61SBarry Smith 
2653264ace61SBarry Smith .keywords: DM, set, type
2654264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2655264ace61SBarry Smith @*/
265619fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
2657264ace61SBarry Smith {
2658264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2659264ace61SBarry Smith   PetscBool      match;
2660264ace61SBarry Smith   PetscErrorCode ierr;
2661264ace61SBarry Smith 
2662264ace61SBarry Smith   PetscFunctionBegin;
2663264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2664251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2665264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2666264ace61SBarry Smith 
2667264ace61SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
26684b91b6eaSBarry Smith   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
266932c0f0efSBarry Smith   if (!r) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2670264ace61SBarry Smith 
2671264ace61SBarry Smith   if (dm->ops->destroy) {
2672264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
2673b5c23020SJed Brown     dm->ops->destroy = PETSC_NULL;
2674264ace61SBarry Smith   }
2675264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2676264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2677264ace61SBarry Smith   PetscFunctionReturn(0);
2678264ace61SBarry Smith }
2679264ace61SBarry Smith 
2680264ace61SBarry Smith #undef __FUNCT__
2681264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2682264ace61SBarry Smith /*@C
2683264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2684264ace61SBarry Smith 
2685264ace61SBarry Smith   Not Collective
2686264ace61SBarry Smith 
2687264ace61SBarry Smith   Input Parameter:
2688264ace61SBarry Smith . dm  - The DM
2689264ace61SBarry Smith 
2690264ace61SBarry Smith   Output Parameter:
2691264ace61SBarry Smith . type - The DM type name
2692264ace61SBarry Smith 
2693264ace61SBarry Smith   Level: intermediate
2694264ace61SBarry Smith 
2695264ace61SBarry Smith .keywords: DM, get, type, name
2696264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2697264ace61SBarry Smith @*/
269819fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
2699264ace61SBarry Smith {
2700264ace61SBarry Smith   PetscErrorCode ierr;
2701264ace61SBarry Smith 
2702264ace61SBarry Smith   PetscFunctionBegin;
2703264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2704264ace61SBarry Smith   PetscValidCharPointer(type,2);
2705264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2706264ace61SBarry Smith     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2707264ace61SBarry Smith   }
2708264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2709264ace61SBarry Smith   PetscFunctionReturn(0);
2710264ace61SBarry Smith }
2711264ace61SBarry Smith 
271267a56275SMatthew G Knepley #undef __FUNCT__
271367a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
271467a56275SMatthew G Knepley /*@C
271567a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
271667a56275SMatthew G Knepley 
271767a56275SMatthew G Knepley   Collective on DM
271867a56275SMatthew G Knepley 
271967a56275SMatthew G Knepley   Input Parameters:
272067a56275SMatthew G Knepley + dm - the DM
272167a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
272267a56275SMatthew G Knepley 
272367a56275SMatthew G Knepley   Output Parameter:
272467a56275SMatthew G Knepley . M - pointer to new DM
272567a56275SMatthew G Knepley 
272667a56275SMatthew G Knepley   Notes:
272767a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
272867a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
272967a56275SMatthew G Knepley   of the input DM.
273067a56275SMatthew G Knepley 
273167a56275SMatthew G Knepley   Level: intermediate
273267a56275SMatthew G Knepley 
273367a56275SMatthew G Knepley .seealso: DMCreate()
273467a56275SMatthew G Knepley @*/
273519fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
273667a56275SMatthew G Knepley {
273767a56275SMatthew G Knepley   DM             B;
273867a56275SMatthew G Knepley   char           convname[256];
273967a56275SMatthew G Knepley   PetscBool      sametype, issame;
274067a56275SMatthew G Knepley   PetscErrorCode ierr;
274167a56275SMatthew G Knepley 
274267a56275SMatthew G Knepley   PetscFunctionBegin;
274367a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
274467a56275SMatthew G Knepley   PetscValidType(dm,1);
274567a56275SMatthew G Knepley   PetscValidPointer(M,3);
2746251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
274767a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
274867a56275SMatthew G Knepley   {
274919fd82e9SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM *) = PETSC_NULL;
275067a56275SMatthew G Knepley 
275167a56275SMatthew G Knepley     /*
275267a56275SMatthew G Knepley        Order of precedence:
275367a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
275467a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
275567a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
275667a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
275767a56275SMatthew G Knepley        5) Use a really basic converter.
275867a56275SMatthew G Knepley     */
275967a56275SMatthew G Knepley 
276067a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
276167a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
276267a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
276367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
276467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
276567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
276667a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
276767a56275SMatthew G Knepley     if (conv) goto foundconv;
276867a56275SMatthew G Knepley 
276967a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
277067a56275SMatthew G Knepley     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
277167a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
277267a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
277367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
277467a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
277567a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
277667a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
277767a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
277867a56275SMatthew G Knepley     if (conv) {
2779fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
278067a56275SMatthew G Knepley       goto foundconv;
278167a56275SMatthew G Knepley     }
278267a56275SMatthew G Knepley 
278367a56275SMatthew G Knepley #if 0
278467a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
278567a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2786fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
278767a56275SMatthew G Knepley     if (conv) goto foundconv;
278867a56275SMatthew G Knepley 
278967a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
279067a56275SMatthew G Knepley     if (dm->ops->convert) {
279167a56275SMatthew G Knepley       conv = dm->ops->convert;
279267a56275SMatthew G Knepley     }
279367a56275SMatthew G Knepley     if (conv) goto foundconv;
279467a56275SMatthew G Knepley #endif
279567a56275SMatthew G Knepley 
279667a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
279767a56275SMatthew G Knepley     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
279867a56275SMatthew G Knepley 
279967a56275SMatthew G Knepley     foundconv:
280067a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
280167a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
280267a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
280367a56275SMatthew G Knepley   }
280467a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
280567a56275SMatthew G Knepley   PetscFunctionReturn(0);
280667a56275SMatthew G Knepley }
2807264ace61SBarry Smith 
2808264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2809264ace61SBarry Smith 
2810264ace61SBarry Smith #undef __FUNCT__
2811264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2812264ace61SBarry Smith /*@C
2813264ace61SBarry Smith   DMRegister - See DMRegisterDynamic()
2814264ace61SBarry Smith 
2815264ace61SBarry Smith   Level: advanced
2816264ace61SBarry Smith @*/
28177087cfbeSBarry Smith PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
2818264ace61SBarry Smith {
2819264ace61SBarry Smith   char fullname[PETSC_MAX_PATH_LEN];
2820264ace61SBarry Smith   PetscErrorCode ierr;
2821264ace61SBarry Smith 
2822264ace61SBarry Smith   PetscFunctionBegin;
2823264ace61SBarry Smith   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
2824264ace61SBarry Smith   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
2825264ace61SBarry Smith   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
2826264ace61SBarry Smith   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
2827264ace61SBarry Smith   PetscFunctionReturn(0);
2828264ace61SBarry Smith }
2829264ace61SBarry Smith 
2830264ace61SBarry Smith 
2831264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2832264ace61SBarry Smith #undef __FUNCT__
2833264ace61SBarry Smith #define __FUNCT__ "DMRegisterDestroy"
2834264ace61SBarry Smith /*@C
2835264ace61SBarry Smith    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
2836264ace61SBarry Smith 
2837264ace61SBarry Smith    Not Collective
2838264ace61SBarry Smith 
2839264ace61SBarry Smith    Level: advanced
2840264ace61SBarry Smith 
2841264ace61SBarry Smith .keywords: DM, register, destroy
2842264ace61SBarry Smith .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
2843264ace61SBarry Smith @*/
28447087cfbeSBarry Smith PetscErrorCode  DMRegisterDestroy(void)
2845264ace61SBarry Smith {
2846264ace61SBarry Smith   PetscErrorCode ierr;
2847264ace61SBarry Smith 
2848264ace61SBarry Smith   PetscFunctionBegin;
2849264ace61SBarry Smith   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
2850264ace61SBarry Smith   DMRegisterAllCalled = PETSC_FALSE;
2851264ace61SBarry Smith   PetscFunctionReturn(0);
2852264ace61SBarry Smith }
285323f975d1SBarry Smith 
285423f975d1SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2855c6db04a5SJed Brown #include <mex.h>
285623f975d1SBarry Smith 
28573014e516SBarry Smith typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext;
285823f975d1SBarry Smith 
285923f975d1SBarry Smith #undef __FUNCT__
286023f975d1SBarry Smith #define __FUNCT__ "DMComputeFunction_Matlab"
286123f975d1SBarry Smith /*
286223f975d1SBarry Smith    DMComputeFunction_Matlab - Calls the function that has been set with
286323f975d1SBarry Smith                          DMSetFunctionMatlab().
286423f975d1SBarry Smith 
286523f975d1SBarry Smith    For linear problems x is null
286623f975d1SBarry Smith 
286723f975d1SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
286823f975d1SBarry Smith */
28697087cfbeSBarry Smith PetscErrorCode  DMComputeFunction_Matlab(DM dm,Vec x,Vec y)
287023f975d1SBarry Smith {
287123f975d1SBarry Smith   PetscErrorCode    ierr;
287223f975d1SBarry Smith   DMMatlabContext   *sctx;
287323f975d1SBarry Smith   int               nlhs = 1,nrhs = 4;
287423f975d1SBarry Smith   mxArray	    *plhs[1],*prhs[4];
287523f975d1SBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
287623f975d1SBarry Smith 
287723f975d1SBarry Smith   PetscFunctionBegin;
287823f975d1SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
287923f975d1SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
288023f975d1SBarry Smith   PetscCheckSameComm(dm,1,y,3);
288123f975d1SBarry Smith 
288223f975d1SBarry Smith   /* call Matlab function in ctx with arguments x and y */
28831b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
288423f975d1SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
288523f975d1SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
28863014e516SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(y));CHKERRQ(ierr);
288723f975d1SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
288823f975d1SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
288923f975d1SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
289023f975d1SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
2891b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");CHKERRQ(ierr);
289223f975d1SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
289323f975d1SBarry Smith   mxDestroyArray(prhs[0]);
289423f975d1SBarry Smith   mxDestroyArray(prhs[1]);
289523f975d1SBarry Smith   mxDestroyArray(prhs[2]);
289623f975d1SBarry Smith   mxDestroyArray(prhs[3]);
289723f975d1SBarry Smith   mxDestroyArray(plhs[0]);
289823f975d1SBarry Smith   PetscFunctionReturn(0);
289923f975d1SBarry Smith }
290023f975d1SBarry Smith 
290123f975d1SBarry Smith 
290223f975d1SBarry Smith #undef __FUNCT__
290323f975d1SBarry Smith #define __FUNCT__ "DMSetFunctionMatlab"
290423f975d1SBarry Smith /*
290523f975d1SBarry Smith    DMSetFunctionMatlab - Sets the function evaluation routine
290623f975d1SBarry Smith 
290723f975d1SBarry Smith */
29087087cfbeSBarry Smith PetscErrorCode  DMSetFunctionMatlab(DM dm,const char *func)
290923f975d1SBarry Smith {
291023f975d1SBarry Smith   PetscErrorCode    ierr;
291123f975d1SBarry Smith   DMMatlabContext   *sctx;
291223f975d1SBarry Smith 
291323f975d1SBarry Smith   PetscFunctionBegin;
2914171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
291523f975d1SBarry Smith   /* currently sctx is memory bleed */
29161b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
29173014e516SBarry Smith   if (!sctx) {
291823f975d1SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
29193014e516SBarry Smith   }
292023f975d1SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
29211b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
292223f975d1SBarry Smith   ierr = DMSetFunction(dm,DMComputeFunction_Matlab);CHKERRQ(ierr);
292323f975d1SBarry Smith   PetscFunctionReturn(0);
292423f975d1SBarry Smith }
29253014e516SBarry Smith 
29263014e516SBarry Smith #undef __FUNCT__
29273014e516SBarry Smith #define __FUNCT__ "DMComputeJacobian_Matlab"
29283014e516SBarry Smith /*
29293014e516SBarry Smith    DMComputeJacobian_Matlab - Calls the function that has been set with
29303014e516SBarry Smith                          DMSetJacobianMatlab().
29313014e516SBarry Smith 
29323014e516SBarry Smith    For linear problems x is null
29333014e516SBarry Smith 
29343014e516SBarry Smith .seealso: DMSetFunction(), DMGetFunction()
29353014e516SBarry Smith */
29367087cfbeSBarry Smith PetscErrorCode  DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str)
29373014e516SBarry Smith {
29383014e516SBarry Smith   PetscErrorCode    ierr;
29393014e516SBarry Smith   DMMatlabContext   *sctx;
29403014e516SBarry Smith   int               nlhs = 2,nrhs = 5;
29413014e516SBarry Smith   mxArray	    *plhs[2],*prhs[5];
29423014e516SBarry Smith   long long int     lx = 0,lA = 0,lB = 0,ls = 0;
29433014e516SBarry Smith 
29443014e516SBarry Smith   PetscFunctionBegin;
29453014e516SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
29463014e516SBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
29473014e516SBarry Smith 
2948e3c5b3baSBarry Smith   /* call MATLAB function in ctx with arguments x, A, and B */
29491b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
29503014e516SBarry Smith   ierr = PetscMemcpy(&ls,&dm,sizeof(dm));CHKERRQ(ierr);
29513014e516SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
29523014e516SBarry Smith   ierr = PetscMemcpy(&lA,&A,sizeof(A));CHKERRQ(ierr);
29533014e516SBarry Smith   ierr = PetscMemcpy(&lB,&B,sizeof(B));CHKERRQ(ierr);
29543014e516SBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
29553014e516SBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
29563014e516SBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
29573014e516SBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
29583014e516SBarry Smith   prhs[4] =  mxCreateString(sctx->jacname);
2959b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");CHKERRQ(ierr);
2960c980e822SBarry Smith   *str    =  (MatStructure) mxGetScalar(plhs[0]);
2961c088a8dcSBarry Smith   ierr    =  (PetscInt) mxGetScalar(plhs[1]);CHKERRQ(ierr);
29623014e516SBarry Smith   mxDestroyArray(prhs[0]);
29633014e516SBarry Smith   mxDestroyArray(prhs[1]);
29643014e516SBarry Smith   mxDestroyArray(prhs[2]);
29653014e516SBarry Smith   mxDestroyArray(prhs[3]);
29663014e516SBarry Smith   mxDestroyArray(prhs[4]);
29673014e516SBarry Smith   mxDestroyArray(plhs[0]);
29683014e516SBarry Smith   mxDestroyArray(plhs[1]);
29693014e516SBarry Smith   PetscFunctionReturn(0);
29703014e516SBarry Smith }
29713014e516SBarry Smith 
29723014e516SBarry Smith 
29733014e516SBarry Smith #undef __FUNCT__
29743014e516SBarry Smith #define __FUNCT__ "DMSetJacobianMatlab"
29753014e516SBarry Smith /*
29763014e516SBarry Smith    DMSetJacobianMatlab - Sets the Jacobian function evaluation routine
29773014e516SBarry Smith 
29783014e516SBarry Smith */
29797087cfbeSBarry Smith PetscErrorCode  DMSetJacobianMatlab(DM dm,const char *func)
29803014e516SBarry Smith {
29813014e516SBarry Smith   PetscErrorCode    ierr;
29823014e516SBarry Smith   DMMatlabContext   *sctx;
29833014e516SBarry Smith 
29843014e516SBarry Smith   PetscFunctionBegin;
2985171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
29863014e516SBarry Smith   /* currently sctx is memory bleed */
29871b2093e4SBarry Smith   ierr = DMGetApplicationContext(dm,&sctx);CHKERRQ(ierr);
29883014e516SBarry Smith   if (!sctx) {
29893014e516SBarry Smith     ierr = PetscMalloc(sizeof(DMMatlabContext),&sctx);CHKERRQ(ierr);
29903014e516SBarry Smith   }
29913014e516SBarry Smith   ierr = PetscStrallocpy(func,&sctx->jacname);CHKERRQ(ierr);
29921b2093e4SBarry Smith   ierr = DMSetApplicationContext(dm,sctx);CHKERRQ(ierr);
29933014e516SBarry Smith   ierr = DMSetJacobian(dm,DMComputeJacobian_Matlab);CHKERRQ(ierr);
29943014e516SBarry Smith   PetscFunctionReturn(0);
29953014e516SBarry Smith }
299623f975d1SBarry Smith #endif
2997b859378eSBarry Smith 
2998b859378eSBarry Smith #undef __FUNCT__
2999b859378eSBarry Smith #define __FUNCT__ "DMLoad"
3000b859378eSBarry Smith /*@C
3001*55849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
3002b859378eSBarry Smith 
3003b859378eSBarry Smith   Collective on PetscViewer
3004b859378eSBarry Smith 
3005b859378eSBarry Smith   Input Parameters:
3006b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
3007b859378eSBarry Smith            some related function before a call to DMLoad().
3008b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
3009b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
3010b859378eSBarry Smith 
3011b859378eSBarry Smith    Level: intermediate
3012b859378eSBarry Smith 
3013b859378eSBarry Smith   Notes:
3014*55849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
3015b859378eSBarry Smith 
3016b859378eSBarry Smith   Notes for advanced users:
3017b859378eSBarry Smith   Most users should not need to know the details of the binary storage
3018b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
3019b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
3020b859378eSBarry Smith   format is
3021b859378eSBarry Smith .vb
3022b859378eSBarry Smith      has not yet been determined
3023b859378eSBarry Smith .ve
3024b859378eSBarry Smith 
3025b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
3026b859378eSBarry Smith @*/
3027b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
3028b859378eSBarry Smith {
3029b859378eSBarry Smith   PetscErrorCode ierr;
303032c0f0efSBarry Smith   PetscBool      isbinary;
3031*55849f57SBarry Smith   PetscInt       classid;
303232c0f0efSBarry Smith   char           type[256];
3033b859378eSBarry Smith 
3034b859378eSBarry Smith   PetscFunctionBegin;
3035b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
3036b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
303732c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
303832c0f0efSBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
3039b859378eSBarry Smith 
304032c0f0efSBarry Smith   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
304132c0f0efSBarry Smith   if (classid != DM_FILE_CLASSID) SETERRQ(((PetscObject)newdm)->comm,PETSC_ERR_ARG_WRONG,"Not DM next in file");
304232c0f0efSBarry Smith   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
304332c0f0efSBarry Smith   ierr = DMSetType(newdm, type);CHKERRQ(ierr);
3044b859378eSBarry Smith   ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
3045b859378eSBarry Smith   PetscFunctionReturn(0);
3046b859378eSBarry Smith }
3047b859378eSBarry Smith 
30487da65231SMatthew G Knepley /******************************** FEM Support **********************************/
30497da65231SMatthew G Knepley 
30507da65231SMatthew G Knepley #undef __FUNCT__
30517da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
30527da65231SMatthew G Knepley PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
30531d47ebbbSSatish Balay   PetscInt       f;
30541b30c384SMatthew G Knepley   PetscErrorCode ierr;
30551b30c384SMatthew G Knepley 
30567da65231SMatthew G Knepley   PetscFunctionBegin;
305774778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
30581d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
305974778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
30607da65231SMatthew G Knepley   }
30617da65231SMatthew G Knepley   PetscFunctionReturn(0);
30627da65231SMatthew G Knepley }
30637da65231SMatthew G Knepley 
30647da65231SMatthew G Knepley #undef __FUNCT__
30657da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
30667da65231SMatthew G Knepley PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
30671b30c384SMatthew G Knepley   PetscInt       f, g;
30687da65231SMatthew G Knepley   PetscErrorCode ierr;
30697da65231SMatthew G Knepley 
30707da65231SMatthew G Knepley   PetscFunctionBegin;
307174778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
30721d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
307374778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
30741d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
307574778d6cSJed Brown       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
30767da65231SMatthew G Knepley     }
307774778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
30787da65231SMatthew G Knepley   }
30797da65231SMatthew G Knepley   PetscFunctionReturn(0);
30807da65231SMatthew G Knepley }
3081e7c4fc90SDmitry Karpeev 
3082970e74d5SMatthew G Knepley #undef __FUNCT__
3083970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalFunction"
3084970e74d5SMatthew G Knepley /*@C
3085970e74d5SMatthew G Knepley   DMGetLocalFunction - Get the local residual function from this DM
3086970e74d5SMatthew G Knepley 
3087970e74d5SMatthew G Knepley   Not collective
3088970e74d5SMatthew G Knepley 
3089970e74d5SMatthew G Knepley   Input Parameter:
3090970e74d5SMatthew G Knepley . dm - The DM
3091970e74d5SMatthew G Knepley 
3092970e74d5SMatthew G Knepley   Output Parameter:
3093970e74d5SMatthew G Knepley . lf - The local residual function
3094970e74d5SMatthew G Knepley 
3095970e74d5SMatthew G Knepley    Calling sequence of lf:
3096970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
3097970e74d5SMatthew G Knepley 
3098970e74d5SMatthew G Knepley +  snes - the SNES context
3099970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3100970e74d5SMatthew G Knepley .  f - local vector to put residual in
3101970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3102970e74d5SMatthew G Knepley 
3103970e74d5SMatthew G Knepley   Level: intermediate
3104970e74d5SMatthew G Knepley 
3105970e74d5SMatthew G Knepley .seealso DMSetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
3106970e74d5SMatthew G Knepley @*/
3107970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalFunction(DM dm, PetscErrorCode (**lf)(DM, Vec, Vec, void *))
3108970e74d5SMatthew G Knepley {
3109970e74d5SMatthew G Knepley   PetscFunctionBegin;
3110970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3111970e74d5SMatthew G Knepley   if (lf) *lf = dm->lf;
3112970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3113970e74d5SMatthew G Knepley }
3114970e74d5SMatthew G Knepley 
3115970e74d5SMatthew G Knepley #undef __FUNCT__
3116970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalFunction"
3117970e74d5SMatthew G Knepley /*@C
3118970e74d5SMatthew G Knepley   DMSetLocalFunction - Set the local residual function from this DM
3119970e74d5SMatthew G Knepley 
3120970e74d5SMatthew G Knepley   Not collective
3121970e74d5SMatthew G Knepley 
3122970e74d5SMatthew G Knepley   Input Parameters:
3123970e74d5SMatthew G Knepley + dm - The DM
3124970e74d5SMatthew G Knepley - lf - The local residual function
3125970e74d5SMatthew G Knepley 
3126970e74d5SMatthew G Knepley    Calling sequence of lf:
3127970e74d5SMatthew G Knepley $    lf (SNES snes, Vec x, Vec f, void *ctx);
3128970e74d5SMatthew G Knepley 
3129970e74d5SMatthew G Knepley +  snes - the SNES context
3130970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3131970e74d5SMatthew G Knepley .  f - local vector to put residual in
3132970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3133970e74d5SMatthew G Knepley 
3134970e74d5SMatthew G Knepley   Level: intermediate
3135970e74d5SMatthew G Knepley 
3136970e74d5SMatthew G Knepley .seealso DMGetLocalFunction(), DMGetLocalJacobian(), DMSetLocalJacobian()
3137970e74d5SMatthew G Knepley @*/
3138970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalFunction(DM dm, PetscErrorCode (*lf)(DM, Vec, Vec, void *))
3139970e74d5SMatthew G Knepley {
3140970e74d5SMatthew G Knepley   PetscFunctionBegin;
3141970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3142970e74d5SMatthew G Knepley   dm->lf = lf;
3143970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3144970e74d5SMatthew G Knepley }
3145970e74d5SMatthew G Knepley 
3146970e74d5SMatthew G Knepley #undef __FUNCT__
3147970e74d5SMatthew G Knepley #define __FUNCT__ "DMGetLocalJacobian"
3148970e74d5SMatthew G Knepley /*@C
3149970e74d5SMatthew G Knepley   DMGetLocalJacobian - Get the local Jacobian function from this DM
3150970e74d5SMatthew G Knepley 
3151970e74d5SMatthew G Knepley   Not collective
3152970e74d5SMatthew G Knepley 
3153970e74d5SMatthew G Knepley   Input Parameter:
3154970e74d5SMatthew G Knepley . dm - The DM
3155970e74d5SMatthew G Knepley 
3156970e74d5SMatthew G Knepley   Output Parameter:
3157970e74d5SMatthew G Knepley . lj - The local Jacobian function
3158970e74d5SMatthew G Knepley 
3159970e74d5SMatthew G Knepley    Calling sequence of lj:
3160970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
3161970e74d5SMatthew G Knepley 
3162970e74d5SMatthew G Knepley +  snes - the SNES context
3163970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3164970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
3165970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
3166970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3167970e74d5SMatthew G Knepley 
3168970e74d5SMatthew G Knepley   Level: intermediate
3169970e74d5SMatthew G Knepley 
3170970e74d5SMatthew G Knepley .seealso DMSetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
3171970e74d5SMatthew G Knepley @*/
3172970e74d5SMatthew G Knepley PetscErrorCode DMGetLocalJacobian(DM dm, PetscErrorCode (**lj)(DM, Vec, Mat, Mat, void *))
3173970e74d5SMatthew G Knepley {
3174970e74d5SMatthew G Knepley   PetscFunctionBegin;
3175970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3176970e74d5SMatthew G Knepley   if (lj) *lj = dm->lj;
3177970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3178970e74d5SMatthew G Knepley }
3179970e74d5SMatthew G Knepley 
3180970e74d5SMatthew G Knepley #undef __FUNCT__
3181970e74d5SMatthew G Knepley #define __FUNCT__ "DMSetLocalJacobian"
3182970e74d5SMatthew G Knepley /*@C
3183970e74d5SMatthew G Knepley   DMSetLocalJacobian - Set the local Jacobian function from this DM
3184970e74d5SMatthew G Knepley 
3185970e74d5SMatthew G Knepley   Not collective
3186970e74d5SMatthew G Knepley 
3187970e74d5SMatthew G Knepley   Input Parameters:
3188970e74d5SMatthew G Knepley + dm - The DM
3189970e74d5SMatthew G Knepley - lj - The local Jacobian function
3190970e74d5SMatthew G Knepley 
3191970e74d5SMatthew G Knepley    Calling sequence of lj:
3192970e74d5SMatthew G Knepley $    lj (SNES snes, Vec x, Mat J, Mat M, void *ctx);
3193970e74d5SMatthew G Knepley 
3194970e74d5SMatthew G Knepley +  snes - the SNES context
3195970e74d5SMatthew G Knepley .  x - local vector with the state at which to evaluate residual
3196970e74d5SMatthew G Knepley .  J - matrix to put Jacobian in
3197970e74d5SMatthew G Knepley .  M - matrix to use for defining Jacobian preconditioner
3198970e74d5SMatthew G Knepley -  ctx - optional user-defined function context
3199970e74d5SMatthew G Knepley 
3200970e74d5SMatthew G Knepley   Level: intermediate
3201970e74d5SMatthew G Knepley 
3202970e74d5SMatthew G Knepley .seealso DMGetLocalJacobian(), DMGetLocalFunction(), DMSetLocalFunction()
3203970e74d5SMatthew G Knepley @*/
3204970e74d5SMatthew G Knepley PetscErrorCode DMSetLocalJacobian(DM dm, PetscErrorCode (*lj)(DM, Vec, Mat,  Mat, void *))
3205970e74d5SMatthew G Knepley {
3206970e74d5SMatthew G Knepley   PetscFunctionBegin;
3207970e74d5SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3208970e74d5SMatthew G Knepley   dm->lj = lj;
3209970e74d5SMatthew G Knepley   PetscFunctionReturn(0);
3210970e74d5SMatthew G Knepley }
321188ed4aceSMatthew G Knepley 
321288ed4aceSMatthew G Knepley #undef __FUNCT__
321388ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
321488ed4aceSMatthew G Knepley /*@
321588ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
321688ed4aceSMatthew G Knepley 
321788ed4aceSMatthew G Knepley   Input Parameter:
321888ed4aceSMatthew G Knepley . dm - The DM
321988ed4aceSMatthew G Knepley 
322088ed4aceSMatthew G Knepley   Output Parameter:
322188ed4aceSMatthew G Knepley . section - The PetscSection
322288ed4aceSMatthew G Knepley 
322388ed4aceSMatthew G Knepley   Level: intermediate
322488ed4aceSMatthew G Knepley 
322588ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
322688ed4aceSMatthew G Knepley 
322788ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
322888ed4aceSMatthew G Knepley @*/
322988ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) {
323088ed4aceSMatthew G Knepley   PetscFunctionBegin;
323188ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
323288ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
323388ed4aceSMatthew G Knepley   *section = dm->defaultSection;
323488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
323588ed4aceSMatthew G Knepley }
323688ed4aceSMatthew G Knepley 
323788ed4aceSMatthew G Knepley #undef __FUNCT__
323888ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
323988ed4aceSMatthew G Knepley /*@
324088ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
324188ed4aceSMatthew G Knepley 
324288ed4aceSMatthew G Knepley   Input Parameters:
324388ed4aceSMatthew G Knepley + dm - The DM
324488ed4aceSMatthew G Knepley - section - The PetscSection
324588ed4aceSMatthew G Knepley 
324688ed4aceSMatthew G Knepley   Level: intermediate
324788ed4aceSMatthew G Knepley 
324888ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
324988ed4aceSMatthew G Knepley 
325088ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
325188ed4aceSMatthew G Knepley @*/
325288ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) {
3253af122d2aSMatthew G Knepley   PetscInt       numFields;
3254af122d2aSMatthew G Knepley   PetscInt       f;
325588ed4aceSMatthew G Knepley   PetscErrorCode ierr;
325688ed4aceSMatthew G Knepley 
325788ed4aceSMatthew G Knepley   PetscFunctionBegin;
325888ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
325988ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
326088ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
326188ed4aceSMatthew G Knepley   dm->defaultSection = section;
3262af122d2aSMatthew G Knepley   ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);
3263af122d2aSMatthew G Knepley   if (numFields) {
3264af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
3265af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
3266af122d2aSMatthew G Knepley       const char *name;
3267af122d2aSMatthew G Knepley 
3268af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
3269af122d2aSMatthew G Knepley       ierr = PetscObjectSetName(dm->fields[f], name);CHKERRQ(ierr);
3270af122d2aSMatthew G Knepley     }
3271af122d2aSMatthew G Knepley   }
327288ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
327388ed4aceSMatthew G Knepley }
327488ed4aceSMatthew G Knepley 
327588ed4aceSMatthew G Knepley #undef __FUNCT__
327688ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
327788ed4aceSMatthew G Knepley /*@
327888ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
327988ed4aceSMatthew G Knepley 
32808b1ab98fSJed Brown   Collective on DM
32818b1ab98fSJed Brown 
328288ed4aceSMatthew G Knepley   Input Parameter:
328388ed4aceSMatthew G Knepley . dm - The DM
328488ed4aceSMatthew G Knepley 
328588ed4aceSMatthew G Knepley   Output Parameter:
328688ed4aceSMatthew G Knepley . section - The PetscSection
328788ed4aceSMatthew G Knepley 
328888ed4aceSMatthew G Knepley   Level: intermediate
328988ed4aceSMatthew G Knepley 
329088ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
329188ed4aceSMatthew G Knepley 
329288ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
329388ed4aceSMatthew G Knepley @*/
329488ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) {
329588ed4aceSMatthew G Knepley   PetscErrorCode ierr;
329688ed4aceSMatthew G Knepley 
329788ed4aceSMatthew G Knepley   PetscFunctionBegin;
329888ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
329988ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
330088ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
330140e8a239SMatthew G Knepley     if (!dm->defaultSection || !dm->sf) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "DM must have a default PetscSection and PetscSF in order to create a global PetscSection");
3302b21d0597SMatthew G Knepley     ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
33038b1ab98fSJed Brown     ierr = PetscSectionGetValueLayout(((PetscObject)dm)->comm,dm->defaultGlobalSection,&dm->map);CHKERRQ(ierr);
330488ed4aceSMatthew G Knepley   }
330588ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
330688ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
330788ed4aceSMatthew G Knepley }
330888ed4aceSMatthew G Knepley 
330988ed4aceSMatthew G Knepley #undef __FUNCT__
3310b21d0597SMatthew G Knepley #define __FUNCT__ "DMSetDefaultGlobalSection"
3311b21d0597SMatthew G Knepley /*@
3312b21d0597SMatthew G Knepley   DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM.
3313b21d0597SMatthew G Knepley 
3314b21d0597SMatthew G Knepley   Input Parameters:
3315b21d0597SMatthew G Knepley + dm - The DM
3316b21d0597SMatthew G Knepley - section - The PetscSection
3317b21d0597SMatthew G Knepley 
3318b21d0597SMatthew G Knepley   Level: intermediate
3319b21d0597SMatthew G Knepley 
3320b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
3321b21d0597SMatthew G Knepley 
3322b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection()
3323b21d0597SMatthew G Knepley @*/
3324b21d0597SMatthew G Knepley PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section) {
3325b21d0597SMatthew G Knepley   PetscErrorCode ierr;
3326b21d0597SMatthew G Knepley 
3327b21d0597SMatthew G Knepley   PetscFunctionBegin;
3328b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3329b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
3330b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
3331b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3332b21d0597SMatthew G Knepley }
3333b21d0597SMatthew G Knepley 
3334b21d0597SMatthew G Knepley #undef __FUNCT__
333588ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
333688ed4aceSMatthew G Knepley /*@
333788ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
333888ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
333988ed4aceSMatthew G Knepley 
334088ed4aceSMatthew G Knepley   Input Parameter:
334188ed4aceSMatthew G Knepley . dm - The DM
334288ed4aceSMatthew G Knepley 
334388ed4aceSMatthew G Knepley   Output Parameter:
334488ed4aceSMatthew G Knepley . sf - The PetscSF
334588ed4aceSMatthew G Knepley 
334688ed4aceSMatthew G Knepley   Level: intermediate
334788ed4aceSMatthew G Knepley 
334888ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
334988ed4aceSMatthew G Knepley 
335088ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
335188ed4aceSMatthew G Knepley @*/
335288ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) {
335388ed4aceSMatthew G Knepley   PetscInt       nroots;
335488ed4aceSMatthew G Knepley   PetscErrorCode ierr;
335588ed4aceSMatthew G Knepley 
335688ed4aceSMatthew G Knepley   PetscFunctionBegin;
335788ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
335888ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
335988ed4aceSMatthew G Knepley   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
336088ed4aceSMatthew G Knepley   if (nroots < 0) {
336188ed4aceSMatthew G Knepley     PetscSection section, gSection;
336288ed4aceSMatthew G Knepley 
336388ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
336431ea6d37SMatthew G Knepley     if (section) {
336588ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
336688ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
336731ea6d37SMatthew G Knepley     } else {
336831ea6d37SMatthew G Knepley       *sf = PETSC_NULL;
336931ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
337031ea6d37SMatthew G Knepley     }
337188ed4aceSMatthew G Knepley   }
337288ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
337388ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
337488ed4aceSMatthew G Knepley }
337588ed4aceSMatthew G Knepley 
337688ed4aceSMatthew G Knepley #undef __FUNCT__
337788ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
337888ed4aceSMatthew G Knepley /*@
337988ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
338088ed4aceSMatthew G Knepley 
338188ed4aceSMatthew G Knepley   Input Parameters:
338288ed4aceSMatthew G Knepley + dm - The DM
338388ed4aceSMatthew G Knepley - sf - The PetscSF
338488ed4aceSMatthew G Knepley 
338588ed4aceSMatthew G Knepley   Level: intermediate
338688ed4aceSMatthew G Knepley 
338788ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
338888ed4aceSMatthew G Knepley 
338988ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
339088ed4aceSMatthew G Knepley @*/
339188ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) {
339288ed4aceSMatthew G Knepley   PetscErrorCode ierr;
339388ed4aceSMatthew G Knepley 
339488ed4aceSMatthew G Knepley   PetscFunctionBegin;
339588ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
339688ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
339788ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
339888ed4aceSMatthew G Knepley   dm->defaultSF = sf;
339988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
340088ed4aceSMatthew G Knepley }
340188ed4aceSMatthew G Knepley 
340288ed4aceSMatthew G Knepley #undef __FUNCT__
340388ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
340488ed4aceSMatthew G Knepley /*@C
340588ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
340688ed4aceSMatthew G Knepley   describing the data layout.
340788ed4aceSMatthew G Knepley 
340888ed4aceSMatthew G Knepley   Input Parameters:
340988ed4aceSMatthew G Knepley + dm - The DM
341088ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
341188ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
341288ed4aceSMatthew G Knepley 
341388ed4aceSMatthew G Knepley   Level: intermediate
341488ed4aceSMatthew G Knepley 
341588ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
341688ed4aceSMatthew G Knepley @*/
341788ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
341888ed4aceSMatthew G Knepley {
341988ed4aceSMatthew G Knepley   MPI_Comm        comm = ((PetscObject) dm)->comm;
342088ed4aceSMatthew G Knepley   PetscLayout     layout;
342188ed4aceSMatthew G Knepley   const PetscInt *ranges;
342288ed4aceSMatthew G Knepley   PetscInt       *local;
342388ed4aceSMatthew G Knepley   PetscSFNode    *remote;
342488ed4aceSMatthew G Knepley   PetscInt        pStart, pEnd, p, nroots, nleaves, l;
342588ed4aceSMatthew G Knepley   PetscMPIInt     size, rank;
342688ed4aceSMatthew G Knepley   PetscErrorCode  ierr;
342788ed4aceSMatthew G Knepley 
342888ed4aceSMatthew G Knepley   PetscFunctionBegin;
342988ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
343088ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
343188ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
343288ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
343388ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
343488ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
343588ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
343688ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
343788ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
343888ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
343988ed4aceSMatthew G Knepley   for (p = pStart, nleaves = 0; p < pEnd; ++p) {
34406636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
344188ed4aceSMatthew G Knepley 
34426636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
34436636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
34446636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
344588ed4aceSMatthew G Knepley   }
344688ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr);
344788ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr);
344888ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
34491f588964SMatthew G Knepley     const PetscInt *cind;
34506636e97aSMatthew G Knepley     PetscInt        dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
345188ed4aceSMatthew G Knepley 
345288ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
345388ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
345488ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
345588ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
345688ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
34576636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
345888ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
34596636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
34606636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
34616636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
3462057b4bcdSMatthew G Knepley       if (gsize != dof) SETERRQ4(comm, PETSC_ERR_ARG_WRONG, "Global dof %d for point %d is neither the constrained size %d, nor the unconstrained %d", gsize, p, dof-cdof, dof);
34636636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
34646636e97aSMatthew G Knepley     }
346588ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
346688ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
346788ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
346888ed4aceSMatthew G Knepley     }
346988ed4aceSMatthew G Knepley     if (gdof < 0) {
34706636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
347188ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
347288ed4aceSMatthew G Knepley 
347388ed4aceSMatthew G Knepley         for (r = 0; r < size; ++r) {
347488ed4aceSMatthew G Knepley           if ((offset >= ranges[r]) && (offset < ranges[r+1])) break;
347588ed4aceSMatthew G Knepley         }
347688ed4aceSMatthew G Knepley         remote[l].rank  = r;
347788ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
347888ed4aceSMatthew G Knepley       }
347988ed4aceSMatthew G Knepley     } else {
34806636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
348188ed4aceSMatthew G Knepley         remote[l].rank  = rank;
348288ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
348388ed4aceSMatthew G Knepley       }
348488ed4aceSMatthew G Knepley     }
348588ed4aceSMatthew G Knepley   }
34866636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
348788ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
348888ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
348988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
349088ed4aceSMatthew G Knepley }
3491af122d2aSMatthew G Knepley 
3492af122d2aSMatthew G Knepley #undef __FUNCT__
3493b21d0597SMatthew G Knepley #define __FUNCT__ "DMGetPointSF"
3494b21d0597SMatthew G Knepley /*@
3495b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
3496b21d0597SMatthew G Knepley 
3497b21d0597SMatthew G Knepley   Input Parameter:
3498b21d0597SMatthew G Knepley . dm - The DM
3499b21d0597SMatthew G Knepley 
3500b21d0597SMatthew G Knepley   Output Parameter:
3501b21d0597SMatthew G Knepley . sf - The PetscSF
3502b21d0597SMatthew G Knepley 
3503b21d0597SMatthew G Knepley   Level: intermediate
3504b21d0597SMatthew G Knepley 
3505b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
3506b21d0597SMatthew G Knepley 
3507057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3508b21d0597SMatthew G Knepley @*/
3509b21d0597SMatthew G Knepley PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) {
3510b21d0597SMatthew G Knepley   PetscFunctionBegin;
3511b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3512b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
3513b21d0597SMatthew G Knepley   *sf = dm->sf;
3514b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3515b21d0597SMatthew G Knepley }
3516b21d0597SMatthew G Knepley 
3517b21d0597SMatthew G Knepley #undef __FUNCT__
3518057b4bcdSMatthew G Knepley #define __FUNCT__ "DMSetPointSF"
3519057b4bcdSMatthew G Knepley /*@
3520057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
3521057b4bcdSMatthew G Knepley 
3522057b4bcdSMatthew G Knepley   Input Parameters:
3523057b4bcdSMatthew G Knepley + dm - The DM
3524057b4bcdSMatthew G Knepley - sf - The PetscSF
3525057b4bcdSMatthew G Knepley 
3526057b4bcdSMatthew G Knepley   Level: intermediate
3527057b4bcdSMatthew G Knepley 
3528057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3529057b4bcdSMatthew G Knepley @*/
3530057b4bcdSMatthew G Knepley PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) {
3531057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
3532057b4bcdSMatthew G Knepley 
3533057b4bcdSMatthew G Knepley   PetscFunctionBegin;
3534057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3535057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1);
3536057b4bcdSMatthew G Knepley   ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
3537057b4bcdSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
3538057b4bcdSMatthew G Knepley   dm->sf = sf;
3539057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
3540057b4bcdSMatthew G Knepley }
3541057b4bcdSMatthew G Knepley 
3542057b4bcdSMatthew G Knepley #undef __FUNCT__
3543af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetNumFields"
3544af122d2aSMatthew G Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
3545af122d2aSMatthew G Knepley {
3546af122d2aSMatthew G Knepley   PetscFunctionBegin;
3547af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3548af122d2aSMatthew G Knepley   PetscValidPointer(numFields, 2);
3549af122d2aSMatthew G Knepley   *numFields = dm->numFields;
3550af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3551af122d2aSMatthew G Knepley }
3552af122d2aSMatthew G Knepley 
3553af122d2aSMatthew G Knepley #undef __FUNCT__
3554af122d2aSMatthew G Knepley #define __FUNCT__ "DMSetNumFields"
3555af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
3556af122d2aSMatthew G Knepley {
3557af122d2aSMatthew G Knepley   PetscInt       f;
3558af122d2aSMatthew G Knepley   PetscErrorCode ierr;
3559af122d2aSMatthew G Knepley 
3560af122d2aSMatthew G Knepley   PetscFunctionBegin;
3561af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3562af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3563af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&dm->fields[f]);CHKERRQ(ierr);
3564af122d2aSMatthew G Knepley   }
3565af122d2aSMatthew G Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
3566af122d2aSMatthew G Knepley   dm->numFields = numFields;
3567af122d2aSMatthew G Knepley   ierr = PetscMalloc(dm->numFields * sizeof(PetscObject), &dm->fields);CHKERRQ(ierr);
3568af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3569af122d2aSMatthew G Knepley     ierr = PetscContainerCreate(((PetscObject) dm)->comm, (PetscContainer *) &dm->fields[f]);CHKERRQ(ierr);
3570af122d2aSMatthew G Knepley   }
3571af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3572af122d2aSMatthew G Knepley }
3573af122d2aSMatthew G Knepley 
3574af122d2aSMatthew G Knepley #undef __FUNCT__
3575af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetField"
3576af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field)
3577af122d2aSMatthew G Knepley {
3578af122d2aSMatthew G Knepley   PetscFunctionBegin;
3579af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3580af122d2aSMatthew G Knepley   PetscValidPointer(field, 2);
3581af122d2aSMatthew G Knepley   if (!dm->fields) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Fields have not been setup in this DM. Call DMSetNumFields()");
3582af122d2aSMatthew G Knepley   if ((f < 0) || (f >= dm->numFields)) SETERRQ3(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Field %d should be in [%d,%d)", f, 0, dm->numFields);
3583af122d2aSMatthew G Knepley   *field = dm->fields[f];
3584af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3585af122d2aSMatthew G Knepley }
35866636e97aSMatthew G Knepley 
35876636e97aSMatthew G Knepley #undef __FUNCT__
35886636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinates"
35896636e97aSMatthew G Knepley /*@
35906636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
35916636e97aSMatthew G Knepley 
35926636e97aSMatthew G Knepley   Collective on DM
35936636e97aSMatthew G Knepley 
35946636e97aSMatthew G Knepley   Input Parameters:
35956636e97aSMatthew G Knepley + dm - the DM
35966636e97aSMatthew G Knepley - c - coordinate vector
35976636e97aSMatthew G Knepley 
35986636e97aSMatthew G Knepley   Note:
35996636e97aSMatthew G Knepley   The coordinates do include those for ghost points, which are in the local vector
36006636e97aSMatthew G Knepley 
36016636e97aSMatthew G Knepley   Level: intermediate
36026636e97aSMatthew G Knepley 
36036636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
36046636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM()
36056636e97aSMatthew G Knepley @*/
36066636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
36076636e97aSMatthew G Knepley {
36086636e97aSMatthew G Knepley   PetscErrorCode ierr;
36096636e97aSMatthew G Knepley 
36106636e97aSMatthew G Knepley   PetscFunctionBegin;
36116636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
36126636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
36136636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
36146636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
36156636e97aSMatthew G Knepley   dm->coordinates = c;
36166636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
36176636e97aSMatthew G Knepley   PetscFunctionReturn(0);
36186636e97aSMatthew G Knepley }
36196636e97aSMatthew G Knepley 
36206636e97aSMatthew G Knepley #undef __FUNCT__
36216636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinatesLocal"
36226636e97aSMatthew G Knepley /*@
36236636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
36246636e97aSMatthew G Knepley 
36256636e97aSMatthew G Knepley   Collective on DM
36266636e97aSMatthew G Knepley 
36276636e97aSMatthew G Knepley    Input Parameters:
36286636e97aSMatthew G Knepley +  dm - the DM
36296636e97aSMatthew G Knepley -  c - coordinate vector
36306636e97aSMatthew G Knepley 
36316636e97aSMatthew G Knepley   Note:
36326636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
36336636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
36346636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
36356636e97aSMatthew G Knepley 
36366636e97aSMatthew G Knepley   Level: intermediate
36376636e97aSMatthew G Knepley 
36386636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
36396636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
36406636e97aSMatthew G Knepley @*/
36416636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
36426636e97aSMatthew G Knepley {
36436636e97aSMatthew G Knepley   PetscErrorCode ierr;
36446636e97aSMatthew G Knepley 
36456636e97aSMatthew G Knepley   PetscFunctionBegin;
36466636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
36476636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
36486636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
36496636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
36506636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
36516636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
36526636e97aSMatthew G Knepley   PetscFunctionReturn(0);
36536636e97aSMatthew G Knepley }
36546636e97aSMatthew G Knepley 
36556636e97aSMatthew G Knepley #undef __FUNCT__
36566636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinates"
36576636e97aSMatthew G Knepley /*@
36586636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
36596636e97aSMatthew G Knepley 
36606636e97aSMatthew G Knepley   Not Collective
36616636e97aSMatthew G Knepley 
36626636e97aSMatthew G Knepley   Input Parameter:
36636636e97aSMatthew G Knepley . dm - the DM
36646636e97aSMatthew G Knepley 
36656636e97aSMatthew G Knepley   Output Parameter:
36666636e97aSMatthew G Knepley . c - global coordinate vector
36676636e97aSMatthew G Knepley 
36686636e97aSMatthew G Knepley   Note:
36696636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
36706636e97aSMatthew G Knepley 
36716636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
36726636e97aSMatthew G Knepley 
36736636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
36746636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
36756636e97aSMatthew G Knepley 
36766636e97aSMatthew G Knepley   Level: intermediate
36776636e97aSMatthew G Knepley 
36786636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
36796636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
36806636e97aSMatthew G Knepley @*/
36816636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
36826636e97aSMatthew G Knepley {
36836636e97aSMatthew G Knepley   PetscErrorCode ierr;
36846636e97aSMatthew G Knepley 
36856636e97aSMatthew G Knepley   PetscFunctionBegin;
36866636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
36876636e97aSMatthew G Knepley   PetscValidPointer(c,2);
36881f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
36896636e97aSMatthew G Knepley     DM cdm;
36906636e97aSMatthew G Knepley 
36916636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
36926636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
36936636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
36946636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
36956636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
36966636e97aSMatthew G Knepley   }
36976636e97aSMatthew G Knepley   *c = dm->coordinates;
36986636e97aSMatthew G Knepley   PetscFunctionReturn(0);
36996636e97aSMatthew G Knepley }
37006636e97aSMatthew G Knepley 
37016636e97aSMatthew G Knepley #undef __FUNCT__
37026636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinatesLocal"
37036636e97aSMatthew G Knepley /*@
37046636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
37056636e97aSMatthew G Knepley 
37066636e97aSMatthew G Knepley   Collective on DM
37076636e97aSMatthew G Knepley 
37086636e97aSMatthew G Knepley   Input Parameter:
37096636e97aSMatthew G Knepley . dm - the DM
37106636e97aSMatthew G Knepley 
37116636e97aSMatthew G Knepley   Output Parameter:
37126636e97aSMatthew G Knepley . c - coordinate vector
37136636e97aSMatthew G Knepley 
37146636e97aSMatthew G Knepley   Note:
37156636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
37166636e97aSMatthew G Knepley 
37176636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
37186636e97aSMatthew G Knepley 
37196636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
37206636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
37216636e97aSMatthew G Knepley 
37226636e97aSMatthew G Knepley   Level: intermediate
37236636e97aSMatthew G Knepley 
37246636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
37256636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
37266636e97aSMatthew G Knepley @*/
37276636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
37286636e97aSMatthew G Knepley {
37296636e97aSMatthew G Knepley   PetscErrorCode ierr;
37306636e97aSMatthew G Knepley 
37316636e97aSMatthew G Knepley   PetscFunctionBegin;
37326636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
37336636e97aSMatthew G Knepley   PetscValidPointer(c,2);
37341f588964SMatthew G Knepley   if (!dm->coordinatesLocal && dm->coordinates) {
37356636e97aSMatthew G Knepley     DM cdm;
37366636e97aSMatthew G Knepley 
37376636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
37386636e97aSMatthew G Knepley     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
37396636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
37406636e97aSMatthew G Knepley     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
37416636e97aSMatthew G Knepley     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
37426636e97aSMatthew G Knepley   }
37436636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
37446636e97aSMatthew G Knepley   PetscFunctionReturn(0);
37456636e97aSMatthew G Knepley }
37466636e97aSMatthew G Knepley 
37476636e97aSMatthew G Knepley #undef __FUNCT__
37486636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinateDM"
37496636e97aSMatthew G Knepley /*@
37506636e97aSMatthew G Knepley   DMGetCoordinateDM - Gets the DM that scatters between global and local coordinates
37516636e97aSMatthew G Knepley 
37526636e97aSMatthew G Knepley   Collective on DM
37536636e97aSMatthew G Knepley 
37546636e97aSMatthew G Knepley   Input Parameter:
37556636e97aSMatthew G Knepley . dm - the DM
37566636e97aSMatthew G Knepley 
37576636e97aSMatthew G Knepley   Output Parameter:
37586636e97aSMatthew G Knepley . cdm - coordinate DM
37596636e97aSMatthew G Knepley 
37606636e97aSMatthew G Knepley   Level: intermediate
37616636e97aSMatthew G Knepley 
37626636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
37636636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
37646636e97aSMatthew G Knepley @*/
37656636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
37666636e97aSMatthew G Knepley {
37676636e97aSMatthew G Knepley   PetscErrorCode ierr;
37686636e97aSMatthew G Knepley 
37696636e97aSMatthew G Knepley   PetscFunctionBegin;
37706636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
37716636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
37726636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
37736636e97aSMatthew G Knepley     if (!dm->ops->createcoordinatedm) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Unable to create coordinates for this DM");
37746636e97aSMatthew G Knepley     ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr);
37756636e97aSMatthew G Knepley   }
37766636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
37776636e97aSMatthew G Knepley   PetscFunctionReturn(0);
37786636e97aSMatthew G Knepley }
3779