xref: /petsc/src/dm/interface/dm.c (revision d425c65490e4ac82ba86abf85610d07f1bd23b6b)
1b45d2f2cSJed Brown #include <petsc-private/dmimpl.h>     /*I      "petscdm.h"     I*/
247c6ae99SBarry Smith 
3732e2eb9SMatthew G Knepley PetscClassId  DM_CLASSID;
467a56275SMatthew G Knepley PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal;
567a56275SMatthew G Knepley 
647c6ae99SBarry Smith #undef __FUNCT__
7a4121054SBarry Smith #define __FUNCT__ "DMCreate"
8a4121054SBarry Smith /*@
9de043629SMatthew G Knepley   DMCreate - Creates an empty DM object. The type can then be set with DMSetType().
10a4121054SBarry Smith 
11a4121054SBarry Smith    If you never  call DMSetType()  it will generate an
12a4121054SBarry Smith    error when you try to use the vector.
13a4121054SBarry Smith 
14a4121054SBarry Smith   Collective on MPI_Comm
15a4121054SBarry Smith 
16a4121054SBarry Smith   Input Parameter:
17a4121054SBarry Smith . comm - The communicator for the DM object
18a4121054SBarry Smith 
19a4121054SBarry Smith   Output Parameter:
20a4121054SBarry Smith . dm - The DM object
21a4121054SBarry Smith 
22a4121054SBarry Smith   Level: beginner
23a4121054SBarry Smith 
24a4121054SBarry Smith .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE
25a4121054SBarry Smith @*/
267087cfbeSBarry Smith PetscErrorCode  DMCreate(MPI_Comm comm,DM *dm)
27a4121054SBarry Smith {
28a4121054SBarry Smith   DM             v;
29a4121054SBarry Smith   PetscErrorCode ierr;
30a4121054SBarry Smith 
31a4121054SBarry Smith   PetscFunctionBegin;
321411c6eeSJed Brown   PetscValidPointer(dm,2);
331411c6eeSJed Brown   *dm = PETSC_NULL;
34a4121054SBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
35b84caa0eSBarry Smith   ierr = VecInitializePackage(PETSC_NULL);CHKERRQ(ierr);
36b84caa0eSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
37a4121054SBarry Smith   ierr = DMInitializePackage(PETSC_NULL);CHKERRQ(ierr);
38a4121054SBarry Smith #endif
39a4121054SBarry Smith 
403194b578SJed Brown   ierr = PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, -1, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);CHKERRQ(ierr);
41a4121054SBarry Smith   ierr = PetscMemzero(v->ops, sizeof(struct _DMOps));CHKERRQ(ierr);
421411c6eeSJed Brown 
43e7c4fc90SDmitry Karpeev 
441411c6eeSJed Brown   v->ltogmap      = PETSC_NULL;
451411c6eeSJed Brown   v->ltogmapb     = PETSC_NULL;
461411c6eeSJed Brown   v->bs           = 1;
47171400e9SBarry Smith   v->coloringtype = IS_COLORING_GLOBAL;
4888ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->sf);CHKERRQ(ierr);
4988ed4aceSMatthew G Knepley   ierr = PetscSFCreate(comm, &v->defaultSF);CHKERRQ(ierr);
5088ed4aceSMatthew G Knepley   v->defaultSection       = PETSC_NULL;
5188ed4aceSMatthew G Knepley   v->defaultGlobalSection = PETSC_NULL;
52435a35e8SMatthew G Knepley   {
53435a35e8SMatthew G Knepley     PetscInt i;
54435a35e8SMatthew G Knepley     for (i = 0; i < 10; ++i) {
55435a35e8SMatthew G Knepley       v->nullspaceConstructors[i] = PETSC_NULL;
56435a35e8SMatthew G Knepley     }
57435a35e8SMatthew G Knepley   }
58af122d2aSMatthew G Knepley   v->numFields = 0;
59af122d2aSMatthew G Knepley   v->fields    = PETSC_NULL;
601411c6eeSJed Brown 
611411c6eeSJed Brown   *dm = v;
62a4121054SBarry Smith   PetscFunctionReturn(0);
63a4121054SBarry Smith }
64a4121054SBarry Smith 
65a4121054SBarry Smith #undef __FUNCT__
669a42bb27SBarry Smith #define __FUNCT__ "DMSetVecType"
679a42bb27SBarry Smith /*@C
68564755cdSBarry Smith        DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
699a42bb27SBarry Smith 
70aa219208SBarry Smith    Logically Collective on DMDA
719a42bb27SBarry Smith 
729a42bb27SBarry Smith    Input Parameter:
739a42bb27SBarry Smith +  da - initial distributed array
748154be41SBarry Smith .  ctype - the vector type, currently either VECSTANDARD or VECCUSP
759a42bb27SBarry Smith 
769a42bb27SBarry Smith    Options Database:
77dd85299cSBarry Smith .   -dm_vec_type ctype
789a42bb27SBarry Smith 
799a42bb27SBarry Smith    Level: intermediate
809a42bb27SBarry Smith 
81aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
829a42bb27SBarry Smith @*/
8319fd82e9SBarry Smith PetscErrorCode  DMSetVecType(DM da,VecType ctype)
849a42bb27SBarry Smith {
859a42bb27SBarry Smith   PetscErrorCode ierr;
869a42bb27SBarry Smith 
879a42bb27SBarry Smith   PetscFunctionBegin;
889a42bb27SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
899a42bb27SBarry Smith   ierr = PetscFree(da->vectype);CHKERRQ(ierr);
9019fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&da->vectype);CHKERRQ(ierr);
919a42bb27SBarry Smith   PetscFunctionReturn(0);
929a42bb27SBarry Smith }
939a42bb27SBarry Smith 
949a42bb27SBarry Smith #undef __FUNCT__
955f1ad066SMatthew G Knepley #define __FUNCT__ "VecGetDM"
965f1ad066SMatthew G Knepley /*@
9734f98d34SBarry Smith   VecGetDM - Gets the DM defining the data layout of the vector
985f1ad066SMatthew G Knepley 
995f1ad066SMatthew G Knepley   Not collective
1005f1ad066SMatthew G Knepley 
1015f1ad066SMatthew G Knepley   Input Parameter:
1025f1ad066SMatthew G Knepley . v - The Vec
1035f1ad066SMatthew G Knepley 
1045f1ad066SMatthew G Knepley   Output Parameter:
1055f1ad066SMatthew G Knepley . dm - The DM
1065f1ad066SMatthew G Knepley 
1075f1ad066SMatthew G Knepley   Level: intermediate
1085f1ad066SMatthew G Knepley 
1095f1ad066SMatthew G Knepley .seealso: VecSetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
1105f1ad066SMatthew G Knepley @*/
1115f1ad066SMatthew G Knepley PetscErrorCode VecGetDM(Vec v, DM *dm)
1125f1ad066SMatthew G Knepley {
1135f1ad066SMatthew G Knepley   PetscErrorCode ierr;
1145f1ad066SMatthew G Knepley 
1155f1ad066SMatthew G Knepley   PetscFunctionBegin;
1165f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1175f1ad066SMatthew G Knepley   PetscValidPointer(dm,2);
1185f1ad066SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) v, "__PETSc_dm", (PetscObject *) dm);CHKERRQ(ierr);
1195f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
1205f1ad066SMatthew G Knepley }
1215f1ad066SMatthew G Knepley 
1225f1ad066SMatthew G Knepley #undef __FUNCT__
1235f1ad066SMatthew G Knepley #define __FUNCT__ "VecSetDM"
1245f1ad066SMatthew G Knepley /*@
1255f1ad066SMatthew G Knepley   VecSetDM - Sets the DM defining the data layout of the vector
1265f1ad066SMatthew G Knepley 
1275f1ad066SMatthew G Knepley   Not collective
1285f1ad066SMatthew G Knepley 
1295f1ad066SMatthew G Knepley   Input Parameters:
1305f1ad066SMatthew G Knepley + v - The Vec
1315f1ad066SMatthew G Knepley - dm - The DM
1325f1ad066SMatthew G Knepley 
1335f1ad066SMatthew G Knepley   Level: intermediate
1345f1ad066SMatthew G Knepley 
1355f1ad066SMatthew G Knepley .seealso: VecGetDM(), DMGetLocalVector(), DMGetGlobalVector(), DMSetVecType()
1365f1ad066SMatthew G Knepley @*/
1375f1ad066SMatthew G Knepley PetscErrorCode VecSetDM(Vec v, DM dm)
1385f1ad066SMatthew G Knepley {
1395f1ad066SMatthew G Knepley   PetscErrorCode ierr;
1405f1ad066SMatthew G Knepley 
1415f1ad066SMatthew G Knepley   PetscFunctionBegin;
1425f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(v,VEC_CLASSID,1);
1435f1ad066SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
1445f1ad066SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) v, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
1455f1ad066SMatthew G Knepley   PetscFunctionReturn(0);
1465f1ad066SMatthew G Knepley }
1475f1ad066SMatthew G Knepley 
1485f1ad066SMatthew G Knepley #undef __FUNCT__
149521d9a4cSLisandro Dalcin #define __FUNCT__ "DMSetMatType"
150521d9a4cSLisandro Dalcin /*@C
151521d9a4cSLisandro Dalcin        DMSetMatType - Sets the type of matrix created with DMCreateMatrix()
152521d9a4cSLisandro Dalcin 
153521d9a4cSLisandro Dalcin    Logically Collective on DM
154521d9a4cSLisandro Dalcin 
155521d9a4cSLisandro Dalcin    Input Parameter:
156521d9a4cSLisandro Dalcin +  dm - the DM context
157521d9a4cSLisandro Dalcin .  ctype - the matrix type
158521d9a4cSLisandro Dalcin 
159521d9a4cSLisandro Dalcin    Options Database:
160521d9a4cSLisandro Dalcin .   -dm_mat_type ctype
161521d9a4cSLisandro Dalcin 
162521d9a4cSLisandro Dalcin    Level: intermediate
163521d9a4cSLisandro Dalcin 
164521d9a4cSLisandro Dalcin .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMCreateMatrix(), DMSetMatrixPreallocateOnly(), MatType
165521d9a4cSLisandro Dalcin @*/
16619fd82e9SBarry Smith PetscErrorCode  DMSetMatType(DM dm,MatType ctype)
167521d9a4cSLisandro Dalcin {
168521d9a4cSLisandro Dalcin   PetscErrorCode ierr;
169521d9a4cSLisandro Dalcin   PetscFunctionBegin;
170521d9a4cSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
171521d9a4cSLisandro Dalcin   ierr = PetscFree(dm->mattype);CHKERRQ(ierr);
17219fd82e9SBarry Smith   ierr = PetscStrallocpy(ctype,(char**)&dm->mattype);CHKERRQ(ierr);
173521d9a4cSLisandro Dalcin   PetscFunctionReturn(0);
174521d9a4cSLisandro Dalcin }
175521d9a4cSLisandro Dalcin 
176521d9a4cSLisandro Dalcin #undef __FUNCT__
177c688c046SMatthew G Knepley #define __FUNCT__ "MatGetDM"
178c688c046SMatthew G Knepley /*@
17934f98d34SBarry Smith   MatGetDM - Gets the DM defining the data layout of the matrix
180c688c046SMatthew G Knepley 
181c688c046SMatthew G Knepley   Not collective
182c688c046SMatthew G Knepley 
183c688c046SMatthew G Knepley   Input Parameter:
184c688c046SMatthew G Knepley . A - The Mat
185c688c046SMatthew G Knepley 
186c688c046SMatthew G Knepley   Output Parameter:
187c688c046SMatthew G Knepley . dm - The DM
188c688c046SMatthew G Knepley 
189c688c046SMatthew G Knepley   Level: intermediate
190c688c046SMatthew G Knepley 
191c688c046SMatthew G Knepley .seealso: MatSetDM(), DMCreateMatrix(), DMSetMatType()
192c688c046SMatthew G Knepley @*/
193c688c046SMatthew G Knepley PetscErrorCode MatGetDM(Mat A, DM *dm)
194c688c046SMatthew G Knepley {
195c688c046SMatthew G Knepley   PetscErrorCode ierr;
196c688c046SMatthew G Knepley 
197c688c046SMatthew G Knepley   PetscFunctionBegin;
198c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
199c688c046SMatthew G Knepley   PetscValidPointer(dm,2);
200c688c046SMatthew G Knepley   ierr = PetscObjectQuery((PetscObject) A, "__PETSc_dm", (PetscObject *) dm);CHKERRQ(ierr);
201c688c046SMatthew G Knepley   PetscFunctionReturn(0);
202c688c046SMatthew G Knepley }
203c688c046SMatthew G Knepley 
204c688c046SMatthew G Knepley #undef __FUNCT__
205c688c046SMatthew G Knepley #define __FUNCT__ "MatSetDM"
206c688c046SMatthew G Knepley /*@
207c688c046SMatthew G Knepley   MatSetDM - Sets the DM defining the data layout of the matrix
208c688c046SMatthew G Knepley 
209c688c046SMatthew G Knepley   Not collective
210c688c046SMatthew G Knepley 
211c688c046SMatthew G Knepley   Input Parameters:
212c688c046SMatthew G Knepley + A - The Mat
213c688c046SMatthew G Knepley - dm - The DM
214c688c046SMatthew G Knepley 
215c688c046SMatthew G Knepley   Level: intermediate
216c688c046SMatthew G Knepley 
217c688c046SMatthew G Knepley .seealso: MatGetDM(), DMCreateMatrix(), DMSetMatType()
218c688c046SMatthew G Knepley @*/
219c688c046SMatthew G Knepley PetscErrorCode MatSetDM(Mat A, DM dm)
220c688c046SMatthew G Knepley {
221c688c046SMatthew G Knepley   PetscErrorCode ierr;
222c688c046SMatthew G Knepley 
223c688c046SMatthew G Knepley   PetscFunctionBegin;
224c688c046SMatthew G Knepley   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
225a85f731bSMatthew G Knepley   if (dm) {PetscValidHeaderSpecific(dm,DM_CLASSID,2);}
226c688c046SMatthew G Knepley   ierr = PetscObjectCompose((PetscObject) A, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
227c688c046SMatthew G Knepley   PetscFunctionReturn(0);
228c688c046SMatthew G Knepley }
229c688c046SMatthew G Knepley 
230c688c046SMatthew G Knepley #undef __FUNCT__
2319a42bb27SBarry Smith #define __FUNCT__ "DMSetOptionsPrefix"
2329a42bb27SBarry Smith /*@C
2339a42bb27SBarry Smith    DMSetOptionsPrefix - Sets the prefix used for searching for all
234aa219208SBarry Smith    DMDA options in the database.
2359a42bb27SBarry Smith 
236aa219208SBarry Smith    Logically Collective on DMDA
2379a42bb27SBarry Smith 
2389a42bb27SBarry Smith    Input Parameter:
239aa219208SBarry Smith +  da - the DMDA context
2409a42bb27SBarry Smith -  prefix - the prefix to prepend to all option names
2419a42bb27SBarry Smith 
2429a42bb27SBarry Smith    Notes:
2439a42bb27SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
2449a42bb27SBarry Smith    The first character of all runtime options is AUTOMATICALLY the hyphen.
2459a42bb27SBarry Smith 
2469a42bb27SBarry Smith    Level: advanced
2479a42bb27SBarry Smith 
248aa219208SBarry Smith .keywords: DMDA, set, options, prefix, database
2499a42bb27SBarry Smith 
2509a42bb27SBarry Smith .seealso: DMSetFromOptions()
2519a42bb27SBarry Smith @*/
2527087cfbeSBarry Smith PetscErrorCode  DMSetOptionsPrefix(DM dm,const char prefix[])
2539a42bb27SBarry Smith {
2549a42bb27SBarry Smith   PetscErrorCode ierr;
2559a42bb27SBarry Smith 
2569a42bb27SBarry Smith   PetscFunctionBegin;
2579a42bb27SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2589a42bb27SBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);CHKERRQ(ierr);
2599a42bb27SBarry Smith   PetscFunctionReturn(0);
2609a42bb27SBarry Smith }
2619a42bb27SBarry Smith 
2629a42bb27SBarry Smith #undef __FUNCT__
26347c6ae99SBarry Smith #define __FUNCT__ "DMDestroy"
26447c6ae99SBarry Smith /*@
265aa219208SBarry Smith     DMDestroy - Destroys a vector packer or DMDA.
26647c6ae99SBarry Smith 
26747c6ae99SBarry Smith     Collective on DM
26847c6ae99SBarry Smith 
26947c6ae99SBarry Smith     Input Parameter:
27047c6ae99SBarry Smith .   dm - the DM object to destroy
27147c6ae99SBarry Smith 
27247c6ae99SBarry Smith     Level: developer
27347c6ae99SBarry Smith 
274e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
27547c6ae99SBarry Smith 
27647c6ae99SBarry Smith @*/
277fcfd50ebSBarry Smith PetscErrorCode  DMDestroy(DM *dm)
27847c6ae99SBarry Smith {
279af122d2aSMatthew G Knepley   PetscInt       i, cnt = 0, f;
280dfe15315SJed Brown   DMNamedVecLink nlink,nnext;
28147c6ae99SBarry Smith   PetscErrorCode ierr;
28247c6ae99SBarry Smith 
28347c6ae99SBarry Smith   PetscFunctionBegin;
2846bf464f9SBarry Smith   if (!*dm) PetscFunctionReturn(0);
2856bf464f9SBarry Smith   PetscValidHeaderSpecific((*dm),DM_CLASSID,1);
28687e657c6SBarry Smith 
28787e657c6SBarry Smith   /* count all the circular references of DM and its contained Vecs */
288732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
2896bf464f9SBarry Smith     if ((*dm)->localin[i])  {cnt++;}
2906bf464f9SBarry Smith     if ((*dm)->globalin[i]) {cnt++;}
291732e2eb9SMatthew G Knepley   }
292dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nlink->next) cnt++;
29371cd77b2SBarry Smith   if ((*dm)->x) {
294c688c046SMatthew G Knepley     DM obj;
295c688c046SMatthew G Knepley     ierr = VecGetDM((*dm)->x, &obj);CHKERRQ(ierr);
296c688c046SMatthew G Knepley     if (obj == *dm) cnt++;
29771cd77b2SBarry Smith   }
298732e2eb9SMatthew G Knepley 
2996bf464f9SBarry Smith   if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; PetscFunctionReturn(0);}
300732e2eb9SMatthew G Knepley   /*
301732e2eb9SMatthew G Knepley      Need this test because the dm references the vectors that
302732e2eb9SMatthew G Knepley      reference the dm, so destroying the dm calls destroy on the
303732e2eb9SMatthew G Knepley      vectors that cause another destroy on the dm
304732e2eb9SMatthew G Knepley   */
3056bf464f9SBarry Smith   if (((PetscObject)(*dm))->refct < 0) PetscFunctionReturn(0);
3066bf464f9SBarry Smith   ((PetscObject) (*dm))->refct = 0;
307732e2eb9SMatthew G Knepley   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
3086bf464f9SBarry Smith     if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
3096bf464f9SBarry Smith     ierr = VecDestroy(&(*dm)->localin[i]);CHKERRQ(ierr);
310732e2eb9SMatthew G Knepley   }
311dfe15315SJed Brown   for (nlink=(*dm)->namedglobal; nlink; nlink=nnext) { /* Destroy the named vectors */
312dfe15315SJed Brown     nnext = nlink->next;
313dfe15315SJed 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);
314dfe15315SJed Brown     ierr = PetscFree(nlink->name);CHKERRQ(ierr);
315dfe15315SJed Brown     ierr = VecDestroy(&nlink->X);CHKERRQ(ierr);
316dfe15315SJed Brown     ierr = PetscFree(nlink);CHKERRQ(ierr);
317dfe15315SJed Brown   }
318dfe15315SJed Brown   (*dm)->namedglobal = PETSC_NULL;
3191a266240SBarry Smith 
320b17ce1afSJed Brown   /* Destroy the list of hooks */
321c833c3b5SJed Brown   {
322c833c3b5SJed Brown     DMCoarsenHookLink link,next;
323b17ce1afSJed Brown     for (link=(*dm)->coarsenhook; link; link=next) {
324b17ce1afSJed Brown       next = link->next;
325b17ce1afSJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
326b17ce1afSJed Brown     }
327b17ce1afSJed Brown     (*dm)->coarsenhook = PETSC_NULL;
328c833c3b5SJed Brown   }
329c833c3b5SJed Brown   {
330c833c3b5SJed Brown     DMRefineHookLink link,next;
331c833c3b5SJed Brown     for (link=(*dm)->refinehook; link; link=next) {
332c833c3b5SJed Brown       next = link->next;
333c833c3b5SJed Brown       ierr = PetscFree(link);CHKERRQ(ierr);
334c833c3b5SJed Brown     }
335c833c3b5SJed Brown     (*dm)->refinehook = PETSC_NULL;
336c833c3b5SJed Brown   }
337be081cd6SPeter Brune   {
338be081cd6SPeter Brune     DMSubDomainHookLink link,next;
339be081cd6SPeter Brune     for (link=(*dm)->subdomainhook; link; link=next) {
340be081cd6SPeter Brune       next = link->next;
341be081cd6SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
342be081cd6SPeter Brune     }
343be081cd6SPeter Brune     (*dm)->subdomainhook = PETSC_NULL;
344be081cd6SPeter Brune   }
345baf369e7SPeter Brune   {
346baf369e7SPeter Brune     DMGlobalToLocalHookLink link,next;
347baf369e7SPeter Brune     for (link=(*dm)->gtolhook; link; link=next) {
348baf369e7SPeter Brune       next = link->next;
349baf369e7SPeter Brune       ierr = PetscFree(link);CHKERRQ(ierr);
350baf369e7SPeter Brune     }
351baf369e7SPeter Brune     (*dm)->gtolhook = PETSC_NULL;
352baf369e7SPeter Brune   }
353aa1993deSMatthew G Knepley   /* Destroy the work arrays */
354aa1993deSMatthew G Knepley   {
355aa1993deSMatthew G Knepley     DMWorkLink link,next;
356aa1993deSMatthew G Knepley     if ((*dm)->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Work array still checked out");
357aa1993deSMatthew G Knepley     for (link=(*dm)->workin; link; link=next) {
358aa1993deSMatthew G Knepley       next = link->next;
359aa1993deSMatthew G Knepley       ierr = PetscFree(link->mem);CHKERRQ(ierr);
360aa1993deSMatthew G Knepley       ierr = PetscFree(link);CHKERRQ(ierr);
361aa1993deSMatthew G Knepley     }
362aa1993deSMatthew G Knepley     (*dm)->workin = PETSC_NULL;
363aa1993deSMatthew G Knepley   }
364b17ce1afSJed Brown 
36552536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmksp);CHKERRQ(ierr);
36652536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmsnes);CHKERRQ(ierr);
36752536dc3SBarry Smith   ierr = PetscObjectDestroy(&(*dm)->dmts);CHKERRQ(ierr);
36852536dc3SBarry Smith 
3691a266240SBarry Smith   if ((*dm)->ctx && (*dm)->ctxdestroy) {
3701a266240SBarry Smith     ierr = (*(*dm)->ctxdestroy)(&(*dm)->ctx);CHKERRQ(ierr);
3711a266240SBarry Smith   }
37287e657c6SBarry Smith   ierr = VecDestroy(&(*dm)->x);CHKERRQ(ierr);
37371cd77b2SBarry Smith   ierr = MatFDColoringDestroy(&(*dm)->fd);CHKERRQ(ierr);
3744dcab191SBarry Smith   ierr = DMClearGlobalVectors(*dm);CHKERRQ(ierr);
3756bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);CHKERRQ(ierr);
3766bf464f9SBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);CHKERRQ(ierr);
3776bf464f9SBarry Smith   ierr = PetscFree((*dm)->vectype);CHKERRQ(ierr);
378073dac72SJed Brown   ierr = PetscFree((*dm)->mattype);CHKERRQ(ierr);
37988ed4aceSMatthew G Knepley 
38088ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultSection);CHKERRQ(ierr);
38188ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&(*dm)->defaultGlobalSection);CHKERRQ(ierr);
3828b1ab98fSJed Brown   ierr = PetscLayoutDestroy(&(*dm)->map);CHKERRQ(ierr);
38388ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->sf);CHKERRQ(ierr);
38488ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&(*dm)->defaultSF);CHKERRQ(ierr);
385af122d2aSMatthew G Knepley 
3866636e97aSMatthew G Knepley   ierr = DMDestroy(&(*dm)->coordinateDM);CHKERRQ(ierr);
3876636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinates);CHKERRQ(ierr);
3886636e97aSMatthew G Knepley   ierr = VecDestroy(&(*dm)->coordinatesLocal);CHKERRQ(ierr);
3896636e97aSMatthew G Knepley 
390af122d2aSMatthew G Knepley   for (f = 0; f < (*dm)->numFields; ++f) {
391af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&(*dm)->fields[f]);CHKERRQ(ierr);
392af122d2aSMatthew G Knepley   }
393af122d2aSMatthew G Knepley   ierr = PetscFree((*dm)->fields);CHKERRQ(ierr);
394732e2eb9SMatthew G Knepley   /* if memory was published with AMS then destroy it */
3956bf464f9SBarry Smith   ierr = PetscObjectDepublish(*dm);CHKERRQ(ierr);
396732e2eb9SMatthew G Knepley 
3976bf464f9SBarry Smith   ierr = (*(*dm)->ops->destroy)(*dm);CHKERRQ(ierr);
398435a35e8SMatthew G Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
399732e2eb9SMatthew G Knepley   ierr = PetscHeaderDestroy(dm);CHKERRQ(ierr);
40047c6ae99SBarry Smith   PetscFunctionReturn(0);
40147c6ae99SBarry Smith }
40247c6ae99SBarry Smith 
40347c6ae99SBarry Smith #undef __FUNCT__
404d7bf68aeSBarry Smith #define __FUNCT__ "DMSetUp"
405d7bf68aeSBarry Smith /*@
406d7bf68aeSBarry Smith     DMSetUp - sets up the data structures inside a DM object
407d7bf68aeSBarry Smith 
408d7bf68aeSBarry Smith     Collective on DM
409d7bf68aeSBarry Smith 
410d7bf68aeSBarry Smith     Input Parameter:
411d7bf68aeSBarry Smith .   dm - the DM object to setup
412d7bf68aeSBarry Smith 
413d7bf68aeSBarry Smith     Level: developer
414d7bf68aeSBarry Smith 
415e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
416d7bf68aeSBarry Smith 
417d7bf68aeSBarry Smith @*/
4187087cfbeSBarry Smith PetscErrorCode  DMSetUp(DM dm)
419d7bf68aeSBarry Smith {
420d7bf68aeSBarry Smith   PetscErrorCode ierr;
421d7bf68aeSBarry Smith 
422d7bf68aeSBarry Smith   PetscFunctionBegin;
423171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4248387afaaSJed Brown   if (dm->setupcalled) PetscFunctionReturn(0);
425d7bf68aeSBarry Smith   if (dm->ops->setup) {
426d7bf68aeSBarry Smith     ierr = (*dm->ops->setup)(dm);CHKERRQ(ierr);
427d7bf68aeSBarry Smith   }
4288387afaaSJed Brown   dm->setupcalled = PETSC_TRUE;
429d7bf68aeSBarry Smith   PetscFunctionReturn(0);
430d7bf68aeSBarry Smith }
431d7bf68aeSBarry Smith 
432d7bf68aeSBarry Smith #undef __FUNCT__
433d7bf68aeSBarry Smith #define __FUNCT__ "DMSetFromOptions"
434d7bf68aeSBarry Smith /*@
435d7bf68aeSBarry Smith     DMSetFromOptions - sets parameters in a DM from the options database
436d7bf68aeSBarry Smith 
437d7bf68aeSBarry Smith     Collective on DM
438d7bf68aeSBarry Smith 
439d7bf68aeSBarry Smith     Input Parameter:
440d7bf68aeSBarry Smith .   dm - the DM object to set options for
441d7bf68aeSBarry Smith 
442732e2eb9SMatthew G Knepley     Options Database:
443dd85299cSBarry Smith +   -dm_preallocate_only: Only preallocate the matrix for DMCreateMatrix(), but do not fill it with zeros
444dd85299cSBarry Smith .   -dm_vec_type <type>  type of vector to create inside DM
445171400e9SBarry Smith .   -dm_mat_type <type>  type of matrix to create inside DM
446171400e9SBarry Smith -   -dm_coloring_type <global or ghosted>
447732e2eb9SMatthew G Knepley 
448d7bf68aeSBarry Smith     Level: developer
449d7bf68aeSBarry Smith 
450e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
451d7bf68aeSBarry Smith 
452d7bf68aeSBarry Smith @*/
4537087cfbeSBarry Smith PetscErrorCode  DMSetFromOptions(DM dm)
454d7bf68aeSBarry Smith {
45567ad5babSMatthew G Knepley   PetscBool      flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg;
456d7bf68aeSBarry Smith   PetscErrorCode ierr;
457f9ba7244SBarry Smith   char           typeName[256] = MATAIJ;
458d7bf68aeSBarry Smith 
459d7bf68aeSBarry Smith   PetscFunctionBegin;
460171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4613194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)dm);CHKERRQ(ierr);
46282fcb398SMatthew G Knepley     ierr = PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);CHKERRQ(ierr);
463c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_detail", "Exhaustive mesh description", "DMView", flg2, &flg2, PETSC_NULL);CHKERRQ(ierr);
464c4721b0eSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_vtk", "Output mesh in VTK format", "DMView", flg3, &flg3, PETSC_NULL);CHKERRQ(ierr);
46567ad5babSMatthew G Knepley     ierr = PetscOptionsBool("-dm_view_latex", "Output mesh in LaTeX TikZ format", "DMView", flg4, &flg4, PETSC_NULL);CHKERRQ(ierr);
466073dac72SJed 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);
467f9ba7244SBarry Smith     ierr = PetscOptionsList("-dm_vec_type","Vector type used for created vectors","DMSetVecType",VecList,dm->vectype,typeName,256,&flg);CHKERRQ(ierr);
468f9ba7244SBarry Smith     if (flg) {
469f9ba7244SBarry Smith       ierr = DMSetVecType(dm,typeName);CHKERRQ(ierr);
470f9ba7244SBarry Smith     }
4718caf3d72SBarry 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);
472073dac72SJed Brown     if (flg) {
473521d9a4cSLisandro Dalcin       ierr = DMSetMatType(dm,typeName);CHKERRQ(ierr);
474073dac72SJed Brown     }
4751b89239cSHong 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);
476f9ba7244SBarry Smith     if (dm->ops->setfromoptions) {
477f9ba7244SBarry Smith       ierr = (*dm->ops->setfromoptions)(dm);CHKERRQ(ierr);
478f9ba7244SBarry Smith     }
479f9ba7244SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
480f9ba7244SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject) dm);CHKERRQ(ierr);
48182fcb398SMatthew G Knepley   ierr = PetscOptionsEnd();CHKERRQ(ierr);
48282fcb398SMatthew G Knepley   if (flg1) {
48382fcb398SMatthew G Knepley     ierr = DMView(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
48482fcb398SMatthew G Knepley   }
485c4721b0eSMatthew G Knepley   if (flg2) {
486c4721b0eSMatthew G Knepley     PetscViewer viewer;
487c4721b0eSMatthew G Knepley 
488c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
489c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
490c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
491c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
492c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
493c4721b0eSMatthew G Knepley   }
494c4721b0eSMatthew G Knepley   if (flg3) {
495c4721b0eSMatthew G Knepley     PetscViewer viewer;
496c4721b0eSMatthew G Knepley 
497c4721b0eSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
498c4721b0eSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
499c4721b0eSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr);
500c4721b0eSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.vtk");CHKERRQ(ierr);
501c4721b0eSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
502c4721b0eSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
503c4721b0eSMatthew G Knepley   }
50467ad5babSMatthew G Knepley   if (flg4) {
50567ad5babSMatthew G Knepley     PetscViewer viewer;
50667ad5babSMatthew G Knepley 
50767ad5babSMatthew G Knepley     ierr = PetscViewerCreate(((PetscObject) dm)->comm, &viewer);CHKERRQ(ierr);
50867ad5babSMatthew G Knepley     ierr = PetscViewerSetType(viewer, PETSCVIEWERASCII);CHKERRQ(ierr);
50967ad5babSMatthew G Knepley     ierr = PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_LATEX);CHKERRQ(ierr);
51067ad5babSMatthew G Knepley     ierr = PetscViewerFileSetName(viewer, "mesh.tex");CHKERRQ(ierr);
51167ad5babSMatthew G Knepley     ierr = DMView(dm, viewer);CHKERRQ(ierr);
51267ad5babSMatthew G Knepley     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
51367ad5babSMatthew G Knepley   }
514d7bf68aeSBarry Smith   PetscFunctionReturn(0);
515d7bf68aeSBarry Smith }
516d7bf68aeSBarry Smith 
517d7bf68aeSBarry Smith #undef __FUNCT__
51847c6ae99SBarry Smith #define __FUNCT__ "DMView"
519fc9bc008SSatish Balay /*@C
520aa219208SBarry Smith     DMView - Views a vector packer or DMDA.
52147c6ae99SBarry Smith 
52247c6ae99SBarry Smith     Collective on DM
52347c6ae99SBarry Smith 
52447c6ae99SBarry Smith     Input Parameter:
52547c6ae99SBarry Smith +   dm - the DM object to view
52647c6ae99SBarry Smith -   v - the viewer
52747c6ae99SBarry Smith 
52847c6ae99SBarry Smith     Level: developer
52947c6ae99SBarry Smith 
530e727c939SJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
53147c6ae99SBarry Smith 
53247c6ae99SBarry Smith @*/
5337087cfbeSBarry Smith PetscErrorCode  DMView(DM dm,PetscViewer v)
53447c6ae99SBarry Smith {
53547c6ae99SBarry Smith   PetscErrorCode ierr;
53632c0f0efSBarry Smith   PetscBool      isbinary;
53747c6ae99SBarry Smith 
53847c6ae99SBarry Smith   PetscFunctionBegin;
539171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5403014e516SBarry Smith   if (!v) {
5413014e516SBarry Smith     ierr = PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);CHKERRQ(ierr);
5423014e516SBarry Smith   }
54332c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)v,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
54432c0f0efSBarry Smith   if (isbinary) {
54555849f57SBarry Smith     PetscInt         classid = DM_FILE_CLASSID;
54632c0f0efSBarry Smith     char             type[256];
54732c0f0efSBarry Smith 
54832c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
54932c0f0efSBarry Smith     ierr = PetscStrncpy(type,((PetscObject)dm)->type_name,256);CHKERRQ(ierr);
55032c0f0efSBarry Smith     ierr = PetscViewerBinaryWrite(v,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
55132c0f0efSBarry Smith   }
5520c010503SBarry Smith   if (dm->ops->view) {
5530c010503SBarry Smith     ierr = (*dm->ops->view)(dm,v);CHKERRQ(ierr);
55447c6ae99SBarry Smith   }
55547c6ae99SBarry Smith   PetscFunctionReturn(0);
55647c6ae99SBarry Smith }
55747c6ae99SBarry Smith 
558ba654b55SMatthew G Knepley PETSC_EXTERN PetscErrorCode VecView_Complex_Local(Vec, PetscViewer);
559ba654b55SMatthew G Knepley PETSC_EXTERN PetscErrorCode VecView_Complex(Vec, PetscViewer);
560ba654b55SMatthew G Knepley 
56147c6ae99SBarry Smith #undef __FUNCT__
56247c6ae99SBarry Smith #define __FUNCT__ "DMCreateGlobalVector"
56347c6ae99SBarry Smith /*@
564aa219208SBarry Smith     DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
56547c6ae99SBarry Smith 
56647c6ae99SBarry Smith     Collective on DM
56747c6ae99SBarry Smith 
56847c6ae99SBarry Smith     Input Parameter:
56947c6ae99SBarry Smith .   dm - the DM object
57047c6ae99SBarry Smith 
57147c6ae99SBarry Smith     Output Parameter:
57247c6ae99SBarry Smith .   vec - the global vector
57347c6ae99SBarry Smith 
574073dac72SJed Brown     Level: beginner
57547c6ae99SBarry Smith 
576e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
57747c6ae99SBarry Smith 
57847c6ae99SBarry Smith @*/
5797087cfbeSBarry Smith PetscErrorCode  DMCreateGlobalVector(DM dm,Vec *vec)
58047c6ae99SBarry Smith {
58147c6ae99SBarry Smith   PetscErrorCode ierr;
58247c6ae99SBarry Smith 
58347c6ae99SBarry Smith   PetscFunctionBegin;
584171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
58588ed4aceSMatthew G Knepley   if (dm->defaultSection) {
58688ed4aceSMatthew G Knepley     PetscSection gSection;
5871f588964SMatthew G Knepley     PetscInt     localSize, blockSize = -1, pStart, pEnd, p;
58888ed4aceSMatthew G Knepley 
58988ed4aceSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
5901f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
5911f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
5921f588964SMatthew G Knepley       PetscInt dof, cdof;
5931f588964SMatthew G Knepley 
5941f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
5951f588964SMatthew G Knepley       ierr = PetscSectionGetConstraintDof(dm->defaultSection, p, &cdof);CHKERRQ(ierr);
5961f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof-cdof;
5971f588964SMatthew G Knepley       if ((dof > 0) && (dof-cdof != blockSize)) {
5981f588964SMatthew G Knepley         blockSize = 1;
5991f588964SMatthew G Knepley         break;
6001f588964SMatthew G Knepley       }
6011f588964SMatthew G Knepley     }
60288ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstrainedStorageSize(dm->defaultGlobalSection, &localSize);CHKERRQ(ierr);
6031f588964SMatthew G Knepley     if (localSize%blockSize) SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONG, "Mismatch between blocksize %d and local storage size %d", blockSize, localSize);
60488ed4aceSMatthew G Knepley     ierr = VecCreate(((PetscObject) dm)->comm, vec);CHKERRQ(ierr);
60588ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, PETSC_DETERMINE);CHKERRQ(ierr);
6061f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
60788ed4aceSMatthew G Knepley     /* ierr = VecSetType(*vec, dm->vectype);CHKERRQ(ierr); */
60888ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
609c688c046SMatthew G Knepley     ierr = VecSetDM(*vec, dm);CHKERRQ(ierr);
61088ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMapping(*vec, dm->ltogmap);CHKERRQ(ierr); */
61188ed4aceSMatthew G Knepley     /* ierr = VecSetLocalToGlobalMappingBlock(*vec, dm->ltogmapb);CHKERRQ(ierr); */
61288ed4aceSMatthew G Knepley     /* ierr = VecSetOperation(*vec, VECOP_DUPLICATE, (void(*)(void)) VecDuplicate_MPI_DM);CHKERRQ(ierr); */
613ba654b55SMatthew G Knepley     ierr = VecSetOperation(*vec, VECOP_VIEW, (void(*)(void)) VecView_Complex);CHKERRQ(ierr);
61488ed4aceSMatthew G Knepley   } else {
61547c6ae99SBarry Smith     ierr = (*dm->ops->createglobalvector)(dm,vec);CHKERRQ(ierr);
61688ed4aceSMatthew G Knepley   }
61747c6ae99SBarry Smith   PetscFunctionReturn(0);
61847c6ae99SBarry Smith }
61947c6ae99SBarry Smith 
62047c6ae99SBarry Smith #undef __FUNCT__
62147c6ae99SBarry Smith #define __FUNCT__ "DMCreateLocalVector"
62247c6ae99SBarry Smith /*@
623aa219208SBarry Smith     DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
62447c6ae99SBarry Smith 
62547c6ae99SBarry Smith     Not Collective
62647c6ae99SBarry Smith 
62747c6ae99SBarry Smith     Input Parameter:
62847c6ae99SBarry Smith .   dm - the DM object
62947c6ae99SBarry Smith 
63047c6ae99SBarry Smith     Output Parameter:
63147c6ae99SBarry Smith .   vec - the local vector
63247c6ae99SBarry Smith 
633073dac72SJed Brown     Level: beginner
63447c6ae99SBarry Smith 
635e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
63647c6ae99SBarry Smith 
63747c6ae99SBarry Smith @*/
6387087cfbeSBarry Smith PetscErrorCode  DMCreateLocalVector(DM dm,Vec *vec)
63947c6ae99SBarry Smith {
64047c6ae99SBarry Smith   PetscErrorCode ierr;
64147c6ae99SBarry Smith 
64247c6ae99SBarry Smith   PetscFunctionBegin;
643171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
64488ed4aceSMatthew G Knepley   if (dm->defaultSection) {
6451f588964SMatthew G Knepley     PetscInt localSize, blockSize = -1, pStart, pEnd, p;
64688ed4aceSMatthew G Knepley 
6471f588964SMatthew G Knepley     ierr = PetscSectionGetChart(dm->defaultSection, &pStart, &pEnd);CHKERRQ(ierr);
6481f588964SMatthew G Knepley     for(p = pStart; p < pEnd; ++p) {
6491f588964SMatthew G Knepley       PetscInt dof;
6501f588964SMatthew G Knepley 
6511f588964SMatthew G Knepley       ierr = PetscSectionGetDof(dm->defaultSection, p, &dof);CHKERRQ(ierr);
6521f588964SMatthew G Knepley       if ((blockSize < 0) && (dof > 0)) blockSize = dof;
6531f588964SMatthew G Knepley       if ((dof > 0) && (dof != blockSize)) {
6541f588964SMatthew G Knepley         blockSize = 1;
6551f588964SMatthew G Knepley         break;
6561f588964SMatthew G Knepley       }
6571f588964SMatthew G Knepley     }
65888ed4aceSMatthew G Knepley     ierr = PetscSectionGetStorageSize(dm->defaultSection, &localSize);CHKERRQ(ierr);
65988ed4aceSMatthew G Knepley     ierr = VecCreate(PETSC_COMM_SELF, vec);CHKERRQ(ierr);
66088ed4aceSMatthew G Knepley     ierr = VecSetSizes(*vec, localSize, localSize);CHKERRQ(ierr);
6611f588964SMatthew G Knepley     ierr = VecSetBlockSize(*vec, blockSize);CHKERRQ(ierr);
66288ed4aceSMatthew G Knepley     ierr = VecSetFromOptions(*vec);CHKERRQ(ierr);
663c688c046SMatthew G Knepley     ierr = VecSetDM(*vec, dm);CHKERRQ(ierr);
664ba654b55SMatthew G Knepley     ierr = VecSetOperation(*vec, VECOP_VIEW, (void(*)(void)) VecView_Complex_Local);CHKERRQ(ierr);
66588ed4aceSMatthew G Knepley   } else {
66647c6ae99SBarry Smith     ierr = (*dm->ops->createlocalvector)(dm,vec);CHKERRQ(ierr);
66788ed4aceSMatthew G Knepley   }
66847c6ae99SBarry Smith   PetscFunctionReturn(0);
66947c6ae99SBarry Smith }
67047c6ae99SBarry Smith 
67147c6ae99SBarry Smith #undef __FUNCT__
6721411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMapping"
6731411c6eeSJed Brown /*@
6741411c6eeSJed Brown    DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
6751411c6eeSJed Brown 
6761411c6eeSJed Brown    Collective on DM
6771411c6eeSJed Brown 
6781411c6eeSJed Brown    Input Parameter:
6791411c6eeSJed Brown .  dm - the DM that provides the mapping
6801411c6eeSJed Brown 
6811411c6eeSJed Brown    Output Parameter:
6821411c6eeSJed Brown .  ltog - the mapping
6831411c6eeSJed Brown 
6841411c6eeSJed Brown    Level: intermediate
6851411c6eeSJed Brown 
6861411c6eeSJed Brown    Notes:
6871411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMapping() or
6881411c6eeSJed Brown    MatSetLocalToGlobalMapping().
6891411c6eeSJed Brown 
6901411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
6911411c6eeSJed Brown @*/
6927087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
6931411c6eeSJed Brown {
6941411c6eeSJed Brown   PetscErrorCode ierr;
6951411c6eeSJed Brown 
6961411c6eeSJed Brown   PetscFunctionBegin;
6971411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6981411c6eeSJed Brown   PetscValidPointer(ltog,2);
6991411c6eeSJed Brown   if (!dm->ltogmap) {
70037d0c07bSMatthew G Knepley     PetscSection section, sectionGlobal;
70137d0c07bSMatthew G Knepley 
70237d0c07bSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
70337d0c07bSMatthew G Knepley     if (section) {
70437d0c07bSMatthew G Knepley       PetscInt      *ltog;
70537d0c07bSMatthew G Knepley       PetscInt       pStart, pEnd, size, p, l;
70637d0c07bSMatthew G Knepley 
70737d0c07bSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
70837d0c07bSMatthew G Knepley       ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr);
70937d0c07bSMatthew G Knepley       ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr);
71037d0c07bSMatthew G Knepley       ierr = PetscMalloc(size * sizeof(PetscInt), &ltog);CHKERRQ(ierr); /* We want the local+overlap size */
71137d0c07bSMatthew G Knepley       for (p = pStart, l = 0; p < pEnd; ++p) {
71237d0c07bSMatthew G Knepley         PetscInt dof, off, c;
71337d0c07bSMatthew G Knepley 
71437d0c07bSMatthew G Knepley         /* Should probably use constrained dofs */
71537d0c07bSMatthew G Knepley         ierr = PetscSectionGetDof(section, p, &dof);CHKERRQ(ierr);
71637d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr);
71737d0c07bSMatthew G Knepley         for (c = 0; c < dof; ++c, ++l) {
71837d0c07bSMatthew G Knepley           ltog[l] = off+c;
71937d0c07bSMatthew G Knepley         }
72037d0c07bSMatthew G Knepley       }
72137d0c07bSMatthew G Knepley       ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, size, ltog, PETSC_OWN_POINTER, &dm->ltogmap);CHKERRQ(ierr);
72237d0c07bSMatthew G Knepley       ierr = PetscLogObjectParent(dm, dm->ltogmap);CHKERRQ(ierr);
72337d0c07bSMatthew G Knepley     } else {
7241411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
7251411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmapping)(dm);CHKERRQ(ierr);
7261411c6eeSJed Brown     }
72737d0c07bSMatthew G Knepley   }
7281411c6eeSJed Brown   *ltog = dm->ltogmap;
7291411c6eeSJed Brown   PetscFunctionReturn(0);
7301411c6eeSJed Brown }
7311411c6eeSJed Brown 
7321411c6eeSJed Brown #undef __FUNCT__
7331411c6eeSJed Brown #define __FUNCT__ "DMGetLocalToGlobalMappingBlock"
7341411c6eeSJed Brown /*@
7351411c6eeSJed Brown    DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
7361411c6eeSJed Brown 
7371411c6eeSJed Brown    Collective on DM
7381411c6eeSJed Brown 
7391411c6eeSJed Brown    Input Parameter:
7401411c6eeSJed Brown .  da - the distributed array that provides the mapping
7411411c6eeSJed Brown 
7421411c6eeSJed Brown    Output Parameter:
7431411c6eeSJed Brown .  ltog - the block mapping
7441411c6eeSJed Brown 
7451411c6eeSJed Brown    Level: intermediate
7461411c6eeSJed Brown 
7471411c6eeSJed Brown    Notes:
7481411c6eeSJed Brown    This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
7491411c6eeSJed Brown    MatSetLocalToGlobalMappingBlock().
7501411c6eeSJed Brown 
7511411c6eeSJed Brown .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
7521411c6eeSJed Brown @*/
7537087cfbeSBarry Smith PetscErrorCode  DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
7541411c6eeSJed Brown {
7551411c6eeSJed Brown   PetscErrorCode ierr;
7561411c6eeSJed Brown 
7571411c6eeSJed Brown   PetscFunctionBegin;
7581411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7591411c6eeSJed Brown   PetscValidPointer(ltog,2);
7601411c6eeSJed Brown   if (!dm->ltogmapb) {
7611411c6eeSJed Brown     PetscInt bs;
7621411c6eeSJed Brown     ierr = DMGetBlockSize(dm,&bs);CHKERRQ(ierr);
7631411c6eeSJed Brown     if (bs > 1) {
7641411c6eeSJed Brown       if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
7651411c6eeSJed Brown       ierr = (*dm->ops->createlocaltoglobalmappingblock)(dm);CHKERRQ(ierr);
7661411c6eeSJed Brown     } else {
7671411c6eeSJed Brown       ierr = DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);CHKERRQ(ierr);
7681411c6eeSJed Brown       ierr = PetscObjectReference((PetscObject)dm->ltogmapb);CHKERRQ(ierr);
7691411c6eeSJed Brown     }
7701411c6eeSJed Brown   }
7711411c6eeSJed Brown   *ltog = dm->ltogmapb;
7721411c6eeSJed Brown   PetscFunctionReturn(0);
7731411c6eeSJed Brown }
7741411c6eeSJed Brown 
7751411c6eeSJed Brown #undef __FUNCT__
7761411c6eeSJed Brown #define __FUNCT__ "DMGetBlockSize"
7771411c6eeSJed Brown /*@
7781411c6eeSJed Brown    DMGetBlockSize - Gets the inherent block size associated with a DM
7791411c6eeSJed Brown 
7801411c6eeSJed Brown    Not Collective
7811411c6eeSJed Brown 
7821411c6eeSJed Brown    Input Parameter:
7831411c6eeSJed Brown .  dm - the DM with block structure
7841411c6eeSJed Brown 
7851411c6eeSJed Brown    Output Parameter:
7861411c6eeSJed Brown .  bs - the block size, 1 implies no exploitable block structure
7871411c6eeSJed Brown 
7881411c6eeSJed Brown    Level: intermediate
7891411c6eeSJed Brown 
7901411c6eeSJed Brown .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
7911411c6eeSJed Brown @*/
7927087cfbeSBarry Smith PetscErrorCode  DMGetBlockSize(DM dm,PetscInt *bs)
7931411c6eeSJed Brown {
7941411c6eeSJed Brown   PetscFunctionBegin;
7951411c6eeSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7961411c6eeSJed Brown   PetscValidPointer(bs,2);
7971411c6eeSJed 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");
7981411c6eeSJed Brown   *bs = dm->bs;
7991411c6eeSJed Brown   PetscFunctionReturn(0);
8001411c6eeSJed Brown }
8011411c6eeSJed Brown 
8021411c6eeSJed Brown #undef __FUNCT__
803e727c939SJed Brown #define __FUNCT__ "DMCreateInterpolation"
80447c6ae99SBarry Smith /*@
805e727c939SJed Brown     DMCreateInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
80647c6ae99SBarry Smith 
80747c6ae99SBarry Smith     Collective on DM
80847c6ae99SBarry Smith 
80947c6ae99SBarry Smith     Input Parameter:
81047c6ae99SBarry Smith +   dm1 - the DM object
81147c6ae99SBarry Smith -   dm2 - the second, finer DM object
81247c6ae99SBarry Smith 
81347c6ae99SBarry Smith     Output Parameter:
81447c6ae99SBarry Smith +  mat - the interpolation
81547c6ae99SBarry Smith -  vec - the scaling (optional)
81647c6ae99SBarry Smith 
81747c6ae99SBarry Smith     Level: developer
81847c6ae99SBarry Smith 
81985afcc9aSBarry 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
82085afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
821d52bd9f3SBarry Smith 
8221f588964SMatthew G Knepley         For DMDA objects you can use this interpolation (more precisely the interpolation from the DMGetCoordinateDM()) to interpolate the mesh coordinate vectors
823d52bd9f3SBarry Smith         EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
82485afcc9aSBarry Smith 
82585afcc9aSBarry Smith 
826e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMRefine(), DMCoarsen()
82747c6ae99SBarry Smith 
82847c6ae99SBarry Smith @*/
829e727c939SJed Brown PetscErrorCode  DMCreateInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
83047c6ae99SBarry Smith {
83147c6ae99SBarry Smith   PetscErrorCode ierr;
83247c6ae99SBarry Smith 
83347c6ae99SBarry Smith   PetscFunctionBegin;
834171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
835171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
83625296bd5SBarry Smith   ierr = (*dm1->ops->createinterpolation)(dm1,dm2,mat,vec);CHKERRQ(ierr);
83747c6ae99SBarry Smith   PetscFunctionReturn(0);
83847c6ae99SBarry Smith }
83947c6ae99SBarry Smith 
84047c6ae99SBarry Smith #undef __FUNCT__
841e727c939SJed Brown #define __FUNCT__ "DMCreateInjection"
84247c6ae99SBarry Smith /*@
843e727c939SJed Brown     DMCreateInjection - Gets injection matrix between two DMDA or DMComposite objects
84447c6ae99SBarry Smith 
84547c6ae99SBarry Smith     Collective on DM
84647c6ae99SBarry Smith 
84747c6ae99SBarry Smith     Input Parameter:
84847c6ae99SBarry Smith +   dm1 - the DM object
84947c6ae99SBarry Smith -   dm2 - the second, finer DM object
85047c6ae99SBarry Smith 
85147c6ae99SBarry Smith     Output Parameter:
85247c6ae99SBarry Smith .   ctx - the injection
85347c6ae99SBarry Smith 
85447c6ae99SBarry Smith     Level: developer
85547c6ae99SBarry Smith 
85685afcc9aSBarry 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
85785afcc9aSBarry Smith         DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
85885afcc9aSBarry Smith 
859e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateColoring(), DMCreateMatrix(), DMCreateInterpolation()
86047c6ae99SBarry Smith 
86147c6ae99SBarry Smith @*/
862e727c939SJed Brown PetscErrorCode  DMCreateInjection(DM dm1,DM dm2,VecScatter *ctx)
86347c6ae99SBarry Smith {
86447c6ae99SBarry Smith   PetscErrorCode ierr;
86547c6ae99SBarry Smith 
86647c6ae99SBarry Smith   PetscFunctionBegin;
867171400e9SBarry Smith   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
868171400e9SBarry Smith   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
86947c6ae99SBarry Smith   ierr = (*dm1->ops->getinjection)(dm1,dm2,ctx);CHKERRQ(ierr);
87047c6ae99SBarry Smith   PetscFunctionReturn(0);
87147c6ae99SBarry Smith }
87247c6ae99SBarry Smith 
87347c6ae99SBarry Smith #undef __FUNCT__
874e727c939SJed Brown #define __FUNCT__ "DMCreateColoring"
875d1e2c406SBarry Smith /*@C
876e727c939SJed Brown     DMCreateColoring - Gets coloring for a DMDA or DMComposite
87747c6ae99SBarry Smith 
87847c6ae99SBarry Smith     Collective on DM
87947c6ae99SBarry Smith 
88047c6ae99SBarry Smith     Input Parameter:
88147c6ae99SBarry Smith +   dm - the DM object
88247c6ae99SBarry Smith .   ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
88347c6ae99SBarry Smith -   matype - either MATAIJ or MATBAIJ
88447c6ae99SBarry Smith 
88547c6ae99SBarry Smith     Output Parameter:
88647c6ae99SBarry Smith .   coloring - the coloring
88747c6ae99SBarry Smith 
88847c6ae99SBarry Smith     Level: developer
88947c6ae99SBarry Smith 
890e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateMatrix()
89147c6ae99SBarry Smith 
892aab9d709SJed Brown @*/
89319fd82e9SBarry Smith PetscErrorCode  DMCreateColoring(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring)
89447c6ae99SBarry Smith {
89547c6ae99SBarry Smith   PetscErrorCode ierr;
89647c6ae99SBarry Smith 
89747c6ae99SBarry Smith   PetscFunctionBegin;
898171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
89947c6ae99SBarry Smith   if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
90047c6ae99SBarry Smith   ierr = (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);CHKERRQ(ierr);
90147c6ae99SBarry Smith   PetscFunctionReturn(0);
90247c6ae99SBarry Smith }
90347c6ae99SBarry Smith 
90447c6ae99SBarry Smith #undef __FUNCT__
905950540a4SJed Brown #define __FUNCT__ "DMCreateMatrix"
90647c6ae99SBarry Smith /*@C
907950540a4SJed Brown     DMCreateMatrix - Gets empty Jacobian for a DMDA or DMComposite
90847c6ae99SBarry Smith 
90947c6ae99SBarry Smith     Collective on DM
91047c6ae99SBarry Smith 
91147c6ae99SBarry Smith     Input Parameter:
91247c6ae99SBarry Smith +   dm - the DM object
91347c6ae99SBarry Smith -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
91494013140SBarry Smith             any type which inherits from one of these (such as MATAIJ)
91547c6ae99SBarry Smith 
91647c6ae99SBarry Smith     Output Parameter:
91747c6ae99SBarry Smith .   mat - the empty Jacobian
91847c6ae99SBarry Smith 
919073dac72SJed Brown     Level: beginner
92047c6ae99SBarry Smith 
92194013140SBarry Smith     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
92294013140SBarry Smith        do not need to do it yourself.
92394013140SBarry Smith 
92494013140SBarry Smith        By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
925aa219208SBarry Smith        the nonzero pattern call DMDASetMatPreallocateOnly()
92694013140SBarry Smith 
92794013140SBarry 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
92894013140SBarry Smith        internally by PETSc.
92994013140SBarry Smith 
93094013140SBarry Smith        For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
931aa219208SBarry Smith        the indices for the global numbering for DMDAs which is complicated.
93294013140SBarry Smith 
933e727c939SJed Brown .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
93447c6ae99SBarry Smith 
935aab9d709SJed Brown @*/
93619fd82e9SBarry Smith PetscErrorCode  DMCreateMatrix(DM dm,MatType mtype,Mat *mat)
93747c6ae99SBarry Smith {
93847c6ae99SBarry Smith   PetscErrorCode ierr;
93947c6ae99SBarry Smith 
94047c6ae99SBarry Smith   PetscFunctionBegin;
941171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
942235683edSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
943235683edSBarry Smith   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
944235683edSBarry Smith #endif
945c7b7c8a4SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
946c7b7c8a4SJed Brown   PetscValidPointer(mat,3);
947073dac72SJed Brown   if (dm->mattype) {
94825296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,dm->mattype,mat);CHKERRQ(ierr);
949073dac72SJed Brown   } else {
95025296bd5SBarry Smith     ierr = (*dm->ops->creatematrix)(dm,mtype,mat);CHKERRQ(ierr);
951c7b7c8a4SJed Brown   }
95247c6ae99SBarry Smith   PetscFunctionReturn(0);
95347c6ae99SBarry Smith }
95447c6ae99SBarry Smith 
95547c6ae99SBarry Smith #undef __FUNCT__
956732e2eb9SMatthew G Knepley #define __FUNCT__ "DMSetMatrixPreallocateOnly"
957732e2eb9SMatthew G Knepley /*@
958950540a4SJed Brown   DMSetMatrixPreallocateOnly - When DMCreateMatrix() is called the matrix will be properly
959732e2eb9SMatthew G Knepley     preallocated but the nonzero structure and zero values will not be set.
960732e2eb9SMatthew G Knepley 
961732e2eb9SMatthew G Knepley   Logically Collective on DMDA
962732e2eb9SMatthew G Knepley 
963732e2eb9SMatthew G Knepley   Input Parameter:
964732e2eb9SMatthew G Knepley + dm - the DM
965732e2eb9SMatthew G Knepley - only - PETSC_TRUE if only want preallocation
966732e2eb9SMatthew G Knepley 
967732e2eb9SMatthew G Knepley   Level: developer
968950540a4SJed Brown .seealso DMCreateMatrix()
969732e2eb9SMatthew G Knepley @*/
970732e2eb9SMatthew G Knepley PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
971732e2eb9SMatthew G Knepley {
972732e2eb9SMatthew G Knepley   PetscFunctionBegin;
973732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
974732e2eb9SMatthew G Knepley   dm->prealloc_only = only;
975732e2eb9SMatthew G Knepley   PetscFunctionReturn(0);
976732e2eb9SMatthew G Knepley }
977732e2eb9SMatthew G Knepley 
978732e2eb9SMatthew G Knepley #undef __FUNCT__
979a89ea682SMatthew G Knepley #define __FUNCT__ "DMGetWorkArray"
980a89ea682SMatthew G Knepley /*@C
981aa1993deSMatthew G Knepley   DMGetWorkArray - Gets a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
982a89ea682SMatthew G Knepley 
983a89ea682SMatthew G Knepley   Not Collective
984a89ea682SMatthew G Knepley 
985a89ea682SMatthew G Knepley   Input Parameters:
986a89ea682SMatthew G Knepley + dm - the DM object
987aa1993deSMatthew G Knepley . count - The minium size
988aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
989a89ea682SMatthew G Knepley 
990a89ea682SMatthew G Knepley   Output Parameter:
991a89ea682SMatthew G Knepley . array - the work array
992a89ea682SMatthew G Knepley 
993a89ea682SMatthew G Knepley   Level: developer
994a89ea682SMatthew G Knepley 
995a89ea682SMatthew G Knepley .seealso DMDestroy(), DMCreate()
996a89ea682SMatthew G Knepley @*/
997aa1993deSMatthew G Knepley PetscErrorCode DMGetWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
998a89ea682SMatthew G Knepley {
999a89ea682SMatthew G Knepley   PetscErrorCode ierr;
1000aa1993deSMatthew G Knepley   DMWorkLink link;
1001aa1993deSMatthew G Knepley   size_t size;
1002a89ea682SMatthew G Knepley 
1003a89ea682SMatthew G Knepley   PetscFunctionBegin;
1004a89ea682SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1005aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1006aa1993deSMatthew G Knepley   if (dm->workin) {
1007aa1993deSMatthew G Knepley     link = dm->workin;
1008aa1993deSMatthew G Knepley     dm->workin = dm->workin->next;
1009aa1993deSMatthew G Knepley   } else {
1010aa1993deSMatthew G Knepley     ierr = PetscNewLog(dm,struct _DMWorkLink,&link);CHKERRQ(ierr);
1011a89ea682SMatthew G Knepley   }
1012aa1993deSMatthew G Knepley   ierr = PetscDataTypeGetSize(dtype,&size);CHKERRQ(ierr);
1013aa1993deSMatthew G Knepley   if (size*count > link->bytes) {
1014aa1993deSMatthew G Knepley     ierr = PetscFree(link->mem);CHKERRQ(ierr);
1015aa1993deSMatthew G Knepley     ierr = PetscMalloc(size*count,&link->mem);CHKERRQ(ierr);
1016aa1993deSMatthew G Knepley     link->bytes = size*count;
1017aa1993deSMatthew G Knepley   }
1018aa1993deSMatthew G Knepley   link->next = dm->workout;
1019aa1993deSMatthew G Knepley   dm->workout = link;
1020aa1993deSMatthew G Knepley   *(void**)mem = link->mem;
1021a89ea682SMatthew G Knepley   PetscFunctionReturn(0);
1022a89ea682SMatthew G Knepley }
1023a89ea682SMatthew G Knepley 
1024aa1993deSMatthew G Knepley #undef __FUNCT__
1025aa1993deSMatthew G Knepley #define __FUNCT__ "DMRestoreWorkArray"
1026aa1993deSMatthew G Knepley /*@C
1027aa1993deSMatthew G Knepley   DMRestoreWorkArray - Restores a work array guaranteed to be at least the input size, restore with DMRestoreWorkArray()
1028aa1993deSMatthew G Knepley 
1029aa1993deSMatthew G Knepley   Not Collective
1030aa1993deSMatthew G Knepley 
1031aa1993deSMatthew G Knepley   Input Parameters:
1032aa1993deSMatthew G Knepley + dm - the DM object
1033aa1993deSMatthew G Knepley . count - The minium size
1034aa1993deSMatthew G Knepley - dtype - data type (PETSC_REAL, PETSC_SCALAR, PETSC_INT)
1035aa1993deSMatthew G Knepley 
1036aa1993deSMatthew G Knepley   Output Parameter:
1037aa1993deSMatthew G Knepley . array - the work array
1038aa1993deSMatthew G Knepley 
1039aa1993deSMatthew G Knepley   Level: developer
1040aa1993deSMatthew G Knepley 
1041aa1993deSMatthew G Knepley .seealso DMDestroy(), DMCreate()
1042aa1993deSMatthew G Knepley @*/
1043aa1993deSMatthew G Knepley PetscErrorCode DMRestoreWorkArray(DM dm,PetscInt count,PetscDataType dtype,void *mem)
1044aa1993deSMatthew G Knepley {
1045aa1993deSMatthew G Knepley   DMWorkLink *p,link;
1046aa1993deSMatthew G Knepley 
1047aa1993deSMatthew G Knepley   PetscFunctionBegin;
1048aa1993deSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1049aa1993deSMatthew G Knepley   PetscValidPointer(mem,4);
1050aa1993deSMatthew G Knepley   for (p=&dm->workout; (link=*p); p=&link->next) {
1051aa1993deSMatthew G Knepley     if (link->mem == *(void**)mem) {
1052aa1993deSMatthew G Knepley       *p = link->next;
1053aa1993deSMatthew G Knepley       link->next = dm->workin;
1054aa1993deSMatthew G Knepley       dm->workin = link;
1055aa1993deSMatthew G Knepley       *(void**)mem = PETSC_NULL;
1056aa1993deSMatthew G Knepley       PetscFunctionReturn(0);
1057aa1993deSMatthew G Knepley     }
1058aa1993deSMatthew G Knepley   }
1059aa1993deSMatthew G Knepley   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Array was not checked out");
1060aa1993deSMatthew G Knepley   PetscFunctionReturn(0);
1061aa1993deSMatthew G Knepley }
1062e7c4fc90SDmitry Karpeev 
1063e7c4fc90SDmitry Karpeev #undef __FUNCT__
1064435a35e8SMatthew G Knepley #define __FUNCT__ "DMSetNullSpaceConstructor"
1065435a35e8SMatthew G Knepley PetscErrorCode DMSetNullSpaceConstructor(DM dm, PetscInt field, PetscErrorCode (*nullsp)(DM dm, PetscInt field, MatNullSpace *nullSpace))
1066435a35e8SMatthew G Knepley {
1067435a35e8SMatthew G Knepley   PetscFunctionBegin;
1068435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1069435a35e8SMatthew G Knepley   if (field >= 10) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %d >= 10 fields", field);
1070435a35e8SMatthew G Knepley   dm->nullspaceConstructors[field] = nullsp;
1071435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1072435a35e8SMatthew G Knepley }
1073435a35e8SMatthew G Knepley 
1074435a35e8SMatthew G Knepley #undef __FUNCT__
10754d343eeaSMatthew G Knepley #define __FUNCT__ "DMCreateFieldIS"
10764f3b5142SJed Brown /*@C
10774d343eeaSMatthew G Knepley   DMCreateFieldIS - Creates a set of IS objects with the global indices of dofs for each field
10784d343eeaSMatthew G Knepley 
10794d343eeaSMatthew G Knepley   Not collective
10804d343eeaSMatthew G Knepley 
10814d343eeaSMatthew G Knepley   Input Parameter:
10824d343eeaSMatthew G Knepley . dm - the DM object
10834d343eeaSMatthew G Knepley 
10844d343eeaSMatthew G Knepley   Output Parameters:
108521c9b008SJed Brown + numFields  - The number of fields (or PETSC_NULL if not requested)
108637d0c07bSMatthew G Knepley . fieldNames - The name for each field (or PETSC_NULL if not requested)
108721c9b008SJed Brown - fields     - The global indices for each field (or PETSC_NULL if not requested)
10884d343eeaSMatthew G Knepley 
10894d343eeaSMatthew G Knepley   Level: intermediate
10904d343eeaSMatthew G Knepley 
109121c9b008SJed Brown   Notes:
109221c9b008SJed Brown   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
109321c9b008SJed Brown   PetscFree(), every entry of fields should be destroyed with ISDestroy(), and both arrays should be freed with
109421c9b008SJed Brown   PetscFree().
109521c9b008SJed Brown 
10964d343eeaSMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix()
10974d343eeaSMatthew G Knepley @*/
109837d0c07bSMatthew G Knepley PetscErrorCode DMCreateFieldIS(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields)
10994d343eeaSMatthew G Knepley {
110037d0c07bSMatthew G Knepley   PetscSection   section, sectionGlobal;
11014d343eeaSMatthew G Knepley   PetscErrorCode ierr;
11024d343eeaSMatthew G Knepley 
11034d343eeaSMatthew G Knepley   PetscFunctionBegin;
11044d343eeaSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
110569ca1f37SDmitry Karpeev   if (numFields) {
110669ca1f37SDmitry Karpeev     PetscValidPointer(numFields,2);
110769ca1f37SDmitry Karpeev     *numFields = 0;
110869ca1f37SDmitry Karpeev   }
110937d0c07bSMatthew G Knepley   if (fieldNames) {
111037d0c07bSMatthew G Knepley     PetscValidPointer(fieldNames,3);
111137d0c07bSMatthew G Knepley     *fieldNames = PETSC_NULL;
111269ca1f37SDmitry Karpeev   }
111369ca1f37SDmitry Karpeev   if (fields) {
111469ca1f37SDmitry Karpeev     PetscValidPointer(fields,4);
111569ca1f37SDmitry Karpeev     *fields = PETSC_NULL;
111669ca1f37SDmitry Karpeev   }
111737d0c07bSMatthew G Knepley   ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
111837d0c07bSMatthew G Knepley   if (section) {
111937d0c07bSMatthew G Knepley     PetscInt *fieldSizes, **fieldIndices;
112037d0c07bSMatthew G Knepley     PetscInt  nF, f, pStart, pEnd, p;
112137d0c07bSMatthew G Knepley 
112237d0c07bSMatthew G Knepley     ierr = DMGetDefaultGlobalSection(dm, &sectionGlobal);CHKERRQ(ierr);
112337d0c07bSMatthew G Knepley     ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr);
112437d0c07bSMatthew G Knepley     ierr = PetscMalloc2(nF,PetscInt,&fieldSizes,nF,PetscInt *,&fieldIndices);CHKERRQ(ierr);
112537d0c07bSMatthew G Knepley     ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr);
112637d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
112737d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
112837d0c07bSMatthew G Knepley     }
112937d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
113037d0c07bSMatthew G Knepley       PetscInt gdof;
113137d0c07bSMatthew G Knepley 
113237d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
113337d0c07bSMatthew G Knepley       if (gdof > 0) {
113437d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
113537d0c07bSMatthew G Knepley           PetscInt fdof, fcdof;
113637d0c07bSMatthew G Knepley 
113737d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
113837d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
113937d0c07bSMatthew G Knepley           fieldSizes[f] += fdof-fcdof;
114037d0c07bSMatthew G Knepley         }
114137d0c07bSMatthew G Knepley       }
114237d0c07bSMatthew G Knepley     }
114337d0c07bSMatthew G Knepley     for (f = 0; f < nF; ++f) {
114437d0c07bSMatthew G Knepley       ierr = PetscMalloc(fieldSizes[f] * sizeof(PetscInt), &fieldIndices[f]);CHKERRQ(ierr);
114537d0c07bSMatthew G Knepley       fieldSizes[f] = 0;
114637d0c07bSMatthew G Knepley     }
114737d0c07bSMatthew G Knepley     for (p = pStart; p < pEnd; ++p) {
114837d0c07bSMatthew G Knepley       PetscInt gdof, goff;
114937d0c07bSMatthew G Knepley 
115037d0c07bSMatthew G Knepley       ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr);
115137d0c07bSMatthew G Knepley       if (gdof > 0) {
115237d0c07bSMatthew G Knepley         ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr);
115337d0c07bSMatthew G Knepley         for (f = 0; f < nF; ++f) {
115437d0c07bSMatthew G Knepley           PetscInt fdof, fcdof, fc;
115537d0c07bSMatthew G Knepley 
115637d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr);
115737d0c07bSMatthew G Knepley           ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr);
115837d0c07bSMatthew G Knepley           for (fc = 0; fc < fdof-fcdof; ++fc, ++fieldSizes[f]) {
115937d0c07bSMatthew G Knepley             fieldIndices[f][fieldSizes[f]] = goff++;
116037d0c07bSMatthew G Knepley           }
116137d0c07bSMatthew G Knepley         }
116237d0c07bSMatthew G Knepley       }
116337d0c07bSMatthew G Knepley     }
116437d0c07bSMatthew G Knepley     if (numFields) {*numFields = nF;}
116537d0c07bSMatthew G Knepley     if (fieldNames) {
116637d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(char *), fieldNames);CHKERRQ(ierr);
116737d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
116837d0c07bSMatthew G Knepley         const char *fieldName;
116937d0c07bSMatthew G Knepley 
117037d0c07bSMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
117137d0c07bSMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*fieldNames)[f]);CHKERRQ(ierr);
117237d0c07bSMatthew G Knepley       }
117337d0c07bSMatthew G Knepley     }
117437d0c07bSMatthew G Knepley     if (fields) {
117537d0c07bSMatthew G Knepley       ierr = PetscMalloc(nF * sizeof(IS), fields);CHKERRQ(ierr);
117637d0c07bSMatthew G Knepley       for (f = 0; f < nF; ++f) {
117737d0c07bSMatthew G Knepley         ierr = ISCreateGeneral(((PetscObject) dm)->comm, fieldSizes[f], fieldIndices[f], PETSC_OWN_POINTER, &(*fields)[f]);CHKERRQ(ierr);
117837d0c07bSMatthew G Knepley       }
117937d0c07bSMatthew G Knepley     }
118037d0c07bSMatthew G Knepley     ierr = PetscFree2(fieldSizes,fieldIndices);CHKERRQ(ierr);
118137d0c07bSMatthew G Knepley   } else {
118237d0c07bSMatthew G Knepley     if (dm->ops->createfieldis) {ierr = (*dm->ops->createfieldis)(dm, numFields, fieldNames, fields);CHKERRQ(ierr);}
118369ca1f37SDmitry Karpeev   }
11844d343eeaSMatthew G Knepley   PetscFunctionReturn(0);
11854d343eeaSMatthew G Knepley }
11864d343eeaSMatthew G Knepley 
1187a89ea682SMatthew G Knepley #undef __FUNCT__
118816621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecompositionDM"
1189e7c4fc90SDmitry Karpeev /*@C
119016621825SDmitry Karpeev   DMCreateFieldDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into fields.
119116621825SDmitry Karpeev 
119216621825SDmitry Karpeev   Not Collective
119316621825SDmitry Karpeev 
119416621825SDmitry Karpeev   Input Parameters:
119516621825SDmitry Karpeev + dm   - the DM object
119616621825SDmitry Karpeev - name - the name of the field decomposition
119716621825SDmitry Karpeev 
119816621825SDmitry Karpeev   Output Parameter:
119916621825SDmitry Karpeev . ddm  - the field decomposition DM (PETSC_NULL, if no such decomposition is known)
120016621825SDmitry Karpeev 
120116621825SDmitry Karpeev   Level: advanced
120216621825SDmitry Karpeev 
120316621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
120416621825SDmitry Karpeev @*/
120516621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecompositionDM(DM dm, const char* name, DM *ddm)
120616621825SDmitry Karpeev {
120716621825SDmitry Karpeev   PetscErrorCode ierr;
120816621825SDmitry Karpeev 
120916621825SDmitry Karpeev   PetscFunctionBegin;
121016621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
121116621825SDmitry Karpeev   PetscValidCharPointer(name,2);
121216621825SDmitry Karpeev   PetscValidPointer(ddm,3);
121316621825SDmitry Karpeev   *ddm = PETSC_NULL;
1214731c8d9eSDmitry Karpeev   if (dm->ops->createfielddecompositiondm) {
121516621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
121616621825SDmitry Karpeev   }
121716621825SDmitry Karpeev   PetscFunctionReturn(0);
121816621825SDmitry Karpeev }
121916621825SDmitry Karpeev 
122016621825SDmitry Karpeev #undef __FUNCT__
122116621825SDmitry Karpeev #define __FUNCT__ "DMCreateFieldDecomposition"
122216621825SDmitry Karpeev /*@C
122316621825SDmitry Karpeev   DMCreateFieldDecomposition - Returns a list of IS objects defining a decomposition of a problem into subproblems
122416621825SDmitry Karpeev                           corresponding to different fields: each IS contains the global indices of the dofs of the
122516621825SDmitry Karpeev                           corresponding field. The optional list of DMs define the DM for each subproblem.
1226e7c4fc90SDmitry Karpeev                           Generalizes DMCreateFieldIS().
1227e7c4fc90SDmitry Karpeev 
1228e7c4fc90SDmitry Karpeev   Not collective
1229e7c4fc90SDmitry Karpeev 
1230e7c4fc90SDmitry Karpeev   Input Parameter:
1231e7c4fc90SDmitry Karpeev . dm - the DM object
1232e7c4fc90SDmitry Karpeev 
1233e7c4fc90SDmitry Karpeev   Output Parameters:
123416621825SDmitry Karpeev + len       - The number of subproblems in the field decomposition (or PETSC_NULL if not requested)
123516621825SDmitry Karpeev . namelist  - The name for each field (or PETSC_NULL if not requested)
123616621825SDmitry Karpeev . islist    - The global indices for each field (or PETSC_NULL if not requested)
123716621825SDmitry Karpeev - dmlist    - The DMs for each field subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
1238e7c4fc90SDmitry Karpeev 
1239e7c4fc90SDmitry Karpeev   Level: intermediate
1240e7c4fc90SDmitry Karpeev 
1241e7c4fc90SDmitry Karpeev   Notes:
1242e7c4fc90SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
1243e7c4fc90SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
1244e7c4fc90SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
1245e7c4fc90SDmitry Karpeev 
1246e7c4fc90SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1247e7c4fc90SDmitry Karpeev @*/
124816621825SDmitry Karpeev PetscErrorCode DMCreateFieldDecomposition(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
1249e7c4fc90SDmitry Karpeev {
1250e7c4fc90SDmitry Karpeev   PetscErrorCode ierr;
1251e7c4fc90SDmitry Karpeev 
1252e7c4fc90SDmitry Karpeev   PetscFunctionBegin;
1253e7c4fc90SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1254731c8d9eSDmitry Karpeev   if (len)      {PetscValidPointer(len,2);      *len      = 0;}
1255731c8d9eSDmitry Karpeev   if (namelist) {PetscValidPointer(namelist,3); *namelist = 0;}
1256731c8d9eSDmitry Karpeev   if (islist)   {PetscValidPointer(islist,4);   *islist   = 0;}
1257731c8d9eSDmitry Karpeev   if (dmlist)   {PetscValidPointer(dmlist,5);   *dmlist   = 0;}
125816621825SDmitry Karpeev   if (!dm->ops->createfielddecomposition) {
1259435a35e8SMatthew G Knepley     PetscSection section;
1260435a35e8SMatthew G Knepley     PetscInt     numFields, f;
1261435a35e8SMatthew G Knepley 
1262435a35e8SMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
1263435a35e8SMatthew G Knepley     if (section) {ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr);}
1264435a35e8SMatthew G Knepley     if (section && numFields && dm->ops->createsubdm) {
1265435a35e8SMatthew G Knepley       *len = numFields;
1266435a35e8SMatthew G Knepley       ierr = PetscMalloc3(numFields,char*,namelist,numFields,IS,islist,numFields,DM,dmlist);CHKERRQ(ierr);
1267435a35e8SMatthew G Knepley       for (f = 0; f < numFields; ++f) {
1268435a35e8SMatthew G Knepley         const char *fieldName;
1269435a35e8SMatthew G Knepley 
1270435a35e8SMatthew G Knepley         ierr = DMCreateSubDM(dm, 1, &f, &(*islist)[f], &(*dmlist)[f]);CHKERRQ(ierr);
1271435a35e8SMatthew G Knepley         ierr = PetscSectionGetFieldName(section, f, &fieldName);CHKERRQ(ierr);
1272435a35e8SMatthew G Knepley         ierr = PetscStrallocpy(fieldName, (char **) &(*namelist)[f]);CHKERRQ(ierr);
1273435a35e8SMatthew G Knepley       }
1274435a35e8SMatthew G Knepley     } else {
127569ca1f37SDmitry Karpeev       ierr = DMCreateFieldIS(dm, len, namelist, islist);CHKERRQ(ierr);
1276e7c4fc90SDmitry Karpeev       /* By default there are no DMs associated with subproblems. */
1277e7c4fc90SDmitry Karpeev       if (dmlist) *dmlist = PETSC_NULL;
1278e7c4fc90SDmitry Karpeev     }
1279435a35e8SMatthew G Knepley   }
1280e7c4fc90SDmitry Karpeev   else {
128116621825SDmitry Karpeev     ierr = (*dm->ops->createfielddecomposition)(dm,len,namelist,islist,dmlist); CHKERRQ(ierr);
128216621825SDmitry Karpeev   }
128316621825SDmitry Karpeev   PetscFunctionReturn(0);
128416621825SDmitry Karpeev }
128516621825SDmitry Karpeev 
128616621825SDmitry Karpeev #undef __FUNCT__
1287435a35e8SMatthew G Knepley #define __FUNCT__ "DMCreateSubDM"
1288435a35e8SMatthew G Knepley /*@C
1289435a35e8SMatthew G Knepley   DMCreateSubDM - Returns an IS and DM encapsulating a subproblem defined by the fields passed in.
1290435a35e8SMatthew G Knepley                   The fields are defined by DMCreateFieldIS().
1291435a35e8SMatthew G Knepley 
1292435a35e8SMatthew G Knepley   Not collective
1293435a35e8SMatthew G Knepley 
1294435a35e8SMatthew G Knepley   Input Parameters:
1295435a35e8SMatthew G Knepley + dm - the DM object
1296435a35e8SMatthew G Knepley . numFields - number of fields in this subproblem
1297435a35e8SMatthew G Knepley - len       - The number of subproblems in the decomposition (or PETSC_NULL if not requested)
1298435a35e8SMatthew G Knepley 
1299435a35e8SMatthew G Knepley   Output Parameters:
1300435a35e8SMatthew G Knepley . is - The global indices for the subproblem
1301435a35e8SMatthew G Knepley - dm - The DM for the subproblem
1302435a35e8SMatthew G Knepley 
1303435a35e8SMatthew G Knepley   Level: intermediate
1304435a35e8SMatthew G Knepley 
1305435a35e8SMatthew G Knepley .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1306435a35e8SMatthew G Knepley @*/
1307435a35e8SMatthew G Knepley PetscErrorCode DMCreateSubDM(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1308435a35e8SMatthew G Knepley {
1309435a35e8SMatthew G Knepley   PetscErrorCode ierr;
1310435a35e8SMatthew G Knepley 
1311435a35e8SMatthew G Knepley   PetscFunctionBegin;
1312435a35e8SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1313435a35e8SMatthew G Knepley   PetscValidPointer(fields,3);
1314435a35e8SMatthew G Knepley   if (is) {PetscValidPointer(is,4);}
1315435a35e8SMatthew G Knepley   if (subdm) {PetscValidPointer(subdm,5);}
1316435a35e8SMatthew G Knepley   if (dm->ops->createsubdm) {
1317435a35e8SMatthew G Knepley     ierr = (*dm->ops->createsubdm)(dm, numFields, fields, is, subdm); CHKERRQ(ierr);
1318435a35e8SMatthew G Knepley   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateSubDM implementation defined");
1319435a35e8SMatthew G Knepley   PetscFunctionReturn(0);
1320435a35e8SMatthew G Knepley }
1321435a35e8SMatthew G Knepley 
1322435a35e8SMatthew G Knepley #undef __FUNCT__
132316621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecompositionDM"
132416621825SDmitry Karpeev /*@C
132516621825SDmitry Karpeev   DMCreateDomainDecompositionDM - creates a DM that encapsulates a decomposition of the original DM into subdomains.
132616621825SDmitry Karpeev 
132716621825SDmitry Karpeev   Not Collective
132816621825SDmitry Karpeev 
132916621825SDmitry Karpeev   Input Parameters:
133016621825SDmitry Karpeev + dm   - the DM object
133116621825SDmitry Karpeev - name - the name of the subdomain decomposition
133216621825SDmitry Karpeev 
133316621825SDmitry Karpeev   Output Parameter:
133416621825SDmitry Karpeev . ddm  - the subdomain decomposition DM (PETSC_NULL, if no such decomposition is known)
133516621825SDmitry Karpeev 
133616621825SDmitry Karpeev   Level: advanced
133716621825SDmitry Karpeev 
133816621825SDmitry Karpeev .seealso DMDestroy(), DMCreate(), DMCreateFieldDecomposition(), DMCreateDomainDecompositionDM()
133916621825SDmitry Karpeev @*/
134016621825SDmitry Karpeev PetscErrorCode DMCreateDomainDecompositionDM(DM dm, const char* name, DM *ddm)
134116621825SDmitry Karpeev {
134216621825SDmitry Karpeev   PetscErrorCode ierr;
134316621825SDmitry Karpeev 
134416621825SDmitry Karpeev   PetscFunctionBegin;
134516621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
134616621825SDmitry Karpeev   PetscValidCharPointer(name,2);
134716621825SDmitry Karpeev   PetscValidPointer(ddm,3);
134816621825SDmitry Karpeev   *ddm = PETSC_NULL;
1349731c8d9eSDmitry Karpeev   if (dm->ops->createdomaindecompositiondm) {
135016621825SDmitry Karpeev     ierr = (*dm->ops->createdomaindecompositiondm)(dm,name,ddm); CHKERRQ(ierr);
135116621825SDmitry Karpeev   }
135216621825SDmitry Karpeev   PetscFunctionReturn(0);
135316621825SDmitry Karpeev }
135416621825SDmitry Karpeev 
135516621825SDmitry Karpeev #undef __FUNCT__
135616621825SDmitry Karpeev #define __FUNCT__ "DMCreateDomainDecomposition"
135716621825SDmitry Karpeev /*@C
13588d4ac253SDmitry Karpeev   DMCreateDomainDecomposition - Returns lists of IS objects defining a decomposition of a problem into subproblems
13598d4ac253SDmitry Karpeev                           corresponding to restrictions to pairs nested subdomains: each IS contains the global
13608d4ac253SDmitry Karpeev                           indices of the dofs of the corresponding subdomains.  The inner subdomains conceptually
13618d4ac253SDmitry Karpeev                           define a nonoverlapping covering, while outer subdomains can overlap.
13628d4ac253SDmitry Karpeev                           The optional list of DMs define the DM for each subproblem.
136316621825SDmitry Karpeev 
136416621825SDmitry Karpeev   Not collective
136516621825SDmitry Karpeev 
136616621825SDmitry Karpeev   Input Parameter:
136716621825SDmitry Karpeev . dm - the DM object
136816621825SDmitry Karpeev 
136916621825SDmitry Karpeev   Output Parameters:
137016621825SDmitry Karpeev + len         - The number of subproblems in the domain decomposition (or PETSC_NULL if not requested)
137116621825SDmitry Karpeev . namelist    - The name for each subdomain (or PETSC_NULL if not requested)
13728d4ac253SDmitry Karpeev . innerislist - The global indices for each inner subdomain (or PETSC_NULL, if not requested)
13738d4ac253SDmitry Karpeev . outerislist - The global indices for each outer subdomain (or PETSC_NULL, if not requested)
137416621825SDmitry Karpeev - dmlist      - The DMs for each subdomain subproblem (or PETSC_NULL, if not requested; if PETSC_NULL is returned, no DMs are defined)
137516621825SDmitry Karpeev 
137616621825SDmitry Karpeev   Level: intermediate
137716621825SDmitry Karpeev 
137816621825SDmitry Karpeev   Notes:
137916621825SDmitry Karpeev   The user is responsible for freeing all requested arrays. In particular, every entry of names should be freed with
138016621825SDmitry Karpeev   PetscFree(), every entry of is should be destroyed with ISDestroy(), every entry of dm should be destroyed with DMDestroy(),
138116621825SDmitry Karpeev   and all of the arrays should be freed with PetscFree().
138216621825SDmitry Karpeev 
13838d4ac253SDmitry Karpeev .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateDomainDecompositionDM(), DMCreateFieldDecomposition()
138416621825SDmitry Karpeev @*/
13858d4ac253SDmitry Karpeev PetscErrorCode DMCreateDomainDecomposition(DM dm, PetscInt *len, char ***namelist, IS **innerislist, IS **outerislist, DM **dmlist)
138616621825SDmitry Karpeev {
138716621825SDmitry Karpeev   PetscErrorCode ierr;
1388be081cd6SPeter Brune   DMSubDomainHookLink link;
1389be081cd6SPeter Brune   PetscInt            i,l;
139016621825SDmitry Karpeev 
139116621825SDmitry Karpeev   PetscFunctionBegin;
139216621825SDmitry Karpeev   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1393731c8d9eSDmitry Karpeev   if (len)           {PetscValidPointer(len,2);            *len         = PETSC_NULL;}
139416621825SDmitry Karpeev   if (namelist)      {PetscValidPointer(namelist,3);       *namelist    = PETSC_NULL;}
13958d4ac253SDmitry Karpeev   if (innerislist)   {PetscValidPointer(innerislist,4);    *innerislist = PETSC_NULL;}
13968d4ac253SDmitry Karpeev   if (outerislist)   {PetscValidPointer(outerislist,5);    *outerislist = PETSC_NULL;}
13978d4ac253SDmitry Karpeev   if (dmlist)        {PetscValidPointer(dmlist,6);         *dmlist      = PETSC_NULL;}
139816621825SDmitry Karpeev   if (dm->ops->createdomaindecomposition) {
1399be081cd6SPeter Brune     ierr = (*dm->ops->createdomaindecomposition)(dm,&l,namelist,innerislist,outerislist,dmlist); CHKERRQ(ierr);
1400*d425c654SPeter Brune   } else {
1401*d425c654SPeter Brune     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DMCreateDomainDecomposition not supported for this DM type!");CHKERRQ(ierr);
1402e7c4fc90SDmitry Karpeev   }
1403be081cd6SPeter Brune   if (len) *len = l;
1404be081cd6SPeter Brune   for (i = 0; i < l; i++) {
1405be081cd6SPeter Brune     for (link=dm->subdomainhook; link; link=link->next) {
1406be081cd6SPeter Brune       if (link->ddhook) {ierr = (*link->ddhook)(dm,(*dmlist)[i],link->ctx);CHKERRQ(ierr);}
1407be081cd6SPeter Brune     }
1408*d425c654SPeter Brune     (*dmlist)[i]->ctx = dm->ctx;
1409e7c4fc90SDmitry Karpeev   }
1410e30e807fSPeter Brune   PetscFunctionReturn(0);
1411e30e807fSPeter Brune }
1412e30e807fSPeter Brune 
1413e30e807fSPeter Brune 
1414e30e807fSPeter Brune #undef __FUNCT__
1415e30e807fSPeter Brune #define __FUNCT__ "DMCreateDomainDecompositionScatters"
1416e30e807fSPeter Brune /*@C
1417e30e807fSPeter Brune   DMCreateDomainDecompositionScatters - Returns scatters to the subdomain vectors from the global vector
1418e30e807fSPeter Brune 
1419e30e807fSPeter Brune   Not collective
1420e30e807fSPeter Brune 
1421e30e807fSPeter Brune   Input Parameters:
1422e30e807fSPeter Brune + dm - the DM object
1423e30e807fSPeter Brune . n  - the number of subdomain scatters
1424e30e807fSPeter Brune - subdms - the local subdomains
1425e30e807fSPeter Brune 
1426e30e807fSPeter Brune   Output Parameters:
1427e30e807fSPeter Brune + n     - the number of scatters returned
1428e30e807fSPeter Brune . iscat - scatter from global vector to nonoverlapping global vector entries on subdomain
1429e30e807fSPeter Brune . oscat - scatter from global vector to overlapping global vector entries on subdomain
1430e30e807fSPeter Brune - gscat - scatter from global vector to local vector on subdomain (fills in ghosts)
1431e30e807fSPeter Brune 
1432e30e807fSPeter Brune   Notes: This is an alternative to the iis and ois arguments in DMCreateDomainDecomposition that allow for the solution
1433e30e807fSPeter Brune   of general nonlinear problems with overlapping subdomain methods.  While merely having index sets that enable subsets
1434e30e807fSPeter Brune   of the residual equations to be created is fine for linear problems, nonlinear problems require local assembly of
1435e30e807fSPeter Brune   solution and residual data.
1436e30e807fSPeter Brune 
1437e30e807fSPeter Brune   Level: developer
1438e30e807fSPeter Brune 
1439e30e807fSPeter Brune .seealso DMDestroy(), DMView(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMCreateFieldIS()
1440e30e807fSPeter Brune @*/
1441e30e807fSPeter Brune PetscErrorCode DMCreateDomainDecompositionScatters(DM dm,PetscInt n,DM *subdms,VecScatter **iscat,VecScatter **oscat,VecScatter **gscat)
1442e30e807fSPeter Brune {
1443e30e807fSPeter Brune   PetscErrorCode ierr;
1444e30e807fSPeter Brune 
1445e30e807fSPeter Brune   PetscFunctionBegin;
1446e30e807fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1447e30e807fSPeter Brune   PetscValidPointer(subdms,3);
1448e30e807fSPeter Brune   PetscValidPointer(iscat,4);
1449e30e807fSPeter Brune   PetscValidPointer(oscat,5);
1450e30e807fSPeter Brune   PetscValidPointer(gscat,6);
1451e30e807fSPeter Brune   if (dm->ops->createddscatters) {
1452e30e807fSPeter Brune     ierr = (*dm->ops->createddscatters)(dm,n,subdms,iscat,oscat,gscat); CHKERRQ(ierr);
1453e30e807fSPeter Brune   } else SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "This type has no DMCreateDomainDecompositionLocalScatter implementation defined");
1454e7c4fc90SDmitry Karpeev   PetscFunctionReturn(0);
1455e7c4fc90SDmitry Karpeev }
1456e7c4fc90SDmitry Karpeev 
1457731c8d9eSDmitry Karpeev #undef __FUNCT__
145847c6ae99SBarry Smith #define __FUNCT__ "DMRefine"
145947c6ae99SBarry Smith /*@
146047c6ae99SBarry Smith   DMRefine - Refines a DM object
146147c6ae99SBarry Smith 
146247c6ae99SBarry Smith   Collective on DM
146347c6ae99SBarry Smith 
146447c6ae99SBarry Smith   Input Parameter:
146547c6ae99SBarry Smith + dm   - the DM object
146691d95f02SJed Brown - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
146747c6ae99SBarry Smith 
146847c6ae99SBarry Smith   Output Parameter:
1469ae0a1c52SMatthew G Knepley . dmf - the refined DM, or PETSC_NULL
1470ae0a1c52SMatthew G Knepley 
1471ae0a1c52SMatthew G Knepley   Note: If no refinement was done, the return value is PETSC_NULL
147247c6ae99SBarry Smith 
147347c6ae99SBarry Smith   Level: developer
147447c6ae99SBarry Smith 
1475e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
147647c6ae99SBarry Smith @*/
14777087cfbeSBarry Smith PetscErrorCode  DMRefine(DM dm,MPI_Comm comm,DM *dmf)
147847c6ae99SBarry Smith {
147947c6ae99SBarry Smith   PetscErrorCode ierr;
1480c833c3b5SJed Brown   DMRefineHookLink link;
148147c6ae99SBarry Smith 
148247c6ae99SBarry Smith   PetscFunctionBegin;
1483732e2eb9SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
148447c6ae99SBarry Smith   ierr = (*dm->ops->refine)(dm,comm,dmf);CHKERRQ(ierr);
14854057135bSMatthew G Knepley   if (*dmf) {
148643842a1eSJed Brown     (*dmf)->ops->creatematrix = dm->ops->creatematrix;
14878cd211a4SJed Brown     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);CHKERRQ(ierr);
1488644e2e5bSBarry Smith     (*dmf)->ctx       = dm->ctx;
14890598a293SJed Brown     (*dmf)->leveldown = dm->leveldown;
1490656b349aSBarry Smith     (*dmf)->levelup   = dm->levelup + 1;
1491e4b4b23bSJed Brown     ierr = DMSetMatType(*dmf,dm->mattype);CHKERRQ(ierr);
1492c833c3b5SJed Brown     for (link=dm->refinehook; link; link=link->next) {
1493c833c3b5SJed Brown       if (link->refinehook) {ierr = (*link->refinehook)(dm,*dmf,link->ctx);CHKERRQ(ierr);}
1494c833c3b5SJed Brown     }
1495c833c3b5SJed Brown   }
1496c833c3b5SJed Brown   PetscFunctionReturn(0);
1497c833c3b5SJed Brown }
1498c833c3b5SJed Brown 
1499c833c3b5SJed Brown #undef __FUNCT__
1500c833c3b5SJed Brown #define __FUNCT__ "DMRefineHookAdd"
1501c833c3b5SJed Brown /*@
1502c833c3b5SJed Brown    DMRefineHookAdd - adds a callback to be run when interpolating a nonlinear problem to a finer grid
1503c833c3b5SJed Brown 
1504c833c3b5SJed Brown    Logically Collective
1505c833c3b5SJed Brown 
1506c833c3b5SJed Brown    Input Arguments:
1507c833c3b5SJed Brown +  coarse - nonlinear solver context on which to run a hook when restricting to a coarser level
1508c833c3b5SJed Brown .  refinehook - function to run when setting up a coarser level
1509c833c3b5SJed Brown .  interphook - function to run to update data on finer levels (once per SNESSolve())
1510c833c3b5SJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1511c833c3b5SJed Brown 
1512c833c3b5SJed Brown    Calling sequence of refinehook:
1513c833c3b5SJed Brown $    refinehook(DM coarse,DM fine,void *ctx);
1514c833c3b5SJed Brown 
1515c833c3b5SJed Brown +  coarse - coarse level DM
1516c833c3b5SJed Brown .  fine - fine level DM to interpolate problem to
1517c833c3b5SJed Brown -  ctx - optional user-defined function context
1518c833c3b5SJed Brown 
1519c833c3b5SJed Brown    Calling sequence for interphook:
1520c833c3b5SJed Brown $    interphook(DM coarse,Mat interp,DM fine,void *ctx)
1521c833c3b5SJed Brown 
1522c833c3b5SJed Brown +  coarse - coarse level DM
1523c833c3b5SJed Brown .  interp - matrix interpolating a coarse-level solution to the finer grid
1524c833c3b5SJed Brown .  fine - fine level DM to update
1525c833c3b5SJed Brown -  ctx - optional user-defined function context
1526c833c3b5SJed Brown 
1527c833c3b5SJed Brown    Level: advanced
1528c833c3b5SJed Brown 
1529c833c3b5SJed Brown    Notes:
1530c833c3b5SJed Brown    This function is only needed if auxiliary data needs to be passed to fine grids while grid sequencing
1531c833c3b5SJed Brown 
1532c833c3b5SJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1533c833c3b5SJed Brown 
1534c833c3b5SJed Brown .seealso: DMCoarsenHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1535c833c3b5SJed Brown @*/
1536c833c3b5SJed Brown PetscErrorCode DMRefineHookAdd(DM coarse,PetscErrorCode (*refinehook)(DM,DM,void*),PetscErrorCode (*interphook)(DM,Mat,DM,void*),void *ctx)
1537c833c3b5SJed Brown {
1538c833c3b5SJed Brown   PetscErrorCode ierr;
1539c833c3b5SJed Brown   DMRefineHookLink link,*p;
1540c833c3b5SJed Brown 
1541c833c3b5SJed Brown   PetscFunctionBegin;
1542c833c3b5SJed Brown   PetscValidHeaderSpecific(coarse,DM_CLASSID,1);
1543c833c3b5SJed Brown   for (p=&coarse->refinehook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1544c833c3b5SJed Brown   ierr = PetscMalloc(sizeof(struct _DMRefineHookLink),&link);CHKERRQ(ierr);
1545c833c3b5SJed Brown   link->refinehook = refinehook;
1546c833c3b5SJed Brown   link->interphook = interphook;
1547c833c3b5SJed Brown   link->ctx = ctx;
1548c833c3b5SJed Brown   link->next = PETSC_NULL;
1549c833c3b5SJed Brown   *p = link;
1550c833c3b5SJed Brown   PetscFunctionReturn(0);
1551c833c3b5SJed Brown }
1552c833c3b5SJed Brown 
1553c833c3b5SJed Brown #undef __FUNCT__
1554c833c3b5SJed Brown #define __FUNCT__ "DMInterpolate"
1555c833c3b5SJed Brown /*@
1556c833c3b5SJed Brown    DMInterpolate - interpolates user-defined problem data to a finer DM by running hooks registered by DMRefineHookAdd()
1557c833c3b5SJed Brown 
1558c833c3b5SJed Brown    Collective if any hooks are
1559c833c3b5SJed Brown 
1560c833c3b5SJed Brown    Input Arguments:
1561c833c3b5SJed Brown +  coarse - coarser DM to use as a base
1562c833c3b5SJed Brown .  restrct - interpolation matrix, apply using MatInterpolate()
1563c833c3b5SJed Brown -  fine - finer DM to update
1564c833c3b5SJed Brown 
1565c833c3b5SJed Brown    Level: developer
1566c833c3b5SJed Brown 
1567c833c3b5SJed Brown .seealso: DMRefineHookAdd(), MatInterpolate()
1568c833c3b5SJed Brown @*/
1569c833c3b5SJed Brown PetscErrorCode DMInterpolate(DM coarse,Mat interp,DM fine)
1570c833c3b5SJed Brown {
1571c833c3b5SJed Brown   PetscErrorCode ierr;
1572c833c3b5SJed Brown   DMRefineHookLink link;
1573c833c3b5SJed Brown 
1574c833c3b5SJed Brown   PetscFunctionBegin;
1575c833c3b5SJed Brown   for (link=fine->refinehook; link; link=link->next) {
1576c833c3b5SJed Brown     if (link->interphook) {ierr = (*link->interphook)(coarse,interp,fine,link->ctx);CHKERRQ(ierr);}
15774057135bSMatthew G Knepley   }
157847c6ae99SBarry Smith   PetscFunctionReturn(0);
157947c6ae99SBarry Smith }
158047c6ae99SBarry Smith 
158147c6ae99SBarry Smith #undef __FUNCT__
1582eb3f98d2SBarry Smith #define __FUNCT__ "DMGetRefineLevel"
1583eb3f98d2SBarry Smith /*@
1584eb3f98d2SBarry Smith     DMGetRefineLevel - Get's the number of refinements that have generated this DM.
1585eb3f98d2SBarry Smith 
1586eb3f98d2SBarry Smith     Not Collective
1587eb3f98d2SBarry Smith 
1588eb3f98d2SBarry Smith     Input Parameter:
1589eb3f98d2SBarry Smith .   dm - the DM object
1590eb3f98d2SBarry Smith 
1591eb3f98d2SBarry Smith     Output Parameter:
1592eb3f98d2SBarry Smith .   level - number of refinements
1593eb3f98d2SBarry Smith 
1594eb3f98d2SBarry Smith     Level: developer
1595eb3f98d2SBarry Smith 
15966a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetCoarsenLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
1597eb3f98d2SBarry Smith 
1598eb3f98d2SBarry Smith @*/
1599eb3f98d2SBarry Smith PetscErrorCode  DMGetRefineLevel(DM dm,PetscInt *level)
1600eb3f98d2SBarry Smith {
1601eb3f98d2SBarry Smith   PetscFunctionBegin;
1602eb3f98d2SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1603eb3f98d2SBarry Smith   *level = dm->levelup;
1604eb3f98d2SBarry Smith   PetscFunctionReturn(0);
1605eb3f98d2SBarry Smith }
1606eb3f98d2SBarry Smith 
1607eb3f98d2SBarry Smith #undef __FUNCT__
1608baf369e7SPeter Brune #define __FUNCT__ "DMGlobalToLocalHookAdd"
1609baf369e7SPeter Brune /*@
1610baf369e7SPeter Brune    DMGlobalToLocalHookAdd - adds a callback to be run when global to local is called
1611baf369e7SPeter Brune 
1612baf369e7SPeter Brune    Logically Collective
1613baf369e7SPeter Brune 
1614baf369e7SPeter Brune    Input Arguments:
1615baf369e7SPeter Brune +  dm - the DM
1616baf369e7SPeter Brune .  beginhook - function to run at the beginning of DMGlobalToLocalBegin()
1617baf369e7SPeter Brune .  endhook - function to run after DMGlobalToLocalEnd() has completed
1618baf369e7SPeter Brune -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1619baf369e7SPeter Brune 
1620baf369e7SPeter Brune    Calling sequence for beginhook:
1621baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1622baf369e7SPeter Brune 
1623baf369e7SPeter Brune +  dm - global DM
1624baf369e7SPeter Brune .  g - global vector
1625baf369e7SPeter Brune .  mode - mode
1626baf369e7SPeter Brune .  l - local vector
1627baf369e7SPeter Brune -  ctx - optional user-defined function context
1628baf369e7SPeter Brune 
1629baf369e7SPeter Brune 
1630baf369e7SPeter Brune    Calling sequence for endhook:
1631baf369e7SPeter Brune $    beginhook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
1632baf369e7SPeter Brune 
1633baf369e7SPeter Brune +  global - global DM
1634baf369e7SPeter Brune -  ctx - optional user-defined function context
1635baf369e7SPeter Brune 
1636baf369e7SPeter Brune    Level: advanced
1637baf369e7SPeter Brune 
1638baf369e7SPeter Brune    Notes:
1639baf369e7SPeter Brune    This function is only needed if auxiliary data needs to be set up on coarse grids.
1640baf369e7SPeter Brune 
1641baf369e7SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
1642baf369e7SPeter Brune 
1643baf369e7SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1644baf369e7SPeter Brune    extract the finest level information from its context (instead of from the SNES).
1645baf369e7SPeter Brune 
1646baf369e7SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1647baf369e7SPeter Brune @*/
1648baf369e7SPeter Brune PetscErrorCode DMGlobalToLocalHookAdd(DM dm,PetscErrorCode (*beginhook)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*endhook)(DM,Vec,InsertMode,Vec,void*),void *ctx)
1649baf369e7SPeter Brune {
1650baf369e7SPeter Brune   PetscErrorCode ierr;
1651baf369e7SPeter Brune   DMGlobalToLocalHookLink link,*p;
1652baf369e7SPeter Brune 
1653baf369e7SPeter Brune   PetscFunctionBegin;
1654baf369e7SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1655baf369e7SPeter Brune   for (p=&dm->gtolhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1656baf369e7SPeter Brune   ierr = PetscMalloc(sizeof(struct _DMGlobalToLocalHookLink),&link);CHKERRQ(ierr);
1657baf369e7SPeter Brune   link->beginhook = beginhook;
1658baf369e7SPeter Brune   link->endhook = endhook;
1659baf369e7SPeter Brune   link->ctx = ctx;
1660baf369e7SPeter Brune   link->next = PETSC_NULL;
1661baf369e7SPeter Brune   *p = link;
1662baf369e7SPeter Brune   PetscFunctionReturn(0);
1663baf369e7SPeter Brune }
1664baf369e7SPeter Brune 
1665baf369e7SPeter Brune #undef __FUNCT__
166647c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalBegin"
166747c6ae99SBarry Smith /*@
166847c6ae99SBarry Smith     DMGlobalToLocalBegin - Begins updating local vectors from global vector
166947c6ae99SBarry Smith 
167047c6ae99SBarry Smith     Neighbor-wise Collective on DM
167147c6ae99SBarry Smith 
167247c6ae99SBarry Smith     Input Parameters:
167347c6ae99SBarry Smith +   dm - the DM object
167447c6ae99SBarry Smith .   g - the global vector
167547c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
167647c6ae99SBarry Smith -   l - the local vector
167747c6ae99SBarry Smith 
167847c6ae99SBarry Smith 
167947c6ae99SBarry Smith     Level: beginner
168047c6ae99SBarry Smith 
1681e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
168247c6ae99SBarry Smith 
168347c6ae99SBarry Smith @*/
16847087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
168547c6ae99SBarry Smith {
16867128ae9fSMatthew G Knepley   PetscSF        sf;
168747c6ae99SBarry Smith   PetscErrorCode ierr;
1688baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
168947c6ae99SBarry Smith 
169047c6ae99SBarry Smith   PetscFunctionBegin;
1691171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1692baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
1693baf369e7SPeter Brune     if (link->beginhook) {ierr = (*link->beginhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
1694baf369e7SPeter Brune   }
16957128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
16967128ae9fSMatthew G Knepley   if (sf) {
16977128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
16987128ae9fSMatthew G Knepley 
16997128ae9fSMatthew G Knepley     if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17007128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
17017128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
17027128ae9fSMatthew G Knepley     ierr = PetscSFBcastBegin(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
17037128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
17047128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
17057128ae9fSMatthew G Knepley   } else {
1706843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalbegin)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
17077128ae9fSMatthew G Knepley   }
170847c6ae99SBarry Smith   PetscFunctionReturn(0);
170947c6ae99SBarry Smith }
171047c6ae99SBarry Smith 
171147c6ae99SBarry Smith #undef __FUNCT__
171247c6ae99SBarry Smith #define __FUNCT__ "DMGlobalToLocalEnd"
171347c6ae99SBarry Smith /*@
171447c6ae99SBarry Smith     DMGlobalToLocalEnd - Ends updating local vectors from global vector
171547c6ae99SBarry Smith 
171647c6ae99SBarry Smith     Neighbor-wise Collective on DM
171747c6ae99SBarry Smith 
171847c6ae99SBarry Smith     Input Parameters:
171947c6ae99SBarry Smith +   dm - the DM object
172047c6ae99SBarry Smith .   g - the global vector
172147c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
172247c6ae99SBarry Smith -   l - the local vector
172347c6ae99SBarry Smith 
172447c6ae99SBarry Smith 
172547c6ae99SBarry Smith     Level: beginner
172647c6ae99SBarry Smith 
1727e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
172847c6ae99SBarry Smith 
172947c6ae99SBarry Smith @*/
17307087cfbeSBarry Smith PetscErrorCode  DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
173147c6ae99SBarry Smith {
17327128ae9fSMatthew G Knepley   PetscSF        sf;
173347c6ae99SBarry Smith   PetscErrorCode ierr;
173461a3c1faSSatish Balay   PetscScalar    *lArray, *gArray;
1735baf369e7SPeter Brune   DMGlobalToLocalHookLink link;
173647c6ae99SBarry Smith 
173747c6ae99SBarry Smith   PetscFunctionBegin;
1738171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17397128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17407128ae9fSMatthew G Knepley   if (sf) {
17417128ae9fSMatthew G Knepley   if (mode == ADD_VALUES) SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
17427128ae9fSMatthew G Knepley 
17437128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
17447128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
17457128ae9fSMatthew G Knepley     ierr = PetscSFBcastEnd(sf, MPIU_SCALAR, gArray, lArray);CHKERRQ(ierr);
17467128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
17477128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
17487128ae9fSMatthew G Knepley   } else {
1749843c4018SMatthew G Knepley     ierr = (*dm->ops->globaltolocalend)(dm,g,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),l);CHKERRQ(ierr);
17507128ae9fSMatthew G Knepley   }
1751baf369e7SPeter Brune   for (link=dm->gtolhook; link; link=link->next) {
1752baf369e7SPeter Brune     if (link->endhook) {ierr = (*link->endhook)(dm,g,mode,l,link->ctx);CHKERRQ(ierr);}
1753baf369e7SPeter Brune   }
175447c6ae99SBarry Smith   PetscFunctionReturn(0);
175547c6ae99SBarry Smith }
175647c6ae99SBarry Smith 
175747c6ae99SBarry Smith #undef __FUNCT__
17589a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalBegin"
175947c6ae99SBarry Smith /*@
17609a42bb27SBarry Smith     DMLocalToGlobalBegin - updates global vectors from local vectors
17619a42bb27SBarry Smith 
17629a42bb27SBarry Smith     Neighbor-wise Collective on DM
17639a42bb27SBarry Smith 
17649a42bb27SBarry Smith     Input Parameters:
17659a42bb27SBarry Smith +   dm - the DM object
1766f6813fd5SJed Brown .   l - the local vector
17679a42bb27SBarry 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
17689a42bb27SBarry Smith            base point.
1769f6813fd5SJed Brown - - the global vector
17709a42bb27SBarry Smith 
17719a42bb27SBarry 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
17729a42bb27SBarry 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
17739a42bb27SBarry Smith            global array to the final global array with VecAXPY().
17749a42bb27SBarry Smith 
17759a42bb27SBarry Smith     Level: beginner
17769a42bb27SBarry Smith 
1777e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
17789a42bb27SBarry Smith 
17799a42bb27SBarry Smith @*/
17807087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
17819a42bb27SBarry Smith {
17827128ae9fSMatthew G Knepley   PetscSF        sf;
17839a42bb27SBarry Smith   PetscErrorCode ierr;
17849a42bb27SBarry Smith 
17859a42bb27SBarry Smith   PetscFunctionBegin;
1786171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
17877128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
17887128ae9fSMatthew G Knepley   if (sf) {
17897128ae9fSMatthew G Knepley     MPI_Op       op;
17907128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
17917128ae9fSMatthew G Knepley 
17927128ae9fSMatthew G Knepley     switch(mode) {
17937128ae9fSMatthew G Knepley     case INSERT_VALUES:
17947128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
17957128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
17967128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
17977128ae9fSMatthew G Knepley #else
17987128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
17997128ae9fSMatthew G Knepley #endif
18007128ae9fSMatthew G Knepley     case ADD_VALUES:
18017128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
18027128ae9fSMatthew G Knepley       op = MPI_SUM; break;
18037128ae9fSMatthew G Knepley   default:
18047128ae9fSMatthew G Knepley     SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
18057128ae9fSMatthew G Knepley     }
18067128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
18077128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
18087128ae9fSMatthew G Knepley     ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
18097128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
18107128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
18117128ae9fSMatthew G Knepley   } else {
1812843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalbegin)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
18137128ae9fSMatthew G Knepley   }
18149a42bb27SBarry Smith   PetscFunctionReturn(0);
18159a42bb27SBarry Smith }
18169a42bb27SBarry Smith 
18179a42bb27SBarry Smith #undef __FUNCT__
18189a42bb27SBarry Smith #define __FUNCT__ "DMLocalToGlobalEnd"
18199a42bb27SBarry Smith /*@
18209a42bb27SBarry Smith     DMLocalToGlobalEnd - updates global vectors from local vectors
182147c6ae99SBarry Smith 
182247c6ae99SBarry Smith     Neighbor-wise Collective on DM
182347c6ae99SBarry Smith 
182447c6ae99SBarry Smith     Input Parameters:
182547c6ae99SBarry Smith +   dm - the DM object
1826f6813fd5SJed Brown .   l - the local vector
182747c6ae99SBarry Smith .   mode - INSERT_VALUES or ADD_VALUES
1828f6813fd5SJed Brown -   g - the global vector
182947c6ae99SBarry Smith 
183047c6ae99SBarry Smith 
183147c6ae99SBarry Smith     Level: beginner
183247c6ae99SBarry Smith 
1833e727c939SJed Brown .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
183447c6ae99SBarry Smith 
183547c6ae99SBarry Smith @*/
18367087cfbeSBarry Smith PetscErrorCode  DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
183747c6ae99SBarry Smith {
18387128ae9fSMatthew G Knepley   PetscSF        sf;
183947c6ae99SBarry Smith   PetscErrorCode ierr;
184047c6ae99SBarry Smith 
184147c6ae99SBarry Smith   PetscFunctionBegin;
1842171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
18437128ae9fSMatthew G Knepley   ierr = DMGetDefaultSF(dm, &sf);CHKERRQ(ierr);
18447128ae9fSMatthew G Knepley   if (sf) {
18457128ae9fSMatthew G Knepley     MPI_Op       op;
18467128ae9fSMatthew G Knepley     PetscScalar *lArray, *gArray;
18477128ae9fSMatthew G Knepley 
18487128ae9fSMatthew G Knepley     switch(mode) {
18497128ae9fSMatthew G Knepley     case INSERT_VALUES:
18507128ae9fSMatthew G Knepley     case INSERT_ALL_VALUES:
18517128ae9fSMatthew G Knepley #if defined(PETSC_HAVE_MPI_REPLACE)
18527128ae9fSMatthew G Knepley       op = MPI_REPLACE; break;
18537128ae9fSMatthew G Knepley #else
18547128ae9fSMatthew G Knepley       SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No support for INSERT_VALUES without an MPI-2 implementation");
18557128ae9fSMatthew G Knepley #endif
18567128ae9fSMatthew G Knepley     case ADD_VALUES:
18577128ae9fSMatthew G Knepley     case ADD_ALL_VALUES:
18587128ae9fSMatthew G Knepley       op = MPI_SUM; break;
18597128ae9fSMatthew G Knepley     default:
18607128ae9fSMatthew G Knepley       SETERRQ1(((PetscObject) dm)->comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid insertion mode %D", mode);
18617128ae9fSMatthew G Knepley     }
18627128ae9fSMatthew G Knepley     ierr = VecGetArray(l, &lArray);CHKERRQ(ierr);
18637128ae9fSMatthew G Knepley     ierr = VecGetArray(g, &gArray);CHKERRQ(ierr);
18647128ae9fSMatthew G Knepley     ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, op);CHKERRQ(ierr);
18657128ae9fSMatthew G Knepley     ierr = VecRestoreArray(l, &lArray);CHKERRQ(ierr);
18667128ae9fSMatthew G Knepley     ierr = VecRestoreArray(g, &gArray);CHKERRQ(ierr);
18677128ae9fSMatthew G Knepley   } else {
1868843c4018SMatthew G Knepley     ierr = (*dm->ops->localtoglobalend)(dm,l,mode == INSERT_ALL_VALUES ? INSERT_VALUES : (mode == ADD_ALL_VALUES ? ADD_VALUES : mode),g);CHKERRQ(ierr);
18697128ae9fSMatthew G Knepley   }
187047c6ae99SBarry Smith   PetscFunctionReturn(0);
187147c6ae99SBarry Smith }
187247c6ae99SBarry Smith 
187347c6ae99SBarry Smith #undef __FUNCT__
187447c6ae99SBarry Smith #define __FUNCT__ "DMCoarsen"
187547c6ae99SBarry Smith /*@
187647c6ae99SBarry Smith     DMCoarsen - Coarsens a DM object
187747c6ae99SBarry Smith 
187847c6ae99SBarry Smith     Collective on DM
187947c6ae99SBarry Smith 
188047c6ae99SBarry Smith     Input Parameter:
188147c6ae99SBarry Smith +   dm - the DM object
188291d95f02SJed Brown -   comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
188347c6ae99SBarry Smith 
188447c6ae99SBarry Smith     Output Parameter:
188547c6ae99SBarry Smith .   dmc - the coarsened DM
188647c6ae99SBarry Smith 
188747c6ae99SBarry Smith     Level: developer
188847c6ae99SBarry Smith 
1889e727c939SJed Brown .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
189047c6ae99SBarry Smith 
189147c6ae99SBarry Smith @*/
18927087cfbeSBarry Smith PetscErrorCode  DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
189347c6ae99SBarry Smith {
189447c6ae99SBarry Smith   PetscErrorCode ierr;
1895b17ce1afSJed Brown   DMCoarsenHookLink link;
189647c6ae99SBarry Smith 
189747c6ae99SBarry Smith   PetscFunctionBegin;
1898171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
189947c6ae99SBarry Smith   ierr = (*dm->ops->coarsen)(dm, comm, dmc);CHKERRQ(ierr);
190043842a1eSJed Brown   (*dmc)->ops->creatematrix = dm->ops->creatematrix;
19018cd211a4SJed Brown   ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);CHKERRQ(ierr);
1902644e2e5bSBarry Smith   (*dmc)->ctx       = dm->ctx;
19030598a293SJed Brown   (*dmc)->levelup   = dm->levelup;
1904656b349aSBarry Smith   (*dmc)->leveldown = dm->leveldown + 1;
1905e4b4b23bSJed Brown   ierr = DMSetMatType(*dmc,dm->mattype);CHKERRQ(ierr);
1906b17ce1afSJed Brown   for (link=dm->coarsenhook; link; link=link->next) {
1907b17ce1afSJed Brown     if (link->coarsenhook) {ierr = (*link->coarsenhook)(dm,*dmc,link->ctx);CHKERRQ(ierr);}
1908b17ce1afSJed Brown   }
1909b17ce1afSJed Brown   PetscFunctionReturn(0);
1910b17ce1afSJed Brown }
1911b17ce1afSJed Brown 
1912b17ce1afSJed Brown #undef __FUNCT__
1913b17ce1afSJed Brown #define __FUNCT__ "DMCoarsenHookAdd"
1914b17ce1afSJed Brown /*@
1915b17ce1afSJed Brown    DMCoarsenHookAdd - adds a callback to be run when restricting a nonlinear problem to the coarse grid
1916b17ce1afSJed Brown 
1917b17ce1afSJed Brown    Logically Collective
1918b17ce1afSJed Brown 
1919b17ce1afSJed Brown    Input Arguments:
1920b17ce1afSJed Brown +  fine - nonlinear solver context on which to run a hook when restricting to a coarser level
1921b17ce1afSJed Brown .  coarsenhook - function to run when setting up a coarser level
1922b17ce1afSJed Brown .  restricthook - function to run to update data on coarser levels (once per SNESSolve())
1923b17ce1afSJed Brown -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
1924b17ce1afSJed Brown 
1925b17ce1afSJed Brown    Calling sequence of coarsenhook:
1926b17ce1afSJed Brown $    coarsenhook(DM fine,DM coarse,void *ctx);
1927b17ce1afSJed Brown 
1928b17ce1afSJed Brown +  fine - fine level DM
1929b17ce1afSJed Brown .  coarse - coarse level DM to restrict problem to
1930b17ce1afSJed Brown -  ctx - optional user-defined function context
1931b17ce1afSJed Brown 
1932b17ce1afSJed Brown    Calling sequence for restricthook:
1933c833c3b5SJed Brown $    restricthook(DM fine,Mat mrestrict,Vec rscale,Mat inject,DM coarse,void *ctx)
1934b17ce1afSJed Brown 
1935b17ce1afSJed Brown +  fine - fine level DM
1936b17ce1afSJed Brown .  mrestrict - matrix restricting a fine-level solution to the coarse grid
1937c833c3b5SJed Brown .  rscale - scaling vector for restriction
1938c833c3b5SJed Brown .  inject - matrix restricting by injection
1939b17ce1afSJed Brown .  coarse - coarse level DM to update
1940b17ce1afSJed Brown -  ctx - optional user-defined function context
1941b17ce1afSJed Brown 
1942b17ce1afSJed Brown    Level: advanced
1943b17ce1afSJed Brown 
1944b17ce1afSJed Brown    Notes:
1945b17ce1afSJed Brown    This function is only needed if auxiliary data needs to be set up on coarse grids.
1946b17ce1afSJed Brown 
1947b17ce1afSJed Brown    If this function is called multiple times, the hooks will be run in the order they are added.
1948b17ce1afSJed Brown 
1949b17ce1afSJed Brown    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
1950b17ce1afSJed Brown    extract the finest level information from its context (instead of from the SNES).
1951b17ce1afSJed Brown 
1952c833c3b5SJed Brown .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
1953b17ce1afSJed Brown @*/
1954b17ce1afSJed Brown PetscErrorCode DMCoarsenHookAdd(DM fine,PetscErrorCode (*coarsenhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,Mat,Vec,Mat,DM,void*),void *ctx)
1955b17ce1afSJed Brown {
1956b17ce1afSJed Brown   PetscErrorCode ierr;
1957b17ce1afSJed Brown   DMCoarsenHookLink link,*p;
1958b17ce1afSJed Brown 
1959b17ce1afSJed Brown   PetscFunctionBegin;
1960b17ce1afSJed Brown   PetscValidHeaderSpecific(fine,DM_CLASSID,1);
19616bfea28cSJed Brown   for (p=&fine->coarsenhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
1962b17ce1afSJed Brown   ierr = PetscMalloc(sizeof(struct _DMCoarsenHookLink),&link);CHKERRQ(ierr);
1963b17ce1afSJed Brown   link->coarsenhook = coarsenhook;
1964b17ce1afSJed Brown   link->restricthook = restricthook;
1965b17ce1afSJed Brown   link->ctx = ctx;
19666cab3a1bSJed Brown   link->next = PETSC_NULL;
1967b17ce1afSJed Brown   *p = link;
1968b17ce1afSJed Brown   PetscFunctionReturn(0);
1969b17ce1afSJed Brown }
1970b17ce1afSJed Brown 
1971b17ce1afSJed Brown #undef __FUNCT__
1972b17ce1afSJed Brown #define __FUNCT__ "DMRestrict"
1973b17ce1afSJed Brown /*@
1974b17ce1afSJed Brown    DMRestrict - restricts user-defined problem data to a coarser DM by running hooks registered by DMCoarsenHookAdd()
1975b17ce1afSJed Brown 
1976b17ce1afSJed Brown    Collective if any hooks are
1977b17ce1afSJed Brown 
1978b17ce1afSJed Brown    Input Arguments:
1979b17ce1afSJed Brown +  fine - finer DM to use as a base
1980b17ce1afSJed Brown .  restrct - restriction matrix, apply using MatRestrict()
1981b17ce1afSJed Brown .  inject - injection matrix, also use MatRestrict()
1982b17ce1afSJed Brown -  coarse - coarer DM to update
1983b17ce1afSJed Brown 
1984b17ce1afSJed Brown    Level: developer
1985b17ce1afSJed Brown 
1986b17ce1afSJed Brown .seealso: DMCoarsenHookAdd(), MatRestrict()
1987b17ce1afSJed Brown @*/
1988b17ce1afSJed Brown PetscErrorCode DMRestrict(DM fine,Mat restrct,Vec rscale,Mat inject,DM coarse)
1989b17ce1afSJed Brown {
1990b17ce1afSJed Brown   PetscErrorCode ierr;
1991b17ce1afSJed Brown   DMCoarsenHookLink link;
1992b17ce1afSJed Brown 
1993b17ce1afSJed Brown   PetscFunctionBegin;
1994b17ce1afSJed Brown   for (link=fine->coarsenhook; link; link=link->next) {
1995b17ce1afSJed Brown     if (link->restricthook) {ierr = (*link->restricthook)(fine,restrct,rscale,inject,coarse,link->ctx);CHKERRQ(ierr);}
1996b17ce1afSJed Brown   }
199747c6ae99SBarry Smith   PetscFunctionReturn(0);
199847c6ae99SBarry Smith }
199947c6ae99SBarry Smith 
200047c6ae99SBarry Smith #undef __FUNCT__
2001be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainHookAdd"
20025dbd56e3SPeter Brune /*@
2003be081cd6SPeter Brune    DMSubDomainHookAdd - adds a callback to be run when restricting a problem to the coarse grid
20045dbd56e3SPeter Brune 
20055dbd56e3SPeter Brune    Logically Collective
20065dbd56e3SPeter Brune 
20075dbd56e3SPeter Brune    Input Arguments:
20085dbd56e3SPeter Brune +  global - global DM
2009be081cd6SPeter Brune .
20105dbd56e3SPeter Brune .  restricthook - function to run to update data on block solve (at the beginning of the block solve)
20115dbd56e3SPeter Brune -  ctx - [optional] user-defined context for provide data for the hooks (may be PETSC_NULL)
20125dbd56e3SPeter Brune 
20135dbd56e3SPeter Brune    Calling sequence for restricthook:
20145dbd56e3SPeter Brune $    restricthook(DM fine,VecScatter out,VecScatter in,DM coarse,void *ctx)
20155dbd56e3SPeter Brune 
20165dbd56e3SPeter Brune +  global - global DM
20175dbd56e3SPeter Brune .  out    - scatter to the outer (with ghost and overlap points) block vector
20185dbd56e3SPeter Brune .  in     - scatter to block vector values only owned locally
20195dbd56e3SPeter Brune .  block  - block DM (may just be a shell if the global DM is passed in correctly)
20205dbd56e3SPeter Brune -  ctx - optional user-defined function context
20215dbd56e3SPeter Brune 
20225dbd56e3SPeter Brune    Level: advanced
20235dbd56e3SPeter Brune 
20245dbd56e3SPeter Brune    Notes:
20255dbd56e3SPeter Brune    This function is only needed if auxiliary data needs to be set up on coarse grids.
20265dbd56e3SPeter Brune 
20275dbd56e3SPeter Brune    If this function is called multiple times, the hooks will be run in the order they are added.
20285dbd56e3SPeter Brune 
20295dbd56e3SPeter Brune    In order to compose with nonlinear preconditioning without duplicating storage, the hook should be implemented to
20305dbd56e3SPeter Brune    extract the finest level information from its context (instead of from the SNES).
20315dbd56e3SPeter Brune 
20325dbd56e3SPeter Brune .seealso: DMRefineHookAdd(), SNESFASGetInterpolation(), SNESFASGetInjection(), PetscObjectCompose(), PetscContainerCreate()
20335dbd56e3SPeter Brune @*/
2034be081cd6SPeter Brune PetscErrorCode DMSubDomainHookAdd(DM global,PetscErrorCode (*ddhook)(DM,DM,void*),PetscErrorCode (*restricthook)(DM,VecScatter,VecScatter,DM,void*),void *ctx)
20355dbd56e3SPeter Brune {
20365dbd56e3SPeter Brune   PetscErrorCode ierr;
2037be081cd6SPeter Brune   DMSubDomainHookLink link,*p;
20385dbd56e3SPeter Brune 
20395dbd56e3SPeter Brune   PetscFunctionBegin;
20405dbd56e3SPeter Brune   PetscValidHeaderSpecific(global,DM_CLASSID,1);
2041be081cd6SPeter Brune   for (p=&global->subdomainhook; *p; p=&(*p)->next) {} /* Scan to the end of the current list of hooks */
2042be081cd6SPeter Brune   ierr = PetscMalloc(sizeof(struct _DMSubDomainHookLink),&link);CHKERRQ(ierr);
20435dbd56e3SPeter Brune   link->restricthook = restricthook;
2044be081cd6SPeter Brune   link->ddhook = ddhook;
20455dbd56e3SPeter Brune   link->ctx = ctx;
20465dbd56e3SPeter Brune   link->next = PETSC_NULL;
20475dbd56e3SPeter Brune   *p = link;
20485dbd56e3SPeter Brune   PetscFunctionReturn(0);
20495dbd56e3SPeter Brune }
20505dbd56e3SPeter Brune 
20515dbd56e3SPeter Brune #undef __FUNCT__
2052be081cd6SPeter Brune #define __FUNCT__ "DMSubDomainRestrict"
20535dbd56e3SPeter Brune /*@
2054be081cd6SPeter Brune    DMSubDomainRestrict - restricts user-defined problem data to a block DM by running hooks registered by DMSubDomainHookAdd()
20555dbd56e3SPeter Brune 
20565dbd56e3SPeter Brune    Collective if any hooks are
20575dbd56e3SPeter Brune 
20585dbd56e3SPeter Brune    Input Arguments:
20595dbd56e3SPeter Brune +  fine - finer DM to use as a base
2060be081cd6SPeter Brune .  oscatter - scatter from domain global vector filling subdomain global vector with overlap
2061be081cd6SPeter Brune .  gscatter - scatter from domain global vector filling subdomain local vector with ghosts
20625dbd56e3SPeter Brune -  coarse - coarer DM to update
20635dbd56e3SPeter Brune 
20645dbd56e3SPeter Brune    Level: developer
20655dbd56e3SPeter Brune 
20665dbd56e3SPeter Brune .seealso: DMCoarsenHookAdd(), MatRestrict()
20675dbd56e3SPeter Brune @*/
2068be081cd6SPeter Brune PetscErrorCode DMSubDomainRestrict(DM global,VecScatter oscatter,VecScatter gscatter,DM subdm)
20695dbd56e3SPeter Brune {
20705dbd56e3SPeter Brune   PetscErrorCode ierr;
2071be081cd6SPeter Brune   DMSubDomainHookLink link;
20725dbd56e3SPeter Brune 
20735dbd56e3SPeter Brune   PetscFunctionBegin;
2074be081cd6SPeter Brune   for (link=global->subdomainhook; link; link=link->next) {
2075be081cd6SPeter Brune     if (link->restricthook) {ierr = (*link->restricthook)(global,oscatter,gscatter,subdm,link->ctx);CHKERRQ(ierr);}
20765dbd56e3SPeter Brune   }
20775dbd56e3SPeter Brune   PetscFunctionReturn(0);
20785dbd56e3SPeter Brune }
20795dbd56e3SPeter Brune 
20805dbd56e3SPeter Brune #undef __FUNCT__
20815fe1f584SPeter Brune #define __FUNCT__ "DMGetCoarsenLevel"
20825fe1f584SPeter Brune /*@
20836a7d9d85SPeter Brune     DMGetCoarsenLevel - Get's the number of coarsenings that have generated this DM.
20845fe1f584SPeter Brune 
20855fe1f584SPeter Brune     Not Collective
20865fe1f584SPeter Brune 
20875fe1f584SPeter Brune     Input Parameter:
20885fe1f584SPeter Brune .   dm - the DM object
20895fe1f584SPeter Brune 
20905fe1f584SPeter Brune     Output Parameter:
20916a7d9d85SPeter Brune .   level - number of coarsenings
20925fe1f584SPeter Brune 
20935fe1f584SPeter Brune     Level: developer
20945fe1f584SPeter Brune 
20956a7d9d85SPeter Brune .seealso DMCoarsen(), DMGetRefineLevel(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
20965fe1f584SPeter Brune 
20975fe1f584SPeter Brune @*/
20985fe1f584SPeter Brune PetscErrorCode  DMGetCoarsenLevel(DM dm,PetscInt *level)
20995fe1f584SPeter Brune {
21005fe1f584SPeter Brune   PetscFunctionBegin;
21015fe1f584SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21025fe1f584SPeter Brune   *level = dm->leveldown;
21035fe1f584SPeter Brune   PetscFunctionReturn(0);
21045fe1f584SPeter Brune }
21055fe1f584SPeter Brune 
21065fe1f584SPeter Brune 
21075fe1f584SPeter Brune 
21085fe1f584SPeter Brune #undef __FUNCT__
210947c6ae99SBarry Smith #define __FUNCT__ "DMRefineHierarchy"
211047c6ae99SBarry Smith /*@C
211147c6ae99SBarry Smith     DMRefineHierarchy - Refines a DM object, all levels at once
211247c6ae99SBarry Smith 
211347c6ae99SBarry Smith     Collective on DM
211447c6ae99SBarry Smith 
211547c6ae99SBarry Smith     Input Parameter:
211647c6ae99SBarry Smith +   dm - the DM object
211747c6ae99SBarry Smith -   nlevels - the number of levels of refinement
211847c6ae99SBarry Smith 
211947c6ae99SBarry Smith     Output Parameter:
212047c6ae99SBarry Smith .   dmf - the refined DM hierarchy
212147c6ae99SBarry Smith 
212247c6ae99SBarry Smith     Level: developer
212347c6ae99SBarry Smith 
2124e727c939SJed Brown .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
212547c6ae99SBarry Smith 
212647c6ae99SBarry Smith @*/
21277087cfbeSBarry Smith PetscErrorCode  DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
212847c6ae99SBarry Smith {
212947c6ae99SBarry Smith   PetscErrorCode ierr;
213047c6ae99SBarry Smith 
213147c6ae99SBarry Smith   PetscFunctionBegin;
2132171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
213347c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
213447c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
213547c6ae99SBarry Smith   if (dm->ops->refinehierarchy) {
213647c6ae99SBarry Smith     ierr = (*dm->ops->refinehierarchy)(dm,nlevels,dmf);CHKERRQ(ierr);
213747c6ae99SBarry Smith   } else if (dm->ops->refine) {
213847c6ae99SBarry Smith     PetscInt i;
213947c6ae99SBarry Smith 
214047c6ae99SBarry Smith     ierr = DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);CHKERRQ(ierr);
214147c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
214247c6ae99SBarry Smith       ierr = DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);CHKERRQ(ierr);
214347c6ae99SBarry Smith     }
214447c6ae99SBarry Smith   } else {
214547c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
214647c6ae99SBarry Smith   }
214747c6ae99SBarry Smith   PetscFunctionReturn(0);
214847c6ae99SBarry Smith }
214947c6ae99SBarry Smith 
215047c6ae99SBarry Smith #undef __FUNCT__
215147c6ae99SBarry Smith #define __FUNCT__ "DMCoarsenHierarchy"
215247c6ae99SBarry Smith /*@C
215347c6ae99SBarry Smith     DMCoarsenHierarchy - Coarsens a DM object, all levels at once
215447c6ae99SBarry Smith 
215547c6ae99SBarry Smith     Collective on DM
215647c6ae99SBarry Smith 
215747c6ae99SBarry Smith     Input Parameter:
215847c6ae99SBarry Smith +   dm - the DM object
215947c6ae99SBarry Smith -   nlevels - the number of levels of coarsening
216047c6ae99SBarry Smith 
216147c6ae99SBarry Smith     Output Parameter:
216247c6ae99SBarry Smith .   dmc - the coarsened DM hierarchy
216347c6ae99SBarry Smith 
216447c6ae99SBarry Smith     Level: developer
216547c6ae99SBarry Smith 
2166e727c939SJed Brown .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMCreateInterpolation()
216747c6ae99SBarry Smith 
216847c6ae99SBarry Smith @*/
21697087cfbeSBarry Smith PetscErrorCode  DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
217047c6ae99SBarry Smith {
217147c6ae99SBarry Smith   PetscErrorCode ierr;
217247c6ae99SBarry Smith 
217347c6ae99SBarry Smith   PetscFunctionBegin;
2174171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
217547c6ae99SBarry Smith   if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
217647c6ae99SBarry Smith   if (nlevels == 0) PetscFunctionReturn(0);
217747c6ae99SBarry Smith   PetscValidPointer(dmc,3);
217847c6ae99SBarry Smith   if (dm->ops->coarsenhierarchy) {
217947c6ae99SBarry Smith     ierr = (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);CHKERRQ(ierr);
218047c6ae99SBarry Smith   } else if (dm->ops->coarsen) {
218147c6ae99SBarry Smith     PetscInt i;
218247c6ae99SBarry Smith 
218347c6ae99SBarry Smith     ierr = DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);CHKERRQ(ierr);
218447c6ae99SBarry Smith     for (i=1; i<nlevels; i++) {
218547c6ae99SBarry Smith       ierr = DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);CHKERRQ(ierr);
218647c6ae99SBarry Smith     }
218747c6ae99SBarry Smith   } else {
218847c6ae99SBarry Smith     SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
218947c6ae99SBarry Smith   }
219047c6ae99SBarry Smith   PetscFunctionReturn(0);
219147c6ae99SBarry Smith }
219247c6ae99SBarry Smith 
219347c6ae99SBarry Smith #undef __FUNCT__
2194e727c939SJed Brown #define __FUNCT__ "DMCreateAggregates"
219547c6ae99SBarry Smith /*@
2196e727c939SJed Brown    DMCreateAggregates - Gets the aggregates that map between
219747c6ae99SBarry Smith    grids associated with two DMs.
219847c6ae99SBarry Smith 
219947c6ae99SBarry Smith    Collective on DM
220047c6ae99SBarry Smith 
220147c6ae99SBarry Smith    Input Parameters:
220247c6ae99SBarry Smith +  dmc - the coarse grid DM
220347c6ae99SBarry Smith -  dmf - the fine grid DM
220447c6ae99SBarry Smith 
220547c6ae99SBarry Smith    Output Parameters:
220647c6ae99SBarry Smith .  rest - the restriction matrix (transpose of the projection matrix)
220747c6ae99SBarry Smith 
220847c6ae99SBarry Smith    Level: intermediate
220947c6ae99SBarry Smith 
221047c6ae99SBarry Smith .keywords: interpolation, restriction, multigrid
221147c6ae99SBarry Smith 
2212e727c939SJed Brown .seealso: DMRefine(), DMCreateInjection(), DMCreateInterpolation()
221347c6ae99SBarry Smith @*/
2214e727c939SJed Brown PetscErrorCode  DMCreateAggregates(DM dmc, DM dmf, Mat *rest)
221547c6ae99SBarry Smith {
221647c6ae99SBarry Smith   PetscErrorCode ierr;
221747c6ae99SBarry Smith 
221847c6ae99SBarry Smith   PetscFunctionBegin;
2219171400e9SBarry Smith   PetscValidHeaderSpecific(dmc,DM_CLASSID,1);
2220171400e9SBarry Smith   PetscValidHeaderSpecific(dmf,DM_CLASSID,2);
222147c6ae99SBarry Smith   ierr = (*dmc->ops->getaggregates)(dmc, dmf, rest);CHKERRQ(ierr);
222247c6ae99SBarry Smith   PetscFunctionReturn(0);
222347c6ae99SBarry Smith }
222447c6ae99SBarry Smith 
222547c6ae99SBarry Smith #undef __FUNCT__
22261a266240SBarry Smith #define __FUNCT__ "DMSetApplicationContextDestroy"
22271a266240SBarry Smith /*@C
22281a266240SBarry Smith     DMSetApplicationContextDestroy - Sets a user function that will be called to destroy the application context when the DM is destroyed
22291a266240SBarry Smith 
22301a266240SBarry Smith     Not Collective
22311a266240SBarry Smith 
22321a266240SBarry Smith     Input Parameters:
22331a266240SBarry Smith +   dm - the DM object
22341a266240SBarry Smith -   destroy - the destroy function
22351a266240SBarry Smith 
22361a266240SBarry Smith     Level: intermediate
22371a266240SBarry Smith 
2238e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
22391a266240SBarry Smith 
2240f07f9ceaSJed Brown @*/
22411a266240SBarry Smith PetscErrorCode  DMSetApplicationContextDestroy(DM dm,PetscErrorCode (*destroy)(void**))
22421a266240SBarry Smith {
22431a266240SBarry Smith   PetscFunctionBegin;
2244171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
22451a266240SBarry Smith   dm->ctxdestroy = destroy;
22461a266240SBarry Smith   PetscFunctionReturn(0);
22471a266240SBarry Smith }
22481a266240SBarry Smith 
22491a266240SBarry Smith #undef __FUNCT__
22501b2093e4SBarry Smith #define __FUNCT__ "DMSetApplicationContext"
2251b07ff414SBarry Smith /*@
22521b2093e4SBarry Smith     DMSetApplicationContext - Set a user context into a DM object
225347c6ae99SBarry Smith 
225447c6ae99SBarry Smith     Not Collective
225547c6ae99SBarry Smith 
225647c6ae99SBarry Smith     Input Parameters:
225747c6ae99SBarry Smith +   dm - the DM object
225847c6ae99SBarry Smith -   ctx - the user context
225947c6ae99SBarry Smith 
226047c6ae99SBarry Smith     Level: intermediate
226147c6ae99SBarry Smith 
2262e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
226347c6ae99SBarry Smith 
226447c6ae99SBarry Smith @*/
22651b2093e4SBarry Smith PetscErrorCode  DMSetApplicationContext(DM dm,void *ctx)
226647c6ae99SBarry Smith {
226747c6ae99SBarry Smith   PetscFunctionBegin;
2268171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
226947c6ae99SBarry Smith   dm->ctx = ctx;
227047c6ae99SBarry Smith   PetscFunctionReturn(0);
227147c6ae99SBarry Smith }
227247c6ae99SBarry Smith 
227347c6ae99SBarry Smith #undef __FUNCT__
22741b2093e4SBarry Smith #define __FUNCT__ "DMGetApplicationContext"
227547c6ae99SBarry Smith /*@
22761b2093e4SBarry Smith     DMGetApplicationContext - Gets a user context from a DM object
227747c6ae99SBarry Smith 
227847c6ae99SBarry Smith     Not Collective
227947c6ae99SBarry Smith 
228047c6ae99SBarry Smith     Input Parameter:
228147c6ae99SBarry Smith .   dm - the DM object
228247c6ae99SBarry Smith 
228347c6ae99SBarry Smith     Output Parameter:
228447c6ae99SBarry Smith .   ctx - the user context
228547c6ae99SBarry Smith 
228647c6ae99SBarry Smith     Level: intermediate
228747c6ae99SBarry Smith 
2288e727c939SJed Brown .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
228947c6ae99SBarry Smith 
229047c6ae99SBarry Smith @*/
22911b2093e4SBarry Smith PetscErrorCode  DMGetApplicationContext(DM dm,void *ctx)
229247c6ae99SBarry Smith {
229347c6ae99SBarry Smith   PetscFunctionBegin;
2294171400e9SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
22951b2093e4SBarry Smith   *(void**)ctx = dm->ctx;
229647c6ae99SBarry Smith   PetscFunctionReturn(0);
229747c6ae99SBarry Smith }
229847c6ae99SBarry Smith 
229947c6ae99SBarry Smith #undef __FUNCT__
230008da532bSDmitry Karpeev #define __FUNCT__ "DMSetVariableBounds"
230108da532bSDmitry Karpeev /*@C
230208da532bSDmitry Karpeev     DMSetVariableBounds - sets a function to compute the the lower and upper bound vectors for SNESVI.
230308da532bSDmitry Karpeev 
230408da532bSDmitry Karpeev     Logically Collective on DM
230508da532bSDmitry Karpeev 
230608da532bSDmitry Karpeev     Input Parameter:
230708da532bSDmitry Karpeev +   dm - the DM object
230808da532bSDmitry Karpeev -   f - the function that computes variable bounds used by SNESVI (use PETSC_NULL to cancel a previous function that was set)
230908da532bSDmitry Karpeev 
231008da532bSDmitry Karpeev     Level: intermediate
231108da532bSDmitry Karpeev 
2312835c3ec7SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext(),
231308da532bSDmitry Karpeev          DMSetJacobian()
231408da532bSDmitry Karpeev 
231508da532bSDmitry Karpeev @*/
231608da532bSDmitry Karpeev PetscErrorCode  DMSetVariableBounds(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
231708da532bSDmitry Karpeev {
231808da532bSDmitry Karpeev   PetscFunctionBegin;
231908da532bSDmitry Karpeev   dm->ops->computevariablebounds = f;
232008da532bSDmitry Karpeev   PetscFunctionReturn(0);
232108da532bSDmitry Karpeev }
232208da532bSDmitry Karpeev 
232308da532bSDmitry Karpeev #undef __FUNCT__
232408da532bSDmitry Karpeev #define __FUNCT__ "DMHasVariableBounds"
232508da532bSDmitry Karpeev /*@
232608da532bSDmitry Karpeev     DMHasVariableBounds - does the DM object have a variable bounds function?
232708da532bSDmitry Karpeev 
232808da532bSDmitry Karpeev     Not Collective
232908da532bSDmitry Karpeev 
233008da532bSDmitry Karpeev     Input Parameter:
233108da532bSDmitry Karpeev .   dm - the DM object to destroy
233208da532bSDmitry Karpeev 
233308da532bSDmitry Karpeev     Output Parameter:
233408da532bSDmitry Karpeev .   flg - PETSC_TRUE if the variable bounds function exists
233508da532bSDmitry Karpeev 
233608da532bSDmitry Karpeev     Level: developer
233708da532bSDmitry Karpeev 
233874e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
233908da532bSDmitry Karpeev 
234008da532bSDmitry Karpeev @*/
234108da532bSDmitry Karpeev PetscErrorCode  DMHasVariableBounds(DM dm,PetscBool  *flg)
234208da532bSDmitry Karpeev {
234308da532bSDmitry Karpeev   PetscFunctionBegin;
234408da532bSDmitry Karpeev   *flg =  (dm->ops->computevariablebounds) ? PETSC_TRUE : PETSC_FALSE;
234508da532bSDmitry Karpeev   PetscFunctionReturn(0);
234608da532bSDmitry Karpeev }
234708da532bSDmitry Karpeev 
234808da532bSDmitry Karpeev #undef __FUNCT__
234908da532bSDmitry Karpeev #define __FUNCT__ "DMComputeVariableBounds"
235008da532bSDmitry Karpeev /*@C
235108da532bSDmitry Karpeev     DMComputeVariableBounds - compute variable bounds used by SNESVI.
235208da532bSDmitry Karpeev 
235308da532bSDmitry Karpeev     Logically Collective on DM
235408da532bSDmitry Karpeev 
235508da532bSDmitry Karpeev     Input Parameters:
235608da532bSDmitry Karpeev +   dm - the DM object to destroy
235708da532bSDmitry Karpeev -   x  - current solution at which the bounds are computed
235808da532bSDmitry Karpeev 
235908da532bSDmitry Karpeev     Output parameters:
236008da532bSDmitry Karpeev +   xl - lower bound
236108da532bSDmitry Karpeev -   xu - upper bound
236208da532bSDmitry Karpeev 
236308da532bSDmitry Karpeev     Level: intermediate
236408da532bSDmitry Karpeev 
236574e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
236608da532bSDmitry Karpeev 
236708da532bSDmitry Karpeev @*/
236808da532bSDmitry Karpeev PetscErrorCode  DMComputeVariableBounds(DM dm, Vec xl, Vec xu)
236908da532bSDmitry Karpeev {
237008da532bSDmitry Karpeev   PetscErrorCode ierr;
237108da532bSDmitry Karpeev   PetscFunctionBegin;
237208da532bSDmitry Karpeev   PetscValidHeaderSpecific(xl,VEC_CLASSID,2);
237308da532bSDmitry Karpeev   PetscValidHeaderSpecific(xu,VEC_CLASSID,2);
237408da532bSDmitry Karpeev   if (dm->ops->computevariablebounds) {
237508da532bSDmitry Karpeev     ierr = (*dm->ops->computevariablebounds)(dm, xl,xu); CHKERRQ(ierr);
237608da532bSDmitry Karpeev   }
2377a201590fSDmitry Karpeev   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "This DM is incapable of computing variable bounds.");
237808da532bSDmitry Karpeev   PetscFunctionReturn(0);
237908da532bSDmitry Karpeev }
238008da532bSDmitry Karpeev 
238108da532bSDmitry Karpeev #undef __FUNCT__
2382b0ae01b7SPeter Brune #define __FUNCT__ "DMHasColoring"
2383b0ae01b7SPeter Brune /*@
2384b0ae01b7SPeter Brune     DMHasColoring - does the DM object have a method of providing a coloring?
2385b0ae01b7SPeter Brune 
2386b0ae01b7SPeter Brune     Not Collective
2387b0ae01b7SPeter Brune 
2388b0ae01b7SPeter Brune     Input Parameter:
2389b0ae01b7SPeter Brune .   dm - the DM object
2390b0ae01b7SPeter Brune 
2391b0ae01b7SPeter Brune     Output Parameter:
2392b0ae01b7SPeter Brune .   flg - PETSC_TRUE if the DM has facilities for DMCreateColoring().
2393b0ae01b7SPeter Brune 
2394b0ae01b7SPeter Brune     Level: developer
2395b0ae01b7SPeter Brune 
2396b0ae01b7SPeter Brune .seealso DMHasFunction(), DMCreateColoring()
2397b0ae01b7SPeter Brune 
2398b0ae01b7SPeter Brune @*/
2399b0ae01b7SPeter Brune PetscErrorCode  DMHasColoring(DM dm,PetscBool  *flg)
2400b0ae01b7SPeter Brune {
2401b0ae01b7SPeter Brune   PetscFunctionBegin;
2402b0ae01b7SPeter Brune   *flg =  (dm->ops->getcoloring) ? PETSC_TRUE : PETSC_FALSE;
2403b0ae01b7SPeter Brune   PetscFunctionReturn(0);
2404b0ae01b7SPeter Brune }
2405b0ae01b7SPeter Brune 
2406b0ae01b7SPeter Brune #undef  __FUNCT__
240708da532bSDmitry Karpeev #define __FUNCT__ "DMSetVec"
2408748fac09SDmitry Karpeev /*@C
240908da532bSDmitry Karpeev     DMSetVec - set the vector at which to compute residual, Jacobian and VI bounds, if the problem is nonlinear.
241008da532bSDmitry Karpeev 
241108da532bSDmitry Karpeev     Collective on DM
241208da532bSDmitry Karpeev 
241308da532bSDmitry Karpeev     Input Parameter:
241408da532bSDmitry Karpeev +   dm - the DM object
2415e88d7f4bSDmitry Karpeev -   x - location to compute residual and Jacobian, if PETSC_NULL is passed to those routines; will be PETSC_NULL for linear problems.
241608da532bSDmitry Karpeev 
241708da532bSDmitry Karpeev     Level: developer
241808da532bSDmitry Karpeev 
241974e1e8c1SBarry Smith .seealso DMView(), DMCreateGlobalVector(), DMCreateInterpolation(), DMCreateColoring(), DMCreateMatrix(), DMGetApplicationContext()
242008da532bSDmitry Karpeev 
242108da532bSDmitry Karpeev @*/
242208da532bSDmitry Karpeev PetscErrorCode  DMSetVec(DM dm,Vec x)
242308da532bSDmitry Karpeev {
242408da532bSDmitry Karpeev   PetscErrorCode ierr;
242508da532bSDmitry Karpeev   PetscFunctionBegin;
242608da532bSDmitry Karpeev   if (x) {
242708da532bSDmitry Karpeev     if (!dm->x) {
242808da532bSDmitry Karpeev       ierr = DMCreateGlobalVector(dm,&dm->x);CHKERRQ(ierr);
242908da532bSDmitry Karpeev     }
243008da532bSDmitry Karpeev     ierr = VecCopy(x,dm->x);CHKERRQ(ierr);
243108da532bSDmitry Karpeev   }
243208da532bSDmitry Karpeev   else if (dm->x) {
243308da532bSDmitry Karpeev     ierr = VecDestroy(&dm->x);  CHKERRQ(ierr);
243408da532bSDmitry Karpeev   }
243508da532bSDmitry Karpeev   PetscFunctionReturn(0);
243608da532bSDmitry Karpeev }
243708da532bSDmitry Karpeev 
2438264ace61SBarry Smith PetscFList DMList                       = PETSC_NULL;
2439264ace61SBarry Smith PetscBool  DMRegisterAllCalled          = PETSC_FALSE;
2440264ace61SBarry Smith 
2441264ace61SBarry Smith #undef __FUNCT__
2442264ace61SBarry Smith #define __FUNCT__ "DMSetType"
2443264ace61SBarry Smith /*@C
2444264ace61SBarry Smith   DMSetType - Builds a DM, for a particular DM implementation.
2445264ace61SBarry Smith 
2446264ace61SBarry Smith   Collective on DM
2447264ace61SBarry Smith 
2448264ace61SBarry Smith   Input Parameters:
2449264ace61SBarry Smith + dm     - The DM object
2450264ace61SBarry Smith - method - The name of the DM type
2451264ace61SBarry Smith 
2452264ace61SBarry Smith   Options Database Key:
2453264ace61SBarry Smith . -dm_type <type> - Sets the DM type; use -help for a list of available types
2454264ace61SBarry Smith 
2455264ace61SBarry Smith   Notes:
2456e1589f56SBarry Smith   See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
2457264ace61SBarry Smith 
2458264ace61SBarry Smith   Level: intermediate
2459264ace61SBarry Smith 
2460264ace61SBarry Smith .keywords: DM, set, type
2461264ace61SBarry Smith .seealso: DMGetType(), DMCreate()
2462264ace61SBarry Smith @*/
246319fd82e9SBarry Smith PetscErrorCode  DMSetType(DM dm, DMType method)
2464264ace61SBarry Smith {
2465264ace61SBarry Smith   PetscErrorCode (*r)(DM);
2466264ace61SBarry Smith   PetscBool      match;
2467264ace61SBarry Smith   PetscErrorCode ierr;
2468264ace61SBarry Smith 
2469264ace61SBarry Smith   PetscFunctionBegin;
2470264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2471251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, method, &match);CHKERRQ(ierr);
2472264ace61SBarry Smith   if (match) PetscFunctionReturn(0);
2473264ace61SBarry Smith 
2474264ace61SBarry Smith   if (!DMRegisterAllCalled) {ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
24754b91b6eaSBarry Smith   ierr = PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
247632c0f0efSBarry Smith   if (!r) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
2477264ace61SBarry Smith 
2478264ace61SBarry Smith   if (dm->ops->destroy) {
2479264ace61SBarry Smith     ierr = (*dm->ops->destroy)(dm);CHKERRQ(ierr);
2480b5c23020SJed Brown     dm->ops->destroy = PETSC_NULL;
2481264ace61SBarry Smith   }
2482264ace61SBarry Smith   ierr = (*r)(dm);CHKERRQ(ierr);
2483264ace61SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)dm,method);CHKERRQ(ierr);
2484264ace61SBarry Smith   PetscFunctionReturn(0);
2485264ace61SBarry Smith }
2486264ace61SBarry Smith 
2487264ace61SBarry Smith #undef __FUNCT__
2488264ace61SBarry Smith #define __FUNCT__ "DMGetType"
2489264ace61SBarry Smith /*@C
2490264ace61SBarry Smith   DMGetType - Gets the DM type name (as a string) from the DM.
2491264ace61SBarry Smith 
2492264ace61SBarry Smith   Not Collective
2493264ace61SBarry Smith 
2494264ace61SBarry Smith   Input Parameter:
2495264ace61SBarry Smith . dm  - The DM
2496264ace61SBarry Smith 
2497264ace61SBarry Smith   Output Parameter:
2498264ace61SBarry Smith . type - The DM type name
2499264ace61SBarry Smith 
2500264ace61SBarry Smith   Level: intermediate
2501264ace61SBarry Smith 
2502264ace61SBarry Smith .keywords: DM, get, type, name
2503264ace61SBarry Smith .seealso: DMSetType(), DMCreate()
2504264ace61SBarry Smith @*/
250519fd82e9SBarry Smith PetscErrorCode  DMGetType(DM dm, DMType *type)
2506264ace61SBarry Smith {
2507264ace61SBarry Smith   PetscErrorCode ierr;
2508264ace61SBarry Smith 
2509264ace61SBarry Smith   PetscFunctionBegin;
2510264ace61SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID,1);
2511264ace61SBarry Smith   PetscValidCharPointer(type,2);
2512264ace61SBarry Smith   if (!DMRegisterAllCalled) {
2513264ace61SBarry Smith     ierr = DMRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2514264ace61SBarry Smith   }
2515264ace61SBarry Smith   *type = ((PetscObject)dm)->type_name;
2516264ace61SBarry Smith   PetscFunctionReturn(0);
2517264ace61SBarry Smith }
2518264ace61SBarry Smith 
251967a56275SMatthew G Knepley #undef __FUNCT__
252067a56275SMatthew G Knepley #define __FUNCT__ "DMConvert"
252167a56275SMatthew G Knepley /*@C
252267a56275SMatthew G Knepley   DMConvert - Converts a DM to another DM, either of the same or different type.
252367a56275SMatthew G Knepley 
252467a56275SMatthew G Knepley   Collective on DM
252567a56275SMatthew G Knepley 
252667a56275SMatthew G Knepley   Input Parameters:
252767a56275SMatthew G Knepley + dm - the DM
252867a56275SMatthew G Knepley - newtype - new DM type (use "same" for the same type)
252967a56275SMatthew G Knepley 
253067a56275SMatthew G Knepley   Output Parameter:
253167a56275SMatthew G Knepley . M - pointer to new DM
253267a56275SMatthew G Knepley 
253367a56275SMatthew G Knepley   Notes:
253467a56275SMatthew G Knepley   Cannot be used to convert a sequential DM to parallel or parallel to sequential,
253567a56275SMatthew G Knepley   the MPI communicator of the generated DM is always the same as the communicator
253667a56275SMatthew G Knepley   of the input DM.
253767a56275SMatthew G Knepley 
253867a56275SMatthew G Knepley   Level: intermediate
253967a56275SMatthew G Knepley 
254067a56275SMatthew G Knepley .seealso: DMCreate()
254167a56275SMatthew G Knepley @*/
254219fd82e9SBarry Smith PetscErrorCode DMConvert(DM dm, DMType newtype, DM *M)
254367a56275SMatthew G Knepley {
254467a56275SMatthew G Knepley   DM             B;
254567a56275SMatthew G Knepley   char           convname[256];
254667a56275SMatthew G Knepley   PetscBool      sametype, issame;
254767a56275SMatthew G Knepley   PetscErrorCode ierr;
254867a56275SMatthew G Knepley 
254967a56275SMatthew G Knepley   PetscFunctionBegin;
255067a56275SMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
255167a56275SMatthew G Knepley   PetscValidType(dm,1);
255267a56275SMatthew G Knepley   PetscValidPointer(M,3);
2553251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject) dm, newtype, &sametype);CHKERRQ(ierr);
255467a56275SMatthew G Knepley   ierr = PetscStrcmp(newtype, "same", &issame);CHKERRQ(ierr);
255567a56275SMatthew G Knepley   {
255619fd82e9SBarry Smith     PetscErrorCode (*conv)(DM, DMType, DM *) = PETSC_NULL;
255767a56275SMatthew G Knepley 
255867a56275SMatthew G Knepley     /*
255967a56275SMatthew G Knepley        Order of precedence:
256067a56275SMatthew G Knepley        1) See if a specialized converter is known to the current DM.
256167a56275SMatthew G Knepley        2) See if a specialized converter is known to the desired DM class.
256267a56275SMatthew G Knepley        3) See if a good general converter is registered for the desired class
256367a56275SMatthew G Knepley        4) See if a good general converter is known for the current matrix.
256467a56275SMatthew G Knepley        5) Use a really basic converter.
256567a56275SMatthew G Knepley     */
256667a56275SMatthew G Knepley 
256767a56275SMatthew G Knepley     /* 1) See if a specialized converter is known to the current DM and the desired class */
256867a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
256967a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
257067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
257167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
257267a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
257367a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);CHKERRQ(ierr);
257467a56275SMatthew G Knepley     if (conv) goto foundconv;
257567a56275SMatthew G Knepley 
257667a56275SMatthew G Knepley     /* 2)  See if a specialized converter is known to the desired DM class. */
257767a56275SMatthew G Knepley     ierr = DMCreate(((PetscObject) dm)->comm, &B);CHKERRQ(ierr);
257867a56275SMatthew G Knepley     ierr = DMSetType(B, newtype);CHKERRQ(ierr);
257967a56275SMatthew G Knepley     ierr = PetscStrcpy(convname,"DMConvert_");CHKERRQ(ierr);
258067a56275SMatthew G Knepley     ierr = PetscStrcat(convname,((PetscObject) dm)->type_name);CHKERRQ(ierr);
258167a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
258267a56275SMatthew G Knepley     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
258367a56275SMatthew G Knepley     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
258467a56275SMatthew G Knepley     ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
258567a56275SMatthew G Knepley     if (conv) {
2586fcfd50ebSBarry Smith       ierr = DMDestroy(&B);CHKERRQ(ierr);
258767a56275SMatthew G Knepley       goto foundconv;
258867a56275SMatthew G Knepley     }
258967a56275SMatthew G Knepley 
259067a56275SMatthew G Knepley #if 0
259167a56275SMatthew G Knepley     /* 3) See if a good general converter is registered for the desired class */
259267a56275SMatthew G Knepley     conv = B->ops->convertfrom;
2593fcfd50ebSBarry Smith     ierr = DMDestroy(&B);CHKERRQ(ierr);
259467a56275SMatthew G Knepley     if (conv) goto foundconv;
259567a56275SMatthew G Knepley 
259667a56275SMatthew G Knepley     /* 4) See if a good general converter is known for the current matrix */
259767a56275SMatthew G Knepley     if (dm->ops->convert) {
259867a56275SMatthew G Knepley       conv = dm->ops->convert;
259967a56275SMatthew G Knepley     }
260067a56275SMatthew G Knepley     if (conv) goto foundconv;
260167a56275SMatthew G Knepley #endif
260267a56275SMatthew G Knepley 
260367a56275SMatthew G Knepley     /* 5) Use a really basic converter. */
260467a56275SMatthew G Knepley     SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
260567a56275SMatthew G Knepley 
260667a56275SMatthew G Knepley     foundconv:
260767a56275SMatthew G Knepley     ierr = PetscLogEventBegin(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
260867a56275SMatthew G Knepley     ierr = (*conv)(dm,newtype,M);CHKERRQ(ierr);
260967a56275SMatthew G Knepley     ierr = PetscLogEventEnd(DM_Convert,dm,0,0,0);CHKERRQ(ierr);
261067a56275SMatthew G Knepley   }
261167a56275SMatthew G Knepley   ierr = PetscObjectStateIncrease((PetscObject) *M);CHKERRQ(ierr);
261267a56275SMatthew G Knepley   PetscFunctionReturn(0);
261367a56275SMatthew G Knepley }
2614264ace61SBarry Smith 
2615264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2616264ace61SBarry Smith 
2617264ace61SBarry Smith #undef __FUNCT__
2618264ace61SBarry Smith #define __FUNCT__ "DMRegister"
2619264ace61SBarry Smith /*@C
2620264ace61SBarry Smith   DMRegister - See DMRegisterDynamic()
2621264ace61SBarry Smith 
2622264ace61SBarry Smith   Level: advanced
2623264ace61SBarry Smith @*/
26247087cfbeSBarry Smith PetscErrorCode  DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
2625264ace61SBarry Smith {
2626264ace61SBarry Smith   char fullname[PETSC_MAX_PATH_LEN];
2627264ace61SBarry Smith   PetscErrorCode ierr;
2628264ace61SBarry Smith 
2629264ace61SBarry Smith   PetscFunctionBegin;
2630264ace61SBarry Smith   ierr = PetscStrcpy(fullname, path);CHKERRQ(ierr);
2631264ace61SBarry Smith   ierr = PetscStrcat(fullname, ":");CHKERRQ(ierr);
2632264ace61SBarry Smith   ierr = PetscStrcat(fullname, name);CHKERRQ(ierr);
2633264ace61SBarry Smith   ierr = PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);CHKERRQ(ierr);
2634264ace61SBarry Smith   PetscFunctionReturn(0);
2635264ace61SBarry Smith }
2636264ace61SBarry Smith 
2637264ace61SBarry Smith 
2638264ace61SBarry Smith /*--------------------------------------------------------------------------------------------------------------------*/
2639264ace61SBarry Smith #undef __FUNCT__
2640264ace61SBarry Smith #define __FUNCT__ "DMRegisterDestroy"
2641264ace61SBarry Smith /*@C
2642264ace61SBarry Smith    DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
2643264ace61SBarry Smith 
2644264ace61SBarry Smith    Not Collective
2645264ace61SBarry Smith 
2646264ace61SBarry Smith    Level: advanced
2647264ace61SBarry Smith 
2648264ace61SBarry Smith .keywords: DM, register, destroy
2649264ace61SBarry Smith .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
2650264ace61SBarry Smith @*/
26517087cfbeSBarry Smith PetscErrorCode  DMRegisterDestroy(void)
2652264ace61SBarry Smith {
2653264ace61SBarry Smith   PetscErrorCode ierr;
2654264ace61SBarry Smith 
2655264ace61SBarry Smith   PetscFunctionBegin;
2656264ace61SBarry Smith   ierr = PetscFListDestroy(&DMList);CHKERRQ(ierr);
2657264ace61SBarry Smith   DMRegisterAllCalled = PETSC_FALSE;
2658264ace61SBarry Smith   PetscFunctionReturn(0);
2659264ace61SBarry Smith }
266023f975d1SBarry Smith 
2661b859378eSBarry Smith #undef __FUNCT__
2662b859378eSBarry Smith #define __FUNCT__ "DMLoad"
2663b859378eSBarry Smith /*@C
266455849f57SBarry Smith   DMLoad - Loads a DM that has been stored in binary  with DMView().
2665b859378eSBarry Smith 
2666b859378eSBarry Smith   Collective on PetscViewer
2667b859378eSBarry Smith 
2668b859378eSBarry Smith   Input Parameters:
2669b859378eSBarry Smith + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
2670b859378eSBarry Smith            some related function before a call to DMLoad().
2671b859378eSBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
2672b859378eSBarry Smith            HDF5 file viewer, obtained from PetscViewerHDF5Open()
2673b859378eSBarry Smith 
2674b859378eSBarry Smith    Level: intermediate
2675b859378eSBarry Smith 
2676b859378eSBarry Smith   Notes:
267755849f57SBarry Smith    The type is determined by the data in the file, any type set into the DM before this call is ignored.
2678b859378eSBarry Smith 
2679b859378eSBarry Smith   Notes for advanced users:
2680b859378eSBarry Smith   Most users should not need to know the details of the binary storage
2681b859378eSBarry Smith   format, since DMLoad() and DMView() completely hide these details.
2682b859378eSBarry Smith   But for anyone who's interested, the standard binary matrix storage
2683b859378eSBarry Smith   format is
2684b859378eSBarry Smith .vb
2685b859378eSBarry Smith      has not yet been determined
2686b859378eSBarry Smith .ve
2687b859378eSBarry Smith 
2688b859378eSBarry Smith .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
2689b859378eSBarry Smith @*/
2690b859378eSBarry Smith PetscErrorCode  DMLoad(DM newdm, PetscViewer viewer)
2691b859378eSBarry Smith {
2692b859378eSBarry Smith   PetscErrorCode ierr;
269332c0f0efSBarry Smith   PetscBool      isbinary;
269455849f57SBarry Smith   PetscInt       classid;
269532c0f0efSBarry Smith   char           type[256];
2696b859378eSBarry Smith 
2697b859378eSBarry Smith   PetscFunctionBegin;
2698b859378eSBarry Smith   PetscValidHeaderSpecific(newdm,DM_CLASSID,1);
2699b859378eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
270032c0f0efSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
270132c0f0efSBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
2702b859378eSBarry Smith 
270332c0f0efSBarry Smith   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
270432c0f0efSBarry Smith   if (classid != DM_FILE_CLASSID) SETERRQ(((PetscObject)newdm)->comm,PETSC_ERR_ARG_WRONG,"Not DM next in file");
270532c0f0efSBarry Smith   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
270632c0f0efSBarry Smith   ierr = DMSetType(newdm, type);CHKERRQ(ierr);
27072d53ad75SBarry Smith   if (newdm->ops->load) {
2708b859378eSBarry Smith     ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
27092d53ad75SBarry Smith   }
2710b859378eSBarry Smith   PetscFunctionReturn(0);
2711b859378eSBarry Smith }
2712b859378eSBarry Smith 
27137da65231SMatthew G Knepley /******************************** FEM Support **********************************/
27147da65231SMatthew G Knepley 
27157da65231SMatthew G Knepley #undef __FUNCT__
27167da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellVector"
27177da65231SMatthew G Knepley PetscErrorCode DMPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
27181d47ebbbSSatish Balay   PetscInt       f;
27191b30c384SMatthew G Knepley   PetscErrorCode ierr;
27201b30c384SMatthew G Knepley 
27217da65231SMatthew G Knepley   PetscFunctionBegin;
272274778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
27231d47ebbbSSatish Balay   for (f = 0; f < len; ++f) {
272474778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  | %G |\n", PetscRealPart(x[f]));CHKERRQ(ierr);
27257da65231SMatthew G Knepley   }
27267da65231SMatthew G Knepley   PetscFunctionReturn(0);
27277da65231SMatthew G Knepley }
27287da65231SMatthew G Knepley 
27297da65231SMatthew G Knepley #undef __FUNCT__
27307da65231SMatthew G Knepley #define __FUNCT__ "DMPrintCellMatrix"
27317da65231SMatthew G Knepley PetscErrorCode DMPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
27321b30c384SMatthew G Knepley   PetscInt       f, g;
27337da65231SMatthew G Knepley   PetscErrorCode ierr;
27347da65231SMatthew G Knepley 
27357da65231SMatthew G Knepley   PetscFunctionBegin;
273674778d6cSJed Brown   ierr = PetscPrintf(PETSC_COMM_SELF, "Cell %D Element %s\n", c, name);CHKERRQ(ierr);
27371d47ebbbSSatish Balay   for (f = 0; f < rows; ++f) {
273874778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, "  |");CHKERRQ(ierr);
27391d47ebbbSSatish Balay     for (g = 0; g < cols; ++g) {
274074778d6cSJed Brown       ierr = PetscPrintf(PETSC_COMM_SELF, " % 9.5G", PetscRealPart(A[f*cols+g]));CHKERRQ(ierr);
27417da65231SMatthew G Knepley     }
274274778d6cSJed Brown     ierr = PetscPrintf(PETSC_COMM_SELF, " |\n");CHKERRQ(ierr);
27437da65231SMatthew G Knepley   }
27447da65231SMatthew G Knepley   PetscFunctionReturn(0);
27457da65231SMatthew G Knepley }
2746e7c4fc90SDmitry Karpeev 
2747970e74d5SMatthew G Knepley #undef __FUNCT__
274888ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSection"
274988ed4aceSMatthew G Knepley /*@
275088ed4aceSMatthew G Knepley   DMGetDefaultSection - Get the PetscSection encoding the local data layout for the DM.
275188ed4aceSMatthew G Knepley 
275288ed4aceSMatthew G Knepley   Input Parameter:
275388ed4aceSMatthew G Knepley . dm - The DM
275488ed4aceSMatthew G Knepley 
275588ed4aceSMatthew G Knepley   Output Parameter:
275688ed4aceSMatthew G Knepley . section - The PetscSection
275788ed4aceSMatthew G Knepley 
275888ed4aceSMatthew G Knepley   Level: intermediate
275988ed4aceSMatthew G Knepley 
276088ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
276188ed4aceSMatthew G Knepley 
276288ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
276388ed4aceSMatthew G Knepley @*/
276488ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *section) {
276588ed4aceSMatthew G Knepley   PetscFunctionBegin;
276688ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
276788ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
276888ed4aceSMatthew G Knepley   *section = dm->defaultSection;
276988ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
277088ed4aceSMatthew G Knepley }
277188ed4aceSMatthew G Knepley 
277288ed4aceSMatthew G Knepley #undef __FUNCT__
277388ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSection"
277488ed4aceSMatthew G Knepley /*@
277588ed4aceSMatthew G Knepley   DMSetDefaultSection - Set the PetscSection encoding the local data layout for the DM.
277688ed4aceSMatthew G Knepley 
277788ed4aceSMatthew G Knepley   Input Parameters:
277888ed4aceSMatthew G Knepley + dm - The DM
277988ed4aceSMatthew G Knepley - section - The PetscSection
278088ed4aceSMatthew G Knepley 
278188ed4aceSMatthew G Knepley   Level: intermediate
278288ed4aceSMatthew G Knepley 
278388ed4aceSMatthew G Knepley   Note: Any existing Section will be destroyed
278488ed4aceSMatthew G Knepley 
278588ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultGlobalSection()
278688ed4aceSMatthew G Knepley @*/
278788ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSection(DM dm, PetscSection section) {
2788af122d2aSMatthew G Knepley   PetscInt       numFields;
2789af122d2aSMatthew G Knepley   PetscInt       f;
279088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
279188ed4aceSMatthew G Knepley 
279288ed4aceSMatthew G Knepley   PetscFunctionBegin;
279388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
279488ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultSection);CHKERRQ(ierr);
279588ed4aceSMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
279688ed4aceSMatthew G Knepley   dm->defaultSection = section;
2797af122d2aSMatthew G Knepley   ierr = PetscSectionGetNumFields(dm->defaultSection, &numFields);CHKERRQ(ierr);
2798af122d2aSMatthew G Knepley   if (numFields) {
2799af122d2aSMatthew G Knepley     ierr = DMSetNumFields(dm, numFields);CHKERRQ(ierr);
2800af122d2aSMatthew G Knepley     for (f = 0; f < numFields; ++f) {
2801af122d2aSMatthew G Knepley       const char *name;
2802af122d2aSMatthew G Knepley 
2803af122d2aSMatthew G Knepley       ierr = PetscSectionGetFieldName(dm->defaultSection, f, &name);CHKERRQ(ierr);
2804af122d2aSMatthew G Knepley       ierr = PetscObjectSetName(dm->fields[f], name);CHKERRQ(ierr);
2805af122d2aSMatthew G Knepley     }
2806af122d2aSMatthew G Knepley   }
280788ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
280888ed4aceSMatthew G Knepley }
280988ed4aceSMatthew G Knepley 
281088ed4aceSMatthew G Knepley #undef __FUNCT__
281188ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultGlobalSection"
281288ed4aceSMatthew G Knepley /*@
281388ed4aceSMatthew G Knepley   DMGetDefaultGlobalSection - Get the PetscSection encoding the global data layout for the DM.
281488ed4aceSMatthew G Knepley 
28158b1ab98fSJed Brown   Collective on DM
28168b1ab98fSJed Brown 
281788ed4aceSMatthew G Knepley   Input Parameter:
281888ed4aceSMatthew G Knepley . dm - The DM
281988ed4aceSMatthew G Knepley 
282088ed4aceSMatthew G Knepley   Output Parameter:
282188ed4aceSMatthew G Knepley . section - The PetscSection
282288ed4aceSMatthew G Knepley 
282388ed4aceSMatthew G Knepley   Level: intermediate
282488ed4aceSMatthew G Knepley 
282588ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSection.
282688ed4aceSMatthew G Knepley 
282788ed4aceSMatthew G Knepley .seealso: DMSetDefaultSection(), DMGetDefaultSection()
282888ed4aceSMatthew G Knepley @*/
282988ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *section) {
283088ed4aceSMatthew G Knepley   PetscErrorCode ierr;
283188ed4aceSMatthew G Knepley 
283288ed4aceSMatthew G Knepley   PetscFunctionBegin;
283388ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
283488ed4aceSMatthew G Knepley   PetscValidPointer(section, 2);
283588ed4aceSMatthew G Knepley   if (!dm->defaultGlobalSection) {
283640e8a239SMatthew 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");
2837b21d0597SMatthew G Knepley     ierr = PetscSectionCreateGlobalSection(dm->defaultSection, dm->sf, PETSC_FALSE, &dm->defaultGlobalSection);CHKERRQ(ierr);
28388b1ab98fSJed Brown     ierr = PetscSectionGetValueLayout(((PetscObject)dm)->comm,dm->defaultGlobalSection,&dm->map);CHKERRQ(ierr);
283988ed4aceSMatthew G Knepley   }
284088ed4aceSMatthew G Knepley   *section = dm->defaultGlobalSection;
284188ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
284288ed4aceSMatthew G Knepley }
284388ed4aceSMatthew G Knepley 
284488ed4aceSMatthew G Knepley #undef __FUNCT__
2845b21d0597SMatthew G Knepley #define __FUNCT__ "DMSetDefaultGlobalSection"
2846b21d0597SMatthew G Knepley /*@
2847b21d0597SMatthew G Knepley   DMSetDefaultGlobalSection - Set the PetscSection encoding the global data layout for the DM.
2848b21d0597SMatthew G Knepley 
2849b21d0597SMatthew G Knepley   Input Parameters:
2850b21d0597SMatthew G Knepley + dm - The DM
2851b21d0597SMatthew G Knepley - section - The PetscSection
2852b21d0597SMatthew G Knepley 
2853b21d0597SMatthew G Knepley   Level: intermediate
2854b21d0597SMatthew G Knepley 
2855b21d0597SMatthew G Knepley   Note: Any existing Section will be destroyed
2856b21d0597SMatthew G Knepley 
2857b21d0597SMatthew G Knepley .seealso: DMGetDefaultGlobalSection(), DMSetDefaultSection()
2858b21d0597SMatthew G Knepley @*/
2859b21d0597SMatthew G Knepley PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection section) {
2860b21d0597SMatthew G Knepley   PetscErrorCode ierr;
2861b21d0597SMatthew G Knepley 
2862b21d0597SMatthew G Knepley   PetscFunctionBegin;
2863b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2864b21d0597SMatthew G Knepley   ierr = PetscSectionDestroy(&dm->defaultGlobalSection);CHKERRQ(ierr);
2865b21d0597SMatthew G Knepley   dm->defaultGlobalSection = section;
2866b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
2867b21d0597SMatthew G Knepley }
2868b21d0597SMatthew G Knepley 
2869b21d0597SMatthew G Knepley #undef __FUNCT__
287088ed4aceSMatthew G Knepley #define __FUNCT__ "DMGetDefaultSF"
287188ed4aceSMatthew G Knepley /*@
287288ed4aceSMatthew G Knepley   DMGetDefaultSF - Get the PetscSF encoding the parallel dof overlap for the DM. If it has not been set,
287388ed4aceSMatthew G Knepley   it is created from the default PetscSection layouts in the DM.
287488ed4aceSMatthew G Knepley 
287588ed4aceSMatthew G Knepley   Input Parameter:
287688ed4aceSMatthew G Knepley . dm - The DM
287788ed4aceSMatthew G Knepley 
287888ed4aceSMatthew G Knepley   Output Parameter:
287988ed4aceSMatthew G Knepley . sf - The PetscSF
288088ed4aceSMatthew G Knepley 
288188ed4aceSMatthew G Knepley   Level: intermediate
288288ed4aceSMatthew G Knepley 
288388ed4aceSMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
288488ed4aceSMatthew G Knepley 
288588ed4aceSMatthew G Knepley .seealso: DMSetDefaultSF(), DMCreateDefaultSF()
288688ed4aceSMatthew G Knepley @*/
288788ed4aceSMatthew G Knepley PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *sf) {
288888ed4aceSMatthew G Knepley   PetscInt       nroots;
288988ed4aceSMatthew G Knepley   PetscErrorCode ierr;
289088ed4aceSMatthew G Knepley 
289188ed4aceSMatthew G Knepley   PetscFunctionBegin;
289288ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
289388ed4aceSMatthew G Knepley   PetscValidPointer(sf, 2);
289488ed4aceSMatthew G Knepley   ierr = PetscSFGetGraph(dm->defaultSF, &nroots, PETSC_NULL, PETSC_NULL, PETSC_NULL);CHKERRQ(ierr);
289588ed4aceSMatthew G Knepley   if (nroots < 0) {
289688ed4aceSMatthew G Knepley     PetscSection section, gSection;
289788ed4aceSMatthew G Knepley 
289888ed4aceSMatthew G Knepley     ierr = DMGetDefaultSection(dm, &section);CHKERRQ(ierr);
289931ea6d37SMatthew G Knepley     if (section) {
290088ed4aceSMatthew G Knepley       ierr = DMGetDefaultGlobalSection(dm, &gSection);CHKERRQ(ierr);
290188ed4aceSMatthew G Knepley       ierr = DMCreateDefaultSF(dm, section, gSection);CHKERRQ(ierr);
290231ea6d37SMatthew G Knepley     } else {
290331ea6d37SMatthew G Knepley       *sf = PETSC_NULL;
290431ea6d37SMatthew G Knepley       PetscFunctionReturn(0);
290531ea6d37SMatthew G Knepley     }
290688ed4aceSMatthew G Knepley   }
290788ed4aceSMatthew G Knepley   *sf = dm->defaultSF;
290888ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
290988ed4aceSMatthew G Knepley }
291088ed4aceSMatthew G Knepley 
291188ed4aceSMatthew G Knepley #undef __FUNCT__
291288ed4aceSMatthew G Knepley #define __FUNCT__ "DMSetDefaultSF"
291388ed4aceSMatthew G Knepley /*@
291488ed4aceSMatthew G Knepley   DMSetDefaultSF - Set the PetscSF encoding the parallel dof overlap for the DM
291588ed4aceSMatthew G Knepley 
291688ed4aceSMatthew G Knepley   Input Parameters:
291788ed4aceSMatthew G Knepley + dm - The DM
291888ed4aceSMatthew G Knepley - sf - The PetscSF
291988ed4aceSMatthew G Knepley 
292088ed4aceSMatthew G Knepley   Level: intermediate
292188ed4aceSMatthew G Knepley 
292288ed4aceSMatthew G Knepley   Note: Any previous SF is destroyed
292388ed4aceSMatthew G Knepley 
292488ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMCreateDefaultSF()
292588ed4aceSMatthew G Knepley @*/
292688ed4aceSMatthew G Knepley PetscErrorCode DMSetDefaultSF(DM dm, PetscSF sf) {
292788ed4aceSMatthew G Knepley   PetscErrorCode ierr;
292888ed4aceSMatthew G Knepley 
292988ed4aceSMatthew G Knepley   PetscFunctionBegin;
293088ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
293188ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
293288ed4aceSMatthew G Knepley   ierr = PetscSFDestroy(&dm->defaultSF);CHKERRQ(ierr);
293388ed4aceSMatthew G Knepley   dm->defaultSF = sf;
293488ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
293588ed4aceSMatthew G Knepley }
293688ed4aceSMatthew G Knepley 
293788ed4aceSMatthew G Knepley #undef __FUNCT__
293888ed4aceSMatthew G Knepley #define __FUNCT__ "DMCreateDefaultSF"
293988ed4aceSMatthew G Knepley /*@C
294088ed4aceSMatthew G Knepley   DMCreateDefaultSF - Create the PetscSF encoding the parallel dof overlap for the DM based upon the PetscSections
294188ed4aceSMatthew G Knepley   describing the data layout.
294288ed4aceSMatthew G Knepley 
294388ed4aceSMatthew G Knepley   Input Parameters:
294488ed4aceSMatthew G Knepley + dm - The DM
294588ed4aceSMatthew G Knepley . localSection - PetscSection describing the local data layout
294688ed4aceSMatthew G Knepley - globalSection - PetscSection describing the global data layout
294788ed4aceSMatthew G Knepley 
294888ed4aceSMatthew G Knepley   Level: intermediate
294988ed4aceSMatthew G Knepley 
295088ed4aceSMatthew G Knepley .seealso: DMGetDefaultSF(), DMSetDefaultSF()
295188ed4aceSMatthew G Knepley @*/
295288ed4aceSMatthew G Knepley PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection localSection, PetscSection globalSection)
295388ed4aceSMatthew G Knepley {
295488ed4aceSMatthew G Knepley   MPI_Comm        comm = ((PetscObject) dm)->comm;
295588ed4aceSMatthew G Knepley   PetscLayout     layout;
295688ed4aceSMatthew G Knepley   const PetscInt *ranges;
295788ed4aceSMatthew G Knepley   PetscInt       *local;
295888ed4aceSMatthew G Knepley   PetscSFNode    *remote;
295988ed4aceSMatthew G Knepley   PetscInt        pStart, pEnd, p, nroots, nleaves, l;
296088ed4aceSMatthew G Knepley   PetscMPIInt     size, rank;
296188ed4aceSMatthew G Knepley   PetscErrorCode  ierr;
296288ed4aceSMatthew G Knepley 
296388ed4aceSMatthew G Knepley   PetscFunctionBegin;
296488ed4aceSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
296588ed4aceSMatthew G Knepley   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
296688ed4aceSMatthew G Knepley   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
296788ed4aceSMatthew G Knepley   ierr = PetscSectionGetChart(globalSection, &pStart, &pEnd);CHKERRQ(ierr);
296888ed4aceSMatthew G Knepley   ierr = PetscSectionGetConstrainedStorageSize(globalSection, &nroots);CHKERRQ(ierr);
296988ed4aceSMatthew G Knepley   ierr = PetscLayoutCreate(comm, &layout);CHKERRQ(ierr);
297088ed4aceSMatthew G Knepley   ierr = PetscLayoutSetBlockSize(layout, 1);CHKERRQ(ierr);
297188ed4aceSMatthew G Knepley   ierr = PetscLayoutSetLocalSize(layout, nroots);CHKERRQ(ierr);
297288ed4aceSMatthew G Knepley   ierr = PetscLayoutSetUp(layout);CHKERRQ(ierr);
297388ed4aceSMatthew G Knepley   ierr = PetscLayoutGetRanges(layout, &ranges);CHKERRQ(ierr);
297488ed4aceSMatthew G Knepley   for (p = pStart, nleaves = 0; p < pEnd; ++p) {
29756636e97aSMatthew G Knepley     PetscInt gdof, gcdof;
297688ed4aceSMatthew G Knepley 
29776636e97aSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
29786636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
29796636e97aSMatthew G Knepley     nleaves += gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
298088ed4aceSMatthew G Knepley   }
298188ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscInt), &local);CHKERRQ(ierr);
298288ed4aceSMatthew G Knepley   ierr = PetscMalloc(nleaves * sizeof(PetscSFNode), &remote);CHKERRQ(ierr);
298388ed4aceSMatthew G Knepley   for (p = pStart, l = 0; p < pEnd; ++p) {
29841f588964SMatthew G Knepley     const PetscInt *cind;
29856636e97aSMatthew G Knepley     PetscInt        dof, cdof, off, gdof, gcdof, goff, gsize, d, c;
298688ed4aceSMatthew G Knepley 
298788ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(localSection, p, &dof);CHKERRQ(ierr);
298888ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(localSection, p, &off);CHKERRQ(ierr);
298988ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(localSection, p, &cdof);CHKERRQ(ierr);
299088ed4aceSMatthew G Knepley     ierr = PetscSectionGetConstraintIndices(localSection, p, &cind);CHKERRQ(ierr);
299188ed4aceSMatthew G Knepley     ierr = PetscSectionGetDof(globalSection, p, &gdof);CHKERRQ(ierr);
29926636e97aSMatthew G Knepley     ierr = PetscSectionGetConstraintDof(globalSection, p, &gcdof);CHKERRQ(ierr);
299388ed4aceSMatthew G Knepley     ierr = PetscSectionGetOffset(globalSection, p, &goff);CHKERRQ(ierr);
29946636e97aSMatthew G Knepley     if (!gdof) continue; /* Censored point */
29956636e97aSMatthew G Knepley     gsize = gdof < 0 ? -(gdof+1)-gcdof : gdof-gcdof;
29966636e97aSMatthew G Knepley     if (gsize != dof-cdof) {
2997057b4bcdSMatthew 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);
29986636e97aSMatthew G Knepley       cdof = 0; /* Ignore constraints */
29996636e97aSMatthew G Knepley     }
300088ed4aceSMatthew G Knepley     for (d = 0, c = 0; d < dof; ++d) {
300188ed4aceSMatthew G Knepley       if ((c < cdof) && (cind[c] == d)) {++c; continue;}
300288ed4aceSMatthew G Knepley       local[l+d-c] = off+d;
300388ed4aceSMatthew G Knepley     }
300488ed4aceSMatthew G Knepley     if (gdof < 0) {
30056636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
300688ed4aceSMatthew G Knepley         PetscInt offset = -(goff+1) + d, r;
300788ed4aceSMatthew G Knepley 
300831d3f06eSJed Brown         ierr = PetscFindInt(offset,size,ranges,&r);CHKERRQ(ierr);
300931d3f06eSJed Brown         if (r < 0) r = -(r+2);
301088ed4aceSMatthew G Knepley         remote[l].rank  = r;
301188ed4aceSMatthew G Knepley         remote[l].index = offset - ranges[r];
301288ed4aceSMatthew G Knepley       }
301388ed4aceSMatthew G Knepley     } else {
30146636e97aSMatthew G Knepley       for(d = 0; d < gsize; ++d, ++l) {
301588ed4aceSMatthew G Knepley         remote[l].rank  = rank;
301688ed4aceSMatthew G Knepley         remote[l].index = goff+d - ranges[rank];
301788ed4aceSMatthew G Knepley       }
301888ed4aceSMatthew G Knepley     }
301988ed4aceSMatthew G Knepley   }
30206636e97aSMatthew G Knepley   if (l != nleaves) SETERRQ2(comm, PETSC_ERR_PLIB, "Iteration error, l %d != nleaves %d", l, nleaves);
302188ed4aceSMatthew G Knepley   ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr);
302288ed4aceSMatthew G Knepley   ierr = PetscSFSetGraph(dm->defaultSF, nroots, nleaves, local, PETSC_OWN_POINTER, remote, PETSC_OWN_POINTER);CHKERRQ(ierr);
302388ed4aceSMatthew G Knepley   PetscFunctionReturn(0);
302488ed4aceSMatthew G Knepley }
3025af122d2aSMatthew G Knepley 
3026af122d2aSMatthew G Knepley #undef __FUNCT__
3027b21d0597SMatthew G Knepley #define __FUNCT__ "DMGetPointSF"
3028b21d0597SMatthew G Knepley /*@
3029b21d0597SMatthew G Knepley   DMGetPointSF - Get the PetscSF encoding the parallel section point overlap for the DM.
3030b21d0597SMatthew G Knepley 
3031b21d0597SMatthew G Knepley   Input Parameter:
3032b21d0597SMatthew G Knepley . dm - The DM
3033b21d0597SMatthew G Knepley 
3034b21d0597SMatthew G Knepley   Output Parameter:
3035b21d0597SMatthew G Knepley . sf - The PetscSF
3036b21d0597SMatthew G Knepley 
3037b21d0597SMatthew G Knepley   Level: intermediate
3038b21d0597SMatthew G Knepley 
3039b21d0597SMatthew G Knepley   Note: This gets a borrowed reference, so the user should not destroy this PetscSF.
3040b21d0597SMatthew G Knepley 
3041057b4bcdSMatthew G Knepley .seealso: DMSetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3042b21d0597SMatthew G Knepley @*/
3043b21d0597SMatthew G Knepley PetscErrorCode DMGetPointSF(DM dm, PetscSF *sf) {
3044b21d0597SMatthew G Knepley   PetscFunctionBegin;
3045b21d0597SMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3046b21d0597SMatthew G Knepley   PetscValidPointer(sf, 2);
3047b21d0597SMatthew G Knepley   *sf = dm->sf;
3048b21d0597SMatthew G Knepley   PetscFunctionReturn(0);
3049b21d0597SMatthew G Knepley }
3050b21d0597SMatthew G Knepley 
3051b21d0597SMatthew G Knepley #undef __FUNCT__
3052057b4bcdSMatthew G Knepley #define __FUNCT__ "DMSetPointSF"
3053057b4bcdSMatthew G Knepley /*@
3054057b4bcdSMatthew G Knepley   DMSetPointSF - Set the PetscSF encoding the parallel section point overlap for the DM.
3055057b4bcdSMatthew G Knepley 
3056057b4bcdSMatthew G Knepley   Input Parameters:
3057057b4bcdSMatthew G Knepley + dm - The DM
3058057b4bcdSMatthew G Knepley - sf - The PetscSF
3059057b4bcdSMatthew G Knepley 
3060057b4bcdSMatthew G Knepley   Level: intermediate
3061057b4bcdSMatthew G Knepley 
3062057b4bcdSMatthew G Knepley .seealso: DMGetPointSF(), DMGetDefaultSF(), DMSetDefaultSF(), DMCreateDefaultSF()
3063057b4bcdSMatthew G Knepley @*/
3064057b4bcdSMatthew G Knepley PetscErrorCode DMSetPointSF(DM dm, PetscSF sf) {
3065057b4bcdSMatthew G Knepley   PetscErrorCode ierr;
3066057b4bcdSMatthew G Knepley 
3067057b4bcdSMatthew G Knepley   PetscFunctionBegin;
3068057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3069057b4bcdSMatthew G Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1);
3070057b4bcdSMatthew G Knepley   ierr = PetscSFDestroy(&dm->sf);CHKERRQ(ierr);
3071057b4bcdSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) sf);CHKERRQ(ierr);
3072057b4bcdSMatthew G Knepley   dm->sf = sf;
3073057b4bcdSMatthew G Knepley   PetscFunctionReturn(0);
3074057b4bcdSMatthew G Knepley }
3075057b4bcdSMatthew G Knepley 
3076057b4bcdSMatthew G Knepley #undef __FUNCT__
3077af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetNumFields"
3078af122d2aSMatthew G Knepley PetscErrorCode DMGetNumFields(DM dm, PetscInt *numFields)
3079af122d2aSMatthew G Knepley {
3080af122d2aSMatthew G Knepley   PetscFunctionBegin;
3081af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3082af122d2aSMatthew G Knepley   PetscValidPointer(numFields, 2);
3083af122d2aSMatthew G Knepley   *numFields = dm->numFields;
3084af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3085af122d2aSMatthew G Knepley }
3086af122d2aSMatthew G Knepley 
3087af122d2aSMatthew G Knepley #undef __FUNCT__
3088af122d2aSMatthew G Knepley #define __FUNCT__ "DMSetNumFields"
3089af122d2aSMatthew G Knepley PetscErrorCode DMSetNumFields(DM dm, PetscInt numFields)
3090af122d2aSMatthew G Knepley {
3091af122d2aSMatthew G Knepley   PetscInt       f;
3092af122d2aSMatthew G Knepley   PetscErrorCode ierr;
3093af122d2aSMatthew G Knepley 
3094af122d2aSMatthew G Knepley   PetscFunctionBegin;
3095af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3096af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3097af122d2aSMatthew G Knepley     ierr = PetscObjectDestroy(&dm->fields[f]);CHKERRQ(ierr);
3098af122d2aSMatthew G Knepley   }
3099af122d2aSMatthew G Knepley   ierr = PetscFree(dm->fields);CHKERRQ(ierr);
3100af122d2aSMatthew G Knepley   dm->numFields = numFields;
3101af122d2aSMatthew G Knepley   ierr = PetscMalloc(dm->numFields * sizeof(PetscObject), &dm->fields);CHKERRQ(ierr);
3102af122d2aSMatthew G Knepley   for (f = 0; f < dm->numFields; ++f) {
3103af122d2aSMatthew G Knepley     ierr = PetscContainerCreate(((PetscObject) dm)->comm, (PetscContainer *) &dm->fields[f]);CHKERRQ(ierr);
3104af122d2aSMatthew G Knepley   }
3105af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3106af122d2aSMatthew G Knepley }
3107af122d2aSMatthew G Knepley 
3108af122d2aSMatthew G Knepley #undef __FUNCT__
3109af122d2aSMatthew G Knepley #define __FUNCT__ "DMGetField"
3110af122d2aSMatthew G Knepley PetscErrorCode DMGetField(DM dm, PetscInt f, PetscObject *field)
3111af122d2aSMatthew G Knepley {
3112af122d2aSMatthew G Knepley   PetscFunctionBegin;
3113af122d2aSMatthew G Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3114af122d2aSMatthew G Knepley   PetscValidPointer(field, 2);
3115af122d2aSMatthew G Knepley   if (!dm->fields) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Fields have not been setup in this DM. Call DMSetNumFields()");
3116af122d2aSMatthew 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);
3117af122d2aSMatthew G Knepley   *field = dm->fields[f];
3118af122d2aSMatthew G Knepley   PetscFunctionReturn(0);
3119af122d2aSMatthew G Knepley }
31206636e97aSMatthew G Knepley 
31216636e97aSMatthew G Knepley #undef __FUNCT__
31226636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinates"
31236636e97aSMatthew G Knepley /*@
31246636e97aSMatthew G Knepley   DMSetCoordinates - Sets into the DM a global vector that holds the coordinates
31256636e97aSMatthew G Knepley 
31266636e97aSMatthew G Knepley   Collective on DM
31276636e97aSMatthew G Knepley 
31286636e97aSMatthew G Knepley   Input Parameters:
31296636e97aSMatthew G Knepley + dm - the DM
31306636e97aSMatthew G Knepley - c - coordinate vector
31316636e97aSMatthew G Knepley 
31326636e97aSMatthew G Knepley   Note:
31336636e97aSMatthew G Knepley   The coordinates do include those for ghost points, which are in the local vector
31346636e97aSMatthew G Knepley 
31356636e97aSMatthew G Knepley   Level: intermediate
31366636e97aSMatthew G Knepley 
31376636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
31386636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLoca(), DMGetCoordinateDM()
31396636e97aSMatthew G Knepley @*/
31406636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinates(DM dm, Vec c)
31416636e97aSMatthew G Knepley {
31426636e97aSMatthew G Knepley   PetscErrorCode ierr;
31436636e97aSMatthew G Knepley 
31446636e97aSMatthew G Knepley   PetscFunctionBegin;
31456636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31466636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
31476636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
31486636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
31496636e97aSMatthew G Knepley   dm->coordinates = c;
31506636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
31516636e97aSMatthew G Knepley   PetscFunctionReturn(0);
31526636e97aSMatthew G Knepley }
31536636e97aSMatthew G Knepley 
31546636e97aSMatthew G Knepley #undef __FUNCT__
31556636e97aSMatthew G Knepley #define __FUNCT__ "DMSetCoordinatesLocal"
31566636e97aSMatthew G Knepley /*@
31576636e97aSMatthew G Knepley   DMSetCoordinatesLocal - Sets into the DM a local vector that holds the coordinates
31586636e97aSMatthew G Knepley 
31596636e97aSMatthew G Knepley   Collective on DM
31606636e97aSMatthew G Knepley 
31616636e97aSMatthew G Knepley    Input Parameters:
31626636e97aSMatthew G Knepley +  dm - the DM
31636636e97aSMatthew G Knepley -  c - coordinate vector
31646636e97aSMatthew G Knepley 
31656636e97aSMatthew G Knepley   Note:
31666636e97aSMatthew G Knepley   The coordinates of ghost points can be set using DMSetCoordinates()
31676636e97aSMatthew G Knepley   followed by DMGetCoordinatesLocal(). This is intended to enable the
31686636e97aSMatthew G Knepley   setting of ghost coordinates outside of the domain.
31696636e97aSMatthew G Knepley 
31706636e97aSMatthew G Knepley   Level: intermediate
31716636e97aSMatthew G Knepley 
31726636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
31736636e97aSMatthew G Knepley .seealso: DMGetCoordinatesLocal(), DMSetCoordinates(), DMGetCoordinates(), DMGetCoordinateDM()
31746636e97aSMatthew G Knepley @*/
31756636e97aSMatthew G Knepley PetscErrorCode DMSetCoordinatesLocal(DM dm, Vec c)
31766636e97aSMatthew G Knepley {
31776636e97aSMatthew G Knepley   PetscErrorCode ierr;
31786636e97aSMatthew G Knepley 
31796636e97aSMatthew G Knepley   PetscFunctionBegin;
31806636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
31816636e97aSMatthew G Knepley   PetscValidHeaderSpecific(c,VEC_CLASSID,2);
31826636e97aSMatthew G Knepley   ierr = PetscObjectReference((PetscObject) c);CHKERRQ(ierr);
31836636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinatesLocal);CHKERRQ(ierr);
31846636e97aSMatthew G Knepley   dm->coordinatesLocal = c;
31856636e97aSMatthew G Knepley   ierr = VecDestroy(&dm->coordinates);CHKERRQ(ierr);
31866636e97aSMatthew G Knepley   PetscFunctionReturn(0);
31876636e97aSMatthew G Knepley }
31886636e97aSMatthew G Knepley 
31896636e97aSMatthew G Knepley #undef __FUNCT__
31906636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinates"
31916636e97aSMatthew G Knepley /*@
31926636e97aSMatthew G Knepley   DMGetCoordinates - Gets a global vector with the coordinates associated with the DM.
31936636e97aSMatthew G Knepley 
31946636e97aSMatthew G Knepley   Not Collective
31956636e97aSMatthew G Knepley 
31966636e97aSMatthew G Knepley   Input Parameter:
31976636e97aSMatthew G Knepley . dm - the DM
31986636e97aSMatthew G Knepley 
31996636e97aSMatthew G Knepley   Output Parameter:
32006636e97aSMatthew G Knepley . c - global coordinate vector
32016636e97aSMatthew G Knepley 
32026636e97aSMatthew G Knepley   Note:
32036636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
32046636e97aSMatthew G Knepley 
32056636e97aSMatthew G Knepley   Each process has only the local coordinates (does NOT have the ghost coordinates).
32066636e97aSMatthew G Knepley 
32076636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
32086636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
32096636e97aSMatthew G Knepley 
32106636e97aSMatthew G Knepley   Level: intermediate
32116636e97aSMatthew G Knepley 
32126636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
32136636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMGetCoordinatesLocal(), DMGetCoordinateDM()
32146636e97aSMatthew G Knepley @*/
32156636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinates(DM dm, Vec *c)
32166636e97aSMatthew G Knepley {
32176636e97aSMatthew G Knepley   PetscErrorCode ierr;
32186636e97aSMatthew G Knepley 
32196636e97aSMatthew G Knepley   PetscFunctionBegin;
32206636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32216636e97aSMatthew G Knepley   PetscValidPointer(c,2);
32221f588964SMatthew G Knepley   if (!dm->coordinates && dm->coordinatesLocal) {
322387743a01SMatthew G Knepley     DM cdm = PETSC_NULL;
32246636e97aSMatthew G Knepley 
32256636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
32266636e97aSMatthew G Knepley     ierr = DMCreateGlobalVector(cdm, &dm->coordinates);CHKERRQ(ierr);
32276636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinates, "coordinates");CHKERRQ(ierr);
32286636e97aSMatthew G Knepley     ierr = DMLocalToGlobalBegin(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
32296636e97aSMatthew G Knepley     ierr = DMLocalToGlobalEnd(cdm, dm->coordinatesLocal, INSERT_VALUES, dm->coordinates);CHKERRQ(ierr);
32306636e97aSMatthew G Knepley   }
32316636e97aSMatthew G Knepley   *c = dm->coordinates;
32326636e97aSMatthew G Knepley   PetscFunctionReturn(0);
32336636e97aSMatthew G Knepley }
32346636e97aSMatthew G Knepley 
32356636e97aSMatthew G Knepley #undef __FUNCT__
32366636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinatesLocal"
32376636e97aSMatthew G Knepley /*@
32386636e97aSMatthew G Knepley   DMGetCoordinatesLocal - Gets a local vector with the coordinates associated with the DM.
32396636e97aSMatthew G Knepley 
32406636e97aSMatthew G Knepley   Collective on DM
32416636e97aSMatthew G Knepley 
32426636e97aSMatthew G Knepley   Input Parameter:
32436636e97aSMatthew G Knepley . dm - the DM
32446636e97aSMatthew G Knepley 
32456636e97aSMatthew G Knepley   Output Parameter:
32466636e97aSMatthew G Knepley . c - coordinate vector
32476636e97aSMatthew G Knepley 
32486636e97aSMatthew G Knepley   Note:
32496636e97aSMatthew G Knepley   This is a borrowed reference, so the user should NOT destroy this vector
32506636e97aSMatthew G Knepley 
32516636e97aSMatthew G Knepley   Each process has the local and ghost coordinates
32526636e97aSMatthew G Knepley 
32536636e97aSMatthew G Knepley   For DMDA, in two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...)
32546636e97aSMatthew G Knepley   and (x_0,y_0,z_0,x_1,y_1,z_1...)
32556636e97aSMatthew G Knepley 
32566636e97aSMatthew G Knepley   Level: intermediate
32576636e97aSMatthew G Knepley 
32586636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
32596636e97aSMatthew G Knepley .seealso: DMSetCoordinatesLocal(), DMGetCoordinates(), DMSetCoordinates(), DMGetCoordinateDM()
32606636e97aSMatthew G Knepley @*/
32616636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinatesLocal(DM dm, Vec *c)
32626636e97aSMatthew G Knepley {
32636636e97aSMatthew G Knepley   PetscErrorCode ierr;
32646636e97aSMatthew G Knepley 
32656636e97aSMatthew G Knepley   PetscFunctionBegin;
32666636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
32676636e97aSMatthew G Knepley   PetscValidPointer(c,2);
32681f588964SMatthew G Knepley   if (!dm->coordinatesLocal && dm->coordinates) {
326987743a01SMatthew G Knepley     DM cdm = PETSC_NULL;
32706636e97aSMatthew G Knepley 
32716636e97aSMatthew G Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
32726636e97aSMatthew G Knepley     ierr = DMCreateLocalVector(cdm, &dm->coordinatesLocal);CHKERRQ(ierr);
32736636e97aSMatthew G Knepley     ierr = PetscObjectSetName((PetscObject) dm->coordinatesLocal, "coordinates");CHKERRQ(ierr);
32746636e97aSMatthew G Knepley     ierr = DMGlobalToLocalBegin(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
32756636e97aSMatthew G Knepley     ierr = DMGlobalToLocalEnd(cdm, dm->coordinates, INSERT_VALUES, dm->coordinatesLocal);CHKERRQ(ierr);
32766636e97aSMatthew G Knepley   }
32776636e97aSMatthew G Knepley   *c = dm->coordinatesLocal;
32786636e97aSMatthew G Knepley   PetscFunctionReturn(0);
32796636e97aSMatthew G Knepley }
32806636e97aSMatthew G Knepley 
32816636e97aSMatthew G Knepley #undef __FUNCT__
32826636e97aSMatthew G Knepley #define __FUNCT__ "DMGetCoordinateDM"
32836636e97aSMatthew G Knepley /*@
32846636e97aSMatthew G Knepley   DMGetCoordinateDM - Gets the DM that scatters between global and local coordinates
32856636e97aSMatthew G Knepley 
32866636e97aSMatthew G Knepley   Collective on DM
32876636e97aSMatthew G Knepley 
32886636e97aSMatthew G Knepley   Input Parameter:
32896636e97aSMatthew G Knepley . dm - the DM
32906636e97aSMatthew G Knepley 
32916636e97aSMatthew G Knepley   Output Parameter:
32926636e97aSMatthew G Knepley . cdm - coordinate DM
32936636e97aSMatthew G Knepley 
32946636e97aSMatthew G Knepley   Level: intermediate
32956636e97aSMatthew G Knepley 
32966636e97aSMatthew G Knepley .keywords: distributed array, get, corners, nodes, local indices, coordinates
32976636e97aSMatthew G Knepley .seealso: DMSetCoordinates(), DMSetCoordinatesLocal(), DMGetCoordinates(), DMGetCoordinatesLocal()
32986636e97aSMatthew G Knepley @*/
32996636e97aSMatthew G Knepley PetscErrorCode DMGetCoordinateDM(DM dm, DM *cdm)
33006636e97aSMatthew G Knepley {
33016636e97aSMatthew G Knepley   PetscErrorCode ierr;
33026636e97aSMatthew G Knepley 
33036636e97aSMatthew G Knepley   PetscFunctionBegin;
33046636e97aSMatthew G Knepley   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
33056636e97aSMatthew G Knepley   PetscValidPointer(cdm,2);
33066636e97aSMatthew G Knepley   if (!dm->coordinateDM) {
33076636e97aSMatthew G Knepley     if (!dm->ops->createcoordinatedm) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Unable to create coordinates for this DM");
33086636e97aSMatthew G Knepley     ierr = (*dm->ops->createcoordinatedm)(dm, &dm->coordinateDM);CHKERRQ(ierr);
33096636e97aSMatthew G Knepley   }
33106636e97aSMatthew G Knepley   *cdm = dm->coordinateDM;
33116636e97aSMatthew G Knepley   PetscFunctionReturn(0);
33126636e97aSMatthew G Knepley }
3313